* [PATCH 02/20] tlsf_malloc: drop duplicate include
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-07 7:37 ` Sascha Hauer
2013-03-06 9:29 ` [PATCH 03/20] kbuild: add application (app) target Jean-Christophe PLAGNIOL-VILLARD
` (17 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
config.h is not need and already inclued by Makefile
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
common/tlsf_malloc.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
index 5c5bb61..cd01b56 100644
--- a/common/tlsf_malloc.c
+++ b/common/tlsf_malloc.c
@@ -17,10 +17,8 @@
*
*/
-#include <config.h>
#include <malloc.h>
#include <string.h>
-#include <malloc.h>
#include <stdio.h>
#include <module.h>
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 02/20] tlsf_malloc: drop duplicate include
2013-03-06 9:29 ` [PATCH 02/20] tlsf_malloc: drop duplicate include Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-07 7:37 ` Sascha Hauer
0 siblings, 0 replies; 31+ messages in thread
From: Sascha Hauer @ 2013-03-07 7:37 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Wed, Mar 06, 2013 at 10:29:31AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> config.h is not need and already inclued by Makefile
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Applied, thanks
Sascha
> ---
> common/tlsf_malloc.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
> index 5c5bb61..cd01b56 100644
> --- a/common/tlsf_malloc.c
> +++ b/common/tlsf_malloc.c
> @@ -17,10 +17,8 @@
> *
> */
>
> -#include <config.h>
> #include <malloc.h>
> #include <string.h>
> -#include <malloc.h>
>
> #include <stdio.h>
> #include <module.h>
> --
> 1.7.10.4
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 03/20] kbuild: add application (app) target
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 02/20] tlsf_malloc: drop duplicate include Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 04/20] Introduce application (app) support Jean-Christophe PLAGNIOL-VILLARD
` (16 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
This will allow to link compiled object (app-y) to the built-in-app.o across the source
tree that will be finally link to the applications (app-final-y).
Now we compile the source %.c in app-%.o and provide -D__APP__
so we can known in the source when it's compile for barebox or pbl or app.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
Makefile | 5 +++-
scripts/Makefile.build | 78 +++++++++++++++++++++++++++++++++++++++++++++---
scripts/Makefile.lib | 23 ++++++++++++--
3 files changed, 99 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index 4df6464..110f7aa 100644
--- a/Makefile
+++ b/Makefile
@@ -493,6 +493,7 @@ barebox-alldirs := $(sort $(barebox-dirs) $(patsubst %/,%,$(filter %/, \
$(core-n) $(core-) $(drivers-n) $(drivers-) \
$(net-n) $(net-) $(libs-n) $(libs-))))
+app-common-y := $(patsubst %/, %/built-in-app.o, $(common-y))
pbl-common-y := $(patsubst %/, %/built-in-pbl.o, $(common-y))
common-y := $(patsubst %/, %/built-in.o, $(common-y))
@@ -523,6 +524,8 @@ common-y := $(patsubst %/, %/built-in.o, $(common-y))
# System.map is generated to document addresses of all kernel symbols
barebox-common := $(common-y)
+barebox-app-common := $(app-common-y)
+export barebox-app-common
barebox-pbl-common := $(pbl-common-y)
export barebox-pbl-common
barebox-all := $(barebox-common)
@@ -733,7 +736,7 @@ barebox.srec: barebox
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
-$(sort $(barebox-head) $(barebox-common) ) $(barebox-lds) $(barebox-pbl-common): $(barebox-dirs) ;
+$(sort $(barebox-head) $(barebox-common) ) $(barebox-lds) $(barebox-pbl-common) $(barebox-app-common): $(barebox-dirs) ;
# Handle descending into subdirectories listed in $(barebox-dirs)
# Preset locale variables to speed up the build process. Limit locale
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index a95bbe4..600d1f7 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -15,6 +15,8 @@ obj-m :=
lib-y :=
lib-m :=
pbl-y :=
+app-y :=
+app-final-y :=
always :=
targets :=
subdir-y :=
@@ -98,7 +100,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
lib-target := $(obj)/lib.a
endif
-ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target) $(pbl-y)),)
+ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target) $(pbl-y) $(app-y)),)
builtin-target := $(obj)/built-in.o
endif
@@ -108,11 +110,23 @@ pbl-target := $(obj)/built-in-pbl.o
endif
endif
+ifeq ($(CONFIG_APPLICATIONS), y)
+ifneq ($(strip $(app-y) $(builtin-target)),)
+app-target := $(obj)/built-in-app.o
+endif
+
+ifneq ($(strip $(app-final-y)),)
+app-final-target := $(addprefix $(obj)/,$(app-final-y))
+app-final-bin-target := $(addsuffix .app,$(app-final-bin-target))
+endif
+
+endif
+
# We keep a list of all modules in $(MODVERDIR)
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(pbl-target) $(extra-y)) \
+__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(pbl-target) $(app-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- $(subdir-ym) $(always)
+ $(subdir-ym) $(always) $(app-final-target) $(app-final-bin-target)
@:
# Linus' kernel sanity checking tool
@@ -185,10 +199,12 @@ cmd_cc_symtypes_c = \
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
quiet_cmd_pbl_cc_o_c = PBLCC $@
+quiet_cmd_app_cc_o_c = APPCC $@
ifndef CONFIG_MODVERSIONS
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
cmd_pbl_cc_o_c = $(CC) -D__PBL__ $(c_flags) $(PBL_CPPFLAGS) -c -o $@ $<
+cmd_app_cc_o_c = $(CC) -D__APP__ $(APP_CPPFLAGS) $(app_c_flags) -c -o $@ $<
else
# When module versioning is enabled the following steps are executed:
@@ -239,8 +255,23 @@ define rule_pbl_cc_o_c
mv -f $(dot-target).tmp $(dot-target).cmd
endef
+define rule_app_cc_o_c
+ $(call echo-cmd,checksrc) $(cmd_checksrc) \
+ $(call echo-cmd,app_cc_o_c) $(cmd_app_cc_o_c); \
+ $(cmd_modversions) \
+ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,app_cc__o_c)' > \
+ $(dot-target).tmp; \
+ rm -f $(depfile); \
+ mv -f $(dot-target).tmp $(dot-target).cmd
+
+endef
+
# Built-in and composite module parts
+app-%.o: %.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,app_cc_o_c)
+
pbl-%.o: %.c FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,pbl_cc_o_c)
@@ -284,13 +315,19 @@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
quiet_cmd_pbl_as_o_S = PBLAS $@
cmd_pbl_as_o_S = $(CC) -D__PBL__ $(a_flags) $(PBL_CPPFLAGS) -c -o $@ $<
+quiet_cmd_app_as_o_S = APPAS $@
+cmd_app_as_o_S = $(CC) -D__APP__ $(app_a_flags) $(APP_CPPFLAGS) -c -o $@ $<
+
+app-%.o: %.S FORCE
+ $(call if_changed_dep,app_as_o_S)
+
pbl-%.o: %.S FORCE
$(call if_changed_dep,pbl_as_o_S)
%.o: %.S FORCE
$(call if_changed_dep,as_o_S)
-targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(pbl-y)
+targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(pbl-y) $(app-y)
targets += $(extra-y) $(MAKECMDGOALS) $(always)
# Linker scripts preprocessor (.lds.S -> .lds)
@@ -336,6 +373,39 @@ $(pbl-target): $(pbl-y) FORCE
targets += $(pbl-target)
endif # pbl-target
+ifdef app-target
+quiet_cmd_app_link_o_target = APPLD $@
+# If the list of objects to link is empty, just create an empty built-in-app.o
+cmd_app_link_o_target = $(if $(strip $(app-y)),\
+ $(LD) $(app_ld_flags) -r -o $@ $(filter $(app-y), $^),\
+ rm -f $@; $(AR) rcs $@)
+
+$(app-target): $(app-y) FORCE
+ $(call if_changed,app_link_o_target)
+targets += $(app-target)
+endif # app-target
+
+ifdef app-final-target
+quiet_cmd_app_final_ld = APPLD $@
+cmd_app_final_ld = $(LD) $(LDFLAGS) $(LDFLAGS_apps) -o $@ \
+ -T $(apps-lds) \
+ --start-group $(filter-out $(apps-lds) $(barebox-app-common) FORCE ,$^) \
+ $(barebox-app-common) --end-group $(APP_LDFLAGS) \
+ $(filter-out $(apps-lds) $^ $(barebox-app-common) FORCE ,$^)
+
+$(app-final-target): $(obj)/built-in-app.o FORCE
+ $(call if_changed,app_final_ld)
+
+%.app: % FORCE
+ $(call if_changed,objcopy)
+ $(Q)$(kecho) ' Barebox Apps: $@ is ready'
+
+$(app-final-bin-target): $(app-final-target) FORCE
+
+targets += $(app-final-target)
+targets += $(app-final-bin-target)
+endif # app-target
+
#
# Rule to compile a set of .o files into one .a file
#
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 7bb769b..90bf72b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -40,6 +40,17 @@ pbl-y += $(__pbl-y)
pbl-y := $(sort $(patsubst %/, %/built-in-pbl.o, $(pbl-y)))
+# for non dirs add app- prefix to the target
+# so we recompile the source with custom flags and custom quiet
+__app-y := $(notdir $(app-y))
+app-y := $(patsubst %.o,app-%.o,$(__app-y))
+# add subdir from $(obj-y) and $(pbl-y)too so we do not need to have the dir define in
+# both $(obj-y) and $(pbl-y) and $(app-y)
+__app-y := $(filter-out $(app-y), $(filter %/, $(sort $(obj-y) $(pbl-y))))
+app-y += $(__app-y)
+
+app-y := $(sort $(patsubst %/, %/built-in-app.o, $(app-y)))
+
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
@@ -65,9 +76,11 @@ multi-objs := $(multi-objs-y) $(multi-objs-m)
# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
# tell kbuild to descend
-__subdir-obj-y := $(filter %/built-in-pbl.o, $(pbl-y))
+__subdir-pbl-y := $(filter %/built-in-pbl.o, $(pbl-y))
+__subdir-app-y := $(filter %/built-in-app.o, $(app-y))
subdir-obj-y := $(filter %/built-in.o, $(obj-y))
-subdir-obj-y += $(__subdir-obj-y)
+subdir-obj-y += $(__subdir-pbl-y)
+subdir-obj-y += $(__subdir-app-y)
# $(obj-dirs) is a list of directories that contain object files
obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
@@ -85,6 +98,7 @@ obj-y := $(addprefix $(obj)/,$(obj-y))
obj-m := $(addprefix $(obj)/,$(obj-m))
lib-y := $(addprefix $(obj)/,$(lib-y))
pbl-y := $(addprefix $(obj)/,$(pbl-y))
+app-y := $(addprefix $(obj)/,$(app-y))
subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
@@ -141,6 +155,11 @@ ___cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
___ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
+app_c_flags = $(APPINCLUDE) $(___c_flags)
+app_a_flags = $(APPINCLUDE) -D__ASSEMBLY__ $(___a_flags)
+app_cpp_flags = $(APPINCLUDE) $(___cpp_flags)
+app_ld_flags = $(___ld_flags)
+
c_flags = $(LINUXINCLUDE) $(___c_flags)
a_flags = $(LINUXINCLUDE) $(AFLAGS_LINUXINCLUDE) $(___a_flags)
cpp_flags = $(LINUXINCLUDE) $(___cpp_flags)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 04/20] Introduce application (app) support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 02/20] tlsf_malloc: drop duplicate include Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 03/20] kbuild: add application (app) target Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 05/20] app: Introduce libc support Jean-Christophe PLAGNIOL-VILLARD
` (15 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
Makefile | 47 ++++-
apps/Kconfig | 21 +++
apps/Makefile | 19 ++
apps/include/appinfo.h | 58 ++++++
arch/arm/Kconfig | 1 +
commands/Kconfig | 7 +
commands/Makefile | 1 +
commands/appinfo.c | 119 +++++++++++++
common/Kconfig | 3 +
include/apps/syscall_init.h | 23 +++
include/apps/syscalls.h | 76 ++++++++
include/apps/types.h | 24 +++
include/linux/license.h | 14 ++
lib/Makefile | 1 +
lib/apps/Makefile | 1 +
lib/apps/syscalls.c | 413 +++++++++++++++++++++++++++++++++++++++++++
16 files changed, 825 insertions(+), 3 deletions(-)
create mode 100644 apps/Kconfig
create mode 100644 apps/Makefile
create mode 100644 apps/include/appinfo.h
create mode 100644 commands/appinfo.c
create mode 100644 include/apps/syscall_init.h
create mode 100644 include/apps/syscalls.h
create mode 100644 include/apps/types.h
create mode 100644 include/linux/license.h
create mode 100644 lib/apps/Makefile
create mode 100644 lib/apps/syscalls.c
diff --git a/Makefile b/Makefile
index 110f7aa..706a1d4 100644
--- a/Makefile
+++ b/Makefile
@@ -297,6 +297,18 @@ LINUXINCLUDE := -Iinclude \
-include include/generated/autoconf.h \
-include $(srctree)/include/linux/kconfig.h
+# Use APPINCLUDE when you must reference the include/ directory.
+# Needed to be compatible with the O= option
+APPINCLUDE := -Iapps/include \
+ $(if $(KBUILD_SRC), -I$(srctree)/apps/include) \
+ $(if $(KBUILD_SRC), -I$(objtree)/include) \
+ -I$(srctree)/arch/$(ARCH)/include \
+ -I$(objtree)/arch/$(ARCH)/include \
+ -I$(srctree)/arch/$(ARCH)/apps/include \
+ -I$(objtree)/apps/include \
+ -include include/generated/autoconf.h \
+ -include $(srctree)/include/linux/kconfig.h
+
CPPFLAGS := -D__KERNEL__ -D__BAREBOX__ -fno-builtin -ffreestanding
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
@@ -315,9 +327,10 @@ export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export AFLAGS_LINUXINCLUDE
+export APPINCLUDE AFLAGS_LINUXINCLUDE
export CFLAGS CFLAGS_KERNEL
export AFLAGS AFLAGS_KERNEL
+export APP_LDFLAGS
# Files to ignore in find ... statements
@@ -482,7 +495,18 @@ export KBUILD_BINARY ?= barebox.bin
barebox-flash-image: $(KBUILD_IMAGE) FORCE
$(call if_changed,ln)
-all: barebox-flash-image
+ifdef CONFIG_APPLICATIONS
+apps-lds := $(apps-lds-y)
+export apps-lds
+
+apps := apps
+application: barebox-flash-image
+ $(Q)$(MAKE) $(build)=$(apps) $(apps)/$@
+
+APPS-y += application
+endif
+
+all: barebox-flash-image $(APPS-y)
common-$(CONFIG_PBL_IMAGE) += pbl/
@@ -493,7 +517,7 @@ barebox-alldirs := $(sort $(barebox-dirs) $(patsubst %/,%,$(filter %/, \
$(core-n) $(core-) $(drivers-n) $(drivers-) \
$(net-n) $(net-) $(libs-n) $(libs-))))
-app-common-y := $(patsubst %/, %/built-in-app.o, $(common-y))
+app-common-y := $(patsubst %/, %/built-in-app.o, $(common-y) apps/)
pbl-common-y := $(patsubst %/, %/built-in-pbl.o, $(common-y))
common-y := $(patsubst %/, %/built-in.o, $(common-y))
@@ -840,6 +864,23 @@ ifneq ($(KBUILD_SRC),)
/bin/false; \
fi;
$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
+ $(Q)if [ ! -d apps/include ]; then mkdir -p apps/include; fi;
+ $(Q)if [ ! -d apps/include/barebox ]; then mkdir -p apps/include/barebox; fi;
+ $(Q)if [ ! -h apps/include/linux ]; then \
+ ln -fsn $(srctree)/include/linux apps/include/linux; \
+ fi;
+ $(Q)if [ ! -h apps/include/asm-generic ]; then \
+ ln -fsn $(srctree)/include/asm-generic apps/include/asm-generic; \
+ fi;
+ $(Q)if [ ! -h apps/include/generated ]; then \
+ ln -fsn $(objtree)/include/generated apps/include/generated; \
+ fi;
+ $(Q)if [ ! -e apps/include/barebox/fcntl.h ]; then \
+ ln -fsn $(srctree)/include/fcntl.h apps/include/barebox/fcntl.h; \
+ fi;
+ $(Q)if [ ! -e apps/include/barebox/types.h ]; then \
+ ln -fsn $(srctree)/include/apps/types.h apps/include/barebox/types.h; \
+ fi;
$(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/barebox.h ]; then \
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
fi
diff --git a/apps/Kconfig b/apps/Kconfig
new file mode 100644
index 0000000..92899b5
--- /dev/null
+++ b/apps/Kconfig
@@ -0,0 +1,21 @@
+menuconfig APPLICATIONS
+ bool "Applications"
+ depends on HAS_APPLICATIONS
+ depends on EXPERIMENTAL
+ help
+ This option enables support for running applications.
+
+if APPLICATIONS
+
+menu "memory layout"
+
+source "arch/$SRCARCH/apps/Kconfig"
+
+config APP_MALLOC_SIZE
+ hex
+ default 0x400000
+ prompt "malloc area size"
+
+endmenu
+
+endif
diff --git a/apps/Makefile b/apps/Makefile
new file mode 100644
index 0000000..65adfdc
--- /dev/null
+++ b/apps/Makefile
@@ -0,0 +1,19 @@
+
+CPPFLAGS += -I$(srctree)/apps/include
+
+$(obj)/application: $(apps-lds) $(apps-y)
+
+APP_CPPFLAGS += -fdata-sections -ffunction-sections
+
+$(obj)/include/types.h: $(srctree)/include/types.h
+ $(call cmd,shipped)
+
+$(obj)/include/barebox/syscalls.h: $(srctree)/include/apps/syscalls.h
+ $(call cmd,shipped)
+
+$(obj)/include/errno.h: $(srctree)/include/asm-generic/errno.h
+ $(call cmd,shipped)
+
+barebox-app-header += $(obj)/include/types.h
+barebox-app-header += $(obj)/include/errno.h
+barebox-app-header += $(obj)/include/barebox/syscalls.h
diff --git a/apps/include/appinfo.h b/apps/include/appinfo.h
new file mode 100644
index 0000000..94409d7
--- /dev/null
+++ b/apps/include/appinfo.h
@@ -0,0 +1,58 @@
+#ifndef __APPINFO_H__
+#define __APPINFO_H__
+
+/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
+#define ___PASTE(a,b) a##b
+#define __PASTE(a,b) ___PASTE(a,b)
+
+# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
+
+#define __APP_INFO(tag, name, info) \
+ static const char __UNIQUE_ID(name)[] \
+ __attribute__((__used__))\
+ __attribute__((section(".appinfo"), unused, aligned(1))) = \
+ #tag "=" info;
+
+/* Generic info of form tag = "info" */
+#define APP_INFO(tag, info) __APP_INFO(tag, tag, info)
+
+/*
+ * The following license idents are currently accepted as indicating free
+ * software applications
+*
+ * "GPL" [GNU Public License v2 or later]
+ * "GPL v2" [GNU Public License v2]
+ * "GPL and additional rights" [GNU Public License v2 rights and more]
+ * "Dual BSD/GPL" [GNU Public License v2
+ * or BSD license choice]
+ * "Dual MIT/GPL" [GNU Public License v2
+ * or MIT license choice]
+ * "Dual MPL/GPL" [GNU Public License v2
+ * or Mozilla license choice]
+ *
+ * The following other idents are available
+ *
+ * "Proprietary" [Non free products]
+ *
+ * There are dual licensed components, but when running with Linux it is
+ * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
+ * is a GPL combined work.
+ *
+ * This exists for several reasons
+ * 1. So appinfo can show license info for users wanting to vet their setup
+ * is free
+ * 2. So the community can ignore bug reports including proprietary applications
+ * 3. So vendors can do likewise based on their own policies
+ */
+
+#define APP_LICENSE(_license) APP_INFO(license, _license)
+/*
+ * Author(s), use "Name <email>" or just "Name", for multiple
+ * authors use multiple MODULE_AUTHOR() statements/lines.
+ */
+#define APP_AUTHOR(_author) APP_INFO(author, _author)
+
+/* What your application does. */
+#define APP_DESCRIPTION(_description) APP_INFO(description, _description)
+
+#endif /* __APPINFO_H__ */
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7ac134e..f25dcf7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -236,3 +236,4 @@ source drivers/Kconfig
source fs/Kconfig
source lib/Kconfig
source crypto/Kconfig
+source apps/Kconfig
diff --git a/commands/Kconfig b/commands/Kconfig
index c1454c7..b10a8c1 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -242,6 +242,13 @@ config CMD_FILETYPE
select FILETYPE
prompt "filetype"
+config CMD_APPINFO
+ tristate
+ depends on APPLICATIONS
+ prompt "appinfo"
+ help
+ dump barebox applicaion info
+
endmenu
menu "console"
diff --git a/commands/Makefile b/commands/Makefile
index 0ae6b95..b9280eb 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_CMD_APPINFO) += appinfo.o
obj-$(CONFIG_STDDEV) += stddev.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_UIMAGE) += uimage.o
diff --git a/commands/appinfo.c b/commands/appinfo.c
new file mode 100644
index 0000000..9736fce
--- /dev/null
+++ b/commands/appinfo.c
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright (c) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <errno.h>
+
+/*
+ * first search for #info and then we get the section size
+ * the #info is within the first 512 bytes of the file if present
+ */
+
+#define FILE_APP_BUF 512
+
+static int dump_apping(int fd, int offset, int size)
+{
+ char *buf, *tmp;
+ int ret;
+
+ tmp = buf = xzalloc(size);
+
+ ret = lseek(fd, offset, SEEK_SET);
+ if (ret < 0) {
+ perror("lseek");
+ goto err_out;
+ }
+
+ ret = read(fd, buf, size);
+ if (ret < 0) {
+ perror("read");
+ goto err_out;
+ }
+
+ for (; tmp < buf + size || !strcmp(tmp, "appinf#");
+ tmp += strlen(tmp) + 1) {
+ if (tstc())
+ break;
+ if (strlen(tmp) == 0)
+ break;
+ printf("%s\n", tmp);
+ }
+
+ ret = 0;
+
+err_out:
+ free(buf);
+
+ return ret;
+}
+
+static int do_appinfo(int argc, char *argv[])
+{
+ int fd;
+ char *buf, *tmp;
+ int ret = 1;
+
+ if (argc == 1)
+ return COMMAND_ERROR_USAGE;
+
+ fd = open(argv[1], O_RDONLY);
+
+ if (fd < 0) {
+ perror("open");
+ return fd;
+ }
+
+ tmp = buf = xzalloc(FILE_APP_BUF);
+
+ ret = read(fd, buf, FILE_APP_BUF);
+ if (ret < 0) {
+ perror("read");
+ goto err_out;
+ }
+
+ for (; ret-- ; ++tmp) {
+ if (*tmp != '#')
+ continue;
+
+ if (ret < 8)
+ goto no_app_info;
+
+ if (!strcmp(tmp, "#appinf")) {
+ int size = *((uint32_t*)(tmp + 8));
+ int offset = tmp - buf;
+
+ free(buf);
+ ret = dump_apping(fd, offset + 12, size);
+ goto out;
+ }
+ }
+
+no_app_info:
+ printf("no appinfo found\n");
+
+ ret = 0;
+err_out:
+ free(buf);
+out:
+ close(fd);
+
+ return ret;
+}
+
+BAREBOX_CMD_HELP_START(appinfo)
+BAREBOX_CMD_HELP_USAGE("appinfo <file>\n")
+BAREBOX_CMD_HELP_SHORT("display the barebox application information\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(appinfo)
+ .cmd = do_appinfo,
+ .usage = "display the barebox application informatio",
+ BAREBOX_CMD_HELP(cmd_appinfo_help)
+BAREBOX_CMD_END
diff --git a/common/Kconfig b/common/Kconfig
index 3a55e01..6defdbe 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -21,6 +21,9 @@ config HAS_KALLSYMS
config HAS_MODULES
bool
+config HAS_APPLICATIONS
+ bool
+
config CMD_MEMORY
bool
diff --git a/include/apps/syscall_init.h b/include/apps/syscall_init.h
new file mode 100644
index 0000000..4c496ef
--- /dev/null
+++ b/include/apps/syscall_init.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __APPS_SYSCALL_INIT_H__
+#define __APPS_SYSCALL_INIT_H__
+
+#include <types.h>
+
+struct syscall_trace {
+ struct list_head dirs;
+ struct list_head fds;
+ void *dest;
+ uint64_t malloc_base;
+ uint32_t malloc_size;
+};
+
+void syscalls_init(struct syscall_trace *t);
+void syscalls_exit(struct syscall_trace *t);
+
+#endif /* __APPS_SYSCALL_INIT_H__ */
diff --git a/include/apps/syscalls.h b/include/apps/syscalls.h
new file mode 100644
index 0000000..e3b10a8
--- /dev/null
+++ b/include/apps/syscalls.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __APPS_SYSCALLS_H__
+#define __APPS_SYSCALLS_H__
+
+#include <types.h>
+#include <stdarg.h>
+
+#define SYSCALLS_MAGIC "bsyscall"
+
+#define SYS_putchar 0
+#define SYS_getchar 1
+#define SYS_eputc 2
+#define SYS_tstc 3
+
+/* file */
+#define SYS_open 4
+#define SYS_close 5
+#define SYS_read 6
+#define SYS_write 7
+#define SYS_unlink 8
+#define SYS_stat 9
+#define SYS_lstat 10
+#define SYS_lseek 11
+
+/* dir */
+#define SYS_mkdir 12
+#define SYS_rmdir 13
+#define SYS_getcwd 14
+#define SYS_chdir 15
+#define SYS_opendir 16
+#define SYS_readdir 17
+#define SYS_closedir 18
+
+/* symlink */
+#define SYS_symlink 19
+#define SYS_readlink 20
+
+/* mount */
+#define SYS_mount 21
+#define SYS_umount 22
+
+/* device */
+#define SYS_ioctl 23
+
+/* env */
+#define SYS_getenv 24
+#define SYS_setenv 25
+
+/* time */
+#define SYS_ndelay 26
+
+/* exec */
+#define SYS_system 27
+
+/* barebox */
+#define SYS_memmap 100
+
+#ifndef __ASSEMBLY__
+
+struct syscalls_header {
+ char magic[8];
+ uint32_t major;
+ uint32_t minor;
+ uint64_t malloc_base;
+ uint32_t malloc_size;
+ uint32_t nb_syscalls;
+ void *syscalls;
+};
+#endif
+
+#endif /* __APPS_SYSCALLS_H__ */
diff --git a/include/apps/types.h b/include/apps/types.h
new file mode 100644
index 0000000..2bb6ee6
--- /dev/null
+++ b/include/apps/types.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __APPS_TYPES_H__
+#define __APPS_TYPES_H__
+
+#ifndef __APP__
+#define APP_TYPE_(x) APP_##x
+#else
+#define APP_TYPE_(x) x
+#endif
+
+struct APP_TYPE_(dirent) {
+ char d_name[256];
+};
+
+typedef struct APP_TYPE_(dir) {
+ struct APP_TYPE_(dirent) d;
+} APP_TYPE_(DIR);
+
+#endif /* __APPS_TYPES_H__ */
diff --git a/include/linux/license.h b/include/linux/license.h
new file mode 100644
index 0000000..decdbf4
--- /dev/null
+++ b/include/linux/license.h
@@ -0,0 +1,14 @@
+#ifndef __LICENSE_H
+#define __LICENSE_H
+
+static inline int license_is_gpl_compatible(const char *license)
+{
+ return (strcmp(license, "GPL") == 0
+ || strcmp(license, "GPL v2") == 0
+ || strcmp(license, "GPL and additional rights") == 0
+ || strcmp(license, "Dual BSD/GPL") == 0
+ || strcmp(license, "Dual MIT/GPL") == 0
+ || strcmp(license, "Dual MPL/GPL") == 0);
+}
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index 3c94542..731bc5b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_LIBMTD) += libmtd.o
obj-y += gui/
obj-$(CONFIG_XYMODEM) += xymodem.o
obj-y += unlink-recursive.o
+obj-$(CONFIG_APPLICATIONS) += apps/
diff --git a/lib/apps/Makefile b/lib/apps/Makefile
new file mode 100644
index 0000000..86e7071
--- /dev/null
+++ b/lib/apps/Makefile
@@ -0,0 +1 @@
+obj-y += syscalls.o
diff --git a/lib/apps/syscalls.c b/lib/apps/syscalls.c
new file mode 100644
index 0000000..832ba02
--- /dev/null
+++ b/lib/apps/syscalls.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#include <common.h>
+#include <fs.h>
+#include <apps/syscalls.h>
+#include <apps/syscall_init.h>
+#include <apps/types.h>
+#include <linux/stat.h>
+#include <environment.h>
+#include <malloc.h>
+#include <clock.h>
+
+static struct syscall_trace *st_current;
+/*
+ * keep traking of what is open to close it
+ * when returning
+ */
+struct app_dir_opendir {
+ DIR *d;
+ APP_TYPE_(DIR) *app_d;
+ struct list_head list;
+};
+
+struct app_fd_open {
+ int fd;
+ struct list_head list;
+};
+
+static long sys_putchar(char c)
+{
+ putchar(c);
+
+ return 0;
+}
+
+static long sys_getchar(void)
+{
+ return getc();
+}
+
+static long sys_eputc(char c)
+{
+ eputc(c);
+
+ return 0;
+}
+
+static long sys_tstc(void)
+{
+ return tstc();
+}
+
+static struct app_fd_open *sys_get_file(int fd)
+{
+ struct app_fd_open *af;
+
+ list_for_each_entry(af, &(st_current->fds), list) {
+ if (af->fd == fd)
+ return af;
+ }
+
+ return NULL;
+}
+
+/* barebox does not handle the last optionnal arg */
+static long sys_open(const char *filename, int flags, mode_t mode)
+{
+ struct app_fd_open *af;
+ int fd;
+
+ af = calloc(1, sizeof(*af));
+ if (!af)
+ return -ENOMEM;
+
+ fd = open(filename, flags, mode);
+ if (fd < 3) {
+ free(af);
+ } else {
+ af->fd = fd;
+ list_add_tail(&af->list, &st_current->fds);
+ }
+
+ return fd;
+}
+
+static long sys_close(unsigned int fd)
+{
+ struct app_fd_open *af;
+
+ if (fd > 2) {
+ af = sys_get_file(fd);
+ if (!af)
+ return -EINVAL;
+
+ list_del(&af->list);
+ }
+
+ return close(fd);
+}
+
+static long sys_read(unsigned int fd, char *buf, size_t count)
+{
+ return read(fd, buf, count);
+}
+
+static long sys_write(unsigned int fd, char *buf, size_t count)
+{
+ return write(fd, buf, count);
+}
+
+static long sys_unlink(const char *name)
+{
+ return unlink(name);
+}
+
+static long sys_stat(const char *name, struct stat *s)
+{
+ return lstat(name, s);
+}
+
+static long sys_lstat(const char *name, struct stat *s)
+{
+ return lstat(name, s);
+}
+
+static loff_t sys_lseek(int fd, loff_t offset, int whence)
+{
+ return lseek(fd, offset, whence);
+}
+
+static long sys_mkdir(char *name, mode_t mode)
+{
+ return mkdir(name, mode);
+}
+
+static long sys_rmdir(char *name)
+{
+ return rmdir(name);
+}
+
+/* int getcwd(char* buf, size_t size) */
+static long sys_getcwd(char* buf, size_t size)
+{
+ const char *path;
+ int len;
+
+ if (!buf)
+ return -ENOMEM;
+
+ path = getcwd();
+ len = strlen(path);
+
+ strncpy(buf, path, min(len, (int)size));
+
+ return 0;
+}
+
+static long sys_chdir(char *name)
+{
+ return chdir(name);
+}
+
+static struct app_dir_opendir *sys_get_dir(APP_TYPE_(DIR) *d)
+{
+ struct app_dir_opendir *ad;
+
+ list_for_each_entry(ad, &st_current->dirs, list) {
+ if (ad->app_d == d)
+ return ad;
+ }
+
+ return NULL;
+}
+
+/*
+ * int opendir(DIR *, char *name)
+ *
+ * Do not expose barebox internal struct
+ */
+static long sys_opendir(APP_TYPE_(DIR) *dir, const char *name)
+{
+ DIR *d;
+ struct app_dir_opendir *ad;
+ int ret;
+
+ ad = calloc(1, sizeof(*ad));
+ if (!ad)
+ return -ENOMEM;
+
+
+ d = opendir(name);
+ if (!d) {
+ ret = -ENOENT;
+ goto err;
+ }
+
+ strcpy(dir->d.d_name, d->d.d_name);
+
+ ad->app_d = dir;
+ ad->d = d;
+
+ list_add_tail(&ad->list, &st_current->dirs);
+
+ return 0;
+
+err:
+ free(ad);
+ return ret;
+}
+
+static long sys_readdir(APP_TYPE_(DIR) *app_dir, struct APP_TYPE_(dirent) *app_d)
+{
+ struct app_dir_opendir *ad;
+ struct dirent *d;
+
+ ad = sys_get_dir(app_dir);
+ if (!ad) {
+ app_d = NULL;
+ return -EINVAL;
+ }
+
+ d = readdir(ad->d);
+
+ if (!d || !d->d_name) {
+ app_d = NULL;
+ return -ENOENT;
+ }
+
+ strcpy(app_d->d_name, d->d_name);
+
+ return 0;
+}
+
+static long sys_closedir(APP_TYPE_(DIR) *app_dir)
+{
+ struct app_dir_opendir *ad;
+ int ret;
+
+ ad = sys_get_dir(app_dir);
+ if (!ad)
+ return -EINVAL;
+
+ ret = closedir(ad->d);
+
+ list_del(&ad->list);
+
+ return ret;
+}
+
+static long sys_symlink(const char *src, const char *dest)
+{
+ return symlink(src, dest);
+}
+
+static long sys_readlink(const char * path, char * buf, u32 bufsiz)
+{
+ return readlink(path, buf, bufsiz);
+}
+
+/*
+ * libc mount
+ * int mount(const char *source, const char *target,
+ * const char *fstype, unsigned long mountflags,
+ * const void *data);
+ * barebox
+ * int mount(const char *device, const char *fsname, const char *_path)
+ */
+static long sys_mount(char *dev_name, char *dir_name,
+ char *type, unsigned long flags,
+ void *data)
+{
+ return mount(dev_name, type, dir_name);
+}
+
+static long sys_umount(char *name, int flags)
+{
+ return umount(name);
+}
+
+static long sys_ioctl(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ return ioctl(fd, cmd, (void*)arg);
+}
+
+static long sys_getenv(char *value, const char *name)
+{
+ strcpy(value, getenv(name));
+
+ return 0;
+}
+
+static long sys_setenv(const char *name, const char *value)
+{
+ return setenv(name, value);
+}
+
+static long sys_ndelay(unsigned long nsecs)
+{
+ uint64_t start = get_time_ns();
+
+ while(!is_timeout(start, nsecs));
+
+ return 0;
+}
+
+static long sys_nil(unsigned long arg0, unsigned long arg1, unsigned long arg2)
+{
+ pr_err("%s(0x%lx, 0x%lx, 0x%lx)\n", __func__, arg0, arg1, arg2);
+ return -ENOSYS;
+}
+
+#define __SYSCALL(name) [SYS_##name] = sys_##name
+
+static void *sys_funcs[] = {
+ __SYSCALL(putchar),
+ __SYSCALL(getchar),
+ __SYSCALL(eputc),
+ __SYSCALL(tstc),
+ /* file */
+ __SYSCALL(open),
+ __SYSCALL(close),
+ __SYSCALL(read),
+ __SYSCALL(write),
+ __SYSCALL(unlink),
+ __SYSCALL(stat),
+ __SYSCALL(lstat),
+ __SYSCALL(lseek),
+ /* dir */
+ __SYSCALL(mkdir),
+ __SYSCALL(rmdir),
+ __SYSCALL(getcwd),
+ __SYSCALL(chdir),
+ __SYSCALL(opendir),
+ __SYSCALL(readdir),
+ __SYSCALL(closedir),
+ /* symlink */
+ __SYSCALL(symlink),
+ __SYSCALL(readlink),
+ /* mount */
+ __SYSCALL(mount),
+ __SYSCALL(umount),
+ /* device */
+ __SYSCALL(ioctl),
+ /* env */
+ __SYSCALL(getenv),
+ __SYSCALL(setenv),
+ /* env */
+ __SYSCALL(ndelay),
+};
+
+struct syscalls_header syscalls = {
+ .magic = SYSCALLS_MAGIC,
+ .major = 1,
+ .minor = 0,
+ .nb_syscalls = ARRAY_SIZE(sys_funcs),
+ .syscalls = sys_funcs,
+};
+
+void syscalls_init(struct syscall_trace *t)
+{
+ struct syscalls_header *app_syscalls = t->dest;
+ int size = sizeof(syscalls);
+ void **dest;
+ int i;
+
+ pr_debug("t->dest = 0x%p\n", t->dest);
+
+ pr_debug("sizeof = %d\n", size);
+ memcpy(t->dest, &syscalls, sizeof(syscalls));
+
+ app_syscalls->malloc_base = t->malloc_base;
+ app_syscalls->malloc_size = t->malloc_size;
+ dest = t->dest + size;
+
+ size = sizeof(void*) * syscalls.nb_syscalls;
+ pr_debug("dest = 0x%p\n", dest);
+ pr_debug("size = %d\n", size);
+
+ app_syscalls->syscalls = dest;
+ memcpy(dest, sys_funcs, size);
+
+ for (i = 0; i < syscalls.nb_syscalls; i++) {
+ if (!dest[i]) {
+ pr_debug("syscall %d not implemented\n", i);
+ dest[i] = sys_nil;
+ }
+ }
+
+ INIT_LIST_HEAD(&t->dirs);
+ INIT_LIST_HEAD(&t->fds);
+}
+
+void syscalls_exit(struct syscall_trace *t)
+{
+ struct app_dir_opendir *ad, *tmpd;
+ struct app_fd_open *af, *tmpf;
+
+ list_for_each_entry_safe(ad, tmpd, &t->dirs, list) {
+ closedir(ad->d);
+ list_del(&ad->list);
+ }
+
+ list_for_each_entry_safe(af, tmpf, &t->fds, list) {
+ close(af->fd);
+ list_del(&af->list);
+ }
+}
+
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 05/20] app: Introduce libc support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (2 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 04/20] Introduce application (app) support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 06/20] app: add some utils Jean-Christophe PLAGNIOL-VILLARD
` (14 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
with dummy malloc or tslf malloc
and provide a pseudo libc to simplify application porting
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 19 ++
apps/Makefile | 10 +-
apps/include/appinfo.h | 2 +
apps/include/assert.h | 32 +++
apps/include/common.h | 28 ++
apps/include/ctype.h | 100 +++++++
apps/include/dirent.h | 24 ++
apps/include/errno.h | 24 ++
apps/include/fcntl.h | 25 ++
apps/include/getopt.h | 76 ++++++
apps/include/libc_config.h | 139 ++++++++++
apps/include/limits.h | 38 +++
apps/include/malloc.h | 30 +++
apps/include/module.h | 3 +
apps/include/sections.h | 29 ++
apps/include/setjmp.h | 25 ++
apps/include/stddef.h | 1 +
apps/include/stdint.h | 23 ++
apps/include/stdio.h | 70 +++++
apps/include/stdlib.h | 29 ++
apps/include/string.h | 53 ++++
apps/include/sys/ioctl.h | 12 +
apps/include/sys/stat.h | 14 +
apps/include/sys/syscall.h | 14 +
apps/include/sys/types.h | 15 ++
apps/include/time.h | 27 ++
apps/include/unistd.h | 46 ++++
apps/libc/Kconfig | 25 ++
apps/libc/Makefile | 36 +++
apps/libc/appinfo.c | 35 +++
apps/libc/dirent.c | 59 +++++
apps/libc/errno.c | 19 ++
apps/libc/fcntl.c | 25 ++
apps/libc/flags.c | 76 ++++++
apps/libc/getopt.c | 127 +++++++++
apps/libc/getopt_long.c | 625 ++++++++++++++++++++++++++++++++++++++++++++
apps/libc/malloc.c | 50 ++++
apps/libc/malloc.h | 2 +
apps/libc/private.h | 18 ++
apps/libc/stdio.c | 275 +++++++++++++++++++
apps/libc/stdlib.c | 77 ++++++
apps/libc/string.c | 159 +++++++++++
apps/libc/sys/Makefile | 2 +
apps/libc/sys/stat.c | 25 ++
apps/libc/syscalls.c | 103 ++++++++
apps/libc/time.c | 41 +++
apps/libc/unistd.c | 108 ++++++++
47 files changed, 2791 insertions(+), 4 deletions(-)
create mode 100644 apps/include/assert.h
create mode 100644 apps/include/common.h
create mode 100644 apps/include/ctype.h
create mode 100644 apps/include/dirent.h
create mode 100644 apps/include/errno.h
create mode 100644 apps/include/fcntl.h
create mode 100644 apps/include/getopt.h
create mode 100644 apps/include/libc_config.h
create mode 100644 apps/include/limits.h
create mode 100644 apps/include/malloc.h
create mode 100644 apps/include/module.h
create mode 100644 apps/include/sections.h
create mode 100644 apps/include/setjmp.h
create mode 100644 apps/include/stddef.h
create mode 100644 apps/include/stdint.h
create mode 100644 apps/include/stdio.h
create mode 100644 apps/include/stdlib.h
create mode 100644 apps/include/string.h
create mode 100644 apps/include/sys/ioctl.h
create mode 100644 apps/include/sys/stat.h
create mode 100644 apps/include/sys/syscall.h
create mode 100644 apps/include/sys/types.h
create mode 100644 apps/include/time.h
create mode 100644 apps/include/unistd.h
create mode 100644 apps/libc/Kconfig
create mode 100644 apps/libc/Makefile
create mode 100644 apps/libc/appinfo.c
create mode 100644 apps/libc/dirent.c
create mode 100644 apps/libc/errno.c
create mode 100644 apps/libc/fcntl.c
create mode 100644 apps/libc/flags.c
create mode 100644 apps/libc/getopt.c
create mode 100644 apps/libc/getopt_long.c
create mode 100644 apps/libc/malloc.c
create mode 100644 apps/libc/malloc.h
create mode 100644 apps/libc/private.h
create mode 100644 apps/libc/stdio.c
create mode 100644 apps/libc/stdlib.c
create mode 100644 apps/libc/string.c
create mode 100644 apps/libc/sys/Makefile
create mode 100644 apps/libc/sys/stat.c
create mode 100644 apps/libc/syscalls.c
create mode 100644 apps/libc/time.c
create mode 100644 apps/libc/unistd.c
diff --git a/apps/Kconfig b/apps/Kconfig
index 92899b5..4805c50 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -7,6 +7,8 @@ menuconfig APPLICATIONS
if APPLICATIONS
+source "apps/libc/Kconfig"
+
menu "memory layout"
source "arch/$SRCARCH/apps/Kconfig"
@@ -16,6 +18,23 @@ config APP_MALLOC_SIZE
default 0x400000
prompt "malloc area size"
+config APP_PATH_MAX
+ hex
+ default 4096
+ prompt "path max"
+
+config APP_ENV_MAX
+ hex
+ default 4096
+ prompt "env var max size"
+
+config APP_FILE_MAX
+ int
+ default 128
+ prompt "maximun number of FILE"
+ help
+ this does not include stdin, stderr, stdout
+
endmenu
endif
diff --git a/apps/Makefile b/apps/Makefile
index 65adfdc..c5c5c48 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -1,5 +1,9 @@
-CPPFLAGS += -I$(srctree)/apps/include
+APP_CPPFLAGS += -include $(srctree)/apps/include/libc_config.h
+APP_CPPFLAGS += -I$(srctree)/apps/include
+export APP_CPPFLAGS
+
+apps-$(CONFIG_APP_EXAMPLE) += example
$(obj)/application: $(apps-lds) $(apps-y)
@@ -11,9 +15,7 @@ $(obj)/include/types.h: $(srctree)/include/types.h
$(obj)/include/barebox/syscalls.h: $(srctree)/include/apps/syscalls.h
$(call cmd,shipped)
-$(obj)/include/errno.h: $(srctree)/include/asm-generic/errno.h
- $(call cmd,shipped)
+obj-y += libc/
barebox-app-header += $(obj)/include/types.h
-barebox-app-header += $(obj)/include/errno.h
barebox-app-header += $(obj)/include/barebox/syscalls.h
diff --git a/apps/include/appinfo.h b/apps/include/appinfo.h
index 94409d7..ba95e65 100644
--- a/apps/include/appinfo.h
+++ b/apps/include/appinfo.h
@@ -55,4 +55,6 @@
/* What your application does. */
#define APP_DESCRIPTION(_description) APP_INFO(description, _description)
+void print_appinfo(void);
+
#endif /* __APPINFO_H__ */
diff --git a/apps/include/assert.h b/apps/include/assert.h
new file mode 100644
index 0000000..a5d1bdd
--- /dev/null
+++ b/apps/include/assert.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ASSERT_H__
+#define __ASSERT_H__
+
+#define NDEBUG
+#if defined(NDEBUG) || defined(CONFIG_APP_NDEBUG)
+#define assert(expression)
+#else
+#define assert(expression) do { \
+ if (expression) { \
+ fprintf(stderr, "%s:%d: ", str(expression), __FUNCTION__, __LINE__); \
+ exit(EXIT_FAILURE); \
+ } \
+} while(0)
+#endif
+
+#endif /* __ASSERT_H__ */
diff --git a/apps/include/common.h b/apps/include/common.h
new file mode 100644
index 0000000..6e991e8
--- /dev/null
+++ b/apps/include/common.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <stdio.h>
+
+#define BUG() do { \
+} while (0)
+
+#endif /* __COMMON_H__ */
diff --git a/apps/include/ctype.h b/apps/include/ctype.h
new file mode 100644
index 0000000..09eb175
--- /dev/null
+++ b/apps/include/ctype.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __CTYPE_H__
+#define __CTYPE_H__
+
+static inline int tolower(int c)
+{
+ return (c >= 'A' && c <= 'Z') ? (c + 32) : c;
+}
+
+static inline int toupper(int c)
+{
+ return (c >= 'a' && c <= 'z') ? (c - 32) : c;
+}
+
+static inline int toascii(int c)
+{
+ return ((unsigned char)c) & 0x7f;
+}
+
+static inline int isalpha(int c)
+{
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+}
+
+static inline int isascii(int c)
+{
+ return (c >= 0 && c <= 127);
+}
+
+static inline int isblank(int c)
+{
+ return (c == ' ' || c == '\t');
+}
+
+static inline int iscntrl(int c)
+{
+ return (c <= 31 || c == 127);
+}
+
+static inline int isdigit(int c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+static inline int isalnum(int c)
+{
+ return isalpha(c) || isdigit(c);
+}
+
+static inline int isgraph(int c)
+{
+ return (c >= 33 && c <= 126);
+}
+
+static inline int islower(int c)
+{
+ return (c >= 'a' && c <= 'z');
+}
+
+static inline int isprint(int c)
+{
+ return (c >= 32 && c <= 126);
+}
+
+static inline int isspace(int c)
+{
+ return (c == ' ' || (c >= '\t' && c <= '\r'));
+}
+
+static inline int ispunct(int c)
+{
+ return isprint(c) && !isspace(c) && !isalnum(c);
+}
+
+static inline int isupper(int c)
+{
+ return (c >= 'A' && c <= 'Z');
+}
+
+static inline int isxdigit(int c)
+{
+ return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
+}
+
+#endif /* __CTYPE_H__ */
diff --git a/apps/include/dirent.h b/apps/include/dirent.h
new file mode 100644
index 0000000..df26461
--- /dev/null
+++ b/apps/include/dirent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __DIRENT_H__
+#define __DIRENT_H__
+
+DIR *opendir(const char *name);
+struct dirent *readdir(DIR *dir);
+int closedir(DIR *dir);
+
+#endif /* __DIRENT_H__ */
diff --git a/apps/include/errno.h b/apps/include/errno.h
new file mode 100644
index 0000000..e7d5c90
--- /dev/null
+++ b/apps/include/errno.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ERRNO_H__
+#define __ERRNO_H__
+
+#include <asm-generic/errno.h>
+
+extern int errno;
+
+#endif /* __ERRNO_H__ */
diff --git a/apps/include/fcntl.h b/apps/include/fcntl.h
new file mode 100644
index 0000000..7bc8980
--- /dev/null
+++ b/apps/include/fcntl.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __FCNTL_H__
+#define __FCNTL_H__
+
+#include <barebox/fcntl.h>
+
+/* barebox does not handle the last optionnal arg */
+int open(const char *name, int flags, ...);
+
+#endif /* __FCNTL_H__ */
diff --git a/apps/include/getopt.h b/apps/include/getopt.h
new file mode 100644
index 0000000..b6c03d1
--- /dev/null
+++ b/apps/include/getopt.h
@@ -0,0 +1,76 @@
+/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
+/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <sys/types.h>
+
+/*
+ * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ */
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+int getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+int getopt_long_only(int, char * const *, const char *,
+ const struct option *, int *);
+#ifndef _GETOPT_DEFINED_
+#define _GETOPT_DEFINED_
+int getopt(int, char * const *, const char *);
+int getsubopt(char **, char * const *, char **);
+
+extern char *optarg; /* getopt(3) external variables */
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern int optreset;
+extern char *suboptarg; /* getsubopt(3) external variable */
+#endif
+
+#endif /* !_GETOPT_H_ */
diff --git a/apps/include/libc_config.h b/apps/include/libc_config.h
new file mode 100644
index 0000000..752a417
--- /dev/null
+++ b/apps/include/libc_config.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __LIBC_CONFIG_H__
+#define __LIBC_CONFIG_H__
+
+#define LIBC_MAJOR 0
+#define LIBC_MINOR 1
+#define LIBC_SUBMINOR 0
+
+#define __str(x) #x
+#define str(x) __str(x)
+
+#define LIBC_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define LIBC_VERSION_CODE LIBC_VERSION(LIBC_MAJOR, LIBC_MINOR, LIBC_SUBMINOR)
+#define LIBC_VERSION_STRING str(LIBC_MAJOR) "." str(LIBC_MINOR) "." str(LIBC_SUBMINOR)
+
+/* dirent.h */
+#define LIBC_HAVE_DIRENT_H 1
+
+#define LIBC_HAVE_OPENDIR 1
+#define LIBC_HAVE_READDIR 1
+#define LIBC_HAVE_CLOSEDIR 1
+
+/* fcntl.h */
+#define LIBC_HAVE_FCNTL_H 1
+
+#define LIBC_HAVE_OPEN 1
+
+/* getopt.h */
+#define LIBC_HAVE_GETOPT_H 1
+
+#define LIBC_HAVE_GETOPT_LONG 1
+#define LIBC_HAVE_GETOPT_LONG_ONLY 1
+//#define LIBC_HAVE_GETOPT 1
+#define LIBC_HAVE_GETSUBOPT 1
+
+/* malloc.h */
+#define LIBC_HAVE_MALLOC_H 1
+
+#define LIBC_HAVE_MALLOC 1
+#define LIBC_HAVE_FREE 1
+#define LIBC_HAVE_REALLOC 1
+#define LIBC_HAVE_MEMALIGN 1
+#define LIBC_HAVE_CALLOC 1
+#define LIBC_HAVE_CFREE 1
+
+/* stdio.h */
+#define LIBC_HAVE_STDIO_H 1
+
+#define LIBC_HAVE_PUTCHAR 1
+#define LIBC_HAVE_GETCHAR 1
+#define LIBC_HAVE_PUTS 1
+
+#define LIBC_HAVE_FPRINTF 1
+#define LIBC_HAVE_VFPRINTF 1
+#define LIBC_HAVE_FPUTS 1
+#define LIBC_HAVE_FPUTC 1
+#define LIBC_HAVE_FOPEN 1
+#define LIBC_HAVE_FCLOSE 1
+#define LIBC_HAVE_FREAD 1
+#define LIBC_HAVE_FWRITE 1
+#define LIBC_HAVE_FSEEK 1
+
+#define LIBC_HAVE_PRINTF 1
+#define LIBC_HAVE_VPRINTF 1
+#define LIBC_HAVE_SPRINTF 1
+#define LIBC_HAVE_SNPRINTF 1
+#define LIBC_HAVE_VSPRINTF 1
+#define LIBC_HAVE_ASPRINTF 1
+#define LIBC_HAVE_VASPRINTF 1
+#define LIBC_HAVE_VSNPRINTF 1
+#define LIBC_HAVE_VSCNPRINTF 1
+
+/* barebox API */
+#define LIBC_HAVE_BAREBOX_API 1
+
+#define LIBC_HAVE_EPUTC 1
+#define LIBC_HAVE_EPUTS 1
+#define LIBC_HAVE_TSTC 1
+#define LIBC_HAVE_FLUSH 1
+#define LIBC_HAVE_ITOA 1
+
+/* stdlib.h */
+#define LIBC_HAVE_STDLIB_H 1
+
+#define LIBC_HAVE_GETENV 1
+#define LIBC_HAVE_EXIT 1
+
+/* unistd.h */
+#define LIBC_HAVE_UNISTD_H 1
+
+#define LIBC_HAVE_READ 1
+#define LIBC_HAVE_WRITE 1
+#define LIBC_HAVE_CLOSE 1
+#define LIBC_HAVE_STAT 1
+#define LIBC_HAVE_LSTAT 1
+
+#define LIBC_HAVE_LSEEK 1
+#define LIBC_HAVE_UNLINK 1
+#define LIBC_HAVE_SYMLINK 1
+#define LIBC_HAVE_READLINK 1
+#define LIBC_HAVE_RMDIR 1
+#define LIBC_HAVE_GETCWD 1
+#define LIBC_HAVE_GET_CURRENT_DIR_NAME 1
+#define LIBC_HAVE_CHDIR 1
+#define LIBC_HAVE_USLEEP 1
+
+#define LIBC_HAVE_GETOPT 1
+
+/* sys/ioctl.h */
+#define LIBC_HAVE_SYS_IOCTL_H 1
+
+#define LIBC_HAVE_IOCTL 1
+
+/* sys/stat.h */
+#define LIBC_HAVE_SYS_STAT_H 1
+
+#define LIBC_HAVE_MKDIR 1
+
+/* sys/syscall.h */
+#define LIBC_HAVE_SYS_SYSCALL_H 1
+
+#define LIBC_HAVE_SYSCALL 1
+
+#endif /* __LIBC_CONFIG_H__ */
diff --git a/apps/include/limits.h b/apps/include/limits.h
new file mode 100644
index 0000000..3625d07
--- /dev/null
+++ b/apps/include/limits.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __LIMITS_H__
+#define __LIMITS_H__
+
+#include <sys/types.h>
+
+#define USHORT_MAX ((u16)(~0U))
+#define SHORT_MAX ((s16)(USHORT_MAX>>1))
+#define SHORT_MIN (-SHORT_MAX - 1)
+#define INT_MAX ((int)(~0U>>1))
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX (~0U)
+#define LONG_MAX ((long)(~0UL>>1))
+#define LONG_MIN (-LONG_MAX - 1)
+#define ULONG_MAX (~0UL)
+#define LLONG_MAX ((long long)(~0ULL>>1))
+#define LLONG_MIN (-LLONG_MAX - 1)
+#define ULLONG_MAX (~0ULL)
+
+#define PATH_MAX CONFIG_APP_PATH_MAX
+#define ENV_MAX CONFIG_APP_ENV_MAX
+
+#endif /* __LIMITS_H__ */
diff --git a/apps/include/malloc.h b/apps/include/malloc.h
new file mode 100644
index 0000000..0017419
--- /dev/null
+++ b/apps/include/malloc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __MALLOC_H
+#define __MALLOC_H
+
+#include <types.h>
+
+void* malloc(size_t);
+void free(void*);
+void* realloc(void*, size_t);
+void* memalign(size_t, size_t);
+void* calloc(size_t, size_t);
+void cfree(void*);
+
+#endif
+
diff --git a/apps/include/module.h b/apps/include/module.h
new file mode 100644
index 0000000..c62d65b
--- /dev/null
+++ b/apps/include/module.h
@@ -0,0 +1,3 @@
+#define EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL(sym)
+
diff --git a/apps/include/sections.h b/apps/include/sections.h
new file mode 100644
index 0000000..fc262a6
--- /dev/null
+++ b/apps/include/sections.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef _APPS_GENERIC_SECTIONS_H_
+#define _APPS_GENERIC_SECTIONS_H_
+
+extern char _text[], _stext[], _etext[];
+extern char __bss_start[], __bss_stop[];
+extern char _sdata[], _edata[];
+extern char _end[];
+extern void *_barebox_app_image_size;
+extern char __appinfo_start[], __appinfo_end[];
+
+#define _barebox_app_image_size (unsigned int)&_barebox_app_image_size
+
+#endif /* _APPS_GENERIC_SECTIONS_H_ */
diff --git a/apps/include/setjmp.h b/apps/include/setjmp.h
new file mode 100644
index 0000000..ff9dd8d
--- /dev/null
+++ b/apps/include/setjmp.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __SETJMP_H__
+#define __SETJMP_H__
+
+#include <arch/setjmp.h>
+
+int setjmp(jmp_buf);
+void __attribute__((noreturn)) longjmp(jmp_buf, int);
+
+#endif /* __SETJMP_H__ */
diff --git a/apps/include/stddef.h b/apps/include/stddef.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/apps/include/stddef.h
@@ -0,0 +1 @@
+
diff --git a/apps/include/stdint.h b/apps/include/stdint.h
new file mode 100644
index 0000000..f5ad912
--- /dev/null
+++ b/apps/include/stdint.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDINT_H__
+#define __STDINT_H__
+
+#define INT64_C(c) (c ## LL)
+#define UINT64_C(c) (c ## ULL)
+
+#endif /* __STDINT_H__ */
diff --git a/apps/include/stdio.h b/apps/include/stdio.h
new file mode 100644
index 0000000..32a7d25
--- /dev/null
+++ b/apps/include/stdio.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDIO_H__
+#define __STDIO_H__
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+#define EOF -1
+
+void putchar(char c);
+int getchar(void);
+int puts(const char *str);
+
+struct __file;
+typedef struct __file FILE;
+
+extern FILE stdin;
+extern FILE stdout;
+extern FILE stderr;
+
+#define stdin (&stdin)
+#define stdout (&stdout)
+#define stderr (&stderr)
+
+int fprintf(FILE *f, const char *fmt, ...) __attribute__ ((format(__printf__, 2, 3)));
+int vfprintf(FILE *f, const char *fmt, va_list args);
+int fputs(const char *s, FILE *f);
+int fputc(int c, FILE *f);
+FILE *fopen(const char *path, const char *mode);
+int fclose(FILE *f);
+size_t fread(void *buf, size_t size, size_t nb, FILE *f);
+size_t fwrite(const void *buf, size_t size, size_t nb, FILE *f);
+int fseek(FILE *stream, long offset, int whence);
+
+/* barebox API */
+void eputc(char c);
+int eputs(const char *str);
+int tstc(void);
+int flush(int fd);
+char* itoa(int i);
+
+static int printf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2)));
+static inline int printf(const char *fmt, ...)
+{
+ return 0;
+}
+
+static inline int vprintf(const char *fmt, va_list args)
+{
+ return 0;
+}
+
+#endif /* __STDIO_H__ */
diff --git a/apps/include/stdlib.h b/apps/include/stdlib.h
new file mode 100644
index 0000000..7ae78ad
--- /dev/null
+++ b/apps/include/stdlib.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STDLIB_H__
+#define __STDLIB_H__
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+char *getenv(const char *name);
+void exit(int num);
+int atoi(const char *s);
+long atol(const char *s);
+long long atoll(const char *s);
+
+#endif /* __STDLIB_H__ */
diff --git a/apps/include/string.h b/apps/include/string.h
new file mode 100644
index 0000000..95b94a3
--- /dev/null
+++ b/apps/include/string.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __STRING_H
+#define __STRING_H
+
+#include <types.h>
+
+extern char * ___strtok;
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern char * strsep(char **,const char *);
+extern size_t strspn(const char *,const char *);
+
+extern char * strcpy(char *,const char *);
+extern char * strncpy(char *,const char *, size_t);
+size_t strlcpy(char *, const char *, size_t);
+extern char * strcat(char *, const char *);
+extern char * strncat(char *, const char *, size_t);
+extern int strcmp(const char *,const char *);
+extern int strncmp(const char *,const char *,size_t);
+extern char * strchr(const char *,int);
+extern char * strrchr(const char *,int);
+extern char * strstr(const char *,const char *);
+extern size_t strlen(const char *);
+extern size_t strnlen(const char *,size_t);
+extern char * strdup(const char *);
+extern char * strswab(const char *);
+
+extern void * memset(void *,int,size_t);
+extern void * memcpy(void *,const void *,size_t);
+extern void * memmove(void *,const void *,size_t);
+extern void * memscan(void *,int,size_t);
+extern int memcmp(const void *,const void *,size_t);
+extern void * memchr(const void *,int,size_t);
+extern char * skip_spaces(const char *);
+
+extern char *strim(char *);
+
+#endif /* __STRING_H */
diff --git a/apps/include/sys/ioctl.h b/apps/include/sys/ioctl.h
new file mode 100644
index 0000000..58e9760
--- /dev/null
+++ b/apps/include/sys/ioctl.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_IOCTL_H__
+#define __SYS_IOCTL_H__
+
+int ioctl(int fd, int request, void *buf);
+
+#endif /* __SYS_IOCTL_H__ */
diff --git a/apps/include/sys/stat.h b/apps/include/sys/stat.h
new file mode 100644
index 0000000..c1cecf9
--- /dev/null
+++ b/apps/include/sys/stat.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_STAT_H__
+#define __SYS_STAT_H__
+
+#include <linux/stat.h>
+
+int mkdir(const char *path, mode_t mode);
+
+#endif /* __SYS_STAT_H__ */
diff --git a/apps/include/sys/syscall.h b/apps/include/sys/syscall.h
new file mode 100644
index 0000000..4ffb09a
--- /dev/null
+++ b/apps/include/sys/syscall.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_SYSCALL_H__
+#define __SYS_SYSCALL_H__
+
+#include <errno.h>
+
+int syscall(int num, ...);
+
+#endif /* __SYS_SYSCALL_H__ */
diff --git a/apps/include/sys/types.h b/apps/include/sys/types.h
new file mode 100644
index 0000000..ec48b2e
--- /dev/null
+++ b/apps/include/sys/types.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __SYS_TYPES_H__
+#define __SYS_TYPES_H__
+
+#include <linux/types.h>
+#include <barebox/types.h>
+
+typedef unsigned int useconds_t;
+
+#endif /* __SYS_TYPES_H__ */
diff --git a/apps/include/time.h b/apps/include/time.h
new file mode 100644
index 0000000..d067e25
--- /dev/null
+++ b/apps/include/time.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __TIME_H__
+#define __TIME_H__
+
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+
+int nanosleep(const struct timespec *req, struct timespec *rem);
+
+#endif /* __TIME_H__ */
diff --git a/apps/include/unistd.h b/apps/include/unistd.h
new file mode 100644
index 0000000..dbd8cef
--- /dev/null
+++ b/apps/include/unistd.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __UNISTD_H__
+#define __UNISTD_H__
+
+struct stat;
+
+ssize_t read(int fd, void *buf, size_t count);
+ssize_t write(int fd, const void *buf, size_t count);
+int close(int fd);
+int stat(const char *path, struct stat *buf);
+int lstat(const char *path, struct stat *buf);
+
+#define SEEK_SET 1
+#define SEEK_CUR 2
+#define SEEK_END 3
+
+loff_t lseek(int fd, loff_t offset, int whence);
+int unlink(const char *pathname);
+int symlink(const char *pathname, const char *newpath);
+ssize_t readlink(const char *path, char *buf, size_t bufsiz);
+int rmdir(const char *path);
+char *getcwd(char *buf, size_t size);
+char *get_current_dir_name(void);
+int chdir(const char *path);
+int usleep(unsigned int usec);
+
+int getopt(int argc, char * const argv[], const char *optstring);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+#endif /* __UNISTD_H__ */
diff --git a/apps/libc/Kconfig b/apps/libc/Kconfig
new file mode 100644
index 0000000..b9478b5
--- /dev/null
+++ b/apps/libc/Kconfig
@@ -0,0 +1,25 @@
+menu "libc"
+
+choice
+ prompt "malloc implementation"
+
+config APPS_MALLOC_TLSF
+ bool "tlsf"
+
+config APPS_MALLOC_DUMMY
+ bool "dummy malloc"
+ help
+ select this option to use a dummy malloc implementation. With this
+ memory is never freed. This is suitable for well tested noninteractive
+ environments only.
+
+endchoice
+
+config APP_GETOPT_LONG_AS_GETOPT
+ bool "use getopt_long as getopt"
+
+config APP_PRINTF_STACK_SIZE
+ hex "printf stack size"
+ default 0x1000
+
+endmenu
diff --git a/apps/libc/Makefile b/apps/libc/Makefile
new file mode 100644
index 0000000..844ea9b
--- /dev/null
+++ b/apps/libc/Makefile
@@ -0,0 +1,36 @@
+app-y += appinfo.o
+app-y += dirent.o
+app-y += errno.o
+app-y += fcntl.o
+app-y += flags.o
+ifneq ($(CONFIG_APP_GETOPT_LONG_AS_GETOPT),y)
+app-y += getopt.o
+endif
+app-y += getopt_long.o
+app-y += malloc.o
+app-y += stdio.o
+app-y += stdlib.o
+app-y += syscalls.o
+app-y += unistd.o
+app-$(CONFIG_APPS_MALLOC_DUMMY) += dummy_malloc.o
+app-$(CONFIG_APPS_MALLOC_TLSF) += tlsf_malloc.o tlsf.o
+app-y += string.o
+obj-y += sys/
+app-y += time.o
+
+$(obj)/dummy_malloc.c: $(srctree)/common/dummy_malloc.c FORCE
+ $(call cmd,shipped)
+
+$(obj)/tlsf.c: $(srctree)/common/tlsf.c $(obj)/tlsfbits.h FORCE
+ $(call cmd,shipped)
+
+$(obj)/tlsf_malloc.c: $(srctree)/common/tlsf_malloc.c $(obj)/tlsf.h FORCE
+ $(call cmd,shipped)
+
+$(obj)/tlsfbits.h: $(srctree)/common/tlsfbits.h FORCE
+ $(call cmd,shipped)
+
+$(obj)/tlsf.h: $(srctree)/include/tlsf.h FORCE
+ $(call cmd,shipped)
+
+$(obj)/app-malloc.o: $(obj)/tlsfbits.h
diff --git a/apps/libc/appinfo.c b/apps/libc/appinfo.c
new file mode 100644
index 0000000..7eff526
--- /dev/null
+++ b/apps/libc/appinfo.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sections.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <appinfo.h>
+#include <libc_config.h>
+
+void print_appinfo(void)
+{
+ char *info = (char*)&__appinfo_start;
+
+ for (; info < (char*)&__appinfo_end; info += strlen(info) + 1)
+ printf("%s\n", info);
+}
+
+APP_INFO(libc, "barebox libc")
+APP_INFO(libc_author, "Jean-Christophe PLANGIOL-VILLARD <plagnioj@jcrosoft.com>")
+APP_INFO(libc_license, "GPLv2 + exception")
+APP_INFO(libc_version, LIBC_VERSION_STRING)
diff --git a/apps/libc/dirent.c b/apps/libc/dirent.c
new file mode 100644
index 0000000..b2a78ad
--- /dev/null
+++ b/apps/libc/dirent.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <errno.h>
+
+DIR *opendir(const char *name)
+{
+ DIR *d = malloc(sizeof(DIR));
+
+ if (!d)
+ return NULL;
+
+ if (syscall(SYS_opendir, d, name))
+ goto err;
+
+ return d;
+err:
+ free(d);
+ return NULL;
+}
+
+static struct dirent d_read;
+
+struct dirent *readdir(DIR *dir)
+{
+ if (!dir)
+ return NULL;
+
+ if (syscall(SYS_readdir, dir, &d_read))
+ return NULL;
+
+ return &d_read;
+}
+
+int closedir(DIR *dir)
+{
+ if (!dir)
+ return -EINVAL;
+
+ return syscall(SYS_closedir, dir);
+}
diff --git a/apps/libc/errno.c b/apps/libc/errno.c
new file mode 100644
index 0000000..640d09c
--- /dev/null
+++ b/apps/libc/errno.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <errno.h>
+
+int errno;
diff --git a/apps/libc/fcntl.c b/apps/libc/fcntl.c
new file mode 100644
index 0000000..da26955
--- /dev/null
+++ b/apps/libc/fcntl.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+/* barebox does not handle the last optionnal arg */
+int open(const char *name, int flags, ...)
+{
+ return syscall(SYS_open, name, flags);
+}
diff --git a/apps/libc/flags.c b/apps/libc/flags.c
new file mode 100644
index 0000000..4d4487b
--- /dev/null
+++ b/apps/libc/flags.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int __str_to_flags(const char *mode, int *flag)
+{
+ int _mode;
+ int opt;
+
+ switch (*mode++) {
+ case 'r':
+ _mode = O_RDONLY;
+ opt = 0;
+ break;
+
+ case 'w':
+ _mode = O_WRONLY;
+ opt = O_CREAT | O_TRUNC;
+ break;
+
+ case 'a':
+ _mode = O_WRONLY;
+ opt = O_CREAT | O_APPEND;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* binary ingnore it */
+ if (*mode == 'b')
+ mode++;
+
+ /* read/write */
+ if (*mode == '+') {
+ mode++;
+ _mode = O_RDWR;
+ }
+
+ /* binary ingnore it */
+ if (*mode == 'b')
+ mode++;
+
+ /*
+ * barebox does not supprot it
+ * just check we are not it RO mode
+ */
+ if (*mode == 'x') {
+ mode++;
+ if (_mode == O_RDONLY)
+ return -EINVAL;
+ }
+
+ /* barebox does not support it */
+ if (*mode == 'e')
+ mode++;
+
+ *flag = _mode | opt;
+ return 0;
+}
diff --git a/apps/libc/getopt.c b/apps/libc/getopt.c
new file mode 100644
index 0000000..b445af8
--- /dev/null
+++ b/apps/libc/getopt.c
@@ -0,0 +1,127 @@
+/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "private.h"
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const nargv[];
+ const char *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || *place == 0) { /* update scanning pointer */
+ optreset = 0;
+ place = nargv[optind];
+ if (optind >= nargc || *place++ != '-') {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return (-1);
+ }
+ optopt = *place++;
+ if (optopt == '-' && *place == 0) {
+ /* "--" => end of options */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ if (optopt == 0) {
+ /* Solitary '-', treat as a '-' option
+ if the program (eg su) is looking for it. */
+ place = EMSG;
+ if (strchr(ostr, '-') == NULL)
+ return (-1);
+ optopt = '-';
+ }
+ } else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == ':' || (oli = (char*)strchr(ostr, optopt)) == NULL) {
+ if (*place == 0)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", __progname,
+ optopt);
+ return (BADCH);
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ optarg = NULL;
+ if (*place == 0)
+ ++optind;
+ } else {
+ /* Option-argument is either the rest of this argument or the
+ entire next argument. */
+ if (*place)
+ optarg = place;
+ else if (nargc > ++optind)
+ optarg = nargv[optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ __progname, optopt);
+ return (BADCH);
+ }
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* return option letter */
+}
diff --git a/apps/libc/getopt_long.c b/apps/libc/getopt_long.c
new file mode 100644
index 0000000..ed7add7
--- /dev/null
+++ b/apps/libc/getopt_long.c
@@ -0,0 +1,625 @@
+/* $OpenBSD: getopt_long.c,v 1.22 2006/10/04 21:29:04 jmc Exp $ */
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "private.h"
+
+#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */
+
+#ifdef CONFIG_APP_GETOPT_LONG_AS_GETOPT /* we prefer to keep our getopt(3) */
+#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
+#endif
+
+#ifdef REPLACE_GETOPT
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+#endif
+
+#define PRINT_ERROR ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+#ifdef GNU_COMPATIBLE
+#define NO_PREFIX (-1)
+#define D_PREFIX 0
+#define DD_PREFIX 1
+#define W_PREFIX 2
+#endif
+
+static int getopt_internal(int, char * const *, const char *,
+ const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+ const struct option *, int *, int, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
+#ifdef GNU_COMPATIBLE
+static int dash_prefix = NO_PREFIX;
+static const char gnuoptchar[] = "invalid option -- %c";
+
+static const char recargstring[] = "option `%s%s' requires an argument";
+static const char ambig[] = "option `%s%.*s' is ambiguous";
+static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
+static const char illoptstring[] = "unrecognized option `%s%s'";
+#else
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptstring[] = "unknown option -- %s";
+#endif
+
+void warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ (void)fprintf(stderr, "%s: ", __progname);
+ if (fmt != NULL)
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+ char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **) nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * parse_long_options --
+ * Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int short_too, int flags)
+{
+ char *current_argv, *has_equal;
+#ifdef GNU_COMPATIBLE
+ char *current_dash;
+#endif
+ size_t current_argv_len;
+ int i, match, exact_match, second_partial_match;
+
+ current_argv = place;
+#ifdef GNU_COMPATIBLE
+ switch (dash_prefix) {
+ case D_PREFIX:
+ current_dash = "-";
+ break;
+ case DD_PREFIX:
+ current_dash = "--";
+ break;
+ case W_PREFIX:
+ current_dash = "-W ";
+ break;
+ default:
+ current_dash = "";
+ break;
+ }
+#endif
+ match = -1;
+ exact_match = 0;
+ second_partial_match = 0;
+
+ optind++;
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) == current_argv_len) {
+ /* exact match */
+ match = i;
+ exact_match = 1;
+ break;
+ }
+ /*
+ * If this is a known short option, don't allow
+ * a partial match of a single character.
+ */
+ if (short_too && current_argv_len == 1)
+ continue;
+
+ if (match == -1) /* first partial match */
+ match = i;
+ else if ((flags & FLAG_LONGONLY) ||
+ long_options[i].has_arg !=
+ long_options[match].has_arg ||
+ long_options[i].flag != long_options[match].flag ||
+ long_options[i].val != long_options[match].val)
+ second_partial_match = 1;
+ }
+ if (!exact_match && second_partial_match) {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ warnx(ambig,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ warnx(noarg,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+#ifdef GNU_COMPATIBLE
+ return (BADCH);
+#else
+ return (BADARG);
+#endif
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':' indicates no error
+ * should be generated.
+ */
+ if (PRINT_ERROR)
+ warnx(recargstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return (BADARG);
+ }
+ } else { /* unknown option */
+ if (short_too) {
+ --optind;
+ return (-1);
+ }
+ if (PRINT_ERROR)
+ warnx(illoptstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (idx)
+ *idx = match;
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ return (0);
+ } else
+ return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int flags)
+{
+ char *oli; /* option letter list index */
+ int optchar, short_too;
+ int posixly_correct; /* no static, can be changed on the fly */
+
+ if (options == NULL)
+ return (-1);
+
+ /*
+ * Disable GNU extensions if POSIXLY_CORRECT is set or options
+ * string begins with a '+'.
+ */
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+#ifdef GNU_COMPATIBLE
+ if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ else if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+#else
+ if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+ else if (*options == '-')
+ flags |= FLAG_ALLARGS;
+#endif
+ if (*options == '+' || *options == '-')
+ options++;
+
+ /*
+ * XXX Some GNU programs (like cvs) set optind to 0 instead of
+ * XXX using optreset. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = optreset = 1;
+
+ optarg = NULL;
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ if (*(place = nargv[optind]) != '-' ||
+#ifdef GNU_COMPATIBLE
+ place[1] == '\0') {
+#else
+ (place[1] == '\0' && strchr(options, '-') == NULL)) {
+#endif
+ place = EMSG; /* found non-option */
+ if (flags & FLAG_ALLARGS) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return (INORDER);
+ }
+ if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If no permutation wanted, stop parsing
+ * at first non-option.
+ */
+ return (-1);
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+
+ /*
+ * If we have "-" do nothing, if "--" we are done.
+ */
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ optind++;
+ place = EMSG;
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ }
+
+ /*
+ * Check long options if:
+ * 1) we were passed some
+ * 2) the arg is not just "-"
+ * 3) either the arg starts with -- we are getopt_long_only()
+ */
+ if (long_options != NULL && place != nargv[optind] &&
+ (*place == '-' || (flags & FLAG_LONGONLY))) {
+ short_too = 0;
+#ifdef GNU_COMPATIBLE
+ dash_prefix = D_PREFIX;
+#endif
+ if (*place == '-') {
+ place++; /* --foo long option */
+#ifdef GNU_COMPATIBLE
+ dash_prefix = DD_PREFIX;
+#endif
+ } else if (*place != ':' && strchr(options, *place) != NULL)
+ short_too = 1; /* could be short option too */
+
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, short_too, flags);
+ if (optchar != -1) {
+ place = EMSG;
+ return (optchar);
+ }
+ }
+
+ if ((optchar = (int)*place++) == (int)':' ||
+ (optchar == (int)'-' && *place != '\0') ||
+ (oli = (char*)strchr(options, optchar)) == NULL) {
+ /*
+ * If the user specified "-" and '-' isn't listed in
+ * options, return -1 (non-option) as per POSIX.
+ * Otherwise, it is an unknown option character (or ':').
+ */
+ if (optchar == (int)'-' && *place == '\0')
+ return (-1);
+ if (!*place)
+ ++optind;
+#ifdef GNU_COMPATIBLE
+ if (PRINT_ERROR)
+ warnx(posixly_correct ? illoptchar : gnuoptchar,
+ optchar);
+#else
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+#endif
+ optopt = optchar;
+ return (BADCH);
+ }
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+ /* -W long-option */
+ if (*place) /* no space */
+ /* NOTHING */;
+ else if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else /* white space */
+ place = nargv[optind];
+#ifdef GNU_COMPATIBLE
+ dash_prefix = W_PREFIX;
+#endif
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, 0, flags);
+ place = EMSG;
+ return (optchar);
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return (optchar);
+}
+
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+ /*
+ * We don't pass FLAG_PERMUTE to getopt_internal() since
+ * the BSD getopt(3) (unlike GNU) has never done this.
+ *
+ * Furthermore, since many privileged programs call getopt()
+ * before dropping privileges it makes sense to keep things
+ * as simple (and bug-free) as possible.
+ */
+ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE|FLAG_LONGONLY));
+}
diff --git a/apps/libc/malloc.c b/apps/libc/malloc.c
new file mode 100644
index 0000000..ab4b8b5
--- /dev/null
+++ b/apps/libc/malloc.c
@@ -0,0 +1,50 @@
+#include <malloc.h>
+#include <types.h>
+#include <string.h>
+
+#include "malloc.h"
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static unsigned long malloc_start;
+static unsigned long malloc_end;
+static unsigned long malloc_brk;
+
+static void *sbrk_no_zero(ptrdiff_t increment)
+{
+ unsigned long old = malloc_brk;
+ unsigned long new = old + increment;
+
+ if ((new < malloc_start) || (new > malloc_end))
+ return NULL;
+
+ malloc_brk = new;
+
+ return (void *)old;
+}
+
+void *sbrk(ptrdiff_t increment)
+{
+ void *old = sbrk_no_zero(increment);
+
+ /* Only clear increment, if valid address was returned */
+ if (old != NULL)
+ memset(old, 0, increment);
+
+ return old;
+}
+
+#ifdef CONFIG_APPS_MALLOC_TLSF
+#include <tlsf.h>
+tlsf_pool tlsf_mem_pool;
+#endif
+
+void mem_malloc_init(void *start, void *end)
+{
+ malloc_start = (unsigned long)start;
+ malloc_end = (unsigned long)end;
+ malloc_brk = malloc_start;
+#ifdef CONFIG_APPS_MALLOC_TLSF
+ tlsf_mem_pool = tlsf_create(start, end - start + 1);
+#endif
+}
diff --git a/apps/libc/malloc.h b/apps/libc/malloc.h
new file mode 100644
index 0000000..7995fb1
--- /dev/null
+++ b/apps/libc/malloc.h
@@ -0,0 +1,2 @@
+
+void mem_malloc_init(void *start, void *end);
diff --git a/apps/libc/private.h b/apps/libc/private.h
new file mode 100644
index 0000000..9a56544
--- /dev/null
+++ b/apps/libc/private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#ifndef __LIBC_PRIVATE_H__
+#define __LIBC_PRIVATE_H__
+
+extern char *__progname;
+int __str_to_flags(const char *mode, int *flag);
+
+struct __file {
+ int fd;
+ struct __file *cookie; /* to check the file is open */
+};
+
+#endif /* __LIBC_PRIVATE_H__ */
diff --git a/apps/libc/stdio.c b/apps/libc/stdio.c
new file mode 100644
index 0000000..82233f7
--- /dev/null
+++ b/apps/libc/stdio.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <fcntl.h>
+
+#include "private.h"
+
+#undef stderr
+#undef stdin
+#undef stdout
+
+FILE stdin = { .fd = 0, .cookie = &stdin, };
+FILE stdout = { .fd = 1, .cookie = &stdout, };
+FILE stderr = { .fd = 2, .cookie = &stderr, };
+
+void putchar(char c)
+{
+ syscall(SYS_putchar, c);
+}
+
+void eputc(char c)
+{
+ syscall(SYS_eputc, c);
+}
+
+int getchar(void)
+{
+ return syscall(SYS_getchar);
+}
+
+int tstc(void)
+{
+ return syscall(SYS_tstc);
+}
+
+int ioctl(int fd, int request, void *buf)
+{
+ return syscall(SYS_ioctl, fd, request, buf);
+}
+
+int eputs(const char *str)
+{
+ const char *s = str;
+ int i = 0;
+
+ while (*s) {
+ eputc(*s);
+ if (*s == '\n')
+ eputc('\r');
+ s++;
+ i++;
+ }
+
+ return i;
+}
+
+int puts(const char *str)
+{
+ const char *s = str;
+ int i = 0;
+
+ while (*s) {
+ putchar(*s);
+ if (*s == '\n')
+ putchar('\r');
+ s++;
+ i++;
+ }
+
+ return i;
+}
+
+int printf(const char *fmt, ...)
+{
+ va_list args;
+ uint i;
+ char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+ va_start(args, fmt);
+ i = vsprintf (printbuffer, fmt, args);
+ va_end(args);
+
+ puts(printbuffer);
+
+ return i;
+}
+
+int vprintf(const char *fmt, va_list args)
+{
+ uint i;
+ char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+ i = vsprintf(printbuffer, fmt, args);
+
+ puts(printbuffer);
+
+ return i;
+}
+
+/* FILE implementation */
+
+static int __files_used = 0;
+
+static void __file_free(FILE *f)
+{
+ free(f);
+ f = NULL;
+ __files_used--;
+}
+
+static bool __file_sanity_check(FILE *f)
+{
+ return f->cookie != NULL;
+}
+
+static FILE *__file_malloc(void)
+{
+ FILE *f;
+
+ if (__files_used >= CONFIG_APP_FILE_MAX)
+ return NULL;
+
+ f = calloc(1, sizeof(*f));
+ if (!f)
+ return NULL;
+
+ f->cookie = f;
+ __files_used++;
+ return f;
+}
+
+int fputs(const char *s, FILE *f)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ if (f == &stdout)
+ return puts(s);
+ else if (f == &stderr)
+ return eputs(s);
+ else
+ return write(f->fd, s, strlen(s));
+}
+
+int fputc(int c, FILE *f)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ if (f == &stdout)
+ putchar(c);
+ else if (f == &stderr)
+ eputc(c);
+ else
+ return write(f->fd, &c, 1);
+
+ return 1;
+}
+
+int vfprintf(FILE *file, const char *fmt, va_list args)
+{
+ char printbuffer[CONFIG_APP_PRINTF_STACK_SIZE];
+
+ vsprintf(printbuffer, fmt, args);
+
+ return fputs(printbuffer, file);
+}
+
+int fprintf(FILE *file, const char *fmt, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+ ret = vfprintf(file, fmt, args);
+ va_end(args);
+
+ return ret;
+}
+
+FILE *fopen(const char *path, const char *mode)
+{
+ int flags;
+ int fd;
+ FILE *f;
+
+ fd = __str_to_flags(mode, &flags);
+ if (fd)
+ return NULL;
+
+ f = __file_malloc();
+ if (!f)
+ return NULL;
+
+ fd = open(mode, flags);
+ if (fd < 0) {
+ __file_free(f);
+ return NULL;
+ }
+
+ f->fd = fd;
+
+ return f;
+}
+
+int fclose(FILE *f)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ if (f == &stderr || f == &stdout || f == &stdin)
+ return -EINVAL;
+
+ close(f->fd);
+
+ __file_free(f);
+
+ return 0;
+}
+
+size_t fread(void *buf, size_t size, size_t nb, FILE *f)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ return read(f->fd, buf, size * nb);
+}
+
+size_t fwrite(const void *buf, size_t size, size_t nb, FILE *f)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ return write(f->fd, buf, size * nb);
+}
+
+int fseek(FILE *f, long offset, int whence)
+{
+ if (!__file_sanity_check(f))
+ return -EINVAL;
+
+ return lseek(f->fd, offset, whence);
+}
+
+char* itoa(int i)
+{
+ char printbuffer[26];
+ char *p = &printbuffer[25];
+ *p-- = '\0';
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+}
diff --git a/apps/libc/stdlib.c b/apps/libc/stdlib.c
new file mode 100644
index 0000000..0ec07ac
--- /dev/null
+++ b/apps/libc/stdlib.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <limits.h>
+#include <malloc.h>
+#include <errno.h>
+#include <ctype.h>
+
+static char env[ENV_MAX];
+
+char *getenv(const char *name)
+{
+ if (syscall(SYS_getenv, name, env))
+ return NULL;
+
+ return env;
+}
+
+int atoi(const char *s)
+{
+ int i = 0;
+ bool minus;
+
+ if (*s == '-') {
+ minus = true;
+ s++;
+ }
+
+ while (isdigit(*s))
+ i = i * 10 + *(s++) - '0';
+ return (minus) ? -i : i;
+}
+
+long atol(const char *s)
+{
+ long i = 0;
+ bool minus;
+
+ if (*s == '-') {
+ minus = true;
+ s++;
+ }
+
+ while (isdigit(*s))
+ i = i * 10 + *(s++) - '0';
+ return (minus) ? -i : i;
+}
+
+long long atoll(const char *s)
+{
+ long long i = 0;
+ bool minus;
+
+ if (*s == '-') {
+ minus = true;
+ s++;
+ }
+
+ while (isdigit(*s))
+ i = i * 10 + *(s++) - '0';
+ return (minus) ? -i : i;
+}
diff --git a/apps/libc/string.c b/apps/libc/string.c
new file mode 100644
index 0000000..67a34f9
--- /dev/null
+++ b/apps/libc/string.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <malloc.h>
+
+void *memcpy(void *dst, const void *src, size_t count)
+{
+ char *d = (char *)dst;
+ const char *s = (const char *)src;
+
+ while (count--)
+ *d++ = *s++;
+
+ return d;
+}
+
+void *memset(void *dst, int val, size_t count)
+{
+ char *d = (char *)dst;
+
+ while (count--)
+ *d++ = (char)val;
+
+ return d;
+}
+
+int memcmp(const void *dst, const void *src, size_t count)
+{
+ const char *d = (const char *)dst;
+ const char *s = (const char *)src;
+ int r = 0;
+
+ while (count-- && (r = *d++ - *s++) == 0) ;
+
+ return r;
+}
+
+unsigned int strlen(const char *s)
+{
+ const char *p;
+
+ for (p = s; *p != '\0'; p++)
+ ;
+ return p - s;
+}
+
+char *strcpy(char *dst, const char *src)
+{
+ char *tmp = dst;
+
+ while ((*dst++ = *src++) != '\0')
+ ;
+
+ return tmp;
+}
+
+int strcmp(const char *s1, const char *s2)
+{
+ signed char res;
+
+ while (1) {
+ res = *s1 - *s2++;
+
+ if (res)
+ break;
+
+ if (!*s1++)
+ break;
+ }
+
+ return res;
+}
+
+int strncmp(const char *s1, const char *s2, size_t count)
+{
+ signed char res;
+
+ while (count--) {
+ res = *s1 - *s2++;
+
+ if (res)
+ break;
+
+ if (!*s1++)
+ break;
+ }
+
+ return res;
+}
+
+char *strchr(const char *s, int c)
+{
+ for (; *s != (char) c; ++s)
+ if (*s == '\0')
+ return NULL;
+
+ return (char *)s;
+}
+
+void *memchr(const void *src, int val, size_t count)
+{
+ const char *s = src;
+
+ while (count--) {
+ if (*s++ == val)
+ return (void*)(s - 1);
+ }
+
+ return NULL;
+}
+
+void *memmove(void *dst, const void *src, size_t count)
+{
+ char *p, *s;
+
+ if (dst <= src) {
+ p = (char *)dst;
+ s = (char *)src;
+ while (count--)
+ *p++ = *s++;
+ } else {
+ p = (char *)dst + count;
+ s = (char *)src + count;
+ while (count--)
+ *--p = *--s;
+ }
+
+ return dst;
+}
+
+char *strdup(const char *s)
+{
+ char *p;
+
+ if (!s)
+ return NULL;
+
+ p = malloc (strlen(s) + 1);
+ if (!p)
+ return NULL;
+
+ strcpy (p, s);
+ return p;
+}
diff --git a/apps/libc/sys/Makefile b/apps/libc/sys/Makefile
new file mode 100644
index 0000000..119f373
--- /dev/null
+++ b/apps/libc/sys/Makefile
@@ -0,0 +1,2 @@
+
+app-y += stat.o
diff --git a/apps/libc/sys/stat.c b/apps/libc/sys/stat.c
new file mode 100644
index 0000000..decc227
--- /dev/null
+++ b/apps/libc/sys/stat.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int mkdir(const char *path, mode_t mode)
+{
+ return syscall(SYS_mkdir, path, mode);
+}
diff --git a/apps/libc/syscalls.c b/apps/libc/syscalls.c
new file mode 100644
index 0000000..796a681
--- /dev/null
+++ b/apps/libc/syscalls.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sections.h>
+
+#include "malloc.h"
+#include "private.h"
+
+int main(int argc, char **argv);
+
+static bool is_valid_syscall(void *addr)
+{
+ return strncmp(addr, SYSCALLS_MAGIC, 8) == 0;
+}
+
+void panic(char *s)
+{
+ puts(s);
+ exit(10);
+}
+
+static void **syscalls;
+static uint32_t nb_syscalls;
+
+int syscall(int num, ...)
+{
+ long (*__syscall)(unsigned long arg0, unsigned long arg1, unsigned long arg2);
+ va_list args;
+ unsigned long arg0;
+ unsigned long arg1;
+ unsigned long arg2;
+ int ret;
+
+ if (num >= nb_syscalls)
+ return -1;
+
+ va_start(args, num);
+ arg0 = va_arg(args, unsigned long);
+ arg1 = va_arg(args, unsigned long);
+ arg2 = va_arg(args, unsigned long);
+ __syscall = syscalls[num];
+ ret = __syscall(arg0, arg1, arg2);
+
+ va_end(args);
+
+ return ret;
+}
+
+int syscalls_parse(struct syscalls_header *sys)
+{
+#ifndef CONFIG_PHYS_ADDR_T_64BIT
+ uint32_t malloc_base = sys->malloc_base & 0xffffffff;
+ uint32_t malloc_end = malloc_base + sys->malloc_size - 1;
+#else
+ uint64_t malloc_base = sys->malloc_base;
+ uint64_t malloc_end = malloc_base + sys->malloc_size - 1;
+#endif
+
+ if (!sys->syscalls)
+ return 1;
+
+ syscalls = sys->syscalls;
+ nb_syscalls = sys->nb_syscalls;
+
+ mem_malloc_init((void *)malloc_base, (void *)malloc_end);
+
+ return 0;
+}
+
+char *__progname;
+
+int app_start(int argc, char **argv)
+{
+ void *sys = _text - 0x2000;
+
+ if (!is_valid_syscall(sys))
+ return EXIT_FAILURE;
+
+ if (syscalls_parse(sys))
+ return EXIT_FAILURE;
+
+ __progname = argv[0];
+
+ return main(argc, argv);
+}
diff --git a/apps/libc/time.c b/apps/libc/time.c
new file mode 100644
index 0000000..6bb57da
--- /dev/null
+++ b/apps/libc/time.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <types.h>
+
+#define SECOND 1000 * 1000 * 1000
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+ int ret;
+
+ if (req->tv_sec) {
+ ret = syscall(SYS_ndelay, req->tv_sec * SECOND);
+ if (ret)
+ return ret;
+ }
+
+ if (!req->tv_nsec)
+ return 0;
+
+ if (req->tv_nsec > 999999999)
+ return -1;
+
+ return syscall(SYS_ndelay, req->tv_nsec);
+}
diff --git a/apps/libc/unistd.c b/apps/libc/unistd.c
new file mode 100644
index 0000000..ea92604
--- /dev/null
+++ b/apps/libc/unistd.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <barebox/syscalls.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <string.h>
+#include <malloc.h>
+#include <limits.h>
+
+int read(int fd, void *buf, size_t count)
+{
+ return syscall(SYS_read, fd, buf, count);
+}
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+ return syscall(SYS_write, fd, buf, count);
+}
+
+int close(int fd)
+{
+ return syscall(SYS_close, fd);
+}
+
+int unlink(const char *pathname)
+{
+ return syscall(SYS_unlink, pathname);
+}
+
+int stat(const char *path, struct stat *buf)
+{
+ return syscall(SYS_stat, path, buf);
+}
+
+int lstat(const char *path, struct stat *buf)
+{
+ return syscall(SYS_lstat, path, buf);
+}
+
+loff_t lseek(int fd, loff_t offset, int whence)
+{
+ return syscall(SYS_lseek, fd, offset, whence);
+}
+
+int symlink(const char *pathname, const char *newpath)
+{
+ return syscall(SYS_symlink, pathname, newpath);
+}
+
+ssize_t readlink(const char *path, char *buf, size_t bufsiz)
+{
+ return syscall(SYS_readlink, path, buf, bufsiz);
+}
+
+int rmdir(const char *path)
+{
+ return syscall(SYS_rmdir, path);
+}
+
+char *get_current_dir_name(void)
+{
+ size_t size = sizeof(char) * PATH_MAX;
+ char *cwd = malloc(size);
+
+ if (!cwd)
+ return NULL;
+
+ if (syscall(SYS_getcwd, cwd, size))
+ goto err;
+
+ return cwd;
+
+err:
+ free(cwd);
+ return NULL;
+}
+
+char *getcwd(char *buf, size_t size)
+{
+ if (syscall(SYS_getcwd, buf, size))
+ return NULL;
+
+ return buf;
+}
+
+int chdir(const char *path)
+{
+ return syscall(SYS_chdir, path);
+}
+
+int usleep(unsigned int usec)
+{
+ return syscall(SYS_ndelay, usec * 1000);
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 06/20] app: add some utils
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (3 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 05/20] app: Introduce libc support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 21:21 ` Sascha Hauer
2013-03-06 9:29 ` [PATCH 07/20] app: Introduce example application Jean-Christophe PLAGNIOL-VILLARD
` (13 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
- getchar_timeout
- term (try to detect terminal size, position, ansi helper)
- list
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Makefile | 1 +
apps/include/utils/ansi.h | 37 ++++++++++++++
apps/include/utils/getchar.h | 22 ++++++++
apps/include/utils/list.h | 114 ++++++++++++++++++++++++++++++++++++++++++
apps/include/utils/termcap.h | 23 +++++++++
apps/utils/Makefile | 2 +
apps/utils/getchar.c | 43 ++++++++++++++++
apps/utils/termcap.c | 97 +++++++++++++++++++++++++++++++++++
8 files changed, 339 insertions(+)
create mode 100644 apps/include/utils/ansi.h
create mode 100644 apps/include/utils/getchar.h
create mode 100644 apps/include/utils/list.h
create mode 100644 apps/include/utils/termcap.h
create mode 100644 apps/utils/Makefile
create mode 100644 apps/utils/getchar.c
create mode 100644 apps/utils/termcap.c
diff --git a/apps/Makefile b/apps/Makefile
index c5c5c48..28efb0d 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -16,6 +16,7 @@ $(obj)/include/barebox/syscalls.h: $(srctree)/include/apps/syscalls.h
$(call cmd,shipped)
obj-y += libc/
+obj-y += utils/
barebox-app-header += $(obj)/include/types.h
barebox-app-header += $(obj)/include/barebox/syscalls.h
diff --git a/apps/include/utils/ansi.h b/apps/include/utils/ansi.h
new file mode 100644
index 0000000..64f81a8
--- /dev/null
+++ b/apps/include/utils/ansi.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __UTILS_ANSI_H__
+#define __UTILS_ANSI_H__
+
+#define ansi_escape_m(d) printf("\e[%dm", d);
+#define ansi_save_cusror() printf("\e[s")
+#define ansi_restore_cusror() printf("\e[u")
+#define ansi_set_cursor(row, col) printf("\e[%d;%dH", row, col)
+#define ansi_reverse(on) ansi_escape_m((on) ? 7 : 27)
+#define ansi_start_reverse() ansi_escape_m(7)
+#define ansi_end_reverse() ansi_escape_m(27)
+#define ansi_cursor_enable(on) printf( "\e[?25%c", ( on ) ? 'h' : 'l' );
+#define ansi_clear() printf("\e[2J\e[;H");
+#define ansi_bold(on) ansi_escape_m((on) ? 1 : 22)
+#define ansi_blink(on) ansi_escape_m((on) ? 5 : 25)
+#define ansi_start_bold() ansi_escape_m(1)
+#define ansi_end_bold() ansi_escape_m(22)
+#define ansi_start_altcharset() ansi_escape_m(14)
+#define ansi_end_altcharset() ansi_escape_m(10)
+#define ansi_set_color(fg,bg) printf("\e[%d;%dm", fg, bg)
+
+#endif /* __UTILS_ANSI_H__ */
diff --git a/apps/include/utils/getchar.h b/apps/include/utils/getchar.h
new file mode 100644
index 0000000..074d6b2
--- /dev/null
+++ b/apps/include/utils/getchar.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __UTILS_GETCHAR_H__
+#define __UTILS_GETCHAR_H__
+
+int getchar_timeout(int ms);
+
+#endif /* __UTILS_GETCHAR_H__ */
diff --git a/apps/include/utils/list.h b/apps/include/utils/list.h
new file mode 100644
index 0000000..8a18dae
--- /dev/null
+++ b/apps/include/utils/list.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __UTILS_LIST_H__
+#define __UTILS_LIST_H__
+
+struct list_entry {
+ struct list_entry *prev;
+ struct list_entry *next;
+};
+
+struct list {
+ struct list_entry head;
+};
+
+#define LIST_HEAD_INIT(name) \
+ { \
+ .head = { \
+ .prev = &(name).head, \
+ .next = &(name).head \
+ } \
+ }
+
+#define LIST_HEAD(name) \
+ struct list name = LIST_HEAD_INIT(name)
+
+#define container_of(ptr, type, member) \
+ ((type *) (((void *)(ptr)) - ((void *) &(((type *)0)->member))))
+
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->head.next, type, member)
+
+#define list_last_entry(head, type, member) \
+ list_entry((head)->head.prev, type, member)
+
+#define list_for_each(pos, list) \
+ for (pos = (list).head.next; pos != &(list).head; pos = pos->next)
+
+#define list_foreach_safe(pos, n, list) \
+ for (pos = (list).head.next, *n = pos->next; \
+ pos != &(list).head; pos = n, n = pos->next)
+
+#define list_for_each_entry(pos, list, member) \
+ for (pos = list_entry((list)->head.next, typeof(*pos), member); \
+ &pos->member != (&(list)->head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+
+#define list_for_each_entry_safe(pos, n, list, member) \
+ for (pos = list_entry((list)->head.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (&(list)->head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+
+static inline bool list_empty(struct list *list)
+{
+ struct list_entry *head = &list->head;
+
+ return head->next == head;
+}
+
+static inline void __list_add(struct list_entry *new,
+ struct list_entry *prev,
+ struct list_entry *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+static inline void list_add(struct list_entry *new, struct list *list)
+{
+ struct list_entry *head = &list->head;
+
+ __list_add(new, head, head->next);
+}
+
+static inline void list_add_tail(struct list_entry *new, struct list *list)
+{
+ struct list_entry *head = &list->head;
+
+ __list_add(new, head->prev, head);
+}
+
+static inline void list_del(struct list_entry *entry)
+{
+ struct list_entry *prev = entry->prev;
+ struct list_entry *next = entry->next;
+
+ next->prev = prev;
+ prev->next = next;
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+#endif /* __UTILS_LIST_H__ */
diff --git a/apps/include/utils/termcap.h b/apps/include/utils/termcap.h
new file mode 100644
index 0000000..b4305a2
--- /dev/null
+++ b/apps/include/utils/termcap.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __TERMCAP_H__
+#define __TERMCAP_H__
+
+int term_get_size(int *row, int *col);
+int term_get_cursor_pos(int *row, int *col);
+
+#endif /* __TERMCAP_H__ */
diff --git a/apps/utils/Makefile b/apps/utils/Makefile
new file mode 100644
index 0000000..f5b7476
--- /dev/null
+++ b/apps/utils/Makefile
@@ -0,0 +1,2 @@
+app-y += termcap.o
+app-y += getchar.o
diff --git a/apps/utils/getchar.c b/apps/utils/getchar.c
new file mode 100644
index 0000000..e511613
--- /dev/null
+++ b/apps/utils/getchar.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <types.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <utils/getchar.h>
+
+int getchar_timeout(int ms)
+{
+ struct timespec req, rem;
+ int ret;
+
+ req.tv_nsec = 10;
+ req.tv_sec = 0;
+ ms *= 100;
+
+ while (!tstc()) {
+ ret = nanosleep(&req, &rem);
+ if (ret)
+ return ret;
+
+ if (!ms--)
+ return -ETIMEDOUT;
+ }
+
+ return getchar();
+}
diff --git a/apps/utils/termcap.c b/apps/utils/termcap.c
new file mode 100644
index 0000000..dd24f66
--- /dev/null
+++ b/apps/utils/termcap.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <utils/getchar.h>
+#include <utils/termcap.h>
+#include <utils/ansi.h>
+
+#define TIMEOUT_GETC 10
+#define MAX_COL_ROW 9999
+
+static int getnum(char end)
+{
+ int i = 0;
+ int c;
+
+ while ((c = getchar_timeout(TIMEOUT_GETC)) > -1) {
+ if (c == end)
+ return i;
+
+ if (c < 0)
+ return c;
+
+ if (!isdigit(c))
+ return -1;
+
+ i *= 10;
+ i += c - '0';
+ }
+
+ return -1;
+}
+
+int term_get_cursor_pos(int *row, int *col)
+{
+ int c;
+ int __row;
+
+ /* request cursos position */
+ printf("\e[6n");
+
+ /* reply \e[%d;%dR */
+ c = getchar_timeout(TIMEOUT_GETC);
+ if (c != '\e')
+ return -1;
+
+ c = getchar_timeout(TIMEOUT_GETC);
+ if (c != '[')
+ return -1;
+
+ __row = getnum(';');
+ if (__row < 0)
+ return __row;
+
+ c = getnum('R');
+ if (c < 0)
+ return c;
+
+ *row = __row;
+ *col = c;
+
+ return 0;
+}
+
+int term_get_size(int *row, int *col)
+{
+ ansi_save_cusror();
+
+ /* reset scroll */
+ printf("\e[r");
+
+ /* move the cursos to the bottom-right */
+ ansi_set_cursor(MAX_COL_ROW, MAX_COL_ROW);
+
+ term_get_cursor_pos(row, col);
+
+ /* restore cursor */
+ ansi_restore_cusror();
+
+ return 0;
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 06/20] app: add some utils
2013-03-06 9:29 ` [PATCH 06/20] app: add some utils Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 21:21 ` Sascha Hauer
2013-03-06 21:34 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 31+ messages in thread
From: Sascha Hauer @ 2013-03-06 21:21 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Wed, Mar 06, 2013 at 10:29:35AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> - getchar_timeout
> - term (try to detect terminal size, position, ansi helper)
> - list
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
> diff --git a/apps/include/utils/list.h b/apps/include/utils/list.h
> new file mode 100644
> index 0000000..8a18dae
> --- /dev/null
> +++ b/apps/include/utils/list.h
> @@ -0,0 +1,114 @@
> +/*
> + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
> + *
> + * Under GPLv2 only
> + *
> + * As a special exception, if other files instantiate templates or use macros
> + * or inline functions from this file, or you compile this file and link it
> + * with other works to produce a work based on this file, this file does not
> + * by itself cause the resulting work to be covered by the GNU General Public
> + * License. However the source code for this file must still be made available
> + * in accordance with section (3) of the GNU General Public License.
> +
> + * This exception does not invalidate any other reasons why a work based on
> + * this file might be covered by the GNU General Public License.
> + */
This looks suspiciously like the Linux list implementation which I think you
haven't written. Also who gives you the right to add this licence
exception to code you do not own?
Sascha
> +
> +#ifndef __UTILS_LIST_H__
> +#define __UTILS_LIST_H__
> +
> +struct list_entry {
> + struct list_entry *prev;
> + struct list_entry *next;
> +};
> +
> +struct list {
> + struct list_entry head;
> +};
> +
> +#define LIST_HEAD_INIT(name) \
> + { \
> + .head = { \
> + .prev = &(name).head, \
> + .next = &(name).head \
> + } \
> + }
> +
> +#define LIST_HEAD(name) \
> + struct list name = LIST_HEAD_INIT(name)
> +
> +#define container_of(ptr, type, member) \
> + ((type *) (((void *)(ptr)) - ((void *) &(((type *)0)->member))))
> +
> +#define list_entry(ptr, type, member) \
> + container_of(ptr, type, member)
> +
> +#define list_first_entry(ptr, type, member) \
> + list_entry((ptr)->head.next, type, member)
> +
> +#define list_last_entry(head, type, member) \
> + list_entry((head)->head.prev, type, member)
> +
> +#define list_for_each(pos, list) \
> + for (pos = (list).head.next; pos != &(list).head; pos = pos->next)
> +
> +#define list_foreach_safe(pos, n, list) \
> + for (pos = (list).head.next, *n = pos->next; \
> + pos != &(list).head; pos = n, n = pos->next)
> +
> +#define list_for_each_entry(pos, list, member) \
> + for (pos = list_entry((list)->head.next, typeof(*pos), member); \
> + &pos->member != (&(list)->head); \
> + pos = list_entry(pos->member.next, typeof(*pos), member))
> +
> +
> +#define list_for_each_entry_safe(pos, n, list, member) \
> + for (pos = list_entry((list)->head.next, typeof(*pos), member), \
> + n = list_entry(pos->member.next, typeof(*pos), member); \
> + &pos->member != (&(list)->head); \
> + pos = n, n = list_entry(n->member.next, typeof(*n), member))
> +
> +
> +static inline bool list_empty(struct list *list)
> +{
> + struct list_entry *head = &list->head;
> +
> + return head->next == head;
> +}
> +
> +static inline void __list_add(struct list_entry *new,
> + struct list_entry *prev,
> + struct list_entry *next)
> +{
> + next->prev = new;
> + new->next = next;
> + new->prev = prev;
> + prev->next = new;
> +}
> +
> +static inline void list_add(struct list_entry *new, struct list *list)
> +{
> + struct list_entry *head = &list->head;
> +
> + __list_add(new, head, head->next);
> +}
> +
> +static inline void list_add_tail(struct list_entry *new, struct list *list)
> +{
> + struct list_entry *head = &list->head;
> +
> + __list_add(new, head->prev, head);
> +}
> +
> +static inline void list_del(struct list_entry *entry)
> +{
> + struct list_entry *prev = entry->prev;
> + struct list_entry *next = entry->next;
> +
> + next->prev = prev;
> + prev->next = next;
> + entry->next = NULL;
> + entry->prev = NULL;
> +}
> +
> +#endif /* __UTILS_LIST_H__ */
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 06/20] app: add some utils
2013-03-06 21:21 ` Sascha Hauer
@ 2013-03-06 21:34 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-07 7:45 ` Sascha Hauer
0 siblings, 1 reply; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 21:34 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 22:21 Wed 06 Mar , Sascha Hauer wrote:
> On Wed, Mar 06, 2013 at 10:29:35AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > - getchar_timeout
> > - term (try to detect terminal size, position, ansi helper)
> > - list
> >
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > ---
> > diff --git a/apps/include/utils/list.h b/apps/include/utils/list.h
> > new file mode 100644
> > index 0000000..8a18dae
> > --- /dev/null
> > +++ b/apps/include/utils/list.h
> > @@ -0,0 +1,114 @@
> > +/*
> > + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
> > + *
> > + * Under GPLv2 only
> > + *
> > + * As a special exception, if other files instantiate templates or use macros
> > + * or inline functions from this file, or you compile this file and link it
> > + * with other works to produce a work based on this file, this file does not
> > + * by itself cause the resulting work to be covered by the GNU General Public
> > + * License. However the source code for this file must still be made available
> > + * in accordance with section (3) of the GNU General Public License.
> > +
> > + * This exception does not invalidate any other reasons why a work based on
> > + * this file might be covered by the GNU General Public License.
> > + */
>
> This looks suspiciously like the Linux list implementation which I think you
> haven't written. Also who gives you the right to add this licence
> exception to code you do not own?
I did wrote this for years about 10 I just update the code to looks like the
linux one so I do own the code
Best Regards,
J.
>
> Sascha
>
> > +
> > +#ifndef __UTILS_LIST_H__
> > +#define __UTILS_LIST_H__
> > +
> > +struct list_entry {
> > + struct list_entry *prev;
> > + struct list_entry *next;
> > +};
> > +
> > +struct list {
> > + struct list_entry head;
> > +};
> > +
> > +#define LIST_HEAD_INIT(name) \
> > + { \
> > + .head = { \
> > + .prev = &(name).head, \
> > + .next = &(name).head \
> > + } \
> > + }
> > +
> > +#define LIST_HEAD(name) \
> > + struct list name = LIST_HEAD_INIT(name)
> > +
> > +#define container_of(ptr, type, member) \
> > + ((type *) (((void *)(ptr)) - ((void *) &(((type *)0)->member))))
> > +
> > +#define list_entry(ptr, type, member) \
> > + container_of(ptr, type, member)
> > +
> > +#define list_first_entry(ptr, type, member) \
> > + list_entry((ptr)->head.next, type, member)
> > +
> > +#define list_last_entry(head, type, member) \
> > + list_entry((head)->head.prev, type, member)
> > +
> > +#define list_for_each(pos, list) \
> > + for (pos = (list).head.next; pos != &(list).head; pos = pos->next)
> > +
> > +#define list_foreach_safe(pos, n, list) \
> > + for (pos = (list).head.next, *n = pos->next; \
> > + pos != &(list).head; pos = n, n = pos->next)
> > +
> > +#define list_for_each_entry(pos, list, member) \
> > + for (pos = list_entry((list)->head.next, typeof(*pos), member); \
> > + &pos->member != (&(list)->head); \
> > + pos = list_entry(pos->member.next, typeof(*pos), member))
> > +
> > +
> > +#define list_for_each_entry_safe(pos, n, list, member) \
> > + for (pos = list_entry((list)->head.next, typeof(*pos), member), \
> > + n = list_entry(pos->member.next, typeof(*pos), member); \
> > + &pos->member != (&(list)->head); \
> > + pos = n, n = list_entry(n->member.next, typeof(*n), member))
> > +
> > +
> > +static inline bool list_empty(struct list *list)
> > +{
> > + struct list_entry *head = &list->head;
> > +
> > + return head->next == head;
> > +}
> > +
> > +static inline void __list_add(struct list_entry *new,
> > + struct list_entry *prev,
> > + struct list_entry *next)
> > +{
> > + next->prev = new;
> > + new->next = next;
> > + new->prev = prev;
> > + prev->next = new;
> > +}
> > +
> > +static inline void list_add(struct list_entry *new, struct list *list)
> > +{
> > + struct list_entry *head = &list->head;
> > +
> > + __list_add(new, head, head->next);
> > +}
> > +
> > +static inline void list_add_tail(struct list_entry *new, struct list *list)
> > +{
> > + struct list_entry *head = &list->head;
> > +
> > + __list_add(new, head->prev, head);
> > +}
> > +
> > +static inline void list_del(struct list_entry *entry)
> > +{
> > + struct list_entry *prev = entry->prev;
> > + struct list_entry *next = entry->next;
> > +
> > + next->prev = prev;
> > + prev->next = next;
> > + entry->next = NULL;
> > + entry->prev = NULL;
> > +}
> > +
> > +#endif /* __UTILS_LIST_H__ */
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 06/20] app: add some utils
2013-03-06 21:34 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-07 7:45 ` Sascha Hauer
2013-03-07 9:17 ` Alexander Aring
0 siblings, 1 reply; 31+ messages in thread
From: Sascha Hauer @ 2013-03-07 7:45 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Wed, Mar 06, 2013 at 10:34:44PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 22:21 Wed 06 Mar , Sascha Hauer wrote:
> > On Wed, Mar 06, 2013 at 10:29:35AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > - getchar_timeout
> > > - term (try to detect terminal size, position, ansi helper)
> > > - list
> > >
> > > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > > ---
> > > diff --git a/apps/include/utils/list.h b/apps/include/utils/list.h
> > > new file mode 100644
> > > index 0000000..8a18dae
> > > --- /dev/null
> > > +++ b/apps/include/utils/list.h
> > > @@ -0,0 +1,114 @@
> > > +/*
> > > + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
> > > + *
> > > + * Under GPLv2 only
> > > + *
> > > + * As a special exception, if other files instantiate templates or use macros
> > > + * or inline functions from this file, or you compile this file and link it
> > > + * with other works to produce a work based on this file, this file does not
> > > + * by itself cause the resulting work to be covered by the GNU General Public
> > > + * License. However the source code for this file must still be made available
> > > + * in accordance with section (3) of the GNU General Public License.
> > > +
> > > + * This exception does not invalidate any other reasons why a work based on
> > > + * this file might be covered by the GNU General Public License.
> > > + */
> >
> > This looks suspiciously like the Linux list implementation which I think you
> > haven't written. Also who gives you the right to add this licence
> > exception to code you do not own?
> I did wrote this for years about 10 I just update the code to looks like the
> linux one so I do own the code
LOL. I've written my own OS 25 years ago, I just updated the code to look
like Linux.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 06/20] app: add some utils
2013-03-07 7:45 ` Sascha Hauer
@ 2013-03-07 9:17 ` Alexander Aring
0 siblings, 0 replies; 31+ messages in thread
From: Alexander Aring @ 2013-03-07 9:17 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On Thu, Mar 07, 2013 at 08:45:03AM +0100, Sascha Hauer wrote:
> On Wed, Mar 06, 2013 at 10:34:44PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 22:21 Wed 06 Mar , Sascha Hauer wrote:
> > > On Wed, Mar 06, 2013 at 10:29:35AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > > - getchar_timeout
> > > > - term (try to detect terminal size, position, ansi helper)
> > > > - list
> > > >
> > > > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > > > ---
> > > > diff --git a/apps/include/utils/list.h b/apps/include/utils/list.h
> > > > new file mode 100644
> > > > index 0000000..8a18dae
> > > > --- /dev/null
> > > > +++ b/apps/include/utils/list.h
> > > > @@ -0,0 +1,114 @@
> > > > +/*
> > > > + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
> > > > + *
> > > > + * Under GPLv2 only
> > > > + *
> > > > + * As a special exception, if other files instantiate templates or use macros
> > > > + * or inline functions from this file, or you compile this file and link it
> > > > + * with other works to produce a work based on this file, this file does not
> > > > + * by itself cause the resulting work to be covered by the GNU General Public
> > > > + * License. However the source code for this file must still be made available
> > > > + * in accordance with section (3) of the GNU General Public License.
> > > > +
> > > > + * This exception does not invalidate any other reasons why a work based on
> > > > + * this file might be covered by the GNU General Public License.
> > > > + */
> > >
> > > This looks suspiciously like the Linux list implementation which I think you
> > > haven't written. Also who gives you the right to add this licence
> > > exception to code you do not own?
> > I did wrote this for years about 10 I just update the code to looks like the
> > linux one so I do own the code
>
> LOL. I've written my own OS 25 years ago, I just updated the code to look
> like Linux.
>
lol... other question: why we need a second list implementation?
In order to not be dependent on linux headers?
Alex
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 07/20] app: Introduce example application
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (4 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 06/20] app: add some utils Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 08/20] filetype: add barebox arm application Jean-Christophe PLAGNIOL-VILLARD
` (12 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 3 +
apps/Makefile | 5 ++
apps/example/Makefile | 14 +++
apps/example/example.h | 7 ++
apps/example/list.c | 98 ++++++++++++++++++++
apps/example/ls.c | 127 ++++++++++++++++++++++++++
apps/example/main.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++
apps/example/setjmp.c | 24 +++++
8 files changed, 509 insertions(+)
create mode 100644 apps/example/Makefile
create mode 100644 apps/example/example.h
create mode 100644 apps/example/list.c
create mode 100644 apps/example/ls.c
create mode 100644 apps/example/main.c
create mode 100644 apps/example/setjmp.c
diff --git a/apps/Kconfig b/apps/Kconfig
index 4805c50..324e14d 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -37,4 +37,7 @@ config APP_FILE_MAX
endmenu
+config APP_EXAMPLE
+ bool "example"
+
endif
diff --git a/apps/Makefile b/apps/Makefile
index 28efb0d..7f609e7 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -5,6 +5,8 @@ export APP_CPPFLAGS
apps-$(CONFIG_APP_EXAMPLE) += example
+apps-$(CONFIG_APP_EXAMPLE) += example
+
$(obj)/application: $(apps-lds) $(apps-y)
APP_CPPFLAGS += -fdata-sections -ffunction-sections
@@ -20,3 +22,6 @@ obj-y += utils/
barebox-app-header += $(obj)/include/types.h
barebox-app-header += $(obj)/include/barebox/syscalls.h
+
+$(apps-y): $(barebox-app-header) $(barebox-app-common)
+ $(Q)$(MAKE) $(build)=apps/$@ apps/$@/$@.app
diff --git a/apps/example/Makefile b/apps/example/Makefile
new file mode 100644
index 0000000..22f8d68
--- /dev/null
+++ b/apps/example/Makefile
@@ -0,0 +1,14 @@
+targets := example.map
+
+# Make sure files are removed during clean
+extra-y += example.map
+
+app-y += main.o
+app-y += ls.o
+app-y += list.o
+app-y += setjmp.o
+app-final-y = example
+
+OBJCOPYFLAGS_example.app = -O binary
+LDFLAGS_apps := -Map $(obj)/example.map
+LDFLAGS_apps += -static --gc-sections
diff --git a/apps/example/example.h b/apps/example/example.h
new file mode 100644
index 0000000..34675b4
--- /dev/null
+++ b/apps/example/example.h
@@ -0,0 +1,7 @@
+
+#define LS_RECURSIVE 1
+#define LS_SHOWARG 2
+#define LS_COLUMN 4
+int ls(const char *path, ulong flags);
+void test_list(void);
+void test_setjmp(void);
diff --git a/apps/example/list.c b/apps/example/list.c
new file mode 100644
index 0000000..fd5662d
--- /dev/null
+++ b/apps/example/list.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <appinfo.h>
+#include <utils/list.h>
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static LIST_HEAD(test);
+
+struct data {
+ char *name;
+ struct list_entry list;
+};
+
+struct data data[] = {
+ [0] = { .name = "data0", },
+ [1] = { .name = "data1", },
+ [2] = { .name = "data2", },
+ [3] = { .name = "data3", },
+};
+
+static void dump_list(void)
+{
+ struct list_entry *pos;
+ struct data *d;
+ int i;
+
+ i = 0;
+ list_for_each(pos, test) {
+ printf("data[%d].list = %p\n", i, pos);
+ i++;
+ }
+
+ i = 0;
+ list_for_each_entry(d, &test, list) {
+ printf("data[%d].name = %s\n", i, d->name);
+ printf("data[%d].list = %p\n", i, &d->list);
+ i++;
+ }
+}
+
+static void empty_list(void)
+{
+ struct data *d, *tmp;
+ int i;
+
+ i = 0;
+ list_for_each_entry_safe(d, tmp, &test, list) {
+ printf("data[%d].name = %s\n", i, d->name);
+ printf("data[%d].list = %p\n", i, &d->list);
+ list_del(&d->list);
+ i++;
+ }
+}
+
+void test_list(void)
+{
+ int i;
+
+ puts("------ list test ------\n");
+
+ puts("fill list\n");
+
+ for (i = 0; i < ARRAY_SIZE(data); i++) {
+ printf("data[%d].name = %s\n", i, data[i].name);
+ printf("data[%d].list = %p\n", i, &data[i].list);
+ list_add(&data[i].list, &test);
+ }
+
+ puts("dump list\n");
+ dump_list();
+ puts("remove entry 2\n");
+ list_del(&data[2].list);
+ puts("dump list\n");
+ dump_list();
+ puts("empty list\n");
+ empty_list();
+ puts("dump list\n");
+ dump_list();
+ printf("list is %s\n", list_empty(&test) ? "empty" : "filled");
+
+ puts("fill list tail\n");
+ for (i = 0; i < ARRAY_SIZE(data); i++) {
+ printf("data[%d].name = %s\n", i, data[i].name);
+ printf("data[%d].list = %p\n", i, &data[i].list);
+ list_add_tail(&data[i].list, &test);
+ }
+ puts("dump list\n");
+ dump_list();
+
+ puts("------ end ------\n\n");
+}
diff --git a/apps/example/ls.c b/apps/example/ls.c
new file mode 100644
index 0000000..bad0ccb
--- /dev/null
+++ b/apps/example/ls.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "example.h"
+
+static char *mkmodestr(unsigned long mode, char *str)
+{
+ static const char *l = "xwr";
+ int mask = 1, i;
+ char c;
+
+ switch (mode & S_IFMT) {
+ case S_IFDIR: str[0] = 'd'; break;
+ case S_IFBLK: str[0] = 'b'; break;
+ case S_IFCHR: str[0] = 'c'; break;
+ case S_IFIFO: str[0] = 'f'; break;
+ case S_IFLNK: str[0] = 'l'; break;
+ case S_IFSOCK: str[0] = 's'; break;
+ case S_IFREG: str[0] = '-'; break;
+ default: str[0] = '?';
+ }
+
+ for(i = 0; i < 9; i++) {
+ c = l[i%3];
+ str[9-i] = (mode & mask)?c:'-';
+ mask = mask<<1;
+ }
+
+ if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S';
+ if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S';
+ if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T';
+ str[10] = '\0';
+ return str;
+}
+
+static void ls_one(const char *path, const char* fullname, struct stat *s)
+{
+ char modestr[11];
+ unsigned int namelen = strlen(path);
+
+ mkmodestr(s->st_mode, modestr);
+ printf("%s %10llu %*.*s", modestr, s->st_size, namelen, namelen, path);
+
+ if (S_ISLNK(s->st_mode)) {
+ char realname[PATH_MAX];
+
+ memset(realname, 0, PATH_MAX);
+
+ if (readlink(fullname, realname, PATH_MAX - 1) >= 0)
+ printf(" -> %s", realname);
+ }
+
+ puts("\n");
+}
+
+int ls(const char *path, ulong flags)
+{
+ DIR *dir;
+ struct dirent *d;
+ char tmp[PATH_MAX];
+ struct stat s;
+
+ if (lstat(path, &s))
+ return -1;
+
+ if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
+ printf("%s:\n", path);
+
+ if (!(s.st_mode & S_IFDIR)) {
+ ls_one(path, path, &s);
+ return 0;
+ }
+
+ dir = opendir(path);
+ if (!dir)
+ return -1;
+
+ while ((d = readdir(dir))) {
+ sprintf(tmp, "%s/%s", path, d->d_name);
+ if (!strlen(d->d_name))
+ break;
+ if (lstat(tmp, &s))
+ goto out;
+ ls_one(d->d_name, tmp, &s);
+ }
+
+ closedir(dir);
+
+ if (!(flags & LS_RECURSIVE))
+ return 0;
+
+ dir = opendir(path);
+ if (!dir)
+ return -ENOENT;
+
+ while ((d = readdir(dir))) {
+
+ if (!strcmp(d->d_name, "."))
+ continue;
+ if (!strcmp(d->d_name, ".."))
+ continue;
+ sprintf(tmp, "%s/%s", path, d->d_name);
+
+ if (lstat(tmp, &s))
+ goto out;
+ if (s.st_mode & S_IFDIR)
+ ls(tmp, flags);
+ }
+out:
+ closedir(dir);
+
+ return 0;
+}
diff --git a/apps/example/main.c b/apps/example/main.c
new file mode 100644
index 0000000..12fb7f0
--- /dev/null
+++ b/apps/example/main.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+*/
+
+#include <stdio.h>
+#include <malloc.h>
+#include <appinfo.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sections.h>
+#include <sys/stat.h>
+
+#include "example.h"
+
+# define PUTHEX_LL(value) ({ unsigned long v = (unsigned long) (value); \
+ int i; unsigned char ch; \
+ for (i = 8; i--; ) {\
+ ch = ((v >> (i*4)) & 0xf);\
+ ch += (ch >= 10) ? 'a' - 10 : '0';\
+ putchar(ch); }})
+static void test_ls(void)
+{
+ puts(
+ "------ test 1 ------ \n"
+ "coverage:\n"
+ " - opendir/readdir/closedir\n"
+ " - lstat\n"
+ " - readlink\n"
+ "------ start ------ \n");
+
+ puts("ls -l /env/config\n");
+ ls("/env/config", 0);
+ puts("ls -l /dev\n");
+ ls("/dev", 0);
+ puts("ls -l /env\n");
+ ls("/env", 0);
+ puts("------ end ------\n\n");
+}
+
+static void print_ok_failed(int ret)
+{
+ if (ret)
+ printf("failed (%d)\n", ret);
+ else
+ puts(" => OK\n");
+}
+
+static void test_mkdir(void)
+{
+ int fd;
+ int ret;
+ char *test = "/test";
+ char *test_tmp = "/test/tmp";
+ char *readme_txt = "/test/readme.txt";
+ char *readme = "/test/readme";
+ char *txt = "test barebox app\n";
+
+ puts(
+ "------ test 2 ------ \n"
+ "coverage:\n"
+ " - mkdir/rmdir\n"
+ " - open/write\n"
+ " - symlink/unlink\n"
+ "------ start ------ \n");
+
+ printf("mkdir %s ", test);
+ ret = mkdir(test, 0666);
+ print_ok_failed(ret);
+ if (ret)
+ return;
+
+ printf("create %s ", readme_txt);
+ fd = open(readme_txt, O_CREAT | O_WRONLY);
+ if (fd >= 0) {
+ puts(" => OK\n");
+ ret = write(fd, txt, strlen(txt) + 1);
+ if (!ret)
+ printf("fprintf on fd=%d failer (%d)\n", fd, ret);
+ close(fd);
+ } else {
+ printf("failed (%d)\n", fd);
+ }
+
+ printf("ln -s %s %s ", readme_txt, readme);
+ ret = symlink(readme_txt, readme);
+ print_ok_failed(ret);
+
+ printf("mkdir %s ", test_tmp);
+ ret = mkdir(test_tmp, 0666);
+ print_ok_failed(ret);
+
+ printf("ls -l %s\n", test);
+ ls(test, 0);
+
+ if (!ret) {
+ printf("rmdir %s ", test_tmp);
+ ret = rmdir(test_tmp);
+ print_ok_failed(ret);
+ }
+
+ printf("unlink %s ", readme);
+ ret = unlink(readme);
+ print_ok_failed(ret);
+
+ printf("ls -l %s\n", test);
+ ls(test, 0);
+
+ puts("------ end ------\n\n");
+}
+
+static void test_printf(int argc, char **argv)
+{
+ int i;
+ char *test;
+
+ puts("hello world\n");
+ test = malloc(10);
+ puts("mallox of 10 => 0x");
+ PUTHEX_LL(test);
+ puts("\n");
+
+ puts("------ printf test ------\n");
+
+ for (i = 0; i < argc; i++)
+ printf("argv[%d] = %s\n", i, argv[i]);
+
+ printf("mallox of %d => %p\n", 10, test);
+ puts("------ end ------\n\n");
+}
+
+static void test_all(int argc, char **argv)
+{
+ test_printf(argc, argv);
+ test_ls();
+ test_mkdir();
+ test_list();
+ test_setjmp();
+}
+
+void usage(char *name)
+{
+ printf("%s: [-VplmLh]\n"
+ "-V dump app info\n"
+ "-p run printf test\n"
+ "-l run ls test\n"
+ "-m run mkdir test\n"
+ "-L run list test\n"
+ "-j run setjmp test\n"
+ "-h print help\n", name);
+}
+
+int main(int argc, char** argv)
+{
+ int i;
+ int opt;
+ bool do_test_printf = false;
+ bool do_test_ls = false;
+ bool do_test_mkdir = false;
+ bool do_test_list = false;
+ bool do_test_setjmp = false;
+ bool do_test_all = true;
+
+ for (i = 0; i < argc; i++) {
+ puts("argv[0x");
+ PUTHEX_LL(i);
+ puts("] = ");
+ puts(argv[i]);
+ puts("\n");
+ }
+
+ while ((opt = getopt(argc, argv, "VplmLhj")) > 0) {
+ switch (opt) {
+ case 'V':
+ print_appinfo();
+ break;
+ case 'p':
+ do_test_all = false;
+ do_test_printf = true;
+ break;
+ case 'l':
+ do_test_all = false;
+ do_test_ls = true;
+ break;
+ case 'm':
+ do_test_all = false;
+ do_test_mkdir = true;
+ break;
+ case 'L':
+ do_test_all = false;
+ do_test_list = true;
+ break;
+ case 'j':
+ do_test_all = false;
+ do_test_setjmp = true;
+ break;
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ puts("------ start ------\n\n");
+ if (do_test_all) {
+ test_all(argc, argv);
+ return 0;
+ }
+
+ if (do_test_printf)
+ test_printf(argc, argv);
+ if (do_test_ls)
+ test_ls();
+ if (do_test_ls)
+ test_mkdir();
+ if (do_test_list)
+ test_list();
+ if (do_test_setjmp)
+ test_setjmp();
+ puts("------ end ------\n\n");
+
+ return 0;
+}
+
+APP_LICENSE("GPL");
+APP_DESCRIPTION("barebox Application example");
+APP_AUTHOR("Jean-Chrristophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>");
diff --git a/apps/example/setjmp.c b/apps/example/setjmp.c
new file mode 100644
index 0000000..4dee83c
--- /dev/null
+++ b/apps/example/setjmp.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <setjmp.h>
+
+static jmp_buf buf;
+
+void second(void) {
+ printf("second\n");
+ longjmp(buf, 1);
+}
+
+void first(void) {
+ second();
+ printf("first not reach\n");
+}
+
+void test_setjmp(void)
+{
+ puts("------ setjmp/longjmp test ------\n");
+ if (!setjmp(buf))
+ first();
+ else
+ printf("main\n");
+ puts("------ end ------\n\n");
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 08/20] filetype: add barebox arm application
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (5 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 07/20] app: Introduce example application Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 09/20] arm: add application support Jean-Christophe PLAGNIOL-VILLARD
` (11 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
common/filetype.c | 35 +++++++++++++++++++++++++++++++++++
include/filetype.h | 2 ++
2 files changed, 37 insertions(+)
diff --git a/common/filetype.c b/common/filetype.c
index 8652f1d..16b217b 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -23,6 +23,7 @@
#include <fs.h>
#include <malloc.h>
#include <errno.h>
+#include <linux/license.h>
struct filetype_str {
const char *name; /* human readable filetype */
@@ -49,6 +50,8 @@ static const struct filetype_str filetype_str[] = {
[filetype_png] = { "PNG image", "png" },
[filetype_ext] = { "ext filesystem", "ext" },
[filetype_gpt] = { "GUID Partition Table", "gpt" },
+ [filetype_arm_application] = { "arm barebox application", "arm-barebox-app"},
+ [filetype_arm_gpl_application] = { "arm barebox GPL compatible application", "arm-barebox-gpl-app"},
};
const char *file_type_to_string(enum filetype f)
@@ -151,6 +154,35 @@ enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec)
return filetype_mbr;
}
+bool is_barebox_app_gpl_compatible(const uint8_t *buf8, size_t bufsize)
+{
+ int i;
+
+ if (bufsize < 12)
+ return false;
+
+ bufsize -= 12;
+
+ for (i = 0; i < bufsize; i++, buf8++) {
+ if (!strncmp("license=", buf8, 8) &&
+ license_is_gpl_compatible(buf8 + 8))
+ return true;
+ }
+
+ return false;
+}
+
+enum filetype is_barebox_arm_app(const uint8_t *buf8, size_t bufsize)
+{
+ if (strcmp(buf8 + 0x20, "barebox_arm_app"))
+ return filetype_unknown;
+ /* license=GPL */
+ if (is_barebox_app_gpl_compatible(buf8 + 0x80, bufsize))
+ return filetype_arm_gpl_application;
+
+ return filetype_arm_application;
+}
+
enum filetype file_detect_type(const void *_buf, size_t bufsize)
{
const u32 *buf = _buf;
@@ -201,6 +233,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize)
if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01)
return filetype_arm_zimage;
+ type = is_barebox_arm_app(buf8, bufsize);
+ if (type != filetype_unknown)
+ return type;
if (bufsize < 512)
return filetype_unknown;
diff --git a/include/filetype.h b/include/filetype.h
index 78ca5d2..09cdc99 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -24,6 +24,8 @@ enum filetype {
filetype_png,
filetype_ext,
filetype_gpt,
+ filetype_arm_application,
+ filetype_arm_gpl_application,
filetype_max,
};
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 09/20] arm: add application support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (6 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 08/20] filetype: add barebox arm application Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:59 ` Alexander Shiyan
2013-03-06 9:29 ` [PATCH 10/20] app: printf: use HelenOS verison with wide char support Jean-Christophe PLAGNIOL-VILLARD
` (10 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/Kconfig | 1 +
arch/arm/Makefile | 6 +-
arch/arm/apps/Kconfig | 11 ++++
arch/arm/apps/Makefile | 6 ++
arch/arm/apps/apps.lds.S | 64 ++++++++++++++++++
arch/arm/apps/binfmt.c | 111 ++++++++++++++++++++++++++++++++
arch/arm/apps/head.S | 59 +++++++++++++++++
arch/arm/apps/include/arch/asm/macro.h | 46 +++++++++++++
arch/arm/apps/include/arch/setjmp.h | 26 ++++++++
arch/arm/apps/raise.c | 27 ++++++++
arch/arm/apps/setjmp.S | 60 +++++++++++++++++
arch/arm/apps/start.c | 35 ++++++++++
12 files changed, 451 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/apps/Kconfig
create mode 100644 arch/arm/apps/Makefile
create mode 100644 arch/arm/apps/apps.lds.S
create mode 100644 arch/arm/apps/binfmt.c
create mode 100644 arch/arm/apps/head.S
create mode 100644 arch/arm/apps/include/arch/asm/macro.h
create mode 100644 arch/arm/apps/include/arch/setjmp.h
create mode 100644 arch/arm/apps/raise.c
create mode 100644 arch/arm/apps/setjmp.S
create mode 100644 arch/arm/apps/start.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f25dcf7..f30859b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
bool
select HAS_KALLSYMS
select HAS_MODULES
+ select HAS_APPLICATIONS
select HAVE_CONFIGURABLE_TEXT_BASE
select HAVE_PBL_IMAGE
select HAVE_IMAGE_COMPRESSION
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 100a3c4..731d92a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -275,9 +275,13 @@ else
MACH :=
endif
+APP_LDFLAGS += -L $(shell dirname `$(CC) $(CPPFLAGS) -print-libgcc-file-name`) -lgcc
+
common-y += $(BOARD) $(MACH)
common-y += arch/arm/lib/ arch/arm/cpu/
+common-$(CONFIG_APPLICATIONS) += arch/arm/apps/
lds-y := arch/arm/lib/barebox.lds
+apps-lds-y := arch/arm/apps/apps.lds
-CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds barebox-flash-image
+CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds arch/arm/apps/apps.lds barebox-flash-image
diff --git a/arch/arm/apps/Kconfig b/arch/arm/apps/Kconfig
new file mode 100644
index 0000000..8fcb79d
--- /dev/null
+++ b/arch/arm/apps/Kconfig
@@ -0,0 +1,11 @@
+
+config APP_TEXT_BASE_OFFSET
+ hex
+ default 0x800000
+ prompt "application text base offset"
+ help
+ APP_TEXT_BASE = TEXT_BASE - APP_TEXT_BASE_OFFSET
+ all the application will be link at this address
+ the syscall table region of 0x2000 will be add
+ APP_TEXT_BASE - 0x2000 and then the malloc region at
+ APP_TEXT_BASE - 0x2000 - APP_MALLOC_SIZE
diff --git a/arch/arm/apps/Makefile b/arch/arm/apps/Makefile
new file mode 100644
index 0000000..c7e9a80
--- /dev/null
+++ b/arch/arm/apps/Makefile
@@ -0,0 +1,6 @@
+obj-y += binfmt.o
+app-y += head.o
+app-y += start.o
+app-y += raise.o
+app-y += setjmp.o
+extry-y += apps.lds
diff --git a/arch/arm/apps/apps.lds.S b/arch/arm/apps/apps.lds.S
new file mode 100644
index 0000000..b6e4ab9
--- /dev/null
+++ b/arch/arm/apps/apps.lds.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sizes.h>
+#include <asm-generic/barebox.lds.h>
+#include <asm-generic/memory_layout.h>
+
+#define HEAD_BASE (TEXT_BASE - CONFIG_APP_TEXT_BASE_OFFSET)
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = HEAD_BASE;
+
+ . = ALIGN(4);
+ .text :
+ {
+ _stext = .;
+ _text = .;
+ *(.text_head_entry*)
+ . = 0x80;
+ KEEP(*(.appinfo.start))
+ __appinfo_start = .;
+ KEEP(*(.appinfo))
+ __appinfo_end = .;
+ KEEP(*(.appinfo.end))
+ *(.text*)
+ }
+
+ /* Discard unwind if enable in barebox */
+ /DISCARD/ : { *(.ARM.ex*) }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata*) }
+
+ _etext = .; /* End of text and rodata section */
+
+ . = ALIGN(4);
+ .data : { *(.data*) }
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss*) }
+ __bss_stop = .;
+ _end = .;
+
+ _barebox_app_image_size = __bss_start - HEAD_BASE;
+ _barebox_app_info_size = __appinfo_end - __appinfo_start;
+}
diff --git a/arch/arm/apps/binfmt.c b/arch/arm/apps/binfmt.c
new file mode 100644
index 0000000..f6bc450
--- /dev/null
+++ b/arch/arm/apps/binfmt.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <common.h>
+#include <binfmt.h>
+#include <init.h>
+#include <fs.h>
+#include <sizes.h>
+#include <memory.h>
+#include <malloc.h>
+#include <apps/syscall_init.h>
+
+static int arm_application(char *file, int argc, char **argv, bool is_gpl)
+{
+ struct syscall_trace st;
+ u32 *buf32;
+ u32 load_addr, size;
+ int (*jump)(int argc, char** argv);
+ void *barebox_app;
+ int ret = 0;
+ struct resource *app_res, *syscall_res, *malloc_res;
+
+ barebox_app = read_file(file, NULL);
+ if (!barebox_app)
+ return -EINVAL;
+
+ buf32 = barebox_app + 0x30;
+ load_addr = buf32[0];
+ size = buf32[1];
+
+ app_res = request_sdram_region("application", load_addr, size);
+ if (!app_res) {
+ perror("application: request_sdram_region");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ load_addr -= 0x2000;
+
+ syscall_res = request_sdram_region("bsyscall", load_addr, 0x2000);
+ if (!syscall_res) {
+ perror("application: bsyscall request_sdram_region");
+ ret = -ENOMEM;
+ goto err_app_res;
+ }
+
+ load_addr -= CONFIG_APP_MALLOC_SIZE;
+
+ malloc_res = request_sdram_region("application_malloc", load_addr, CONFIG_APP_MALLOC_SIZE);
+ if (!malloc_res) {
+ perror("application: bsyscall request_sdram_region");
+ ret = -ENOMEM;
+ goto err_malloc_res;
+ }
+
+ memset((void*)malloc_res->start, 0, resource_size(malloc_res));
+ memcpy((void*)app_res->start, barebox_app, size);
+
+ st.dest = (void*)syscall_res->start;
+ st.malloc_base = malloc_res->start;
+ st.malloc_size = resource_size(malloc_res);
+ syscalls_init(&st);
+
+ jump = (void*)app_res->start;
+ ret = jump(argc, argv);
+
+ syscalls_exit(&st);
+
+ release_sdram_region(malloc_res);
+err_malloc_res:
+ release_sdram_region(syscall_res);
+err_app_res:
+ release_sdram_region(app_res);
+err:
+ free(barebox_app);
+ return ret;
+}
+
+static int arm_gpl_application(struct binfmt_hook *b, char *file, int argc, char **argv)
+{
+ return arm_application(file, argc, argv, true);
+}
+
+static struct binfmt_hook binfmt_barebox_gpl_app_hook = {
+ .type = filetype_arm_gpl_application,
+ .hook = arm_gpl_application,
+};
+
+static int arm_non_gpl_application(struct binfmt_hook *b, char *file, int argc, char **argv)
+{
+ /* You are NOT allow to remove this warning */
+ pr_warn("non gpl compatible application\n");
+ return arm_application(file, argc, argv, false);
+}
+
+static struct binfmt_hook binfmt_barebox_app_hook = {
+ .type = filetype_arm_application,
+ .hook = arm_non_gpl_application,
+};
+
+static int arm_app_register_image_handler(void)
+{
+ binfmt_register(&binfmt_barebox_app_hook);
+ binfmt_register(&binfmt_barebox_gpl_app_hook);
+
+ return 0;
+}
+late_initcall(arm_app_register_image_handler);
diff --git a/arch/arm/apps/head.S b/arch/arm/apps/head.S
new file mode 100644
index 0000000..9cc714c
--- /dev/null
+++ b/arch/arm/apps/head.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+ .section ".text_head_entry.start"
+ .globl _start
+_start:
+ /* save register */
+ stmfd sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, lr}
+ /* save barebox stack */
+ mov r2, sp
+ /* setup new stack */
+ ldr sp, =_text
+ sub sp, #CONFIG_STACK_SIZE
+ b _next
+ .org 0x20
+ .asciz "barebox_arm_app"
+ .word _text /* text base. If copied there,
+ * barebox can skip relocation
+ */
+ .word _barebox_app_image_size /* image size to copy */
+
+_next:
+ stmfd sp!, {r0-r2}
+1: ldr r0, =__bss_start
+ mov r1, #0
+ ldr r2, =__bss_stop
+ sub r2, r2, r0
+ bl memset /* clear bss */
+ ldmfd sp!, {r0-r2}
+
+ b arm_app_start
+
+ .section ".appinfo.start"
+ .asciz "#appinf"
+ .word _barebox_app_info_size
+
+ .section ".appinfo.end"
+ .asciz "appinf#"
+
+ .text
+ .globl barebox_return
+barebox_return:
+ /* restore barebox the stack */
+ mov sp, r1
+ /* restore register */
+ ldmfd sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, pc}
diff --git a/arch/arm/apps/include/arch/asm/macro.h b/arch/arm/apps/include/arch/asm/macro.h
new file mode 100644
index 0000000..e451024
--- /dev/null
+++ b/arch/arm/apps/include/arch/asm/macro.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ARCH_ASM_MACRO_H__
+#define __ARCH_ASM_MACRO_H__
+
+#if (!defined(__ARM_ARCH_2__) && !defined(__ARM_ARCH_3__) \
+ && !defined(__ARM_ARCH_3M__) && !defined(__ARM_ARCH_4__))
+#define BX(x) bx x
+#else
+#define BX(x) mov pc, x
+#endif
+
+#define __FUNC(x) \
+ .balign 4; \
+ .globl x; \
+
+#ifdef __thumb__
+#define FUNC(x) \
+ __FUNC(x) \
+ .thumb_func; \
+x:
+#else
+#define FUNC(x) \
+ __FUNC(x) \
+x:
+#endif
+
+#define ENDFUNC(x) \
+ .type x, #function; \
+ .size x, .-x
+
+#endif /* __ARCH_ASM_MACRO_H__ */
diff --git a/arch/arm/apps/include/arch/setjmp.h b/arch/arm/apps/include/arch/setjmp.h
new file mode 100644
index 0000000..82058a9
--- /dev/null
+++ b/arch/arm/apps/include/arch/setjmp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#ifndef __ARCH_SETJMP_H__
+#define __ARCH_SETJMP_H__
+
+struct __jmp_buf {
+ unsigned int regs[10];
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* __ARCH_SETJMP_H__ */
diff --git a/arch/arm/apps/raise.c b/arch/arm/apps/raise.c
new file mode 100644
index 0000000..18cc0d8
--- /dev/null
+++ b/arch/arm/apps/raise.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <stdio.h>
+
+int raise(int signum)
+{
+ /* use puts as printf may not be availlable */
+ puts("raise: ");
+ puts(itoa(signum));
+ puts(" caught\n");
+
+ return 0;
+}
diff --git a/arch/arm/apps/setjmp.S b/arch/arm/apps/setjmp.S
new file mode 100644
index 0000000..1607ce3
--- /dev/null
+++ b/arch/arm/apps/setjmp.S
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <arch/asm/macro.h>
+
+ .text
+FUNC(setjmp)
+#ifndef __thumb__
+ stmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+#else
+ /* we need to do it in 2 steps in thumb */
+ mov r3, lr
+ stmia r0!, {r3, r4, r5, r6, r7}
+ mov r3, r8
+ mov r4, r9
+ mov r5, r10
+ mov r6, fp
+ mov r7, sp
+ stmia r0!, {r3, r4, r5, r6, r7}
+#endif /* __thumb__ */
+ mov r0, #0
+ BX(lr)
+ENDFUNC(setjmp)
+
+ .text
+FUNC(longjmp)
+#ifndef __thumb__
+ ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+ mov r0, r1
+ BX(lr)
+#else
+ /* we need to do it in 2 steps in thumb */
+ mov r2, r0
+ add r0, #20
+ ldmia r0!, {r3, r4, r5, r6, r7}
+ mov r8, r3
+ mov r9, r4
+ mov r10, r5
+ mov fp, r6
+ mov sp, r7
+ ldmia r2!, {r3, r4, r5, r6, r7}
+ mov r0, r1
+ bne 1f
+ mov r0, #1
+1: BX(r3)
+#endif /* __thumb__ */
+ENDFUNC(longjmp)
diff --git a/arch/arm/apps/start.c b/arch/arm/apps/start.c
new file mode 100644
index 0000000..af072a1
--- /dev/null
+++ b/arch/arm/apps/start.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ */
+
+#include <sys/types.h>
+
+static void *barebox_sp;
+void barebox_return(int, void*);
+int app_start(int argc, char **argv);
+
+void exit(int c)
+{
+ barebox_return(c, barebox_sp);
+}
+
+void arm_app_start(int argc, char** argv, void *sp)
+{
+ int ret;
+ barebox_sp = sp;
+
+ ret = app_start(argc, argv);
+ exit(ret);
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 09/20] arm: add application support
2013-03-06 9:29 ` [PATCH 09/20] arm: add application support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:59 ` Alexander Shiyan
2013-03-06 10:13 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 31+ messages in thread
From: Alexander Shiyan @ 2013-03-06 9:59 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/Makefile | 6 +-
> arch/arm/apps/Kconfig | 11 ++++
> arch/arm/apps/Makefile | 6 ++
> arch/arm/apps/apps.lds.S | 64 ++++++++++++++++++
> arch/arm/apps/binfmt.c | 111 ++++++++++++++++++++++++++++++++
> arch/arm/apps/head.S | 59 +++++++++++++++++
> arch/arm/apps/include/arch/asm/macro.h | 46 +++++++++++++
> arch/arm/apps/include/arch/setjmp.h | 26 ++++++++
> arch/arm/apps/raise.c | 27 ++++++++
> arch/arm/apps/setjmp.S | 60 +++++++++++++++++
> arch/arm/apps/start.c | 35 ++++++++++
> 12 files changed, 451 insertions(+), 1 deletion(-)
> create mode 100644 arch/arm/apps/Kconfig
> create mode 100644 arch/arm/apps/Makefile
> create mode 100644 arch/arm/apps/apps.lds.S
> create mode 100644 arch/arm/apps/binfmt.c
> create mode 100644 arch/arm/apps/head.S
> create mode 100644 arch/arm/apps/include/arch/asm/macro.h
> create mode 100644 arch/arm/apps/include/arch/setjmp.h
> create mode 100644 arch/arm/apps/raise.c
> create mode 100644 arch/arm/apps/setjmp.S
> create mode 100644 arch/arm/apps/start.c
...
Is this feature really needed? If we Include it, is dramatically increases size of BB.
We have a scripting, maybe just inclusion a small "C" interpreter is enough?
Such as "picoc" (http://code.google.com/p/picoc/), for example.
---
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 09/20] arm: add application support
2013-03-06 9:59 ` Alexander Shiyan
@ 2013-03-06 10:13 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 10:13 UTC (permalink / raw)
To: Alexander Shiyan; +Cc: barebox
On 13:59 Wed 06 Mar , Alexander Shiyan wrote:
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > ---
> > arch/arm/Kconfig | 1 +
> > arch/arm/Makefile | 6 +-
> > arch/arm/apps/Kconfig | 11 ++++
> > arch/arm/apps/Makefile | 6 ++
> > arch/arm/apps/apps.lds.S | 64 ++++++++++++++++++
> > arch/arm/apps/binfmt.c | 111 ++++++++++++++++++++++++++++++++
> > arch/arm/apps/head.S | 59 +++++++++++++++++
> > arch/arm/apps/include/arch/asm/macro.h | 46 +++++++++++++
> > arch/arm/apps/include/arch/setjmp.h | 26 ++++++++
> > arch/arm/apps/raise.c | 27 ++++++++
> > arch/arm/apps/setjmp.S | 60 +++++++++++++++++
> > arch/arm/apps/start.c | 35 ++++++++++
> > 12 files changed, 451 insertions(+), 1 deletion(-)
> > create mode 100644 arch/arm/apps/Kconfig
> > create mode 100644 arch/arm/apps/Makefile
> > create mode 100644 arch/arm/apps/apps.lds.S
> > create mode 100644 arch/arm/apps/binfmt.c
> > create mode 100644 arch/arm/apps/head.S
> > create mode 100644 arch/arm/apps/include/arch/asm/macro.h
> > create mode 100644 arch/arm/apps/include/arch/setjmp.h
> > create mode 100644 arch/arm/apps/raise.c
> > create mode 100644 arch/arm/apps/setjmp.S
> > create mode 100644 arch/arm/apps/start.c
> ...
>
> Is this feature really needed? If we Include it, is dramatically increases size of BB.
> We have a scripting, maybe just inclusion a small "C" interpreter is enough?
> Such as "picoc" (http://code.google.com/p/picoc/), for example.
increase?? no
1 to 2 KiB
on barebox side you just have the syscall
it's nothing and this is optionnal
Best Regards,
J.
>
> ---
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 10/20] app: printf: use HelenOS verison with wide char support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (7 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 09/20] arm: add application support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 11/20] app: printf: add version from contiki Jean-Christophe PLAGNIOL-VILLARD
` (9 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/include/stdio.h | 21 +-
apps/include/stdlib.h | 3 +
apps/include/{stdlib.h => wchar.h} | 24 +-
apps/libc/Kconfig | 10 +
apps/libc/Makefile | 1 +
apps/libc/helenos/Makefile | 4 +
apps/libc/helenos/align.h | 63 ++
apps/libc/helenos/assert.h | 2 +
apps/libc/helenos/ctype.c | 52 ++
apps/libc/helenos/printf_core.c | 905 +++++++++++++++++++
apps/libc/helenos/printf_core.h | 59 ++
apps/libc/helenos/stdio.c | 153 ++++
apps/libc/helenos/str.c | 1755 ++++++++++++++++++++++++++++++++++++
apps/libc/helenos/str.h | 135 +++
apps/libc/helenos/vsnprintf.c | 187 ++++
15 files changed, 3353 insertions(+), 21 deletions(-)
copy apps/include/{stdlib.h => wchar.h} (70%)
create mode 100644 apps/libc/helenos/Makefile
create mode 100644 apps/libc/helenos/align.h
create mode 100644 apps/libc/helenos/assert.h
create mode 100644 apps/libc/helenos/ctype.c
create mode 100644 apps/libc/helenos/printf_core.c
create mode 100644 apps/libc/helenos/printf_core.h
create mode 100644 apps/libc/helenos/stdio.c
create mode 100644 apps/libc/helenos/str.c
create mode 100644 apps/libc/helenos/str.h
create mode 100644 apps/libc/helenos/vsnprintf.c
diff --git a/apps/include/stdio.h b/apps/include/stdio.h
index 32a7d25..9c9720e 100644
--- a/apps/include/stdio.h
+++ b/apps/include/stdio.h
@@ -49,6 +49,16 @@ size_t fread(void *buf, size_t size, size_t nb, FILE *f);
size_t fwrite(const void *buf, size_t size, size_t nb, FILE *f);
int fseek(FILE *stream, long offset, int whence);
+int printf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2)));
+int vprintf(const char *fmt, va_list args);
+int sprintf(char *buf, const char *fmt, ...) __attribute__ ((format(__printf__, 2, 3)));
+int snprintf(char *buf, size_t size, const char *fmt, ...) __attribute__ ((format(__printf__, 3, 4)));
+int vsprintf(char *buf, const char *fmt, va_list args);
+char *asprintf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2)));
+char *vasprintf(const char *fmt, va_list ap);
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
+
/* barebox API */
void eputc(char c);
int eputs(const char *str);
@@ -56,15 +66,4 @@ int tstc(void);
int flush(int fd);
char* itoa(int i);
-static int printf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2)));
-static inline int printf(const char *fmt, ...)
-{
- return 0;
-}
-
-static inline int vprintf(const char *fmt, va_list args)
-{
- return 0;
-}
-
#endif /* __STDIO_H__ */
diff --git a/apps/include/stdlib.h b/apps/include/stdlib.h
index 7ae78ad..e08775f 100644
--- a/apps/include/stdlib.h
+++ b/apps/include/stdlib.h
@@ -26,4 +26,7 @@ int atoi(const char *s);
long atol(const char *s);
long long atoll(const char *s);
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
#endif /* __STDLIB_H__ */
diff --git a/apps/include/stdlib.h b/apps/include/wchar.h
similarity index 70%
copy from apps/include/stdlib.h
copy to apps/include/wchar.h
index 7ae78ad..8610569 100644
--- a/apps/include/stdlib.h
+++ b/apps/include/wchar.h
@@ -14,16 +14,20 @@
* this file might be covered by the GNU General Public License.
*/
-#ifndef __STDLIB_H__
-#define __STDLIB_H__
+#ifndef __WCHAR_H__
+#define __WCHAR_H__
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
+#include <stdio.h>
-char *getenv(const char *name);
-void exit(int num);
-int atoi(const char *s);
-long atol(const char *s);
-long long atoll(const char *s);
+typedef unsigned long wchar_t;
+typedef long wint_t;
-#endif /* __STDLIB_H__ */
+
+#define wprintf printf
+#define fwprintf fprintf
+#define swprintf sprintf
+#define vwprintf vprintf
+#define vfwprintf vfwprintf
+#define vswprintf vswprintf
+
+#endif /* __WCHAR_H__ */
diff --git a/apps/libc/Kconfig b/apps/libc/Kconfig
index b9478b5..25b35ee 100644
--- a/apps/libc/Kconfig
+++ b/apps/libc/Kconfig
@@ -22,4 +22,14 @@ config APP_PRINTF_STACK_SIZE
hex "printf stack size"
default 0x1000
+choice
+ prompt "printf implementation"
+
+config APPS_PRINTF_HELENOS
+ bool "helen os"
+ help
+ support wide char
+
+endchoice
+
endmenu
diff --git a/apps/libc/Makefile b/apps/libc/Makefile
index 844ea9b..c84f00e 100644
--- a/apps/libc/Makefile
+++ b/apps/libc/Makefile
@@ -15,6 +15,7 @@ app-y += unistd.o
app-$(CONFIG_APPS_MALLOC_DUMMY) += dummy_malloc.o
app-$(CONFIG_APPS_MALLOC_TLSF) += tlsf_malloc.o tlsf.o
app-y += string.o
+obj-$(CONFIG_APPS_PRINTF_HELENOS) += helenos/
obj-y += sys/
app-y += time.o
diff --git a/apps/libc/helenos/Makefile b/apps/libc/helenos/Makefile
new file mode 100644
index 0000000..1c34aff
--- /dev/null
+++ b/apps/libc/helenos/Makefile
@@ -0,0 +1,4 @@
+app-y += printf_core.o
+app-y += vsnprintf.o
+app-y += str.o
+app-y += stdio.o
diff --git a/apps/libc/helenos/align.h b/apps/libc/helenos/align.h
new file mode 100644
index 0000000..8ca4270
--- /dev/null
+++ b/apps/libc/helenos/align.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ALIGN_H_
+#define LIBC_ALIGN_H_
+
+/** Align to the nearest lower address which is a power of two.
+ *
+ * @param s Address or size to be aligned.
+ * @param a Size of alignment, must be power of 2.
+ */
+#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
+
+
+/** Align to the nearest higher address which is a power of two.
+ *
+ * @param s Address or size to be aligned.
+ * @param a Size of alignment, must be power of 2.
+ */
+#define ALIGN_UP(s, a) ((long)((s) + ((a) - 1)) & ~((long) (a) - 1))
+
+/** Round up to the nearest higher boundary.
+ *
+ * @param n Number to be aligned.
+ * @param b Boundary, arbitrary unsigned number.
+ */
+#define ROUND_UP(n, b) (((n) / (b) + ((n) % (b) != 0)) * (b))
+
+#endif
+
+/** @}
+ */
diff --git a/apps/libc/helenos/assert.h b/apps/libc/helenos/assert.h
new file mode 100644
index 0000000..16fedb4
--- /dev/null
+++ b/apps/libc/helenos/assert.h
@@ -0,0 +1,2 @@
+
+#define assert(x)
diff --git a/apps/libc/helenos/ctype.c b/apps/libc/helenos/ctype.c
new file mode 100644
index 0000000..6d20da5
--- /dev/null
+++ b/apps/libc/helenos/ctype.c
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ */
+
+/*
+ * linux/lib/ctype.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#include <linux/ctype.h>
+
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
diff --git a/apps/libc/helenos/printf_core.c b/apps/libc/helenos/printf_core.c
new file mode 100644
index 0000000..ccfaaa9
--- /dev/null
+++ b/apps/libc/helenos/printf_core.c
@@ -0,0 +1,905 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2009 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include "printf_core.h"
+#include "str.h"
+
+/** show prefixes 0x or 0 */
+#define __PRINTF_FLAG_PREFIX 0x00000001
+
+/** show the decimal point even if no fractional digits present */
+#define __PRINTF_FLAG_DECIMALPT 0x00000001
+
+/** signed / unsigned number */
+#define __PRINTF_FLAG_SIGNED 0x00000002
+
+/** print leading zeroes */
+#define __PRINTF_FLAG_ZEROPADDED 0x00000004
+
+/** align to left */
+#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
+
+/** always show + sign */
+#define __PRINTF_FLAG_SHOWPLUS 0x00000020
+
+/** print space instead of plus */
+#define __PRINTF_FLAG_SPACESIGN 0x00000040
+
+/** show big characters */
+#define __PRINTF_FLAG_BIGCHARS 0x00000080
+
+/** number has - sign */
+#define __PRINTF_FLAG_NEGATIVE 0x00000100
+
+/** don't print trailing zeros in the fractional part */
+#define __PRINTF_FLAG_NOFRACZEROS 0x00000200
+
+
+/**
+ * Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0
+ * to terminate string... (last one is only for better testing end of buffer by
+ * zero-filling subroutine)
+ */
+#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
+
+/** Enumeration of possible arguments types.
+ */
+typedef enum {
+ PrintfQualifierByte = 0,
+ PrintfQualifierShort,
+ PrintfQualifierInt,
+ PrintfQualifierLong,
+ PrintfQualifierLongLong,
+ PrintfQualifierPointer,
+ PrintfQualifierSize
+} qualifier_t;
+
+static const char *nullstr = "(NULL)";
+static const char digits_small[] = "0123456789abcdef";
+static const char digits_big[] = "0123456789ABCDEF";
+static const char invalch = U_SPECIAL;
+
+/** Print one or more characters without adding newline.
+ *
+ * @param buf Buffer holding characters with size of
+ * at least size bytes. NULL is not allowed!
+ * @param size Size of the buffer in bytes.
+ * @param ps Output method and its data.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putnchars(const char *buf, size_t size,
+ printf_spec_t *ps)
+{
+ return ps->str_write((void *) buf, size, ps->data);
+}
+
+/** Print one or more wide characters without adding newline.
+ *
+ * @param buf Buffer holding wide characters with size of
+ * at least size bytes. NULL is not allowed!
+ * @param size Size of the buffer in bytes.
+ * @param ps Output method and its data.
+ *
+ * @return Number of wide characters printed.
+ *
+ */
+static int printf_wputnchars(const wchar_t *buf, size_t size,
+ printf_spec_t *ps)
+{
+ return ps->wstr_write((void *) buf, size, ps->data);
+}
+
+/** Print string without adding a newline.
+ *
+ * @param str String to print.
+ * @param ps Write function specification and support data.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putstr(const char *str, printf_spec_t *ps)
+{
+ if (str == NULL)
+ return printf_putnchars(nullstr, str_size(nullstr), ps);
+
+ return ps->str_write((void *) str, str_size(str), ps->data);
+}
+
+/** Print one ASCII character.
+ *
+ * @param c ASCII character to be printed.
+ * @param ps Output method.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putchar(const char ch, printf_spec_t *ps)
+{
+ if (!ascii_check(ch))
+ return ps->str_write((void *) &invalch, 1, ps->data);
+
+ return ps->str_write(&ch, 1, ps->data);
+}
+
+/** Print one wide character.
+ *
+ * @param c Wide character to be printed.
+ * @param ps Output method.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+{
+ if (!chr_check(ch))
+ return ps->str_write((void *) &invalch, 1, ps->data);
+
+ return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
+}
+
+/** Print one formatted ASCII character.
+ *
+ * @param ch Character to print.
+ * @param width Width modifier.
+ * @param flags Flags that change the way the character is printed.
+ *
+ * @return Number of characters printed, negative value on failure.
+ *
+ */
+static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
+{
+ size_t counter = 0;
+ if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+ while (--width > 0) {
+ /*
+ * One space is consumed by the character itself, hence
+ * the predecrement.
+ */
+ if (printf_putchar(' ', ps) > 0)
+ counter++;
+ }
+ }
+
+ if (printf_putchar(ch, ps) > 0)
+ counter++;
+
+ while (--width > 0) {
+ /*
+ * One space is consumed by the character itself, hence
+ * the predecrement.
+ */
+ if (printf_putchar(' ', ps) > 0)
+ counter++;
+ }
+
+ return (int) (counter);
+}
+
+/** Print one formatted wide character.
+ *
+ * @param ch Character to print.
+ * @param width Width modifier.
+ * @param flags Flags that change the way the character is printed.
+ *
+ * @return Number of characters printed, negative value on failure.
+ *
+ */
+static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+{
+ size_t counter = 0;
+ if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+ while (--width > 0) {
+ /*
+ * One space is consumed by the character itself, hence
+ * the predecrement.
+ */
+ if (printf_putchar(' ', ps) > 0)
+ counter++;
+ }
+ }
+
+ if (printf_putwchar(ch, ps) > 0)
+ counter++;
+
+ while (--width > 0) {
+ /*
+ * One space is consumed by the character itself, hence
+ * the predecrement.
+ */
+ if (printf_putchar(' ', ps) > 0)
+ counter++;
+ }
+
+ return (int) (counter);
+}
+
+/** Print string.
+ *
+ * @param str String to be printed.
+ * @param width Width modifier.
+ * @param precision Precision modifier.
+ * @param flags Flags that modify the way the string is printed.
+ *
+ * @return Number of characters printed, negative value on failure.
+ */
+static int print_str(char *str, int width, unsigned int precision,
+ uint32_t flags, printf_spec_t *ps)
+{
+ size_t strw;
+ size_t counter = 0;
+ size_t size;
+ int retval;
+
+ if (str == NULL)
+ return printf_putstr(nullstr, ps);
+
+ strw = str_length(str);
+
+ /* Precision unspecified - print everything. */
+ if ((precision == 0) || (precision > strw))
+ precision = strw;
+
+ /* Left padding */
+ width -= precision;
+ if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+ }
+
+ /* Part of @a str fitting into the alloted space. */
+ size = str_lsize(str, precision);
+ if ((retval = printf_putnchars(str, size, ps)) < 0)
+ return -counter;
+
+ counter += retval;
+
+ /* Right padding */
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+
+ return ((int) counter);
+
+}
+
+/** Print wide string.
+ *
+ * @param str Wide string to be printed.
+ * @param width Width modifier.
+ * @param precision Precision modifier.
+ * @param flags Flags that modify the way the string is printed.
+ *
+ * @return Number of wide characters printed, negative value on failure.
+ */
+static int print_wstr(wchar_t *str, int width, unsigned int precision,
+ uint32_t flags, printf_spec_t *ps)
+{
+ size_t counter = 0;
+ size_t strw;
+ int retval;
+ size_t size;
+
+ if (str == NULL)
+ return printf_putstr(nullstr, ps);
+
+ strw = wstr_length(str);
+
+ /* Precision not specified - print everything. */
+ if ((precision == 0) || (precision > strw))
+ precision = strw;
+
+ /* Left padding */
+ width -= precision;
+ if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+ }
+
+ /* Part of @a wstr fitting into the alloted space. */
+ size = wstr_lsize(str, precision);
+ if ((retval = printf_wputnchars(str, size, ps)) < 0)
+ return -counter;
+
+ counter += retval;
+
+ /* Right padding */
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+
+ return ((int) counter);
+}
+
+/** Print a number in a given base.
+ *
+ * Print significant digits of a number in given base.
+ *
+ * @param num Number to print.
+ * @param width Width modifier.
+ * @param precision Precision modifier.
+ * @param base Base to print the number in (must be between 2 and 16).
+ * @param flags Flags that modify the way the number is printed.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int print_number(uint64_t num, int width, int precision, int base,
+ uint64_t flags, printf_spec_t *ps)
+{
+ const char *digits;
+ char d[PRINT_NUMBER_BUFFER_SIZE];
+ char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
+ int size = 0; /* Size of number with all prefixes and signs. */
+ int number_size; /* Size of plain number. */
+ char sgn;
+ int retval;
+ int counter = 0;
+
+ if (flags & __PRINTF_FLAG_BIGCHARS)
+ digits = digits_big;
+ else
+ digits = digits_small;
+
+ /* Put zero at end of string */
+ *ptr-- = 0;
+
+ if (num == 0) {
+ *ptr-- = '0';
+ size++;
+ } else {
+ do {
+ *ptr-- = digits[num % base];
+ size++;
+ } while (num /= base);
+ }
+
+ /* Size of plain number */
+ number_size = size;
+
+ /*
+ * Collect the sum of all prefixes/signs/etc. to calculate padding and
+ * leading zeroes.
+ */
+ if (flags & __PRINTF_FLAG_PREFIX) {
+ switch (base) {
+ case 2:
+ /* Binary formating is not standard, but usefull */
+ size += 2;
+ break;
+ case 8:
+ size++;
+ break;
+ case 16:
+ size += 2;
+ break;
+ }
+ }
+
+ sgn = 0;
+ if (flags & __PRINTF_FLAG_SIGNED) {
+ if (flags & __PRINTF_FLAG_NEGATIVE) {
+ sgn = '-';
+ size++;
+ } else if (flags & __PRINTF_FLAG_SHOWPLUS) {
+ sgn = '+';
+ size++;
+ } else if (flags & __PRINTF_FLAG_SPACESIGN) {
+ sgn = ' ';
+ size++;
+ }
+ }
+
+ if (flags & __PRINTF_FLAG_LEFTALIGNED)
+ flags &= ~__PRINTF_FLAG_ZEROPADDED;
+
+ /*
+ * If the number is left-aligned or precision is specified then
+ * padding with zeros is ignored.
+ */
+ if (flags & __PRINTF_FLAG_ZEROPADDED) {
+ if ((precision == 0) && (width > size))
+ precision = width - size + number_size;
+ }
+
+ /* Print leading spaces */
+ if (number_size > precision) {
+ /* Print the whole number, not only a part */
+ precision = number_size;
+ }
+
+ width -= precision + size - number_size;
+
+ if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+ }
+
+ /* Print sign */
+ if (sgn) {
+ if (printf_putchar(sgn, ps) == 1)
+ counter++;
+ }
+
+ /* Print prefix */
+ if (flags & __PRINTF_FLAG_PREFIX) {
+ switch (base) {
+ case 2:
+ /* Binary formating is not standard, but usefull */
+ if (printf_putchar('0', ps) == 1)
+ counter++;
+ if (flags & __PRINTF_FLAG_BIGCHARS) {
+ if (printf_putchar('B', ps) == 1)
+ counter++;
+ } else {
+ if (printf_putchar('b', ps) == 1)
+ counter++;
+ }
+ break;
+ case 8:
+ if (printf_putchar('o', ps) == 1)
+ counter++;
+ break;
+ case 16:
+ if (printf_putchar('0', ps) == 1)
+ counter++;
+ if (flags & __PRINTF_FLAG_BIGCHARS) {
+ if (printf_putchar('X', ps) == 1)
+ counter++;
+ } else {
+ if (printf_putchar('x', ps) == 1)
+ counter++;
+ }
+ break;
+ }
+ }
+
+ /* Print leading zeroes */
+ precision -= number_size;
+ while (precision-- > 0) {
+ if (printf_putchar('0', ps) == 1)
+ counter++;
+ }
+
+ /* Print the number itself */
+ if ((retval = printf_putstr(++ptr, ps)) > 0)
+ counter += retval;
+
+ /* Print trailing spaces */
+
+ while (width-- > 0) {
+ if (printf_putchar(' ', ps) == 1)
+ counter++;
+ }
+
+ return ((int) counter);
+}
+
+/** Print formatted string.
+ *
+ * Print string formatted according to the fmt parameter and variadic arguments.
+ * Each formatting directive must have the following form:
+ *
+ * \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
+ *
+ * FLAGS:@n
+ * - "#" Force to print prefix. For \%o conversion, the prefix is 0, for
+ * \%x and \%X prefixes are 0x and 0X and for conversion \%b the
+ * prefix is 0b.
+ *
+ * - "-" Align to left.
+ *
+ * - "+" Print positive sign just as negative.
+ *
+ * - " " If the printed number is positive and "+" flag is not set,
+ * print space in place of sign.
+ *
+ * - "0" Print 0 as padding instead of spaces. Zeroes are placed between
+ * sign and the rest of the number. This flag is ignored if "-"
+ * flag is specified.
+ *
+ * WIDTH:@n
+ * - Specify the minimal width of a printed argument. If it is bigger,
+ * width is ignored. If width is specified with a "*" character instead of
+ * number, width is taken from parameter list. And integer parameter is
+ * expected before parameter for processed conversion specification. If
+ * this value is negative its absolute value is taken and the "-" flag is
+ * set.
+ *
+ * PRECISION:@n
+ * - Value precision. For numbers it specifies minimum valid numbers.
+ * Smaller numbers are printed with leading zeroes. Bigger numbers are not
+ * affected. Strings with more than precision characters are cut off. Just
+ * as with width, an "*" can be used used instead of a number. An integer
+ * value is then expected in parameters. When both width and precision are
+ * specified using "*", the first parameter is used for width and the
+ * second one for precision.
+ *
+ * TYPE:@n
+ * - "hh" Signed or unsigned char.@n
+ * - "h" Signed or unsigned short.@n
+ * - "" Signed or unsigned int (default value).@n
+ * - "l" Signed or unsigned long int.@n
+ * If conversion is "c", the character is wint_t (wide character).@n
+ * If conversion is "s", the string is wchar_t * (wide string).@n
+ * - "ll" Signed or unsigned long long int.@n
+ * - "z" Signed or unsigned ssize_t or site_t.@n
+ *
+ * CONVERSION:@n
+ * - % Print percentile character itself.
+ *
+ * - c Print single character. The character is expected to be plain
+ * ASCII (e.g. only values 0 .. 127 are valid).@n
+ * If type is "l", then the character is expected to be wide character
+ * (e.g. values 0 .. 0x10ffff are valid).
+ *
+ * - s Print zero terminated string. If a NULL value is passed as
+ * value, "(NULL)" is printed instead.@n
+ * If type is "l", then the string is expected to be wide string.
+ *
+ * - P, p Print value of a pointer. Void * value is expected and it is
+ * printed in hexadecimal notation with prefix (as with
+ * \%#0.8X / \%#0.8x for 32-bit or \%#0.16lX / \%#0.16lx for 64-bit
+ * long pointers).
+ *
+ * - b Print value as unsigned binary number. Prefix is not printed by
+ * default. (Nonstandard extension.)
+ *
+ * - o Print value as unsigned octal number. Prefix is not printed by
+ * default.
+ *
+ * - d, i Print signed decimal number. There is no difference between d
+ * and i conversion.
+ *
+ * - u Print unsigned decimal number.
+ *
+ * - X, x Print hexadecimal number with upper- or lower-case. Prefix is
+ * not printed by default.
+ *
+ * All other characters from fmt except the formatting directives are printed
+ * verbatim.
+ *
+ * @param fmt Format NULL-terminated string.
+ *
+ * @return Number of characters printed, negative value on failure.
+ *
+ */
+int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
+{
+ size_t i; /* Index of the currently processed character from fmt */
+ size_t nxt = 0; /* Index of the next character from fmt */
+ size_t j = 0; /* Index to the first not printed nonformating character */
+
+ size_t counter = 0; /* Number of characters printed */
+ int retval; /* Return values from nested functions */
+
+ while (true) {
+ wchar_t uc;
+
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+
+ if (uc == 0)
+ break;
+
+ /* Control character */
+ if (uc == '%') {
+ uint32_t flags = 0;
+ bool end = false;
+ int width = 0;
+ int precision = -1;
+ qualifier_t qualifier;
+ unsigned int base = 10;
+ size_t size;
+ uint64_t number;
+
+ /* Print common characters if any processed */
+ if (i > j) {
+ if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
+ /* Error */
+ counter = -counter;
+ goto out;
+ }
+ counter += retval;
+ }
+
+ j = i;
+
+ /* Parse modifiers */
+ do {
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ switch (uc) {
+ case '#':
+ flags |= __PRINTF_FLAG_PREFIX;
+ flags |= __PRINTF_FLAG_DECIMALPT;
+ break;
+ case '-':
+ flags |= __PRINTF_FLAG_LEFTALIGNED;
+ break;
+ case '+':
+ flags |= __PRINTF_FLAG_SHOWPLUS;
+ break;
+ case ' ':
+ flags |= __PRINTF_FLAG_SPACESIGN;
+ break;
+ case '0':
+ flags |= __PRINTF_FLAG_ZEROPADDED;
+ break;
+ default:
+ end = true;
+ };
+ } while (!end);
+
+ /* Width & '*' operator */
+ if (isdigit(uc)) {
+ while (true) {
+ width *= 10;
+ width += uc - '0';
+
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ if (uc == 0)
+ break;
+ if (!isdigit(uc))
+ break;
+ }
+ } else if (uc == '*') {
+ /* Get width value from argument list */
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ width = (int) va_arg(ap, int);
+ if (width < 0) {
+ /* Negative width sets '-' flag */
+ width *= -1;
+ flags |= __PRINTF_FLAG_LEFTALIGNED;
+ }
+ }
+
+ /* Precision and '*' operator */
+ if (uc == '.') {
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ if (isdigit(uc)) {
+ precision = 0;
+ while (true) {
+ precision *= 10;
+ precision += uc - '0';
+
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ if (uc == 0)
+ break;
+ if (!isdigit(uc))
+ break;
+ }
+ } else if (uc == '*') {
+ /* Get precision value from the argument list */
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ precision = (int) va_arg(ap, int);
+ if (precision < 0) {
+ /* Ignore negative precision - use default instead */
+ precision = -1;
+ }
+ }
+ }
+
+ switch (uc) {
+ /** @todo Unimplemented qualifiers:
+ * t ptrdiff_t - ISO C 99
+ */
+ case 'h':
+ /* Char or short */
+ qualifier = PrintfQualifierShort;
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ if (uc == 'h') {
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ qualifier = PrintfQualifierByte;
+ }
+ break;
+ case 'l':
+ /* Long or long long */
+ qualifier = PrintfQualifierLong;
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ if (uc == 'l') {
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ qualifier = PrintfQualifierLongLong;
+ }
+ break;
+ case 'z':
+ qualifier = PrintfQualifierSize;
+ i = nxt;
+ uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+ break;
+ default:
+ /* Default type */
+ qualifier = PrintfQualifierInt;
+ }
+
+ switch (uc) {
+ /*
+ * String and character conversions.
+ */
+ case 's':
+ precision = max(0, precision);
+
+ if (qualifier == PrintfQualifierLong)
+ retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
+ else
+ retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
+
+ if (retval < 0) {
+ counter = -counter;
+ goto out;
+ }
+
+ counter += retval;
+ j = nxt;
+ goto next_char;
+ case 'c':
+ if (qualifier == PrintfQualifierLong)
+ retval = print_wchar(va_arg(ap, wint_t), width, flags, ps);
+ else
+ retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
+
+ if (retval < 0) {
+ counter = -counter;
+ goto out;
+ };
+
+ counter += retval;
+ j = nxt;
+ goto next_char;
+
+ /*
+ * Integer values
+ */
+ case 'P':
+ /* Pointer */
+ flags |= __PRINTF_FLAG_BIGCHARS;
+ case 'p':
+ flags |= __PRINTF_FLAG_PREFIX;
+ flags |= __PRINTF_FLAG_ZEROPADDED;
+ base = 16;
+ qualifier = PrintfQualifierPointer;
+ break;
+ case 'b':
+ base = 2;
+ break;
+ case 'o':
+ base = 8;
+ break;
+ case 'd':
+ case 'i':
+ flags |= __PRINTF_FLAG_SIGNED;
+ case 'u':
+ break;
+ case 'X':
+ flags |= __PRINTF_FLAG_BIGCHARS;
+ case 'x':
+ base = 16;
+ break;
+
+ /* Percentile itself */
+ case '%':
+ j = i;
+ goto next_char;
+
+ /*
+ * Bad formatting.
+ */
+ default:
+ /*
+ * Unknown format. Now, j is the index of '%'
+ * so we will print whole bad format sequence.
+ */
+ goto next_char;
+ }
+
+ /* Print integers */
+ switch (qualifier) {
+ case PrintfQualifierByte:
+ size = sizeof(unsigned char);
+ number = (uint64_t) va_arg(ap, unsigned int);
+ break;
+ case PrintfQualifierShort:
+ size = sizeof(unsigned short);
+ number = (uint64_t) va_arg(ap, unsigned int);
+ break;
+ case PrintfQualifierInt:
+ size = sizeof(unsigned int);
+ number = (uint64_t) va_arg(ap, unsigned int);
+ break;
+ case PrintfQualifierLong:
+ size = sizeof(unsigned long);
+ number = (uint64_t) va_arg(ap, unsigned long);
+ break;
+ case PrintfQualifierLongLong:
+ size = sizeof(unsigned long long);
+ number = (uint64_t) va_arg(ap, unsigned long long);
+ break;
+ case PrintfQualifierPointer:
+ size = sizeof(void *);
+ precision = size << 1;
+ number = (uint64_t) (unsigned long)va_arg(ap, void *);
+ break;
+ case PrintfQualifierSize:
+ size = sizeof(size_t);
+ number = (uint64_t) va_arg(ap, size_t);
+ break;
+ default:
+ /* Unknown qualifier */
+ counter = -counter;
+ goto out;
+ }
+
+ if ((retval = print_number(number, width, precision,
+ base, flags, ps)) < 0) {
+ counter = -counter;
+ goto out;
+ }
+
+ counter += retval;
+ j = nxt;
+ }
+next_char:
+ ;
+ }
+
+ if (i > j) {
+ if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
+ /* Error */
+ counter = -counter;
+ goto out;
+ }
+ counter += retval;
+ }
+
+out:
+ return ((int) counter);
+}
diff --git a/apps/libc/helenos/printf_core.h b/apps/libc/helenos/printf_core.h
new file mode 100644
index 0000000..71c725a
--- /dev/null
+++ b/apps/libc/helenos/printf_core.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_PRINTF_CORE_H_
+#define LIBC_PRINTF_CORE_H_
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+/** Structure for specifying output methods for different printf clones. */
+typedef struct {
+ /* String output function, returns number of printed characters or EOF */
+ int (*str_write)(const char *, size_t, void *);
+
+ /* Wide string output function, returns number of printed characters or EOF */
+ int (*wstr_write)(const wchar_t *, size_t, void *);
+
+ /* User data - output stream specification, state, locks, etc. */
+ void *data;
+} printf_spec_t;
+
+extern int printf_core(const char *, printf_spec_t *, va_list);
+
+#endif
+
+/** @}
+ */
diff --git a/apps/libc/helenos/stdio.c b/apps/libc/helenos/stdio.c
new file mode 100644
index 0000000..e4bf3c6
--- /dev/null
+++ b/apps/libc/helenos/stdio.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2011 Jiri Zarevucky
+ * Copyright (c) 2011 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libposix
+ * @{
+ */
+/** @file Standard buffered input/output.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <malloc.h>
+
+#include "printf_core.h"
+#include "str.h"
+
+
+/**
+ * Write ordinary string to the opened file.
+ *
+ * @param str String to be written.
+ * @param size Size of the string (in bytes)..
+ * @param fd File descriptor of the opened file.
+ * @return The number of written characters.
+ */
+static int _dprintf_str_write(const char *str, size_t size, void *fd)
+{
+ ssize_t wr = write(*(int *) fd, str, size);
+ return str_nlength(str, wr);
+}
+
+/**
+ * Write wide string to the opened file.
+ *
+ * @param str String to be written.
+ * @param size Size of the string (in bytes).
+ * @param fd File descriptor of the opened file.
+ * @return The number of written characters.
+ */
+static int _dprintf_wstr_write(const wchar_t *str, size_t size, void *fd)
+{
+ size_t offset = 0;
+ size_t chars = 0;
+ size_t sz;
+ char buf[4];
+
+ while (offset < size) {
+ sz = 0;
+ if (chr_encode(str[chars], buf, &sz, sizeof(buf)) != 0) {
+ break;
+ }
+
+ if (write(*(int *) fd, buf, sz) != (ssize_t) sz) {
+ break;
+ }
+
+ chars++;
+ offset += sizeof(wchar_t);
+ }
+
+ return chars;
+}
+
+/**
+ * Print formatted output to the opened file.
+ *
+ * @param fildes File descriptor of the opened file.
+ * @param format Format description.
+ * @param ap Print arguments.
+ * @return Either the number of printed characters or negative value on error.
+ */
+int vdprintf(int fildes, const char * format, va_list ap)
+{
+ printf_spec_t spec = {
+ .str_write = _dprintf_str_write,
+ .wstr_write = _dprintf_wstr_write,
+ .data = &fildes
+ };
+
+ return printf_core(format, &spec, ap);
+}
+
+/**
+ * Print formatted output to the string.
+ *
+ * @param s Output string.
+ * @param format Format description.
+ * @return Either the number of printed characters (excluding null byte) or
+ * negative value on error.
+ */
+int sprintf(char *s, const char * format, ...)
+{
+ va_list list;
+ int result;
+
+ va_start(list, format);
+ result = vsprintf(s, format, list);
+ va_end(list);
+ return result;
+}
+
+/**
+ * Print formatted output to the string.
+ *
+ * @param s Output string.
+ * @param format Format description.
+ * @param ap Print arguments.
+ * @return Either the number of printed characters (excluding null byte) or
+ * negative value on error.
+ */
+int vsprintf(char *s, const char * format, va_list ap)
+{
+ return vsnprintf(s, STR_NO_LIMIT, format, ap);
+}
+
+int snprintf(char *str, size_t size, const char *fmt, ...)
+{
+ int ret;
+ va_list args;
+
+ va_start(args, fmt);
+ ret = vsnprintf(str, size, fmt, args);
+ va_end(args);
+
+ return ret;
+}
diff --git a/apps/libc/helenos/str.c b/apps/libc/helenos/str.c
new file mode 100644
index 0000000..cb350e9
--- /dev/null
+++ b/apps/libc/helenos/str.c
@@ -0,0 +1,1755 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2008 Jiri Svoboda
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2011 Oleg Romanenko
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <errno.h>
+#include <limits.h>
+#include <wchar.h>
+#include "align.h"
+#include "assert.h"
+#include "str.h"
+
+/** Check the condition if wchar_t is signed */
+#ifdef WCHAR_IS_UNSIGNED
+ #define WCHAR_SIGNED_CHECK(cond) (true)
+#else
+ #define WCHAR_SIGNED_CHECK(cond) (cond)
+#endif
+
+/** Byte mask consisting of lowest @n bits (out of 8) */
+#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1))
+
+/** Byte mask consisting of lowest @n bits (out of 32) */
+#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1))
+
+/** Byte mask consisting of highest @n bits (out of 8) */
+#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
+
+/** Number of data bits in a UTF-8 continuation byte */
+#define CONT_BITS 6
+
+/** Decode a single character from a string.
+ *
+ * Decode a single character from a string of size @a size. Decoding starts
+ * at @a offset and this offset is moved to the beginning of the next
+ * character. In case of decoding error, offset generally advances at least
+ * by one. However, offset is never moved beyond size.
+ *
+ * @param str String (not necessarily NULL-terminated).
+ * @param offset Byte offset in string where to start decoding.
+ * @param size Size of the string (in bytes).
+ *
+ * @return Value of decoded character, U_SPECIAL on decoding error or
+ * NULL if attempt to decode beyond @a size.
+ *
+ */
+wchar_t str_decode(const char *str, size_t *offset, size_t size)
+{
+ uint8_t b0;
+ unsigned int b0_bits; /* Data bits in first byte */
+ unsigned int cbytes; /* Number of continuation bytes */
+ wchar_t ch;
+
+ if (*offset + 1 > size)
+ return 0;
+
+ /* First byte read from string */
+ b0 = (uint8_t) str[(*offset)++];
+
+ /* Determine code length */
+
+ if ((b0 & 0x80) == 0) {
+ /* 0xxxxxxx (Plain ASCII) */
+ b0_bits = 7;
+ cbytes = 0;
+ } else if ((b0 & 0xe0) == 0xc0) {
+ /* 110xxxxx 10xxxxxx */
+ b0_bits = 5;
+ cbytes = 1;
+ } else if ((b0 & 0xf0) == 0xe0) {
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ b0_bits = 4;
+ cbytes = 2;
+ } else if ((b0 & 0xf8) == 0xf0) {
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ b0_bits = 3;
+ cbytes = 3;
+ } else {
+ /* 10xxxxxx -- unexpected continuation byte */
+ return U_SPECIAL;
+ }
+
+ if (*offset + cbytes > size)
+ return U_SPECIAL;
+
+ ch = b0 & LO_MASK_8(b0_bits);
+
+ /* Decode continuation bytes */
+ while (cbytes > 0) {
+ uint8_t b = (uint8_t) str[(*offset)++];
+
+ /* Must be 10xxxxxx */
+ if ((b & 0xc0) != 0x80)
+ return U_SPECIAL;
+
+ /* Shift data bits to ch */
+ ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+ cbytes--;
+ }
+
+ return ch;
+}
+
+/** Decode a single character from a string to the left.
+ *
+ * Decode a single character from a string of size @a size. Decoding starts
+ * at @a offset and this offset is moved to the beginning of the previous
+ * character. In case of decoding error, offset generally decreases at least
+ * by one. However, offset is never moved before 0.
+ *
+ * @param str String (not necessarily NULL-terminated).
+ * @param offset Byte offset in string where to start decoding.
+ * @param size Size of the string (in bytes).
+ *
+ * @return Value of decoded character, U_SPECIAL on decoding error or
+ * NULL if attempt to decode beyond @a start of str.
+ *
+ */
+wchar_t str_decode_reverse(const char *str, size_t *offset, size_t size)
+{
+ size_t processed = 0;
+
+ if (*offset == 0)
+ return 0;
+
+ /* Continue while continuation bytes found */
+ while (*offset > 0 && processed < 4) {
+ uint8_t b = (uint8_t) str[--(*offset)];
+
+ if (processed == 0 && (b & 0x80) == 0) {
+ /* 0xxxxxxx (Plain ASCII) */
+ return b & 0x7f;
+ }
+ else if ((b & 0xe0) == 0xc0 || (b & 0xf0) == 0xe0 ||
+ (b & 0xf8) == 0xf0) {
+ /* Start byte */
+ size_t start_offset = *offset;
+ return str_decode(str, &start_offset, size);
+ }
+ else if ((b & 0xc0) != 0x80) {
+ /* Not a continuation byte */
+ return U_SPECIAL;
+ }
+ processed++;
+ }
+ /* Too many continuation bytes */
+ return U_SPECIAL;
+}
+
+/** Encode a single character to string representation.
+ *
+ * Encode a single character to string representation (i.e. UTF-8) and store
+ * it into a buffer at @a offset. Encoding starts at @a offset and this offset
+ * is moved to the position where the next character can be written to.
+ *
+ * @param ch Input character.
+ * @param str Output buffer.
+ * @param offset Byte offset where to start writing.
+ * @param size Size of the output buffer (in bytes).
+ *
+ * @return 0 if the character was encoded successfully, EOVERFLOW if there
+ * was not enough space in the output buffer or EINVAL if the character
+ * code was invalid.
+ */
+int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+{
+ unsigned int i;
+ uint32_t cc = (uint32_t) ch;
+ unsigned int b0_bits; /* Data bits in first byte */
+ unsigned int cbytes; /* Number of continuation bytes */
+
+ if (*offset >= size)
+ return EOVERFLOW;
+
+ if (!chr_check(ch))
+ return EINVAL;
+
+ /* Unsigned version of ch (bit operations should only be done
+ on unsigned types). */
+
+ /* Determine how many continuation bytes are needed */
+
+ if ((cc & ~LO_MASK_32(7)) == 0) {
+ b0_bits = 7;
+ cbytes = 0;
+ } else if ((cc & ~LO_MASK_32(11)) == 0) {
+ b0_bits = 5;
+ cbytes = 1;
+ } else if ((cc & ~LO_MASK_32(16)) == 0) {
+ b0_bits = 4;
+ cbytes = 2;
+ } else if ((cc & ~LO_MASK_32(21)) == 0) {
+ b0_bits = 3;
+ cbytes = 3;
+ } else {
+ /* Codes longer than 21 bits are not supported */
+ return EINVAL;
+ }
+
+ /* Check for available space in buffer */
+ if (*offset + cbytes >= size)
+ return EOVERFLOW;
+
+ /* Encode continuation bytes */
+ for (i = cbytes; i > 0; i--) {
+ str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
+ cc = cc >> CONT_BITS;
+ }
+
+ /* Encode first byte */
+ str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
+
+ /* Advance offset */
+ *offset += cbytes + 1;
+
+ return 0;
+}
+
+/** Get size of string.
+ *
+ * Get the number of bytes which are used by the string @a str (excluding the
+ * NULL-terminator).
+ *
+ * @param str String to consider.
+ *
+ * @return Number of bytes used by the string
+ *
+ */
+size_t str_size(const char *str)
+{
+ size_t size = 0;
+
+ while (*str++ != 0)
+ size++;
+
+ return size;
+}
+
+/** Get size of wide string.
+ *
+ * Get the number of bytes which are used by the wide string @a str (excluding the
+ * NULL-terminator).
+ *
+ * @param str Wide string to consider.
+ *
+ * @return Number of bytes used by the wide string
+ *
+ */
+size_t wstr_size(const wchar_t *str)
+{
+ return (wstr_length(str) * sizeof(wchar_t));
+}
+
+/** Get size of string with length limit.
+ *
+ * Get the number of bytes which are used by up to @a max_len first
+ * characters in the string @a str. If @a max_len is greater than
+ * the length of @a str, the entire string is measured (excluding the
+ * NULL-terminator).
+ *
+ * @param str String to consider.
+ * @param max_len Maximum number of characters to measure.
+ *
+ * @return Number of bytes used by the characters.
+ *
+ */
+size_t str_lsize(const char *str, size_t max_len)
+{
+ size_t len = 0;
+ size_t offset = 0;
+
+ while (len < max_len) {
+ if (str_decode(str, &offset, STR_NO_LIMIT) == 0)
+ break;
+
+ len++;
+ }
+
+ return offset;
+}
+
+/** Get size of string with size limit.
+ *
+ * Get the number of bytes which are used by the string @a str
+ * (excluding the NULL-terminator), but no more than @max_size bytes.
+ *
+ * @param str String to consider.
+ * @param max_size Maximum number of bytes to measure.
+ *
+ * @return Number of bytes used by the string
+ *
+ */
+size_t str_nsize(const char *str, size_t max_size)
+{
+ size_t size = 0;
+
+ while ((*str++ != 0) && (size < max_size))
+ size++;
+
+ return size;
+}
+
+/** Get size of wide string with size limit.
+ *
+ * Get the number of bytes which are used by the wide string @a str
+ * (excluding the NULL-terminator), but no more than @max_size bytes.
+ *
+ * @param str Wide string to consider.
+ * @param max_size Maximum number of bytes to measure.
+ *
+ * @return Number of bytes used by the wide string
+ *
+ */
+size_t wstr_nsize(const wchar_t *str, size_t max_size)
+{
+ return (wstr_nlength(str, max_size) * sizeof(wchar_t));
+}
+
+/** Get size of wide string with length limit.
+ *
+ * Get the number of bytes which are used by up to @a max_len first
+ * wide characters in the wide string @a str. If @a max_len is greater than
+ * the length of @a str, the entire wide string is measured (excluding the
+ * NULL-terminator).
+ *
+ * @param str Wide string to consider.
+ * @param max_len Maximum number of wide characters to measure.
+ *
+ * @return Number of bytes used by the wide characters.
+ *
+ */
+size_t wstr_lsize(const wchar_t *str, size_t max_len)
+{
+ return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
+}
+
+/** Get number of characters in a string.
+ *
+ * @param str NULL-terminated string.
+ *
+ * @return Number of characters in string.
+ *
+ */
+size_t str_length(const char *str)
+{
+ size_t len = 0;
+ size_t offset = 0;
+
+ while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
+ len++;
+
+ return len;
+}
+
+/** Get number of characters in a wide string.
+ *
+ * @param str NULL-terminated wide string.
+ *
+ * @return Number of characters in @a str.
+ *
+ */
+size_t wstr_length(const wchar_t *wstr)
+{
+ size_t len = 0;
+
+ while (*wstr++ != 0)
+ len++;
+
+ return len;
+}
+
+/** Get number of characters in a string with size limit.
+ *
+ * @param str NULL-terminated string.
+ * @param size Maximum number of bytes to consider.
+ *
+ * @return Number of characters in string.
+ *
+ */
+size_t str_nlength(const char *str, size_t size)
+{
+ size_t len = 0;
+ size_t offset = 0;
+
+ while (str_decode(str, &offset, size) != 0)
+ len++;
+
+ return len;
+}
+
+/** Get number of characters in a string with size limit.
+ *
+ * @param str NULL-terminated string.
+ * @param size Maximum number of bytes to consider.
+ *
+ * @return Number of characters in string.
+ *
+ */
+size_t wstr_nlength(const wchar_t *str, size_t size)
+{
+ size_t len = 0;
+ size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
+ size_t offset = 0;
+
+ while ((offset < limit) && (*str++ != 0)) {
+ len++;
+ offset += sizeof(wchar_t);
+ }
+
+ return len;
+}
+
+/** Get character display width on a character cell display.
+ *
+ * @param ch Character
+ * @return Width of character in cells.
+ */
+size_t chr_width(wchar_t ch)
+{
+ return 1;
+}
+
+/** Get string display width on a character cell display.
+ *
+ * @param str String
+ * @return Width of string in cells.
+ */
+size_t str_width(const char *str)
+{
+ size_t width = 0;
+ size_t offset = 0;
+ wchar_t ch;
+
+ while ((ch = str_decode(str, &offset, STR_NO_LIMIT)) != 0)
+ width += chr_width(ch);
+
+ return width;
+}
+
+/** Check whether character is plain ASCII.
+ *
+ * @return True if character is plain ASCII.
+ *
+ */
+bool ascii_check(wchar_t ch)
+{
+ if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+ return true;
+
+ return false;
+}
+
+/** Check whether character is valid
+ *
+ * @return True if character is a valid Unicode code point.
+ *
+ */
+bool chr_check(wchar_t ch)
+{
+ if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+ return true;
+
+ return false;
+}
+
+/** Compare two NULL terminated strings.
+ *
+ * Do a char-by-char comparison of two NULL-terminated strings.
+ * The strings are considered equal iff their length is equal
+ * and both strings consist of the same sequence of characters.
+ *
+ * A string S1 is less than another string S2 if it has a character with
+ * lower value at the first character position where the strings differ.
+ * If the strings differ in length, the shorter one is treated as if
+ * padded by characters with a value of zero.
+ *
+ * @param s1 First string to compare.
+ * @param s2 Second string to compare.
+ *
+ * @return 0 if the strings are equal, -1 if the first is less than the second,
+ * 1 if the second is less than the first.
+ *
+ */
+int str_cmp(const char *s1, const char *s2)
+{
+ wchar_t c1 = 0;
+ wchar_t c2 = 0;
+
+ size_t off1 = 0;
+ size_t off2 = 0;
+
+ while (true) {
+ c1 = str_decode(s1, &off1, STR_NO_LIMIT);
+ c2 = str_decode(s2, &off2, STR_NO_LIMIT);
+
+ if (c1 < c2)
+ return -1;
+
+ if (c1 > c2)
+ return 1;
+
+ if (c1 == 0 || c2 == 0)
+ break;
+ }
+
+ return 0;
+}
+
+/** Compare two NULL terminated strings with length limit.
+ *
+ * Do a char-by-char comparison of two NULL-terminated strings.
+ * The strings are considered equal iff
+ * min(str_length(s1), max_len) == min(str_length(s2), max_len)
+ * and both strings consist of the same sequence of characters,
+ * up to max_len characters.
+ *
+ * A string S1 is less than another string S2 if it has a character with
+ * lower value at the first character position where the strings differ.
+ * If the strings differ in length, the shorter one is treated as if
+ * padded by characters with a value of zero. Only the first max_len
+ * characters are considered.
+ *
+ * @param s1 First string to compare.
+ * @param s2 Second string to compare.
+ * @param max_len Maximum number of characters to consider.
+ *
+ * @return 0 if the strings are equal, -1 if the first is less than the second,
+ * 1 if the second is less than the first.
+ *
+ */
+int str_lcmp(const char *s1, const char *s2, size_t max_len)
+{
+ wchar_t c1 = 0;
+ wchar_t c2 = 0;
+
+ size_t off1 = 0;
+ size_t off2 = 0;
+
+ size_t len = 0;
+
+ while (true) {
+ if (len >= max_len)
+ break;
+
+ c1 = str_decode(s1, &off1, STR_NO_LIMIT);
+ c2 = str_decode(s2, &off2, STR_NO_LIMIT);
+
+ if (c1 < c2)
+ return -1;
+
+ if (c1 > c2)
+ return 1;
+
+ if (c1 == 0 || c2 == 0)
+ break;
+
+ ++len;
+ }
+
+ return 0;
+
+}
+
+/** Test whether p is a prefix of s.
+ *
+ * Do a char-by-char comparison of two NULL-terminated strings
+ * and determine if p is a prefix of s.
+ *
+ * @param s The string in which to look
+ * @param p The string to check if it is a prefix of s
+ *
+ * @return true iff p is prefix of s else false
+ *
+ */
+bool str_test_prefix(const char *s, const char *p)
+{
+ wchar_t c1 = 0;
+ wchar_t c2 = 0;
+
+ size_t off1 = 0;
+ size_t off2 = 0;
+
+ while (true) {
+ c1 = str_decode(s, &off1, STR_NO_LIMIT);
+ c2 = str_decode(p, &off2, STR_NO_LIMIT);
+
+ if (c2 == 0)
+ return true;
+
+ if (c1 != c2)
+ return false;
+
+ if (c1 == 0)
+ break;
+ }
+
+ return false;
+}
+
+/** Copy string.
+ *
+ * Copy source string @a src to destination buffer @a dest.
+ * No more than @a size bytes are written. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
+ * @param dest Destination buffer.
+ * @param count Size of the destination buffer (must be > 0).
+ * @param src Source string.
+ *
+ */
+void str_cpy(char *dest, size_t size, const char *src)
+{
+ /* There must be space for a null terminator in the buffer. */
+ size_t src_off = 0;
+ size_t dest_off = 0;
+ wchar_t ch;
+
+ assert(size > 0);
+
+ while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
+ if (chr_encode(ch, dest, &dest_off, size - 1) != 0)
+ break;
+ }
+
+ dest[dest_off] = '\0';
+}
+
+/** Copy size-limited substring.
+ *
+ * Copy prefix of string @a src of max. size @a size to destination buffer
+ * @a dest. No more than @a size bytes are written. The output string will
+ * always be well-formed, i.e. null-terminated and containing only complete
+ * characters.
+ *
+ * No more than @a n bytes are read from the input string, so it does not
+ * have to be null-terminated.
+ *
+ * @param dest Destination buffer.
+ * @param count Size of the destination buffer (must be > 0).
+ * @param src Source string.
+ * @param n Maximum number of bytes to read from @a src.
+ *
+ */
+void str_ncpy(char *dest, size_t size, const char *src, size_t n)
+{
+ /* There must be space for a null terminator in the buffer. */
+ size_t src_off = 0;
+ size_t dest_off = 0;
+ wchar_t ch;
+
+ assert(size > 0);
+
+ while ((ch = str_decode(src, &src_off, n)) != 0) {
+ if (chr_encode(ch, dest, &dest_off, size - 1) != 0)
+ break;
+ }
+
+ dest[dest_off] = '\0';
+}
+
+/** Append one string to another.
+ *
+ * Append source string @a src to string in destination buffer @a dest.
+ * Size of the destination buffer is @a dest. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
+ * @param dest Destination buffer.
+ * @param count Size of the destination buffer.
+ * @param src Source string.
+ */
+void str_append(char *dest, size_t size, const char *src)
+{
+ size_t dstr_size;
+
+ dstr_size = str_size(dest);
+ if (dstr_size >= size)
+ return;
+
+ str_cpy(dest + dstr_size, size - dstr_size, src);
+}
+
+/** Convert space-padded ASCII to string.
+ *
+ * Common legacy text encoding in hardware is 7-bit ASCII fitted into
+ * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces
+ * (ASCII 0x20). Convert space-padded ascii to string representation.
+ *
+ * If the text does not fit into the destination buffer, the function converts
+ * as many characters as possible and returns EOVERFLOW.
+ *
+ * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
+ * converted anyway and invalid characters are replaced with question marks
+ * (U_SPECIAL) and the function returns EIO.
+ *
+ * Regardless of return value upon return @a dest will always be well-formed.
+ *
+ * @param dest Destination buffer
+ * @param size Size of destination buffer
+ * @param src Space-padded ASCII.
+ * @param n Size of the source buffer in bytes.
+ *
+ * @return 0 on success, EOVERFLOW if the text does not fit
+ * destination buffer, EIO if the text contains
+ * non-ASCII bytes.
+ */
+int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
+{
+ size_t sidx;
+ size_t didx;
+ size_t dlast;
+ uint8_t byte;
+ int rc;
+ int result;
+
+ /* There must be space for a null terminator in the buffer. */
+ assert(size > 0);
+ result = 0;
+
+ didx = 0;
+ dlast = 0;
+ for (sidx = 0; sidx < n; ++sidx) {
+ byte = src[sidx];
+ if (!ascii_check(byte)) {
+ byte = U_SPECIAL;
+ result = EIO;
+ }
+
+ rc = chr_encode(byte, dest, &didx, size - 1);
+ if (rc != 0) {
+ assert(rc == EOVERFLOW);
+ dest[didx] = '\0';
+ return rc;
+ }
+
+ /* Remember dest index after last non-empty character */
+ if (byte != 0x20)
+ dlast = didx;
+ }
+
+ /* Terminate string after last non-empty character */
+ dest[dlast] = '\0';
+ return result;
+}
+
+/** Convert wide string to string.
+ *
+ * Convert wide string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed.
+ *
+ * @param dest Destination buffer.
+ * @param size Size of the destination buffer.
+ * @param src Source wide string.
+ */
+void wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
+ wchar_t ch;
+ size_t src_idx;
+ size_t dest_off;
+
+ /* There must be space for a null terminator in the buffer. */
+ assert(size > 0);
+
+ src_idx = 0;
+ dest_off = 0;
+
+ while ((ch = src[src_idx++]) != 0) {
+ if (chr_encode(ch, dest, &dest_off, size - 1) != 0)
+ break;
+ }
+
+ dest[dest_off] = '\0';
+}
+
+/** Convert UTF16 string to string.
+ *
+ * Convert utf16 string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed. Surrogate pairs also supported.
+ *
+ * @param dest Destination buffer.
+ * @param size Size of the destination buffer.
+ * @param src Source utf16 string.
+ *
+ * @return 0, if success, negative otherwise.
+ */
+int utf16_to_str(char *dest, size_t size, const uint16_t *src)
+{
+ size_t idx = 0, dest_off = 0;
+ wchar_t ch;
+ int rc = 0;
+
+ /* There must be space for a null terminator in the buffer. */
+ assert(size > 0);
+
+ while (src[idx]) {
+ if ((src[idx] & 0xfc00) == 0xd800) {
+ if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) {
+ ch = 0x10000;
+ ch += (src[idx] & 0x03FF) << 10;
+ ch += (src[idx + 1] & 0x03FF);
+ idx += 2;
+ }
+ else
+ break;
+ } else {
+ ch = src[idx];
+ idx++;
+ }
+ rc = chr_encode(ch, dest, &dest_off, size - 1);
+ if (rc != 0)
+ break;
+ }
+ dest[dest_off] = '\0';
+ return rc;
+}
+
+int str_to_utf16(uint16_t *dest, size_t size, const char *src)
+{
+ int rc = 0;
+ size_t offset = 0;
+ size_t idx = 0;
+ wchar_t c;
+
+ assert(size > 0);
+
+ while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) {
+ if (c > 0x10000) {
+ if (idx + 2 >= size - 1) {
+ rc = EOVERFLOW;
+ break;
+ }
+ c = (c - 0x10000);
+ dest[idx] = 0xD800 | (c >> 10);
+ dest[idx + 1] = 0xDC00 | (c & 0x3FF);
+ idx++;
+ } else {
+ dest[idx] = c;
+ }
+
+ idx++;
+ if (idx >= size - 1) {
+ rc = EOVERFLOW;
+ break;
+ }
+ }
+
+ dest[idx] = '\0';
+ return rc;
+}
+
+
+/** Convert wide string to new string.
+ *
+ * Convert wide string @a src to string. Space for the new string is allocated
+ * on the heap.
+ *
+ * @param src Source wide string.
+ * @return New string.
+ */
+char *wstr_to_astr(const wchar_t *src)
+{
+ char dbuf[STR_BOUNDS(1)];
+ char *str;
+ wchar_t ch;
+
+ size_t src_idx;
+ size_t dest_off;
+ size_t dest_size;
+
+ /* Compute size of encoded string. */
+
+ src_idx = 0;
+ dest_size = 0;
+
+ while ((ch = src[src_idx++]) != 0) {
+ dest_off = 0;
+ if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != 0)
+ break;
+ dest_size += dest_off;
+ }
+
+ str = malloc(dest_size + 1);
+ if (str == NULL)
+ return NULL;
+
+ /* Encode string. */
+
+ src_idx = 0;
+ dest_off = 0;
+
+ while ((ch = src[src_idx++]) != 0) {
+ if (chr_encode(ch, str, &dest_off, dest_size) != 0)
+ break;
+ }
+
+ str[dest_size] = '\0';
+ return str;
+}
+
+
+/** Convert string to wide string.
+ *
+ * Convert string @a src to wide string. The output is written to the
+ * buffer specified by @a dest and @a dlen. @a dlen must be non-zero
+ * and the wide string written will always be null-terminated.
+ *
+ * @param dest Destination buffer.
+ * @param dlen Length of destination buffer (number of wchars).
+ * @param src Source string.
+ */
+void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+{
+ size_t offset;
+ size_t di;
+ wchar_t c;
+
+ assert(dlen > 0);
+
+ offset = 0;
+ di = 0;
+
+ do {
+ if (di >= dlen - 1)
+ break;
+
+ c = str_decode(src, &offset, STR_NO_LIMIT);
+ dest[di++] = c;
+ } while (c != '\0');
+
+ dest[dlen - 1] = '\0';
+}
+
+/** Convert string to wide string.
+ *
+ * Convert string @a src to wide string. A new wide NULL-terminated
+ * string will be allocated on the heap.
+ *
+ * @param src Source string.
+ */
+wchar_t *str_to_awstr(const char *str)
+{
+ size_t len = str_length(str);
+
+ wchar_t *wstr = calloc(len+1, sizeof(wchar_t));
+ if (wstr == NULL)
+ return NULL;
+
+ str_to_wstr(wstr, len + 1, str);
+ return wstr;
+}
+
+/** Find first occurence of character in string.
+ *
+ * @param str String to search.
+ * @param ch Character to look for.
+ *
+ * @return Pointer to character in @a str or NULL if not found.
+ */
+char *str_chr(const char *str, wchar_t ch)
+{
+ wchar_t acc;
+ size_t off = 0;
+ size_t last = 0;
+
+ while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
+ if (acc == ch)
+ return (char *) (str + last);
+ last = off;
+ }
+
+ return NULL;
+}
+
+/** Removes specified trailing characters from a string.
+ *
+ * @param str String to remove from.
+ * @param ch Character to remove.
+ */
+void str_rtrim(char *str, wchar_t ch)
+{
+ size_t off = 0;
+ size_t pos = 0;
+ wchar_t c;
+ bool update_last_chunk = true;
+ char *last_chunk = NULL;
+
+ while ((c = str_decode(str, &off, STR_NO_LIMIT))) {
+ if (c != ch) {
+ update_last_chunk = true;
+ last_chunk = NULL;
+ } else if (update_last_chunk) {
+ update_last_chunk = false;
+ last_chunk = (str + pos);
+ }
+ pos = off;
+ }
+
+ if (last_chunk)
+ *last_chunk = '\0';
+}
+
+/** Removes specified leading characters from a string.
+ *
+ * @param str String to remove from.
+ * @param ch Character to remove.
+ */
+void str_ltrim(char *str, wchar_t ch)
+{
+ wchar_t acc;
+ size_t off = 0;
+ size_t pos = 0;
+ size_t str_sz = str_size(str);
+
+ while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
+ if (acc != ch)
+ break;
+ else
+ pos = off;
+ }
+
+ if (pos > 0) {
+ memmove(str, &str[pos], str_sz - pos);
+ pos = str_sz - pos;
+ str[str_sz - pos] = '\0';
+ }
+}
+
+/** Find last occurence of character in string.
+ *
+ * @param str String to search.
+ * @param ch Character to look for.
+ *
+ * @return Pointer to character in @a str or NULL if not found.
+ */
+char *str_rchr(const char *str, wchar_t ch)
+{
+ wchar_t acc;
+ size_t off = 0;
+ size_t last = 0;
+ const char *res = NULL;
+
+ while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
+ if (acc == ch)
+ res = (str + last);
+ last = off;
+ }
+
+ return (char *) res;
+}
+
+/** Insert a wide character into a wide string.
+ *
+ * Insert a wide character into a wide string at position
+ * @a pos. The characters after the position are shifted.
+ *
+ * @param str String to insert to.
+ * @param ch Character to insert to.
+ * @param pos Character index where to insert.
+ @ @param max_pos Characters in the buffer.
+ *
+ * @return True if the insertion was sucessful, false if the position
+ * is out of bounds.
+ *
+ */
+bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+{
+ size_t len = wstr_length(str);
+ size_t i;
+
+ if ((pos > len) || (pos + 1 > max_pos))
+ return false;
+
+ for (i = len; i + 1 > pos; i--)
+ str[i + 1] = str[i];
+
+ str[pos] = ch;
+
+ return true;
+}
+
+/** Remove a wide character from a wide string.
+ *
+ * Remove a wide character from a wide string at position
+ * @a pos. The characters after the position are shifted.
+ *
+ * @param str String to remove from.
+ * @param pos Character index to remove.
+ *
+ * @return True if the removal was sucessful, false if the position
+ * is out of bounds.
+ *
+ */
+bool wstr_remove(wchar_t *str, size_t pos)
+{
+ size_t len = wstr_length(str);
+ size_t i;
+
+ if (pos >= len)
+ return false;
+
+ for (i = pos + 1; i <= len; i++)
+ str[i - 1] = str[i];
+
+ return true;
+}
+
+int stricmp(const char *a, const char *b)
+{
+ int c = 0;
+
+ while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c]))))
+ c++;
+
+ return (tolower(a[c]) - tolower(b[c]));
+}
+
+/** Convert string to a number.
+ * Core of strtol and strtoul functions.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, function stores here pointer to the first
+ * invalid character.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param sgn It's set to 1 if minus found.
+ * @return Result of conversion.
+ */
+static unsigned long
+_strtoul(const char *nptr, char **endptr, int base, char *sgn)
+{
+ unsigned char c;
+ unsigned long result = 0;
+ unsigned long a, b;
+ const char *str = nptr;
+ const char *tmpptr;
+
+ while (isspace(*str))
+ str++;
+
+ if (*str == '-') {
+ *sgn = 1;
+ ++str;
+ } else if (*str == '+')
+ ++str;
+
+ if (base) {
+ if ((base == 1) || (base > 36)) {
+ /* FIXME: set errno to EINVAL */
+ return 0;
+ }
+ if ((base == 16) && (*str == '0') && ((str[1] == 'x') ||
+ (str[1] == 'X'))) {
+ str += 2;
+ }
+ } else {
+ base = 10;
+
+ if (*str == '0') {
+ base = 8;
+ if ((str[1] == 'X') || (str[1] == 'x')) {
+ base = 16;
+ str += 2;
+ }
+ }
+ }
+
+ tmpptr = str;
+
+ while (*str) {
+ c = *str;
+ c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 :
+ (c <= '9' ? c - '0' : 0xff)));
+ if (c >= base) {
+ break;
+ }
+
+ a = (result & 0xff) * base + c;
+ b = (result >> 8) * base + (a >> 8);
+
+ if (b > (ULONG_MAX >> 8)) {
+ /* overflow */
+ /* FIXME: errno = ERANGE*/
+ return ULONG_MAX;
+ }
+
+ result = (b << 8) + (a & 0xff);
+ ++str;
+ }
+
+ if (str == tmpptr) {
+ /*
+ * No number was found => first invalid character is the first
+ * character of the string.
+ */
+ /* FIXME: set errno to EINVAL */
+ str = nptr;
+ result = 0;
+ }
+
+ if (endptr)
+ *endptr = (char *) str;
+
+ if (nptr == str) {
+ /*FIXME: errno = EINVAL*/
+ return 0;
+ }
+
+ return result;
+}
+
+/** Convert initial part of string to long int according to given base.
+ * The number may begin with an arbitrary number of whitespaces followed by
+ * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be
+ * inserted and the number will be taken as hexadecimal one. If the base is 0
+ * and the number begin with a zero, number will be taken as octal one (as with
+ * base 8). Otherwise the base 0 is taken as decimal.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, function stores here pointer to the first
+ * invalid character.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @return Result of conversion.
+ */
+long int strtol(const char *nptr, char **endptr, int base)
+{
+ char sgn = 0;
+ unsigned long number = 0;
+
+ number = _strtoul(nptr, endptr, base, &sgn);
+
+ if (number > LONG_MAX) {
+ if ((sgn) && (number == (unsigned long) (LONG_MAX) + 1)) {
+ /* FIXME: set 0 to errno */
+ return number;
+ }
+ /* FIXME: set ERANGE to errno */
+ return (sgn ? LONG_MIN : LONG_MAX);
+ }
+
+ return (sgn ? -number : number);
+}
+
+/** Convert initial part of string to unsigned long according to given base.
+ * The number may begin with an arbitrary number of whitespaces followed by
+ * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be
+ * inserted and the number will be taken as hexadecimal one. If the base is 0
+ * and the number begin with a zero, number will be taken as octal one (as with
+ * base 8). Otherwise the base 0 is taken as decimal.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, function stores here pointer to the first
+ * invalid character
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @return Result of conversion.
+ */
+unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+ char sgn = 0;
+ unsigned long number = 0;
+
+ number = _strtoul(nptr, endptr, base, &sgn);
+
+ return (sgn ? -number : number);
+}
+
+char *strtok(char *s, const char *delim)
+{
+ static char *next;
+
+ return strtok_r(s, delim, &next);
+}
+
+char *strtok_r(char *s, const char *delim, char **next)
+{
+ char *start, *end;
+
+ if (s == NULL)
+ s = *next;
+
+ /* Skip over leading delimiters. */
+ while (*s && (str_chr(delim, *s) != NULL)) ++s;
+ start = s;
+
+ /* Skip over token characters. */
+ while (*s && (str_chr(delim, *s) == NULL)) ++s;
+ end = s;
+ *next = (*s ? s + 1 : s);
+
+ if (start == end) {
+ return NULL; /* No more tokens. */
+ }
+
+ /* Overwrite delimiter with NULL terminator. */
+ *end = '\0';
+ return start;
+}
+
+/** Convert string to uint64_t (internal variant).
+ *
+ * @param nptr Pointer to string.
+ * @param endptr Pointer to the first invalid character is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param neg Indication of unary minus is stored here.
+ * @apram result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+static int str_uint(const char *nptr, char **endptr, unsigned int base,
+ bool *neg, uint64_t *result)
+{
+ const char *str = nptr;
+ const char *startstr;
+
+ assert(endptr != NULL);
+ assert(neg != NULL);
+ assert(result != NULL);
+
+ *neg = false;
+
+ /* Ignore leading whitespace */
+ while (isspace(*str))
+ str++;
+
+ if (*str == '-') {
+ *neg = true;
+ str++;
+ } else if (*str == '+')
+ str++;
+
+ if (base == 0) {
+ /* Decode base if not specified */
+ base = 10;
+
+ if (*str == '0') {
+ base = 8;
+ str++;
+
+ switch (*str) {
+ case 'b':
+ case 'B':
+ base = 2;
+ str++;
+ break;
+ case 'o':
+ case 'O':
+ base = 8;
+ str++;
+ break;
+ case 'd':
+ case 'D':
+ case 't':
+ case 'T':
+ base = 10;
+ str++;
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ str++;
+ break;
+ default:
+ str--;
+ }
+ }
+ } else {
+ /* Check base range */
+ if ((base < 2) || (base > 36)) {
+ *endptr = (char *) str;
+ return EINVAL;
+ }
+ }
+
+ *result = 0;
+ startstr = str;
+
+ while (*str != 0) {
+ unsigned int digit;
+ uint64_t prev;
+
+ if ((*str >= 'a') && (*str <= 'z'))
+ digit = *str - 'a' + 10;
+ else if ((*str >= 'A') && (*str <= 'Z'))
+ digit = *str - 'A' + 10;
+ else if ((*str >= '0') && (*str <= '9'))
+ digit = *str - '0';
+ else
+ break;
+
+ if (digit >= base)
+ break;
+
+ prev = *result;
+ *result = (*result) * base + digit;
+
+ if (*result < prev) {
+ /* Overflow */
+ *endptr = (char *) str;
+ return EOVERFLOW;
+ }
+
+ str++;
+ }
+
+ if (str == startstr) {
+ /*
+ * No digits were decoded => first invalid character is
+ * the first character of the string.
+ */
+ str = nptr;
+ }
+
+ *endptr = (char *) str;
+
+ if (str == nptr)
+ return EINVAL;
+
+ return 0;
+}
+
+/** Convert string to uint8_t.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ * is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+int str_uint8_t(const char *nptr, char **endptr, unsigned int base,
+ bool strict, uint8_t *result)
+{
+ bool neg;
+ char *lendptr;
+ uint64_t res;
+ int ret;
+ uint8_t _res;
+
+ assert(result != NULL);
+
+ ret = str_uint(nptr, &lendptr, base, &neg, &res);
+
+ if (endptr != NULL)
+ *endptr = (char *) lendptr;
+
+ if (ret != 0)
+ return ret;
+
+ /* Do not allow negative values */
+ if (neg)
+ return EINVAL;
+
+ /* Check whether we are at the end of
+ the string in strict mode */
+ if ((strict) && (*lendptr != 0))
+ return EINVAL;
+
+ /* Check for overflow */
+ _res = (uint8_t) res;
+ if (_res != res)
+ return EOVERFLOW;
+
+ *result = _res;
+
+ return 0;
+}
+
+/** Convert string to uint16_t.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ * is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+int str_uint16_t(const char *nptr, char **endptr, unsigned int base,
+ bool strict, uint16_t *result)
+{
+ bool neg;
+ char *lendptr;
+ uint64_t res;
+ int ret;
+ uint16_t _res;
+
+ assert(result != NULL);
+
+ ret = str_uint(nptr, &lendptr, base, &neg, &res);
+
+ if (endptr != NULL)
+ *endptr = (char *) lendptr;
+
+ if (ret != 0)
+ return ret;
+
+ /* Do not allow negative values */
+ if (neg)
+ return EINVAL;
+
+ /* Check whether we are at the end of
+ the string in strict mode */
+ if ((strict) && (*lendptr != 0))
+ return EINVAL;
+
+ /* Check for overflow */
+ _res = (uint16_t) res;
+ if (_res != res)
+ return EOVERFLOW;
+
+ *result = _res;
+
+ return 0;
+}
+
+/** Convert string to uint32_t.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ * is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+int str_uint32_t(const char *nptr, char **endptr, unsigned int base,
+ bool strict, uint32_t *result)
+{
+ bool neg;
+ char *lendptr;
+ uint64_t res;
+ int ret;
+ uint32_t _res;
+
+ assert(result != NULL);
+
+ ret = str_uint(nptr, &lendptr, base, &neg, &res);
+
+ if (endptr != NULL)
+ *endptr = (char *) lendptr;
+
+ if (ret != 0)
+ return ret;
+
+ /* Do not allow negative values */
+ if (neg)
+ return EINVAL;
+
+ /* Check whether we are at the end of
+ the string in strict mode */
+ if ((strict) && (*lendptr != 0))
+ return EINVAL;
+
+ /* Check for overflow */
+ _res = (uint32_t) res;
+ if (_res != res)
+ return EOVERFLOW;
+
+ *result = _res;
+
+ return 0;
+}
+
+/** Convert string to uint64_t.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ * is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+int str_uint64_t(const char *nptr, char **endptr, unsigned int base,
+ bool strict, uint64_t *result)
+{
+ bool neg;
+ char *lendptr;
+ int ret;
+
+ assert(result != NULL);
+
+ ret = str_uint(nptr, &lendptr, base, &neg, result);
+
+ if (endptr != NULL)
+ *endptr = (char *) lendptr;
+
+ if (ret != 0)
+ return ret;
+
+ /* Do not allow negative values */
+ if (neg)
+ return EINVAL;
+
+ /* Check whether we are at the end of
+ the string in strict mode */
+ if ((strict) && (*lendptr != 0))
+ return EINVAL;
+
+ return 0;
+}
+
+/** Convert string to size_t.
+ *
+ * @param nptr Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ * is stored here.
+ * @param base Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @param result Result of the conversion.
+ *
+ * @return 0 if conversion was successful.
+ *
+ */
+int str_size_t(const char *nptr, char **endptr, unsigned int base,
+ bool strict, size_t *result)
+{
+ bool neg;
+ char *lendptr;
+ uint64_t res;
+ int ret;
+ size_t _res;
+
+ assert(result != NULL);
+
+ ret = str_uint(nptr, &lendptr, base, &neg, &res);
+
+ if (endptr != NULL)
+ *endptr = (char *) lendptr;
+
+ if (ret != 0)
+ return ret;
+
+ /* Do not allow negative values */
+ if (neg)
+ return EINVAL;
+
+ /* Check whether we are at the end of
+ the string in strict mode */
+ if ((strict) && (*lendptr != 0))
+ return EINVAL;
+
+ /* Check for overflow */
+ _res = (size_t) res;
+ if (_res != res)
+ return EOVERFLOW;
+
+ *result = _res;
+
+ return 0;
+}
+
+void order_suffix(const uint64_t val, uint64_t *rv, char *suffix)
+{
+ if (val > UINT64_C(10000000000000000000)) {
+ *rv = val / UINT64_C(1000000000000000000);
+ *suffix = 'Z';
+ } else if (val > UINT64_C(1000000000000000000)) {
+ *rv = val / UINT64_C(1000000000000000);
+ *suffix = 'E';
+ } else if (val > UINT64_C(1000000000000000)) {
+ *rv = val / UINT64_C(1000000000000);
+ *suffix = 'T';
+ } else if (val > UINT64_C(1000000000000)) {
+ *rv = val / UINT64_C(1000000000);
+ *suffix = 'G';
+ } else if (val > UINT64_C(1000000000)) {
+ *rv = val / UINT64_C(1000000);
+ *suffix = 'M';
+ } else if (val > UINT64_C(1000000)) {
+ *rv = val / UINT64_C(1000);
+ *suffix = 'k';
+ } else {
+ *rv = val;
+ *suffix = ' ';
+ }
+}
+
+void bin_order_suffix(const uint64_t val, uint64_t *rv, const char **suffix,
+ bool fixed)
+{
+ if (val > UINT64_C(1152921504606846976)) {
+ *rv = val / UINT64_C(1125899906842624);
+ *suffix = "EiB";
+ } else if (val > UINT64_C(1125899906842624)) {
+ *rv = val / UINT64_C(1099511627776);
+ *suffix = "TiB";
+ } else if (val > UINT64_C(1099511627776)) {
+ *rv = val / UINT64_C(1073741824);
+ *suffix = "GiB";
+ } else if (val > UINT64_C(1073741824)) {
+ *rv = val / UINT64_C(1048576);
+ *suffix = "MiB";
+ } else if (val > UINT64_C(1048576)) {
+ *rv = val / UINT64_C(1024);
+ *suffix = "KiB";
+ } else {
+ *rv = val;
+ if (fixed)
+ *suffix = "B ";
+ else
+ *suffix = "B";
+ }
+}
+
+/** @}
+ */
diff --git a/apps/libc/helenos/str.h b/apps/libc/helenos/str.h
new file mode 100644
index 0000000..f114543
--- /dev/null
+++ b/apps/libc/helenos/str.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2011 Oleg Romanenko
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_STR_H_
+#define LIBC_STR_H_
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <wchar.h>
+
+#define U_SPECIAL '?'
+
+/** No size limit constant */
+#define STR_NO_LIMIT ((size_t) -1)
+
+/** Maximum size of a string containing @c length characters */
+#define STR_BOUNDS(length) ((length) << 2)
+
+/**
+ * Maximum size of a buffer needed to a string converted from space-padded
+ * ASCII of size @a spa_size using spascii_to_str().
+ */
+#define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
+
+extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
+extern wchar_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
+extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
+
+extern size_t str_size(const char *str);
+extern size_t wstr_size(const wchar_t *str);
+
+extern size_t str_nsize(const char *str, size_t max_size);
+extern size_t wstr_nsize(const wchar_t *str, size_t max_size);
+
+extern size_t str_lsize(const char *str, size_t max_len);
+extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
+
+extern size_t str_length(const char *str);
+extern size_t wstr_length(const wchar_t *wstr);
+
+extern size_t str_nlength(const char *str, size_t size);
+extern size_t wstr_nlength(const wchar_t *str, size_t size);
+
+extern size_t chr_width(wchar_t ch);
+extern size_t str_width(const char *str);
+
+extern bool ascii_check(wchar_t ch);
+extern bool chr_check(wchar_t ch);
+
+extern int str_cmp(const char *s1, const char *s2);
+extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
+
+extern bool str_test_prefix(const char *s, const char *p);
+
+extern void str_cpy(char *dest, size_t size, const char *src);
+extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
+extern void str_append(char *dest, size_t size, const char *src);
+
+extern int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
+extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
+extern char *wstr_to_astr(const wchar_t *src);
+extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
+extern wchar_t *str_to_awstr(const char *src);
+extern int utf16_to_str(char *dest, size_t size, const uint16_t *src);
+extern int str_to_utf16(uint16_t *dest, size_t size, const char *src);
+
+extern char *str_chr(const char *str, wchar_t ch);
+extern char *str_rchr(const char *str, wchar_t ch);
+
+extern void str_rtrim(char *str, wchar_t ch);
+extern void str_ltrim(char *str, wchar_t ch);
+
+extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
+extern bool wstr_remove(wchar_t *str, size_t pos);
+
+extern char *str_dup(const char *);
+extern char *str_ndup(const char *, size_t max_size);
+
+extern int str_uint8_t(const char *, char **, unsigned int, bool, uint8_t *);
+extern int str_uint16_t(const char *, char **, unsigned int, bool, uint16_t *);
+extern int str_uint32_t(const char *, char **, unsigned int, bool, uint32_t *);
+extern int str_uint64_t(const char *, char **, unsigned int, bool, uint64_t *);
+extern int str_size_t(const char *, char **, unsigned int, bool, size_t *);
+
+extern void order_suffix(const uint64_t, uint64_t *, char *);
+extern void bin_order_suffix(const uint64_t, uint64_t *, const char **, bool);
+
+/*
+ * TODO: Get rid of this.
+ */
+
+extern int stricmp(const char *, const char *);
+
+extern long int strtol(const char *, char **, int);
+extern unsigned long strtoul(const char *, char **, int);
+
+extern char * strtok_r(char *, const char *, char **);
+extern char * strtok(char *, const char *);
+
+#endif
+
+/** @}
+ */
diff --git a/apps/libc/helenos/vsnprintf.c b/apps/libc/helenos/vsnprintf.c
new file mode 100644
index 0000000..7b54719
--- /dev/null
+++ b/apps/libc/helenos/vsnprintf.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "str.h"
+#include "printf_core.h"
+#include <errno.h>
+
+typedef struct {
+ size_t size; /* Total size of the buffer (in bytes) */
+ size_t len; /* Number of already used bytes */
+ char *dst; /* Destination */
+} vsnprintf_data_t;
+
+/** Write string to given buffer.
+ *
+ * Write at most data->size plain characters including trailing zero.
+ * According to C99, snprintf() has to return number of characters that
+ * would have been written if enough space had been available. Hence
+ * the return value is not the number of actually printed characters
+ * but size of the input string.
+ *
+ * @param str Source string to print.
+ * @param size Number of plain characters in str.
+ * @param data Structure describing destination string, counter
+ * of used space and total string size.
+ *
+ * @return Number of characters to print (not characters actually
+ * printed).
+ *
+ */
+static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data)
+{
+ size_t left = data->size - data->len;
+
+ if (left == 0)
+ return ((int) size);
+
+ if (left == 1) {
+ /* We have only one free byte left in buffer
+ * -> store trailing zero
+ */
+ data->dst[data->size - 1] = 0;
+ data->len = data->size;
+ return ((int) size);
+ }
+
+ if (left <= size) {
+ /* We do not have enough space for the whole string
+ * with the trailing zero => print only a part
+ * of string
+ */
+ size_t index = 0;
+
+ while (index < size) {
+ wchar_t uc = str_decode(str, &index, size);
+
+ if (chr_encode(uc, data->dst, &data->len, data->size - 1) != 0)
+ break;
+ }
+
+ /* Put trailing zero at end, but not count it
+ * into data->len so it could be rewritten next time
+ */
+ data->dst[data->len] = 0;
+
+ return ((int) size);
+ }
+
+ /* Buffer is big enough to print the whole string */
+ memcpy((void *)(data->dst + data->len), (void *) str, size);
+ data->len += size;
+
+ /* Put trailing zero at end, but not count it
+ * into data->len so it could be rewritten next time
+ */
+ data->dst[data->len] = 0;
+
+ return ((int) size);
+}
+
+/** Write wide string to given buffer.
+ *
+ * Write at most data->size plain characters including trailing zero.
+ * According to C99, snprintf() has to return number of characters that
+ * would have been written if enough space had been available. Hence
+ * the return value is not the number of actually printed characters
+ * but size of the input string.
+ *
+ * @param str Source wide string to print.
+ * @param size Number of bytes in str.
+ * @param data Structure describing destination string, counter
+ * of used space and total string size.
+ *
+ * @return Number of wide characters to print (not characters actually
+ * printed).
+ *
+ */
+static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+{
+ size_t index = 0;
+
+ while (index < (size / sizeof(wchar_t))) {
+ size_t left = data->size - data->len;
+
+ if (left == 0)
+ return ((int) size);
+
+ if (left == 1) {
+ /* We have only one free byte left in buffer
+ * -> store trailing zero
+ */
+ data->dst[data->size - 1] = 0;
+ data->len = data->size;
+ return ((int) size);
+ }
+
+ if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != 0)
+ break;
+
+ index++;
+ }
+
+ /* Put trailing zero at end, but not count it
+ * into data->len so it could be rewritten next time
+ */
+ data->dst[data->len] = 0;
+
+ return ((int) size);
+}
+
+int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
+{
+ vsnprintf_data_t data = {
+ size,
+ 0,
+ str
+ };
+ printf_spec_t ps = {
+ (int(*) (const char *, size_t, void *)) vsnprintf_str_write,
+ (int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
+ &data
+ };
+
+ /* Print 0 at end of string - fix the case that nothing will be printed */
+ if (size > 0)
+ str[0] = 0;
+
+ /* vsnprintf_write ensures that str will be terminated by zero. */
+ return printf_core(fmt, &ps, ap);
+}
+
+/** @}
+ */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 11/20] app: printf: add version from contiki
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (8 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 10/20] app: printf: use HelenOS verison with wide char support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 12/20] app: add tinycurses support Jean-Christophe PLAGNIOL-VILLARD
` (8 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
the strformat is taken from contiki OS which is under 3-clause BSD license
no wide char support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/libc/Kconfig | 9 +
apps/libc/Makefile | 1 +
apps/libc/contiki/Makefile | 1 +
apps/libc/contiki/strformat.c | 621 +++++++++++++++++++++++++++++++++++++++++
apps/libc/contiki/strformat.h | 25 ++
apps/libc/contiki/vsprintf.c | 116 ++++++++
6 files changed, 773 insertions(+)
create mode 100644 apps/libc/contiki/Makefile
create mode 100644 apps/libc/contiki/strformat.c
create mode 100644 apps/libc/contiki/strformat.h
create mode 100644 apps/libc/contiki/vsprintf.c
diff --git a/apps/libc/Kconfig b/apps/libc/Kconfig
index 25b35ee..8d4fbd6 100644
--- a/apps/libc/Kconfig
+++ b/apps/libc/Kconfig
@@ -24,6 +24,10 @@ config APP_PRINTF_STACK_SIZE
choice
prompt "printf implementation"
+ default APPS_PRINTF_HELENOS
+
+config APPS_PRINTF_CONTIKI
+ bool "contiki"
config APPS_PRINTF_HELENOS
bool "helen os"
@@ -32,4 +36,9 @@ config APPS_PRINTF_HELENOS
endchoice
+config APP_PRINTF_STACK_SIZE
+ hex "printf stack size"
+ default 0x1000
+ depends on APPS_PRINTF_CONTIKI
+
endmenu
diff --git a/apps/libc/Makefile b/apps/libc/Makefile
index c84f00e..832833c 100644
--- a/apps/libc/Makefile
+++ b/apps/libc/Makefile
@@ -15,6 +15,7 @@ app-y += unistd.o
app-$(CONFIG_APPS_MALLOC_DUMMY) += dummy_malloc.o
app-$(CONFIG_APPS_MALLOC_TLSF) += tlsf_malloc.o tlsf.o
app-y += string.o
+obj-$(CONFIG_APPS_PRINTF_CONTIKI) += contiki/
obj-$(CONFIG_APPS_PRINTF_HELENOS) += helenos/
obj-y += sys/
app-y += time.o
diff --git a/apps/libc/contiki/Makefile b/apps/libc/contiki/Makefile
new file mode 100644
index 0000000..e77ee5c
--- /dev/null
+++ b/apps/libc/contiki/Makefile
@@ -0,0 +1 @@
+app-y += vsprintf.o strformat.o
diff --git a/apps/libc/contiki/strformat.c b/apps/libc/contiki/strformat.c
new file mode 100644
index 0000000..82f0535
--- /dev/null
+++ b/apps/libc/contiki/strformat.c
@@ -0,0 +1,621 @@
+/*
+ * from contiki 3-clause BSD license
+ */
+#include <strformat.h>
+
+#ifdef __APP__
+#define HAVE_DOUBLE
+#endif
+
+#define HAVE_LONGLONG
+#ifndef LARGEST_SIGNED
+#ifdef HAVE_LONGLONG
+#define LARGEST_SIGNED long long int
+#else
+#define LARGEST_SIGNED long int
+#endif
+#endif
+
+#ifndef LARGEST_UNSIGNED
+#ifdef HAVE_LONGLONG
+#define LARGEST_UNSIGNED unsigned long long int
+#else
+#define LARGEST_UNSIGNED unsigned long int
+#endif
+#endif
+
+#ifndef POINTER_INT
+#define POINTER_INT unsigned long
+#endif
+
+typedef unsigned int FormatFlags;
+
+#define MAKE_MASK(shift,size) (((1 << size) - 1) << (shift))
+
+#define JUSTIFY_SHIFT 0
+#define JUSTIFY_SIZE 1
+#define JUSTIFY_RIGHT 0x0000
+#define JUSTIFY_LEFT 0x0001
+#define JUSTIFY_MASK MAKE_MASK(JUSTIFY_SHIFT,JUSTIFY_SIZE)
+
+
+/* How a positive number is prefixed */
+#define POSITIVE_SHIFT (JUSTIFY_SHIFT + JUSTIFY_SIZE)
+#define POSITIVE_NONE (0x0000 << POSITIVE_SHIFT)
+#define POSITIVE_SPACE (0x0001 << POSITIVE_SHIFT)
+#define POSITIVE_PLUS (0x0003 << POSITIVE_SHIFT)
+#define POSITIVE_MASK MAKE_MASK(POSITIVE_SHIFT, POSITIVE_SIZE)
+
+#define POSITIVE_SIZE 2
+
+#define ALTERNATE_FORM_SHIFT (POSITIVE_SHIFT + POSITIVE_SIZE)
+#define ALTERNATE_FORM_SIZE 1
+#define ALTERNATE_FORM (0x0001 << ALTERNATE_FORM_SHIFT)
+
+
+#define PAD_SHIFT (ALTERNATE_FORM_SHIFT + ALTERNATE_FORM_SIZE)
+#define PAD_SIZE 1
+#define PAD_SPACE (0x0000 << PAD_SHIFT)
+#define PAD_ZERO (0x0001 << PAD_SHIFT)
+
+#define SIZE_SHIFT (PAD_SHIFT + PAD_SIZE)
+#define SIZE_SIZE 3
+#define SIZE_CHAR (0x0001 << SIZE_SHIFT)
+#define SIZE_SHORT (0x0002 << SIZE_SHIFT)
+#define SIZE_INT (0x0000 << SIZE_SHIFT)
+#define SIZE_LONG (0x0003 << SIZE_SHIFT)
+#define SIZE_LONGLONG (0x0004 << SIZE_SHIFT)
+#define SIZE_MASK MAKE_MASK(SIZE_SHIFT,SIZE_SIZE)
+
+#define CONV_SHIFT (SIZE_SHIFT + SIZE_SIZE)
+#define CONV_SIZE 3
+#define CONV_INTEGER (0x0001 << CONV_SHIFT)
+#define CONV_FLOAT (0x0002 << CONV_SHIFT)
+#define CONV_POINTER (0x0003 << CONV_SHIFT)
+#define CONV_STRING (0x0004 << CONV_SHIFT)
+#define CONV_CHAR (0x0005 << CONV_SHIFT)
+#define CONV_PERCENT (0x0006 << CONV_SHIFT)
+#define CONV_WRITTEN (0x0007 << CONV_SHIFT)
+#define CONV_MASK MAKE_MASK(CONV_SHIFT, CONV_SIZE)
+
+#define RADIX_SHIFT (CONV_SHIFT + CONV_SIZE)
+#define RADIX_SIZE 2
+#define RADIX_DECIMAL (0x0001 << RADIX_SHIFT)
+#define RADIX_OCTAL (0x0002 << RADIX_SHIFT)
+#define RADIX_HEX (0x0003 << RADIX_SHIFT)
+#define RADIX_MASK MAKE_MASK(RADIX_SHIFT,RADIX_SIZE)
+
+#define SIGNED_SHIFT (RADIX_SHIFT + RADIX_SIZE)
+#define SIGNED_SIZE 1
+#define SIGNED_NO (0x0000 << SIGNED_SHIFT)
+#define SIGNED_YES (0x0001 << SIGNED_SHIFT)
+#define SIGNED_MASK MAKE_MASK(SIGNED_SHIFT,SIGNED_SIZE)
+
+#define CAPS_SHIFT (SIGNED_SHIFT + SIGNED_SIZE)
+#define CAPS_SIZE 1
+#define CAPS_NO (0x0000 << CAPS_SHIFT)
+#define CAPS_YES (0x0001 << CAPS_SHIFT)
+#define CAPS_MASK MAKE_MASK(CAPS_SHIFT,CAPS_SIZE)
+
+#define FLOAT_SHIFT (CAPS_SHIFT + CAPS_SIZE)
+#define FLOAT_SIZE 2
+#define FLOAT_NORMAL (0x0000 << FLOAT_SHIFT)
+#define FLOAT_EXPONENT (0x0001 << FLOAT_SHIFT)
+#define FLOAT_DEPENDANT (0x0002 << FLOAT_SHIFT)
+#define FLOAT_HEX (0x0003 << FLOAT_SHIFT)
+#define FLOAT_MASK MAKE_MASK(FLOAT_SHIFT, FLOAT_SIZE)
+
+static FormatFlags
+parse_flags(const char **posp)
+{
+ FormatFlags flags = 0;
+ const char *pos = *posp;
+ while (1) {
+ switch(*pos) {
+ case '-':
+ flags |= JUSTIFY_LEFT;
+ break;
+ case '+':
+ flags |= POSITIVE_PLUS;
+ break;
+ case ' ':
+ flags |= POSITIVE_SPACE;
+ break;
+ case '#':
+ flags |= ALTERNATE_FORM;
+ break;
+ case '0':
+ flags |= PAD_ZERO;
+ break;
+ default:
+ *posp = pos;
+ return flags;
+ }
+ pos++;
+ }
+
+}
+
+static unsigned int
+parse_uint(const char **posp)
+{
+ unsigned v = 0;
+ const char *pos = *posp;
+ char ch;
+ while((ch = *pos) >= '0' && ch <= '9') {
+ v = v * 10 + (ch - '0');
+ pos++;
+ }
+ *posp = pos;
+ return v;
+}
+
+#define MAXCHARS_HEX ((sizeof(LARGEST_UNSIGNED) * 8) / 4 )
+
+/* Largest number of characters needed for converting an unsigned integer.
+ */
+#define MAXCHARS ((sizeof(LARGEST_UNSIGNED) * 8 + 2) / 3 )
+
+static unsigned int
+output_uint_decimal(char **posp, LARGEST_UNSIGNED v)
+{
+ unsigned int len;
+ char *pos = *posp;
+ while (v > 0) {
+ *--pos = (v % 10) + '0';
+ v /= 10;
+ }
+ len = *posp - pos;
+ *posp = pos;
+ return len;
+}
+
+static unsigned int
+output_uint_hex(char **posp, LARGEST_UNSIGNED v, unsigned int flags)
+{
+ unsigned int len;
+ const char *hex = (flags & CAPS_YES) ?"0123456789ABCDEF":"0123456789abcdef";
+ char *pos = *posp;
+ while (v > 0) {
+ *--pos = hex[(v % 16)];
+ v /= 16;
+ }
+ len = *posp - pos;
+ *posp = pos;
+ return len;
+}
+
+static unsigned int
+output_uint_octal(char **posp, LARGEST_UNSIGNED v)
+{
+ unsigned int len;
+ char *pos = *posp;
+ while (v > 0) {
+ *--pos = (v % 8) + '0';
+ v /= 8;
+ }
+ len = *posp - pos;
+ *posp = pos;
+ return len;
+}
+
+static StrFormatResult
+fill_space(const StrFormatContext *ctxt, unsigned int len)
+{
+ StrFormatResult res;
+ static const char buffer[16] = " ";
+ while(len > 16) {
+ res = ctxt->write_str(ctxt->user_data, buffer, 16);
+ if (res != STRFORMAT_OK) return res;
+ len -= 16;
+ }
+ if (len == 0) return STRFORMAT_OK;
+ return ctxt->write_str(ctxt->user_data, buffer, len);
+}
+
+static StrFormatResult
+fill_zero(const StrFormatContext *ctxt, unsigned int len)
+{
+ StrFormatResult res;
+ static const char buffer[16] = "0000000000000000";
+ while(len > 16) {
+ res = ctxt->write_str(ctxt->user_data, buffer, 16);
+ if (res != STRFORMAT_OK) return res;
+ len -= 16;
+ }
+ if (len == 0) return STRFORMAT_OK;
+ return ctxt->write_str(ctxt->user_data, buffer, len);
+}
+
+#define CHECKCB(res) {if ((res) != STRFORMAT_OK) {va_end(ap); return -1;}}
+
+int
+format_str(const StrFormatContext *ctxt, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+ va_start(ap, format);
+ ret = format_str_v(ctxt, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+format_str_v(const StrFormatContext *ctxt, const char *format, va_list ap)
+{
+ unsigned int written = 0;
+ const char *pos = format;
+ while(*pos != '\0') {
+ FormatFlags flags;
+ unsigned int minwidth = 0;
+ int precision = -1; /* Negative means no precision */
+ char ch;
+ const char *start = pos;
+ while( (ch = *pos) != '\0' && ch != '%') pos++;
+ if (pos != start) {
+ CHECKCB(ctxt->write_str(ctxt->user_data, start, pos - start));
+ written += pos - start;
+ }
+ if (*pos == '\0') {
+ va_end(ap);
+ return written;
+ }
+ pos++;
+ if (*pos == '\0') {
+ va_end(ap);
+ return written;
+ }
+ flags = parse_flags(&pos);
+
+ /* parse width */
+ if (*pos >= '1' && *pos <= '9') {
+ minwidth = parse_uint(&pos);
+ } else if (*pos == '*') {
+ int w = va_arg(ap,int);
+ if (w < 0) {
+ flags |= JUSTIFY_LEFT;
+ minwidth = w;
+ } else {
+ minwidth = w;
+ }
+ pos ++;
+ }
+
+ /* parse precision */
+ if (*pos == '.') {
+ pos++;
+ if (*pos >= '0' && *pos <= '9') {
+ precision = parse_uint(&pos);
+ } else if (*pos == '*') {
+ pos++;
+ precision = va_arg(ap,int);
+ }
+ }
+ if (*pos == 'l') {
+ pos++;
+ if (*pos == 'l') {
+ flags |= SIZE_LONGLONG;
+ pos++;
+ } else {
+ flags |= SIZE_LONG;
+ }
+ } else if (*pos == 'h') {
+ pos++;
+ if (*pos == 'h') {
+ flags |= SIZE_CHAR;
+ pos++;
+ } else {
+ flags |= SIZE_SHORT;
+ }
+ }
+
+ /* parse conversion specifier */
+ switch(*pos) {
+ case 'd':
+ case 'i':
+ flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_YES;
+ break;
+ case 'u':
+ flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_NO;
+ break;
+ case 'o':
+ flags |= CONV_INTEGER | RADIX_OCTAL | SIGNED_NO;
+ break;
+ case 'x':
+ flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO;
+ break;
+ case 'X':
+ flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO | CAPS_YES;
+ break;
+#ifdef HAVE_DOUBLE
+ case 'f':
+ flags |= CONV_FLOAT | FLOAT_NORMAL;
+ break;
+ case 'F':
+ flags |= CONV_FLOAT | FLOAT_NORMAL | CAPS_YES;
+ break;
+ case 'e':
+ flags |= CONV_FLOAT | FLOAT_EXPONENT;
+ break;
+ case 'E':
+ flags |= CONV_FLOAT | FLOAT_EXPONENT | CAPS_YES;
+ break;
+ case 'g':
+ flags |= CONV_FLOAT | FLOAT_DEPENDANT;
+ break;
+ case 'G':
+ flags |= CONV_FLOAT | FLOAT_DEPENDANT | CAPS_YES;
+ break;
+ case 'a':
+ flags |= CONV_FLOAT | FLOAT_HEX;
+ break;
+ case 'A':
+ flags |= CONV_FLOAT | FLOAT_HEX | CAPS_YES;
+ break;
+#endif
+ case 'c':
+ flags |= CONV_CHAR;
+ break;
+ case 's':
+ flags |= CONV_STRING;
+ break;
+ case 'p':
+ flags |= CONV_POINTER;
+ break;
+ case 'n':
+ flags |= CONV_WRITTEN;
+ break;
+ case '%':
+ flags |= CONV_PERCENT;
+ break;
+ case '\0':
+ va_end(ap);
+ return written;
+ }
+ pos++;
+ switch(flags & CONV_MASK) {
+ case CONV_PERCENT:
+ CHECKCB(ctxt->write_str(ctxt->user_data, "%", 1));
+ written++;
+ break;
+ case CONV_INTEGER:
+ {
+ /* unsigned integers */
+ char *prefix = 0; /* sign, "0x" or "0X" */
+ unsigned int prefix_len = 0;
+ char buffer[MAXCHARS];
+ char *conv_pos = buffer + MAXCHARS;
+ unsigned int conv_len = 0;
+ unsigned int width = 0;
+ unsigned int precision_fill;
+ unsigned int field_fill;
+ LARGEST_UNSIGNED uvalue = 0;
+ int negative = 0;
+
+ if (precision < 0) precision = 1;
+ else flags &= ~PAD_ZERO;
+
+ if (flags & SIGNED_YES) {
+ /* signed integers */
+ LARGEST_SIGNED value = 0;
+ switch(flags & SIZE_MASK) {
+ case SIZE_CHAR:
+ value = (signed char)va_arg(ap, int);
+ break;
+ case SIZE_SHORT:
+ value = (short)va_arg(ap, int);
+ break;
+ case SIZE_INT:
+ value = va_arg(ap, int);
+ break;
+#ifndef HAVE_LONGLONG
+ case SIZE_LONGLONG: /* Treat long long the same as long */
+#endif
+ case SIZE_LONG:
+ value = va_arg(ap, long);
+ break;
+#ifdef HAVE_LONGLONG
+ case SIZE_LONGLONG:
+ value = va_arg(ap, long long);
+ break;
+#endif
+ }
+ if (value < 0) {
+ uvalue = -value;
+ negative = 1;
+ } else {
+ uvalue = value;
+ }
+ } else {
+
+ switch(flags & SIZE_MASK) {
+ case SIZE_CHAR:
+ uvalue = (unsigned char)va_arg(ap,unsigned int);
+ break;
+ case SIZE_SHORT:
+ uvalue = (unsigned short)va_arg(ap,unsigned int);
+ break;
+ case SIZE_INT:
+ uvalue = va_arg(ap,unsigned int);
+ break;
+#ifndef HAVE_LONGLONG
+ case SIZE_LONGLONG: /* Treat long long the same as long */
+#endif
+ case SIZE_LONG:
+ uvalue = va_arg(ap,unsigned long);
+ break;
+#ifdef HAVE_LONGLONG
+ case SIZE_LONGLONG:
+ uvalue = va_arg(ap,unsigned long long);
+ break;
+#endif
+ }
+ }
+
+ switch(flags & (RADIX_MASK)) {
+ case RADIX_DECIMAL:
+ conv_len = output_uint_decimal(&conv_pos,uvalue);
+ break;
+ case RADIX_OCTAL:
+ conv_len = output_uint_octal(&conv_pos,uvalue);
+ break;
+ case RADIX_HEX:
+ conv_len = output_uint_hex(&conv_pos,uvalue, flags);
+ break;
+ }
+
+ width += conv_len;
+ precision_fill = (precision > conv_len) ? precision - conv_len : 0;
+ if ((flags & (RADIX_MASK | ALTERNATE_FORM))
+ == (RADIX_OCTAL | ALTERNATE_FORM)) {
+ if (precision_fill < 1) precision_fill = 1;
+ }
+
+ width += precision_fill;
+
+ if ((flags & (RADIX_MASK | ALTERNATE_FORM))
+ == (RADIX_HEX | ALTERNATE_FORM) && uvalue != 0) {
+ prefix_len = 2;
+ if (flags & CAPS_YES) {
+ prefix = "0X";
+ } else {
+ prefix = "0x";
+ }
+ }
+
+ if (flags & SIGNED_YES) {
+ if (negative) {
+ prefix = "-";
+ prefix_len = 1;
+ } else {
+ switch(flags & POSITIVE_MASK) {
+ case POSITIVE_SPACE:
+ prefix = " ";
+ prefix_len = 1;
+ break;
+ case POSITIVE_PLUS:
+ prefix = "+";
+ prefix_len = 1;
+ break;
+ }
+ }
+ }
+
+ width += prefix_len;
+
+ field_fill = (minwidth > width) ? minwidth - width : 0;
+
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
+ if (flags & PAD_ZERO) {
+ precision_fill += field_fill;
+ field_fill = 0; /* Do not double count padding */
+ } else {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ }
+
+ if (prefix_len > 0)
+ CHECKCB(ctxt->write_str(ctxt->user_data, prefix, prefix_len));
+ written += prefix_len;
+
+ CHECKCB(fill_zero(ctxt,precision_fill));
+ written += precision_fill;
+
+ CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
+ written += conv_len;
+
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ written += field_fill;
+ }
+ break;
+ case CONV_STRING:
+ {
+ unsigned int field_fill;
+ unsigned int len;
+ char *str = va_arg(ap,char *);
+ if (str) {
+ char *pos = str;
+ while(*pos != '\0') pos++;
+ len = pos - str;
+ } else {
+ str = "(null)";
+ len = 6;
+ }
+ if (precision >= 0 && precision < len) len = precision;
+ field_fill = (minwidth > len) ? minwidth - len : 0;
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ CHECKCB(ctxt->write_str(ctxt->user_data, str,len));
+ written += len;
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ written += field_fill;
+ }
+ break;
+ case CONV_POINTER:
+ {
+ LARGEST_UNSIGNED uvalue =
+ (LARGEST_UNSIGNED)(POINTER_INT)va_arg(ap,void *);
+ char buffer[MAXCHARS_HEX + 2];
+ char *conv_pos = buffer + MAXCHARS_HEX + 2;
+ unsigned int conv_len;
+ unsigned int field_fill;
+
+ conv_len = output_uint_hex(&conv_pos,uvalue,flags);
+ if (conv_len == 0) {
+ *--conv_pos = '0';
+ conv_len++;
+ }
+ *--conv_pos = 'x';
+ *--conv_pos = '0';
+ conv_len += 2;
+
+ field_fill = (minwidth > conv_len) ? minwidth - conv_len : 0;
+
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+
+ CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
+ written += conv_len;
+
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ written += field_fill;
+ }
+ break;
+ case CONV_CHAR:
+ {
+ char ch = va_arg(ap,int);
+ unsigned int field_fill = (minwidth > 1) ? minwidth - 1 : 0;
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ written += field_fill;
+ }
+
+ CHECKCB(ctxt->write_str(ctxt->user_data, &ch, 1));
+ written++;
+
+ if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
+ CHECKCB(fill_space(ctxt,field_fill));
+ }
+ written+= field_fill;
+ }
+ break;
+ case CONV_WRITTEN:
+ {
+ int *p = va_arg(ap,int*);
+ *p = written;
+ }
+ break;
+
+ }
+ }
+
+ return written;
+}
diff --git a/apps/libc/contiki/strformat.h b/apps/libc/contiki/strformat.h
new file mode 100644
index 0000000..d953c3e
--- /dev/null
+++ b/apps/libc/contiki/strformat.h
@@ -0,0 +1,25 @@
+#ifndef __STRFORMAT_H__
+#define __STRFORMAT_H__
+
+#include <stdarg.h>
+
+#define STRFORMAT_OK 0
+#define STRFORMAT_FAILED 1
+typedef unsigned int StrFormatResult;
+
+/* The data argument may only be considered valid during the function call */
+typedef StrFormatResult (*StrFormatWrite)(void *user_data, const char *data, unsigned int len);
+
+typedef struct _StrFormatContext
+{
+ StrFormatWrite write_str;
+ void *user_data;
+} StrFormatContext;
+
+int format_str(const StrFormatContext *ctxt, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 2,3)));
+
+int
+format_str_v(const StrFormatContext *ctxt, const char *format, va_list ap);
+
+#endif /* __STRFORMAT_H__ */
diff --git a/apps/libc/contiki/vsprintf.c b/apps/libc/contiki/vsprintf.c
new file mode 100644
index 0000000..1df7a4d
--- /dev/null
+++ b/apps/libc/contiki/vsprintf.c
@@ -0,0 +1,116 @@
+/*
+ * Coypyright Jean-Chritophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ */
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "strformat.h"
+
+struct FmtBuffer {
+ char *pos;
+ size_t left;
+};
+
+static StrFormatResult buffer_str(void *user_data, const char *data, unsigned int len)
+{
+ struct FmtBuffer *buffer = (struct FmtBuffer*)user_data;
+
+ if (len >= buffer->left) {
+ len = buffer->left;
+ len--;
+ }
+
+ memcpy(buffer->pos, data, len);
+ buffer->pos += len;
+ buffer->left -= len;
+
+ return STRFORMAT_OK;
+}
+
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ struct FmtBuffer buffer;
+ StrFormatContext ctxt;
+ int res;
+
+ ctxt.write_str = buffer_str;
+ ctxt.user_data = &buffer;
+ buffer.pos = buf;
+ buffer.left = size;
+ res = format_str_v(&ctxt, fmt, args);
+ *buffer.pos = '\0';
+
+ return res;
+}
+
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ int i;
+
+ i = vsnprintf(buf, size, fmt, args);
+ return (i >= size) ? (size - 1) : i;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+ return vsnprintf(buf, INT_MAX, fmt, args);
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = vsprintf(buf, fmt, args);
+ va_end(args);
+
+ return i;
+}
+
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, size, fmt, args);
+ va_end(args);
+
+ return i;
+}
+
+char *vasprintf(const char *fmt, va_list ap)
+{
+ unsigned int len;
+ char *p;
+ va_list aq;
+
+ va_copy(aq, ap);
+ len = vsnprintf(NULL, 0, fmt, aq);
+ va_end(aq);
+
+ p = malloc(len + 1);
+ if (!p)
+ return NULL;
+
+ vsnprintf(p, len + 1, fmt, ap);
+
+ return p;
+}
+
+char *asprintf(const char *fmt, ...)
+{
+ va_list ap;
+ char *p;
+
+ va_start(ap, fmt);
+ p = vasprintf(fmt, ap);
+ va_end(ap);
+
+ return p;
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 12/20] app: add tinycurses support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (9 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 11/20] app: printf: add version from contiki Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 11:31 ` Sascha Hauer
2013-03-06 9:29 ` [PATCH 13/20] app: curses: add pdcurses Jean-Christophe PLAGNIOL-VILLARD
` (7 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
take from corboot and upated to use ansi
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 1 +
apps/Makefile | 3 +
apps/lib/Kconfig | 1 +
apps/lib/Makefile | 1 +
apps/lib/Makefile.include | 1 +
apps/lib/curses/Kconfig | 14 +
apps/lib/curses/Makefile | 1 +
apps/lib/curses/Makefile.include | 3 +
apps/lib/curses/tinycurses/Makefile | 3 +
apps/lib/curses/tinycurses/Makefile.include | 1 +
apps/lib/curses/tinycurses/colors.c | 62 +
apps/lib/curses/tinycurses/curses.h | 1680 +++++++++++++++++++++++++++
apps/lib/curses/tinycurses/curses.priv.h | 1317 +++++++++++++++++++++
apps/lib/curses/tinycurses/keyboard.c | 247 ++++
apps/lib/curses/tinycurses/local.h | 89 ++
apps/lib/curses/tinycurses/tinycurses.c | 1016 ++++++++++++++++
16 files changed, 4440 insertions(+)
create mode 100644 apps/lib/Kconfig
create mode 100644 apps/lib/Makefile
create mode 100644 apps/lib/Makefile.include
create mode 100644 apps/lib/curses/Kconfig
create mode 100644 apps/lib/curses/Makefile
create mode 100644 apps/lib/curses/Makefile.include
create mode 100644 apps/lib/curses/tinycurses/Makefile
create mode 100644 apps/lib/curses/tinycurses/Makefile.include
create mode 100644 apps/lib/curses/tinycurses/colors.c
create mode 100644 apps/lib/curses/tinycurses/curses.h
create mode 100644 apps/lib/curses/tinycurses/curses.priv.h
create mode 100644 apps/lib/curses/tinycurses/keyboard.c
create mode 100644 apps/lib/curses/tinycurses/local.h
create mode 100644 apps/lib/curses/tinycurses/tinycurses.c
diff --git a/apps/Kconfig b/apps/Kconfig
index 324e14d..a025955 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -8,6 +8,7 @@ menuconfig APPLICATIONS
if APPLICATIONS
source "apps/libc/Kconfig"
+source "apps/lib/Kconfig"
menu "memory layout"
diff --git a/apps/Makefile b/apps/Makefile
index 7f609e7..cce547e 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -1,6 +1,8 @@
APP_CPPFLAGS += -include $(srctree)/apps/include/libc_config.h
APP_CPPFLAGS += -I$(srctree)/apps/include
+include $(srctree)/apps/lib/Makefile.include
+APP_CPPFLAGS += $(APP_CPPFLAGS-y)
export APP_CPPFLAGS
apps-$(CONFIG_APP_EXAMPLE) += example
@@ -19,6 +21,7 @@ $(obj)/include/barebox/syscalls.h: $(srctree)/include/apps/syscalls.h
obj-y += libc/
obj-y += utils/
+obj-y += lib/
barebox-app-header += $(obj)/include/types.h
barebox-app-header += $(obj)/include/barebox/syscalls.h
diff --git a/apps/lib/Kconfig b/apps/lib/Kconfig
new file mode 100644
index 0000000..6725322
--- /dev/null
+++ b/apps/lib/Kconfig
@@ -0,0 +1 @@
+source apps/lib/curses/Kconfig
diff --git a/apps/lib/Makefile b/apps/lib/Makefile
new file mode 100644
index 0000000..3d3653e
--- /dev/null
+++ b/apps/lib/Makefile
@@ -0,0 +1 @@
+obj-y += curses/
diff --git a/apps/lib/Makefile.include b/apps/lib/Makefile.include
new file mode 100644
index 0000000..c0563cb
--- /dev/null
+++ b/apps/lib/Makefile.include
@@ -0,0 +1 @@
+include $(srctree)/apps/lib/curses/Makefile.include
diff --git a/apps/lib/curses/Kconfig b/apps/lib/curses/Kconfig
new file mode 100644
index 0000000..c6bc573
--- /dev/null
+++ b/apps/lib/curses/Kconfig
@@ -0,0 +1,14 @@
+menuconfig APP_LIB_CURSES
+ bool "curses"
+
+if APP_LIB_CURSES
+
+choice
+ prompt "curses implementation"
+
+config APP_LIB_TINYCURSES
+ bool "tiny"
+
+endchoice
+
+endif
diff --git a/apps/lib/curses/Makefile b/apps/lib/curses/Makefile
new file mode 100644
index 0000000..aeebdd5
--- /dev/null
+++ b/apps/lib/curses/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_APP_LIB_TINYCURSES) += tinycurses/
diff --git a/apps/lib/curses/Makefile.include b/apps/lib/curses/Makefile.include
new file mode 100644
index 0000000..8cf9d52
--- /dev/null
+++ b/apps/lib/curses/Makefile.include
@@ -0,0 +1,3 @@
+inc-$(CONFIG_APP_LIB_TINYCURSES) += $(srctree)/apps/lib/curses/tinycurses/Makefile.include
+
+include $(inc-y)
diff --git a/apps/lib/curses/tinycurses/Makefile b/apps/lib/curses/tinycurses/Makefile
new file mode 100644
index 0000000..05ff063
--- /dev/null
+++ b/apps/lib/curses/tinycurses/Makefile
@@ -0,0 +1,3 @@
+app-y += keyboard.o
+app-y += tinycurses.o
+app-y += colors.o
diff --git a/apps/lib/curses/tinycurses/Makefile.include b/apps/lib/curses/tinycurses/Makefile.include
new file mode 100644
index 0000000..2fe01f7
--- /dev/null
+++ b/apps/lib/curses/tinycurses/Makefile.include
@@ -0,0 +1 @@
+APP_CPPFLAGS-y += -I$(srctree)/apps/lib/curses/tinycurses/
diff --git a/apps/lib/curses/tinycurses/colors.c b/apps/lib/curses/tinycurses/colors.c
new file mode 100644
index 0000000..5065f5c
--- /dev/null
+++ b/apps/lib/curses/tinycurses/colors.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Color pair management */
+
+#include "local.h"
+
+unsigned char color_pairs[256] = {
+ [0] = 0x07,
+};
+
+int start_color(void)
+{
+ return 0;
+}
+
+int init_pair(short index, short fg, short bg)
+{
+ if (index == 0 || index > 255)
+ return ERR;
+
+ color_pairs[index] = ((bg & 0xF) << 4) | (fg & 0xF);
+ return 0;
+}
+
+int pair_content(short index, short *fg, short *bg)
+{
+ if (index < 0 || index > 255)
+ return ERR;
+
+ *bg = (color_pairs[index] >> 4) & 0xF;
+ *fg = color_pairs[index] & 0xF;
+
+ return 0;
+}
diff --git a/apps/lib/curses/tinycurses/curses.h b/apps/lib/curses/tinycurses/curses.h
new file mode 100644
index 0000000..d9b1bf9
--- /dev/null
+++ b/apps/lib/curses/tinycurses/curses.h
@@ -0,0 +1,1680 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
+ ****************************************************************************/
+
+/* $Id: curses.h.in,v 1.167 2006/11/26 01:14:54 tom Exp $ */
+
+#ifndef _CURSES_H
+#define _CURSES_H
+
+#define CURSES 1
+#define CURSES_H 1
+
+/* This should be defined for the enhanced functionality to be visible.
+ * However, some of the wide-character (enhanced) functionality is missing.
+ * So we do not define it (yet).
+#define _XOPEN_CURSES 1
+ */
+
+/* These are defined only in curses.h, and are used for conditional compiles */
+#define NCURSES_VERSION_MAJOR 5
+#define NCURSES_VERSION_MINOR 6
+#define NCURSES_VERSION_PATCH 20061217
+
+/* This is defined in more than one ncurses header, for identification */
+#undef NCURSES_VERSION
+#define NCURSES_VERSION "5.6"
+
+/*
+ * Identify the mouse encoding version.
+ */
+// #define NCURSES_MOUSE_VERSION 1
+
+/*
+ * Definitions to facilitate DLL's.
+ */
+//// #include <ncursesw/ncurses_dll.h>
+
+////---------------------------------------------------------------------------
+//// From ncurses_dll.h:
+////---------------------------------------------------------------------------
+/* Take care of non-cygwin platforms */
+#if !defined(NCURSES_IMPEXP)
+# define NCURSES_IMPEXP /* nothing */
+#endif
+#if !defined(NCURSES_API)
+# define NCURSES_API /* nothing */
+#endif
+#if !defined(NCURSES_EXPORT)
+# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
+#endif
+#if !defined(NCURSES_EXPORT_VAR)
+# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
+#endif
+////---------------------------------------------------------------------------
+
+/*
+ * User-definable tweak to disable the include of <stdbool.h>.
+ */
+#ifndef NCURSES_ENABLE_STDBOOL_H
+#define NCURSES_ENABLE_STDBOOL_H 0 //// XXX
+#endif
+
+/*
+ * NCURSES_ATTR_T is used to quiet compiler warnings when building ncurses
+ * configured using --disable-macros.
+ */
+#ifdef NCURSES_NOMACROS
+#ifndef NCURSES_ATTR_T
+#define NCURSES_ATTR_T attr_t
+#endif
+#endif /* NCURSES_NOMACROS */
+
+#ifndef NCURSES_ATTR_T
+#define NCURSES_ATTR_T int
+#endif
+
+/*
+ * Expands to 'const' if ncurses is configured using --enable-const. Note that
+ * doing so makes it incompatible with other implementations of X/Open Curses.
+ */
+#undef NCURSES_CONST
+#define NCURSES_CONST const
+
+#undef NCURSES_INLINE
+#define NCURSES_INLINE inline
+
+/*
+ * The internal type used for color values
+ */
+#undef NCURSES_COLOR_T
+#define NCURSES_COLOR_T short
+
+/*
+ * The internal type used for window dimensions.
+ */
+#undef NCURSES_SIZE_T
+#define NCURSES_SIZE_T short
+
+/*
+ * Control whether tparm() supports varargs or fixed-parameter list.
+ */
+#undef NCURSES_TPARM_VARARGS
+#define NCURSES_TPARM_VARARGS 1
+
+/*
+ * NCURSES_CH_T is used in building the library, but not used otherwise in
+ * this header file, since that would make the normal/wide-character versions
+ * of the header incompatible.
+ */
+#undef NCURSES_CH_T
+#define NCURSES_CH_T cchar_t
+
+#if 0 && defined(_LP64)
+typedef unsigned chtype;
+typedef unsigned mmask_t;
+#else
+typedef unsigned long chtype;
+typedef unsigned long mmask_t;
+#endif
+
+#include <stdio.h>
+//// #include <ncursesw/unctrl.h>
+#include <stdarg.h> /* we need va_list */
+//// #define va_list int // FIXME
+
+#define _XOPEN_SOURCE_EXTENDED 1 // XXX
+typedef unsigned long wchar_t;
+//// #ifdef _XOPEN_SOURCE_EXTENDED
+//// #include <stddef.h> /* we want wchar_t */
+//// #endif /* _XOPEN_SOURCE_EXTENDED */
+
+/* XSI and SVr4 specify that curses implements 'bool'. However, C++ may also
+ * implement it. If so, we must use the C++ compiler's type to avoid conflict
+ * with other interfaces.
+ *
+ * A further complication is that <stdbool.h> may declare 'bool' to be a
+ * different type, such as an enum which is not necessarily compatible with
+ * C++. If we have <stdbool.h>, make 'bool' a macro, so users may #undef it.
+ * Otherwise, let it remain a typedef to avoid conflicts with other #define's.
+ * In either case, make a typedef for NCURSES_BOOL which can be used if needed
+ * from either C or C++.
+ */
+
+#undef TRUE
+#define TRUE 1
+
+#undef FALSE
+#define FALSE 0
+
+typedef unsigned char NCURSES_BOOL;
+
+#if defined(__cplusplus) /* __cplusplus, etc. */
+
+/* use the C++ compiler's bool type */
+#define NCURSES_BOOL bool
+
+#else /* c89, c99, etc. */
+
+#if NCURSES_ENABLE_STDBOOL_H
+#include <stdbool.h>
+/* use whatever the C compiler decides bool really is */
+#define NCURSES_BOOL bool
+#else
+/* there is no predefined bool - use our own */
+#undef bool
+#define bool NCURSES_BOOL
+#endif
+
+#endif /* !__cplusplus, etc. */
+
+#ifdef __cplusplus
+extern "C" {
+#define NCURSES_CAST(type,value) static_cast<type>(value)
+#else
+#define NCURSES_CAST(type,value) (type)(value)
+#endif
+
+/*
+ * XSI attributes. In the ncurses implementation, they are identical to the
+ * A_ attributes.
+ */
+#define WA_ATTRIBUTES A_ATTRIBUTES
+#define WA_NORMAL A_NORMAL
+#define WA_STANDOUT A_STANDOUT
+#define WA_UNDERLINE A_UNDERLINE
+#define WA_REVERSE A_REVERSE
+#define WA_BLINK A_BLINK
+#define WA_DIM A_DIM
+#define WA_BOLD A_BOLD
+#define WA_ALTCHARSET A_ALTCHARSET
+#define WA_INVIS A_INVIS
+#define WA_PROTECT A_PROTECT
+#define WA_HORIZONTAL A_HORIZONTAL
+#define WA_LEFT A_LEFT
+#define WA_LOW A_LOW
+#define WA_RIGHT A_RIGHT
+#define WA_TOP A_TOP
+#define WA_VERTICAL A_VERTICAL
+
+/* colors */
+extern NCURSES_EXPORT_VAR(int) COLORS;
+extern NCURSES_EXPORT_VAR(int) COLOR_PAIRS;
+
+#define COLOR_BLACK 0
+#define COLOR_RED 1
+#define COLOR_GREEN 2
+#define COLOR_YELLOW 3
+#define COLOR_BLUE 4
+#define COLOR_MAGENTA 5
+#define COLOR_CYAN 6
+#define COLOR_WHITE 7
+
+/* line graphics */
+
+#if 0
+extern NCURSES_EXPORT_VAR(chtype*) _nc_acs_map(void);
+#define acs_map (_nc_acs_map())
+#else
+extern NCURSES_EXPORT_VAR(chtype) acs_map[];
+#endif
+
+#define NCURSES_ACS(c) (acs_map[NCURSES_CAST(unsigned char,c)])
+
+/* VT100 symbols begin here */
+#define ACS_ULCORNER NCURSES_ACS('l') /* upper left corner */
+#define ACS_LLCORNER NCURSES_ACS('m') /* lower left corner */
+#define ACS_URCORNER NCURSES_ACS('k') /* upper right corner */
+#define ACS_LRCORNER NCURSES_ACS('j') /* lower right corner */
+#define ACS_LTEE NCURSES_ACS('t') /* tee pointing right */
+#define ACS_RTEE NCURSES_ACS('u') /* tee pointing left */
+#define ACS_BTEE NCURSES_ACS('v') /* tee pointing up */
+#define ACS_TTEE NCURSES_ACS('w') /* tee pointing down */
+#define ACS_HLINE NCURSES_ACS('q') /* horizontal line */
+#define ACS_VLINE NCURSES_ACS('x') /* vertical line */
+#define ACS_PLUS NCURSES_ACS('n') /* large plus or crossover */
+#define ACS_S1 NCURSES_ACS('o') /* scan line 1 */
+#define ACS_S9 NCURSES_ACS('s') /* scan line 9 */
+#define ACS_DIAMOND NCURSES_ACS('`') /* diamond */
+#define ACS_CKBOARD NCURSES_ACS('a') /* checker board (stipple) */
+#define ACS_DEGREE NCURSES_ACS('f') /* degree symbol */
+#define ACS_PLMINUS NCURSES_ACS('g') /* plus/minus */
+#define ACS_BULLET NCURSES_ACS('~') /* bullet */
+/* Teletype 5410v1 symbols begin here */
+#define ACS_LARROW NCURSES_ACS(',') /* arrow pointing left */
+#define ACS_RARROW NCURSES_ACS('+') /* arrow pointing right */
+#define ACS_DARROW NCURSES_ACS('.') /* arrow pointing down */
+#define ACS_UARROW NCURSES_ACS('-') /* arrow pointing up */
+#define ACS_BOARD NCURSES_ACS('h') /* board of squares */
+#define ACS_LANTERN NCURSES_ACS('i') /* lantern symbol */
+#define ACS_BLOCK NCURSES_ACS('0') /* solid square block */
+/*
+ * These aren't documented, but a lot of System Vs have them anyway
+ * (you can spot pprryyzz{{||}} in a lot of AT&T terminfo strings).
+ * The ACS_names may not match AT&T's, our source didn't know them.
+ */
+#define ACS_S3 NCURSES_ACS('p') /* scan line 3 */
+#define ACS_S7 NCURSES_ACS('r') /* scan line 7 */
+#define ACS_LEQUAL NCURSES_ACS('y') /* less/equal */
+#define ACS_GEQUAL NCURSES_ACS('z') /* greater/equal */
+#define ACS_PI NCURSES_ACS('{') /* Pi */
+#define ACS_NEQUAL NCURSES_ACS('|') /* not equal */
+#define ACS_STERLING NCURSES_ACS('}') /* UK pound sign */
+
+/*
+ * Line drawing ACS names are of the form ACS_trbl, where t is the top, r
+ * is the right, b is the bottom, and l is the left. t, r, b, and l might
+ * be B (blank), S (single), D (double), or T (thick). The subset defined
+ * here only uses B and S.
+ */
+#define ACS_BSSB ACS_ULCORNER
+#define ACS_SSBB ACS_LLCORNER
+#define ACS_BBSS ACS_URCORNER
+#define ACS_SBBS ACS_LRCORNER
+#define ACS_SBSS ACS_RTEE
+#define ACS_SSSB ACS_LTEE
+#define ACS_SSBS ACS_BTEE
+#define ACS_BSSS ACS_TTEE
+#define ACS_BSBS ACS_HLINE
+#define ACS_SBSB ACS_VLINE
+#define ACS_SSSS ACS_PLUS
+
+#undef ERR
+#define ERR (-1)
+
+#undef OK
+#define OK (0)
+
+/* values for the _flags member */
+#define _SUBWIN 0x01 /* is this a sub-window? */
+#define _ENDLINE 0x02 /* is the window flush right? */
+#define _FULLWIN 0x04 /* is the window full-screen? */
+#define _SCROLLWIN 0x08 /* bottom edge is at screen bottom? */
+#define _ISPAD 0x10 /* is this window a pad? */
+#define _HASMOVED 0x20 /* has cursor moved since last refresh? */
+#define _WRAPPED 0x40 /* cursor was just wrappped */
+
+/*
+ * this value is used in the firstchar and lastchar fields to mark
+ * unchanged lines
+ */
+#define _NOCHANGE -1
+
+/*
+ * this value is used in the oldindex field to mark lines created by insertions
+ * and scrolls.
+ */
+#define _NEWINDEX -1
+
+typedef struct screen SCREEN;
+typedef struct _win_st WINDOW;
+
+typedef chtype attr_t; /* ...must be at least as wide as chtype */
+
+#ifdef _XOPEN_SOURCE_EXTENDED
+
+#if 0
+#ifdef mblen /* libutf8.h defines it w/o undefining first */
+#undef mblen
+#endif
+#include <libutf8.h>
+#endif
+
+#if 1
+//// #include <wchar.h> /* ...to get mbstate_t, etc. */
+//typedef unsigned long wchar_t; // XXX
+typedef unsigned long wint_t; // XXX
+#endif
+
+#if 0
+typedef unsigned short wchar_t1;
+#endif
+
+#if 0
+typedef unsigned int wint_t1;
+#endif
+
+#define CCHARW_MAX 5
+typedef struct
+{
+ attr_t attr;
+ wchar_t chars[CCHARW_MAX];
+#if 0
+ int ext_color; /* color pair, must be more than 16-bits */
+#endif
+}
+cchar_t;
+
+#endif /* _XOPEN_SOURCE_EXTENDED */
+
+struct ldat;
+
+struct _win_st
+{
+ NCURSES_SIZE_T _cury, _curx; /* current cursor position */
+
+ /* window location and size */
+ NCURSES_SIZE_T _maxy, _maxx; /* maximums of x and y, NOT window size */
+ NCURSES_SIZE_T _begy, _begx; /* screen coords of upper-left-hand corner */
+
+ short _flags; /* window state flags */
+
+ /* attribute tracking */
+ attr_t _attrs; /* current attribute for non-space character */
+ chtype _bkgd; /* current background char/attribute pair */
+
+ /* option values set by user */
+ bool _notimeout; /* no time out on function-key entry? */
+ bool _clear; /* consider all data in the window invalid? */
+ bool _leaveok; /* OK to not reset cursor on exit? */
+ bool _scroll; /* OK to scroll this window? */
+ bool _idlok; /* OK to use insert/delete line? */
+ bool _idcok; /* OK to use insert/delete char? */
+ bool _immed; /* window in immed mode? (not yet used) */
+ bool _sync; /* window in sync mode? */
+ bool _use_keypad; /* process function keys into KEY_ symbols? */
+ int _delay; /* 0 = nodelay, <0 = blocking, >0 = delay */
+
+ struct ldat *_line; /* the actual line data */
+
+ /* global screen state */
+ NCURSES_SIZE_T _regtop; /* top line of scrolling region */
+ NCURSES_SIZE_T _regbottom; /* bottom line of scrolling region */
+
+ /* these are used only if this is a sub-window */
+ int _parx; /* x coordinate of this window in parent */
+ int _pary; /* y coordinate of this window in parent */
+ WINDOW *_parent; /* pointer to parent if a sub-window */
+
+ /* these are used only if this is a pad */
+ struct pdat
+ {
+ NCURSES_SIZE_T _pad_y, _pad_x;
+ NCURSES_SIZE_T _pad_top, _pad_left;
+ NCURSES_SIZE_T _pad_bottom, _pad_right;
+ } _pad;
+
+ NCURSES_SIZE_T _yoffset; /* real begy is _begy + _yoffset */
+
+#ifdef _XOPEN_SOURCE_EXTENDED
+ cchar_t _bkgrnd; /* current background char/attribute pair */
+//// #if 0
+#if 1
+ int _color; /* current color-pair for non-space character */
+#endif
+#endif
+};
+
+extern NCURSES_EXPORT_VAR(WINDOW *) stdscr;
+extern NCURSES_EXPORT_VAR(WINDOW *) curscr;
+extern NCURSES_EXPORT_VAR(WINDOW *) newscr;
+
+extern NCURSES_EXPORT_VAR(int) LINES;
+extern NCURSES_EXPORT_VAR(int) COLS;
+extern NCURSES_EXPORT_VAR(int) TABSIZE;
+
+/*
+ * This global was an undocumented feature under AIX curses.
+ */
+extern NCURSES_EXPORT_VAR(int) ESCDELAY; /* ESC expire time in milliseconds */
+
+/*
+ * These functions are extensions - not in XSI Curses.
+ */
+#if 1
+extern NCURSES_EXPORT(bool) is_term_resized (int, int);
+extern NCURSES_EXPORT(char *) keybound (int, int);
+extern NCURSES_EXPORT(const char *) curses_version (void);
+extern NCURSES_EXPORT(int) assume_default_colors (int, int);
+extern NCURSES_EXPORT(int) define_key (const char *, int);
+extern NCURSES_EXPORT(int) key_defined (const char *);
+extern NCURSES_EXPORT(int) keyok (int, bool);
+extern NCURSES_EXPORT(int) resize_term (int, int);
+extern NCURSES_EXPORT(int) resizeterm (int, int);
+extern NCURSES_EXPORT(int) use_default_colors (void);
+extern NCURSES_EXPORT(int) use_extended_names (bool);
+extern NCURSES_EXPORT(int) use_legacy_coding (int);
+extern NCURSES_EXPORT(int) wresize (WINDOW *, int, int);
+extern NCURSES_EXPORT(void) nofilter(void);
+#else
+#define curses_version() NCURSES_VERSION
+#endif
+
+/*
+ * This is an extension to support events...
+ */
+#if 1
+#ifdef NCURSES_WGETCH_EVENTS
+#if !defined(__BEOS__) /* Fix _nc_timed_wait() on BEOS... */
+# define NCURSES_EVENT_VERSION 1
+#endif /* !defined(__BEOS__) */
+
+/*
+ * Bits to set in _nc_event.data.flags
+ */
+# define _NC_EVENT_TIMEOUT_MSEC 1
+# define _NC_EVENT_FILE 2
+# define _NC_EVENT_FILE_READABLE 2
+# if 0 /* Not supported yet... */
+# define _NC_EVENT_FILE_WRITABLE 4
+# define _NC_EVENT_FILE_EXCEPTION 8
+# endif
+
+typedef struct
+{
+ int type;
+ union
+ {
+ long timeout_msec; /* _NC_EVENT_TIMEOUT_MSEC */
+ struct
+ {
+ unsigned int flags;
+ int fd;
+ unsigned int result;
+ } fev; /* _NC_EVENT_FILE */
+ } data;
+} _nc_event;
+
+typedef struct
+{
+ int count;
+ int result_flags; /* _NC_EVENT_TIMEOUT_MSEC or _NC_EVENT_FILE_READABLE */
+ _nc_event *events[1];
+} _nc_eventlist;
+
+extern NCURSES_EXPORT(int) wgetch_events(WINDOW *, _nc_eventlist *); /* experimental */
+extern NCURSES_EXPORT(int) wgetnstr_events(WINDOW *,char *,int,_nc_eventlist *);/* experimental */
+
+#endif /* NCURSES_WGETCH_EVENTS */
+#endif /* NCURSES_EXT_FUNCS */
+
+/*
+ * GCC (and some other compilers) define '__attribute__'; we're using this
+ * macro to alert the compiler to flag inconsistencies in printf/scanf-like
+ * function calls. Just in case '__attribute__' isn't defined, make a dummy.
+ * Old versions of G++ do not accept it anyway, at least not consistently with
+ * GCC.
+ */
+#if !(defined(__GNUC__) || defined(__GNUG__) || defined(__attribute__))
+#define __attribute__(p) /* nothing */
+#endif
+
+/*
+ * We cannot define these in ncurses_cfg.h, since they require parameters to be
+ * passed (that is non-portable). If you happen to be using gcc with warnings
+ * enabled, define
+ * GCC_PRINTF
+ * GCC_SCANF
+ * to improve checking of calls to printw(), etc.
+ */
+#ifndef GCC_PRINTFLIKE
+#if defined(GCC_PRINTF) && !defined(printf)
+#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+#else
+#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
+#endif
+#endif
+
+#ifndef GCC_SCANFLIKE
+#if defined(GCC_SCANF) && !defined(scanf)
+#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var)))
+#else
+#define GCC_SCANFLIKE(fmt,var) /*nothing*/
+#endif
+#endif
+
+#ifndef GCC_NORETURN
+#define GCC_NORETURN /* nothing */
+#endif
+
+#ifndef GCC_UNUSED
+#define GCC_UNUSED /* nothing */
+#endif
+
+/*
+ * Function prototypes. This is the complete XSI Curses list of required
+ * functions. Those marked `generated' will have sources generated from the
+ * macro definitions later in this file, in order to satisfy XPG4.2
+ * requirements.
+ */
+
+extern NCURSES_EXPORT(int) addch (const chtype); /* generated */
+extern NCURSES_EXPORT(int) addchnstr (const chtype *, int); /* generated */
+extern NCURSES_EXPORT(int) addchstr (const chtype *); /* generated */
+extern NCURSES_EXPORT(int) addnstr (const char *, int); /* generated */
+extern NCURSES_EXPORT(int) addstr (const char *); /* generated */
+extern NCURSES_EXPORT(int) attroff (NCURSES_ATTR_T); /* generated */
+extern NCURSES_EXPORT(int) attron (NCURSES_ATTR_T); /* generated */
+extern NCURSES_EXPORT(int) attrset (NCURSES_ATTR_T); /* generated */
+extern NCURSES_EXPORT(int) attr_get (attr_t *, short *, void *); /* generated */
+extern NCURSES_EXPORT(int) attr_off (attr_t, void *); /* generated */
+extern NCURSES_EXPORT(int) attr_on (attr_t, void *); /* generated */
+extern NCURSES_EXPORT(int) attr_set (attr_t, short, void *); /* generated */
+extern NCURSES_EXPORT(int) baudrate (void); /* implemented */
+extern NCURSES_EXPORT(int) beep (void); /* implemented */
+extern NCURSES_EXPORT(int) bkgd (chtype); /* generated */
+extern NCURSES_EXPORT(void) bkgdset (chtype); /* generated */
+extern NCURSES_EXPORT(int) border (chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* generated */
+extern NCURSES_EXPORT(int) box (WINDOW *, chtype, chtype); /* generated */
+extern NCURSES_EXPORT(bool) can_change_color (void); /* implemented */
+extern NCURSES_EXPORT(int) cbreak (void); /* implemented */
+extern NCURSES_EXPORT(int) chgat (int, attr_t, short, const void *); /* generated */
+extern NCURSES_EXPORT(int) clear (void); /* generated */
+extern NCURSES_EXPORT(int) clearok (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(int) clrtobot (void); /* generated */
+extern NCURSES_EXPORT(int) clrtoeol (void); /* generated */
+extern NCURSES_EXPORT(int) color_content (short,short*,short*,short*); /* implemented */
+extern NCURSES_EXPORT(int) color_set (short,void*); /* generated */
+extern NCURSES_EXPORT(int) COLOR_PAIR (int); /* generated */
+extern NCURSES_EXPORT(int) copywin (const WINDOW*,WINDOW*,int,int,int,int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) curs_set (int); /* implemented */
+extern NCURSES_EXPORT(int) def_prog_mode (void); /* implemented */
+extern NCURSES_EXPORT(int) def_shell_mode (void); /* implemented */
+extern NCURSES_EXPORT(int) delay_output (int); /* implemented */
+extern NCURSES_EXPORT(int) delch (void); /* generated */
+extern NCURSES_EXPORT(void) delscreen (SCREEN *); /* implemented */
+extern NCURSES_EXPORT(int) delwin (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) deleteln (void); /* generated */
+extern NCURSES_EXPORT(WINDOW *) derwin (WINDOW *,int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) doupdate (void); /* implemented */
+extern NCURSES_EXPORT(WINDOW *) dupwin (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) echo (void); /* implemented */
+extern NCURSES_EXPORT(int) echochar (const chtype); /* generated */
+extern NCURSES_EXPORT(int) erase (void); /* generated */
+extern NCURSES_EXPORT(int) endwin (void); /* implemented */
+extern NCURSES_EXPORT(char) erasechar (void); /* implemented */
+extern NCURSES_EXPORT(void) filter (void); /* implemented */
+extern NCURSES_EXPORT(int) flash (void); /* implemented */
+extern NCURSES_EXPORT(int) flushinp (void); /* implemented */
+extern NCURSES_EXPORT(chtype) getbkgd (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getch (void); /* generated */
+extern NCURSES_EXPORT(int) getnstr (char *, int); /* generated */
+extern NCURSES_EXPORT(int) getstr (char *); /* generated */
+extern NCURSES_EXPORT(WINDOW *) getwin (FILE *); /* implemented */
+extern NCURSES_EXPORT(int) halfdelay (int); /* implemented */
+extern NCURSES_EXPORT(bool) has_colors (void); /* implemented */
+extern NCURSES_EXPORT(bool) has_ic (void); /* implemented */
+extern NCURSES_EXPORT(bool) has_il (void); /* implemented */
+extern NCURSES_EXPORT(int) hline (chtype, int); /* generated */
+extern NCURSES_EXPORT(void) idcok (WINDOW *, bool); /* implemented */
+extern NCURSES_EXPORT(int) idlok (WINDOW *, bool); /* implemented */
+extern NCURSES_EXPORT(void) immedok (WINDOW *, bool); /* implemented */
+extern NCURSES_EXPORT(chtype) inch (void); /* generated */
+extern NCURSES_EXPORT(int) inchnstr (chtype *, int); /* generated */
+extern NCURSES_EXPORT(int) inchstr (chtype *); /* generated */
+extern NCURSES_EXPORT(WINDOW *) initscr (void); /* implemented */
+extern NCURSES_EXPORT(int) init_color (short,short,short,short); /* implemented */
+extern NCURSES_EXPORT(int) init_pair (short,short,short); /* implemented */
+extern NCURSES_EXPORT(int) innstr (char *, int); /* generated */
+extern NCURSES_EXPORT(int) insch (chtype); /* generated */
+extern NCURSES_EXPORT(int) insdelln (int); /* generated */
+extern NCURSES_EXPORT(int) insertln (void); /* generated */
+extern NCURSES_EXPORT(int) insnstr (const char *, int); /* generated */
+extern NCURSES_EXPORT(int) insstr (const char *); /* generated */
+extern NCURSES_EXPORT(int) instr (char *); /* generated */
+extern NCURSES_EXPORT(int) intrflush (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(bool) isendwin (void); /* implemented */
+extern NCURSES_EXPORT(bool) is_linetouched (WINDOW *,int); /* implemented */
+extern NCURSES_EXPORT(bool) is_wintouched (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(NCURSES_CONST char *) keyname (int); /* implemented */
+extern NCURSES_EXPORT(int) keypad (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(char) killchar (void); /* implemented */
+extern NCURSES_EXPORT(int) leaveok (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(char *) longname (void); /* implemented */
+extern NCURSES_EXPORT(int) meta (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(int) move (int, int); /* generated */
+extern NCURSES_EXPORT(int) mvaddch (int, int, const chtype); /* generated */
+extern NCURSES_EXPORT(int) mvaddchnstr (int, int, const chtype *, int); /* generated */
+extern NCURSES_EXPORT(int) mvaddchstr (int, int, const chtype *); /* generated */
+extern NCURSES_EXPORT(int) mvaddnstr (int, int, const char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvaddstr (int, int, const char *); /* generated */
+extern NCURSES_EXPORT(int) mvchgat (int, int, int, attr_t, short, const void *); /* generated */
+extern NCURSES_EXPORT(int) mvcur (int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) mvdelch (int, int); /* generated */
+extern NCURSES_EXPORT(int) mvderwin (WINDOW *, int, int); /* implemented */
+extern NCURSES_EXPORT(int) mvgetch (int, int); /* generated */
+extern NCURSES_EXPORT(int) mvgetnstr (int, int, char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvgetstr (int, int, char *); /* generated */
+extern NCURSES_EXPORT(int) mvhline (int, int, chtype, int); /* generated */
+extern NCURSES_EXPORT(chtype) mvinch (int, int); /* generated */
+extern NCURSES_EXPORT(int) mvinchnstr (int, int, chtype *, int); /* generated */
+extern NCURSES_EXPORT(int) mvinchstr (int, int, chtype *); /* generated */
+extern NCURSES_EXPORT(int) mvinnstr (int, int, char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvinsch (int, int, chtype); /* generated */
+extern NCURSES_EXPORT(int) mvinsnstr (int, int, const char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvinsstr (int, int, const char *); /* generated */
+extern NCURSES_EXPORT(int) mvinstr (int, int, char *); /* generated */
+extern NCURSES_EXPORT(int) mvprintw (int,int, const char *,...) /* implemented */
+ GCC_PRINTFLIKE(3,4);
+extern NCURSES_EXPORT(int) mvscanw (int,int, NCURSES_CONST char *,...) /* implemented */
+ GCC_SCANFLIKE(3,4);
+extern NCURSES_EXPORT(int) mvvline (int, int, chtype, int); /* generated */
+extern NCURSES_EXPORT(int) mvwaddch (WINDOW *, int, int, const chtype); /* generated */
+extern NCURSES_EXPORT(int) mvwaddchnstr (WINDOW *, int, int, const chtype *, int);/* generated */
+extern NCURSES_EXPORT(int) mvwaddchstr (WINDOW *, int, int, const chtype *); /* generated */
+extern NCURSES_EXPORT(int) mvwaddnstr (WINDOW *, int, int, const char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvwaddstr (WINDOW *, int, int, const char *); /* generated */
+extern NCURSES_EXPORT(int) mvwchgat (WINDOW *, int, int, int, attr_t, short, const void *);/* generated */
+extern NCURSES_EXPORT(int) mvwdelch (WINDOW *, int, int); /* generated */
+extern NCURSES_EXPORT(int) mvwgetch (WINDOW *, int, int); /* generated */
+extern NCURSES_EXPORT(int) mvwgetnstr (WINDOW *, int, int, char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvwgetstr (WINDOW *, int, int, char *); /* generated */
+extern NCURSES_EXPORT(int) mvwhline (WINDOW *, int, int, chtype, int); /* generated */
+extern NCURSES_EXPORT(int) mvwin (WINDOW *,int,int); /* implemented */
+extern NCURSES_EXPORT(chtype) mvwinch (WINDOW *, int, int); /* generated */
+extern NCURSES_EXPORT(int) mvwinchnstr (WINDOW *, int, int, chtype *, int); /* generated */
+extern NCURSES_EXPORT(int) mvwinchstr (WINDOW *, int, int, chtype *); /* generated */
+extern NCURSES_EXPORT(int) mvwinnstr (WINDOW *, int, int, char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvwinsch (WINDOW *, int, int, chtype); /* generated */
+extern NCURSES_EXPORT(int) mvwinsnstr (WINDOW *, int, int, const char *, int); /* generated */
+extern NCURSES_EXPORT(int) mvwinsstr (WINDOW *, int, int, const char *); /* generated */
+extern NCURSES_EXPORT(int) mvwinstr (WINDOW *, int, int, char *); /* generated */
+extern NCURSES_EXPORT(int) mvwprintw (WINDOW*,int,int, const char *,...) /* implemented */
+ GCC_PRINTFLIKE(4,5);
+extern NCURSES_EXPORT(int) mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) /* implemented */
+ GCC_SCANFLIKE(4,5);
+extern NCURSES_EXPORT(int) mvwvline (WINDOW *,int, int, chtype, int); /* generated */
+extern NCURSES_EXPORT(int) napms (int); /* implemented */
+extern NCURSES_EXPORT(WINDOW *) newpad (int,int); /* implemented */
+extern NCURSES_EXPORT(SCREEN *) newterm (NCURSES_CONST char *,FILE *,FILE *); /* implemented */
+extern NCURSES_EXPORT(WINDOW *) newwin (int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) nl (void); /* implemented */
+extern NCURSES_EXPORT(int) nocbreak (void); /* implemented */
+extern NCURSES_EXPORT(int) nodelay (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(int) noecho (void); /* implemented */
+extern NCURSES_EXPORT(int) nonl (void); /* implemented */
+extern NCURSES_EXPORT(void) noqiflush (void); /* implemented */
+extern NCURSES_EXPORT(int) noraw (void); /* implemented */
+extern NCURSES_EXPORT(int) notimeout (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(int) overlay (const WINDOW*,WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) overwrite (const WINDOW*,WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) pair_content (short,short*,short*); /* implemented */
+extern NCURSES_EXPORT(int) PAIR_NUMBER (int); /* generated */
+extern NCURSES_EXPORT(int) pechochar (WINDOW *, const chtype); /* implemented */
+extern NCURSES_EXPORT(int) pnoutrefresh (WINDOW*,int,int,int,int,int,int);/* implemented */
+extern NCURSES_EXPORT(int) prefresh (WINDOW *,int,int,int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) printw (const char *,...) /* implemented */
+ GCC_PRINTFLIKE(1,2);
+extern NCURSES_EXPORT(int) putwin (WINDOW *, FILE *); /* implemented */
+extern NCURSES_EXPORT(void) qiflush (void); /* implemented */
+extern NCURSES_EXPORT(int) raw (void); /* implemented */
+extern NCURSES_EXPORT(int) redrawwin (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) refresh (void); /* generated */
+extern NCURSES_EXPORT(int) resetty (void); /* implemented */
+extern NCURSES_EXPORT(int) reset_prog_mode (void); /* implemented */
+extern NCURSES_EXPORT(int) reset_shell_mode (void); /* implemented */
+extern NCURSES_EXPORT(int) ripoffline (int, int (*)(WINDOW *, int)); /* implemented */
+extern NCURSES_EXPORT(int) savetty (void); /* implemented */
+extern NCURSES_EXPORT(int) scanw (NCURSES_CONST char *,...) /* implemented */
+ GCC_SCANFLIKE(1,2);
+extern NCURSES_EXPORT(int) scr_dump (const char *); /* implemented */
+extern NCURSES_EXPORT(int) scr_init (const char *); /* implemented */
+extern NCURSES_EXPORT(int) scrl (int); /* generated */
+extern NCURSES_EXPORT(int) scroll (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) scrollok (WINDOW *,bool); /* implemented */
+extern NCURSES_EXPORT(int) scr_restore (const char *); /* implemented */
+extern NCURSES_EXPORT(int) scr_set (const char *); /* implemented */
+extern NCURSES_EXPORT(int) setscrreg (int,int); /* generated */
+extern NCURSES_EXPORT(SCREEN *) set_term (SCREEN *); /* implemented */
+extern NCURSES_EXPORT(int) slk_attroff (const chtype); /* implemented */
+extern NCURSES_EXPORT(int) slk_attr_off (const attr_t, void *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) slk_attron (const chtype); /* implemented */
+extern NCURSES_EXPORT(int) slk_attr_on (attr_t,void*); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) slk_attrset (const chtype); /* implemented */
+extern NCURSES_EXPORT(attr_t) slk_attr (void); /* implemented */
+extern NCURSES_EXPORT(int) slk_attr_set (const attr_t,short,void*); /* implemented */
+extern NCURSES_EXPORT(int) slk_clear (void); /* implemented */
+extern NCURSES_EXPORT(int) slk_color (short); /* implemented */
+extern NCURSES_EXPORT(int) slk_init (int); /* implemented */
+extern NCURSES_EXPORT(char *) slk_label (int); /* implemented */
+extern NCURSES_EXPORT(int) slk_noutrefresh (void); /* implemented */
+extern NCURSES_EXPORT(int) slk_refresh (void); /* implemented */
+extern NCURSES_EXPORT(int) slk_restore (void); /* implemented */
+extern NCURSES_EXPORT(int) slk_set (int,const char *,int); /* implemented */
+extern NCURSES_EXPORT(int) slk_touch (void); /* implemented */
+extern NCURSES_EXPORT(int) standout (void); /* generated */
+extern NCURSES_EXPORT(int) standend (void); /* generated */
+extern NCURSES_EXPORT(int) start_color (void); /* implemented */
+extern NCURSES_EXPORT(WINDOW *) subpad (WINDOW *, int, int, int, int); /* implemented */
+extern NCURSES_EXPORT(WINDOW *) subwin (WINDOW *,int,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) syncok (WINDOW *, bool); /* implemented */
+extern NCURSES_EXPORT(chtype) termattrs (void); /* implemented */
+extern NCURSES_EXPORT(char *) termname (void); /* implemented */
+extern NCURSES_EXPORT(void) timeout (int); /* generated */
+extern NCURSES_EXPORT(int) touchline (WINDOW *, int, int); /* generated */
+extern NCURSES_EXPORT(int) touchwin (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) typeahead (int); /* implemented */
+extern NCURSES_EXPORT(int) ungetch (int); /* implemented */
+extern NCURSES_EXPORT(int) untouchwin (WINDOW *); /* generated */
+extern NCURSES_EXPORT(void) use_env (bool); /* implemented */
+extern NCURSES_EXPORT(int) vidattr (chtype); /* implemented */
+extern NCURSES_EXPORT(int) vidputs (chtype, int (*)(int)); /* implemented */
+extern NCURSES_EXPORT(int) vline (chtype, int); /* generated */
+extern NCURSES_EXPORT(int) vwprintw (WINDOW *, const char *,va_list); /* implemented */
+extern NCURSES_EXPORT(int) vw_printw (WINDOW *, const char *,va_list); /* generated */
+extern NCURSES_EXPORT(int) vwscanw (WINDOW *, NCURSES_CONST char *,va_list); /* implemented */
+extern NCURSES_EXPORT(int) vw_scanw (WINDOW *, NCURSES_CONST char *,va_list); /* generated */
+extern NCURSES_EXPORT(int) waddch (WINDOW *, const chtype); /* implemented */
+extern NCURSES_EXPORT(int) waddchnstr (WINDOW *,const chtype *,int); /* implemented */
+extern NCURSES_EXPORT(int) waddchstr (WINDOW *,const chtype *); /* generated */
+extern NCURSES_EXPORT(int) waddnstr (WINDOW *,const char *,int); /* implemented */
+extern NCURSES_EXPORT(int) waddstr (WINDOW *,const char *); /* generated */
+extern NCURSES_EXPORT(int) wattron (WINDOW *, int); /* generated */
+extern NCURSES_EXPORT(int) wattroff (WINDOW *, int); /* generated */
+extern NCURSES_EXPORT(int) wattrset (WINDOW *, int); /* generated */
+extern NCURSES_EXPORT(int) wattr_get (WINDOW *, attr_t *, short *, void *); /* generated */
+extern NCURSES_EXPORT(int) wattr_on (WINDOW *, attr_t, void *); /* implemented */
+extern NCURSES_EXPORT(int) wattr_off (WINDOW *, attr_t, void *); /* implemented */
+extern NCURSES_EXPORT(int) wattr_set (WINDOW *, attr_t, short, void *); /* generated */
+extern NCURSES_EXPORT(int) wbkgd (WINDOW *, chtype); /* implemented */
+extern NCURSES_EXPORT(void) wbkgdset (WINDOW *,chtype); /* implemented */
+extern NCURSES_EXPORT(int) wborder (WINDOW *,chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* implemented */
+extern NCURSES_EXPORT(int) wchgat (WINDOW *, int, attr_t, short, const void *);/* implemented */
+extern NCURSES_EXPORT(int) wclear (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wclrtobot (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wclrtoeol (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wcolor_set (WINDOW*,short,void*); /* implemented */
+extern NCURSES_EXPORT(void) wcursyncup (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wdelch (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wdeleteln (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) wechochar (WINDOW *, const chtype); /* implemented */
+extern NCURSES_EXPORT(int) werase (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wgetch (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wgetnstr (WINDOW *,char *,int); /* implemented */
+extern NCURSES_EXPORT(int) wgetstr (WINDOW *, char *); /* generated */
+extern NCURSES_EXPORT(int) whline (WINDOW *, chtype, int); /* implemented */
+extern NCURSES_EXPORT(chtype) winch (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) winchnstr (WINDOW *, chtype *, int); /* implemented */
+extern NCURSES_EXPORT(int) winchstr (WINDOW *, chtype *); /* generated */
+extern NCURSES_EXPORT(int) winnstr (WINDOW *, char *, int); /* implemented */
+extern NCURSES_EXPORT(int) winsch (WINDOW *, chtype); /* implemented */
+extern NCURSES_EXPORT(int) winsdelln (WINDOW *,int); /* implemented */
+extern NCURSES_EXPORT(int) winsertln (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) winsnstr (WINDOW *, const char *,int); /* implemented */
+extern NCURSES_EXPORT(int) winsstr (WINDOW *, const char *); /* generated */
+extern NCURSES_EXPORT(int) winstr (WINDOW *, char *); /* generated */
+extern NCURSES_EXPORT(int) wmove (WINDOW *,int,int); /* implemented */
+extern NCURSES_EXPORT(int) wnoutrefresh (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wprintw (WINDOW *, const char *,...) /* implemented */
+ GCC_PRINTFLIKE(2,3);
+extern NCURSES_EXPORT(int) wredrawln (WINDOW *,int,int); /* implemented */
+extern NCURSES_EXPORT(int) wrefresh (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(int) wscanw (WINDOW *, NCURSES_CONST char *,...) /* implemented */
+ GCC_SCANFLIKE(2,3);
+extern NCURSES_EXPORT(int) wscrl (WINDOW *,int); /* implemented */
+extern NCURSES_EXPORT(int) wsetscrreg (WINDOW *,int,int); /* implemented */
+extern NCURSES_EXPORT(int) wstandout (WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) wstandend (WINDOW *); /* generated */
+extern NCURSES_EXPORT(void) wsyncdown (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(void) wsyncup (WINDOW *); /* implemented */
+extern NCURSES_EXPORT(void) wtimeout (WINDOW *,int); /* implemented */
+extern NCURSES_EXPORT(int) wtouchln (WINDOW *,int,int,int); /* implemented */
+extern NCURSES_EXPORT(int) wvline (WINDOW *,chtype,int); /* implemented */
+
+/*
+ * These are also declared in <ncursesw/term.h>:
+ */
+extern NCURSES_EXPORT(int) tigetflag (NCURSES_CONST char *); /* implemented */
+extern NCURSES_EXPORT(int) tigetnum (NCURSES_CONST char *); /* implemented */
+extern NCURSES_EXPORT(char *) tigetstr (NCURSES_CONST char *); /* implemented */
+extern NCURSES_EXPORT(int) putp (const char *); /* implemented */
+
+#if NCURSES_TPARM_VARARGS
+extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, ...); /* implemented */
+#else
+extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* implemented */
+extern NCURSES_EXPORT(char *) tparm_varargs (NCURSES_CONST char *, ...); /* implemented */
+#endif
+
+extern NCURSES_EXPORT_VAR(char) ttytype[]; /* needed for backward compatibility */
+
+/*
+ * These functions are not in X/Open, but we use them in macro definitions:
+ */
+extern NCURSES_EXPORT(int) getcurx (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getcury (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getbegx (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getbegy (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getmaxx (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getmaxy (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getparx (const WINDOW *); /* generated */
+extern NCURSES_EXPORT(int) getpary (const WINDOW *); /* generated */
+
+/*
+ * vid_attr() was implemented originally based on a draft of XSI curses.
+ */
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define vid_attr(a,pair,opts) vidattr(a)
+#endif
+
+/* attributes */
+
+#define NCURSES_ATTR_SHIFT 8
+#define NCURSES_BITS(mask,shift) ((mask) << ((shift) + NCURSES_ATTR_SHIFT))
+
+#define A_NORMAL (1UL - 1UL)
+#define A_ATTRIBUTES NCURSES_BITS(~(1UL - 1UL),0)
+#define A_CHARTEXT (NCURSES_BITS(1UL,0) - 1UL)
+#define A_COLOR NCURSES_BITS(((1UL) << 8) - 1UL,0)
+#define A_STANDOUT NCURSES_BITS(1UL,8)
+#define A_UNDERLINE NCURSES_BITS(1UL,9)
+#define A_REVERSE NCURSES_BITS(1UL,10)
+#define A_BLINK NCURSES_BITS(1UL,11)
+#define A_DIM NCURSES_BITS(1UL,12)
+#define A_BOLD NCURSES_BITS(1UL,13)
+#define A_ALTCHARSET NCURSES_BITS(1UL,14)
+#define A_INVIS NCURSES_BITS(1UL,15)
+#define A_PROTECT NCURSES_BITS(1UL,16)
+#define A_HORIZONTAL NCURSES_BITS(1UL,17)
+#define A_LEFT NCURSES_BITS(1UL,18)
+#define A_LOW NCURSES_BITS(1UL,19)
+#define A_RIGHT NCURSES_BITS(1UL,20)
+#define A_TOP NCURSES_BITS(1UL,21)
+#define A_VERTICAL NCURSES_BITS(1UL,22)
+
+/*
+ * Most of the pseudo functions are macros that either provide compatibility
+ * with older versions of curses, or provide inline functionality to improve
+ * performance.
+ */
+
+/*
+ * These pseudo functions are always implemented as macros:
+ */
+
+#define getyx(win,y,x) (y = getcury(win), x = getcurx(win))
+#define getbegyx(win,y,x) (y = getbegy(win), x = getbegx(win))
+#define getmaxyx(win,y,x) (y = getmaxy(win), x = getmaxx(win))
+#define getparyx(win,y,x) (y = getpary(win), x = getparx(win))
+
+#define getsyx(y,x) do { if(newscr->_leaveok) (y)=(x)=-1; \
+ else getyx(newscr,(y),(x)); \
+ } while(0)
+#define setsyx(y,x) do { if((y)==-1 && (x)==-1) newscr->_leaveok=TRUE; \
+ else {newscr->_leaveok=FALSE;wmove(newscr,(y),(x));} \
+ } while(0)
+
+#ifndef NCURSES_NOMACROS
+
+/*
+ * These miscellaneous pseudo functions are provided for compatibility:
+ */
+
+#define wgetstr(w, s) wgetnstr(w, s, -1)
+#define getnstr(s, n) wgetnstr(stdscr, s, n)
+
+#define setterm(term) setupterm(term, 1, (int *)0)
+
+#define fixterm() reset_prog_mode()
+#define resetterm() reset_shell_mode()
+#define saveterm() def_prog_mode()
+#define crmode() cbreak()
+#define nocrmode() nocbreak()
+#define gettmode()
+
+/* It seems older SYSV curses versions define these */
+#define getattrs(win) ((win)?(win)->_attrs:A_NORMAL)
+#define getcurx(win) ((win)?(win)->_curx:ERR)
+#define getcury(win) ((win)?(win)->_cury:ERR)
+#define getbegx(win) ((win)?(win)->_begx:ERR)
+#define getbegy(win) ((win)?(win)->_begy:ERR)
+#define getmaxx(win) ((win)?((win)->_maxx + 1):ERR)
+#define getmaxy(win) ((win)?((win)->_maxy + 1):ERR)
+#define getparx(win) ((win)?(win)->_parx:ERR)
+#define getpary(win) ((win)?(win)->_pary:ERR)
+
+#define wstandout(win) (wattrset(win,A_STANDOUT))
+#define wstandend(win) (wattrset(win,A_NORMAL))
+
+#define wattron(win,at) wattr_on(win, NCURSES_CAST(attr_t, at), NULL)
+#define wattroff(win,at) wattr_off(win, NCURSES_CAST(attr_t, at), NULL)
+
+#if defined(_XOPEN_SOURCE_EXTENDED) && 0
+#define wattrset(win,at) ((win)->_color = PAIR_NUMBER(at), \
+ (win)->_attrs = (at))
+#else
+#define wattrset(win,at) ((win)->_attrs = (at))
+#endif
+
+#define scroll(win) wscrl(win,1)
+
+#define touchwin(win) wtouchln((win), 0, getmaxy(win), 1)
+#define touchline(win, s, c) wtouchln((win), s, c, 1)
+#define untouchwin(win) wtouchln((win), 0, getmaxy(win), 0)
+
+#define box(win, v, h) wborder(win, v, v, h, h, 0, 0, 0, 0)
+#define border(ls, rs, ts, bs, tl, tr, bl, br) wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br)
+#define hline(ch, n) whline(stdscr, ch, n)
+#define vline(ch, n) wvline(stdscr, ch, n)
+
+#define winstr(w, s) winnstr(w, s, -1)
+#define winchstr(w, s) winchnstr(w, s, -1)
+#define winsstr(w, s) winsnstr(w, s, -1)
+
+#define redrawwin(win) wredrawln(win, 0, (win)->_maxy+1)
+#define waddstr(win,str) waddnstr(win,str,-1)
+#define waddchstr(win,str) waddchnstr(win,str,-1)
+
+/*
+ * These apply to the first 256 color pairs.
+ */
+#define COLOR_PAIR(n) NCURSES_BITS(n, 0)
+#define PAIR_NUMBER(a) (NCURSES_CAST(int,(((a) & A_COLOR) >> NCURSES_ATTR_SHIFT)))
+
+/*
+ * pseudo functions for standard screen
+ */
+
+#define addch(ch) waddch(stdscr,ch)
+#define addchnstr(str,n) waddchnstr(stdscr,str,n)
+#define addchstr(str) waddchstr(stdscr,str)
+#define addnstr(str,n) waddnstr(stdscr,str,n)
+#define addstr(str) waddnstr(stdscr,str,-1)
+#define attroff(at) wattroff(stdscr,at)
+#define attron(at) wattron(stdscr,at)
+#define attrset(at) wattrset(stdscr,at)
+#define attr_get(ap,cp,o) wattr_get(stdscr,ap,cp,o)
+#define attr_off(a,o) wattr_off(stdscr,a,o)
+#define attr_on(a,o) wattr_on(stdscr,a,o)
+#define attr_set(a,c,o) wattr_set(stdscr,a,c,o)
+#define bkgd(ch) wbkgd(stdscr,ch)
+#define bkgdset(ch) wbkgdset(stdscr,ch)
+#define chgat(n,a,c,o) wchgat(stdscr,n,a,c,o)
+#define clear() wclear(stdscr)
+#define clrtobot() wclrtobot(stdscr)
+#define clrtoeol() wclrtoeol(stdscr)
+#define color_set(c,o) wcolor_set(stdscr,c,o)
+#define delch() wdelch(stdscr)
+#define deleteln() winsdelln(stdscr,-1)
+#define echochar(c) wechochar(stdscr,c)
+#define erase() werase(stdscr)
+#define getch() wgetch(stdscr)
+#define getstr(str) wgetstr(stdscr,str)
+#define inch() winch(stdscr)
+#define inchnstr(s,n) winchnstr(stdscr,s,n)
+#define inchstr(s) winchstr(stdscr,s)
+#define innstr(s,n) winnstr(stdscr,s,n)
+#define insch(c) winsch(stdscr,c)
+#define insdelln(n) winsdelln(stdscr,n)
+#define insertln() winsdelln(stdscr,1)
+#define insnstr(s,n) winsnstr(stdscr,s,n)
+#define insstr(s) winsstr(stdscr,s)
+#define instr(s) winstr(stdscr,s)
+#define move(y,x) wmove(stdscr,y,x)
+#define refresh() wrefresh(stdscr)
+#define scrl(n) wscrl(stdscr,n)
+#define setscrreg(t,b) wsetscrreg(stdscr,t,b)
+#define standend() wstandend(stdscr)
+#define standout() wstandout(stdscr)
+#define timeout(delay) wtimeout(stdscr,delay)
+#define wdeleteln(win) winsdelln(win,-1)
+#define winsertln(win) winsdelln(win,1)
+
+/*
+ * mv functions
+ */
+
+#define mvwaddch(win,y,x,ch) (wmove(win,y,x) == ERR ? ERR : waddch(win,ch))
+#define mvwaddchnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,n))
+#define mvwaddchstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,-1))
+#define mvwaddnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,n))
+#define mvwaddstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,-1))
+#define mvwdelch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wdelch(win))
+#define mvwchgat(win,y,x,n,a,c,o) (wmove(win,y,x) == ERR ? ERR : wchgat(win,n,a,c,o))
+#define mvwgetch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wgetch(win))
+#define mvwgetnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : wgetnstr(win,str,n))
+#define mvwgetstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : wgetstr(win,str))
+#define mvwhline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline(win,c,n))
+#define mvwinch(win,y,x) (wmove(win,y,x) == ERR ? NCURSES_CAST(chtype, ERR) : winch(win))
+#define mvwinchnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winchnstr(win,s,n))
+#define mvwinchstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winchstr(win,s))
+#define mvwinnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winnstr(win,s,n))
+#define mvwinsch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winsch(win,c))
+#define mvwinsnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winsnstr(win,s,n))
+#define mvwinsstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winsstr(win,s))
+#define mvwinstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winstr(win,s))
+#define mvwvline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline(win,c,n))
+
+#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch)
+#define mvaddchnstr(y,x,str,n) mvwaddchnstr(stdscr,y,x,str,n)
+#define mvaddchstr(y,x,str) mvwaddchstr(stdscr,y,x,str)
+#define mvaddnstr(y,x,str,n) mvwaddnstr(stdscr,y,x,str,n)
+#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str)
+#define mvchgat(y,x,n,a,c,o) mvwchgat(stdscr,y,x,n,a,c,o)
+#define mvdelch(y,x) mvwdelch(stdscr,y,x)
+#define mvgetch(y,x) mvwgetch(stdscr,y,x)
+#define mvgetnstr(y,x,str,n) mvwgetnstr(stdscr,y,x,str,n)
+#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str)
+#define mvhline(y,x,c,n) mvwhline(stdscr,y,x,c,n)
+#define mvinch(y,x) mvwinch(stdscr,y,x)
+#define mvinchnstr(y,x,s,n) mvwinchnstr(stdscr,y,x,s,n)
+#define mvinchstr(y,x,s) mvwinchstr(stdscr,y,x,s)
+#define mvinnstr(y,x,s,n) mvwinnstr(stdscr,y,x,s,n)
+#define mvinsch(y,x,c) mvwinsch(stdscr,y,x,c)
+#define mvinsnstr(y,x,s,n) mvwinsnstr(stdscr,y,x,s,n)
+#define mvinsstr(y,x,s) mvwinsstr(stdscr,y,x,s)
+#define mvinstr(y,x,s) mvwinstr(stdscr,y,x,s)
+#define mvvline(y,x,c,n) mvwvline(stdscr,y,x,c,n)
+
+/*
+ * Some wide-character functions can be implemented without the extensions.
+ */
+#define getbkgd(win) ((win)->_bkgd)
+
+#define slk_attr_off(a,v) ((v) ? ERR : slk_attroff(a))
+#define slk_attr_on(a,v) ((v) ? ERR : slk_attron(a))
+
+#if defined(_XOPEN_SOURCE_EXTENDED) && 0
+#define wattr_set(win,a,p,opts) ((win)->_attrs = ((a) & ~A_COLOR), \
+ (win)->_color = (p), \
+ OK)
+#define wattr_get(win,a,p,opts) ((void)((a) != 0 && (*(a) = (win)->_attrs)), \
+ (void)((p) != 0 && (*(p) = (win)->_color)), \
+ OK)
+#else
+#define wattr_set(win,a,p,opts) ((win)->_attrs = (((a) & ~A_COLOR) | COLOR_PAIR(p)), OK)
+#define wattr_get(win,a,p,opts) ((void)((a) != 0 && (*(a) = (win)->_attrs)), \
+ (void)((p) != 0 && (*(p) = PAIR_NUMBER((win)->_attrs))), \
+ OK)
+#endif
+
+/*
+ * XSI curses deprecates SVr4 vwprintw/vwscanw, which are supposed to use
+ * varargs.h. It adds new calls vw_printw/vw_scanw, which are supposed to
+ * use POSIX stdarg.h. The ncurses versions of vwprintw/vwscanw already
+ * use stdarg.h, so...
+ */
+#define vw_printw vwprintw
+#define vw_scanw vwscanw
+
+/*
+ * Export fallback function for use in C++ binding.
+ */
+#if !1
+#define vsscanf(a,b,c) _nc_vsscanf(a,b,c)
+NCURSES_EXPORT(int) vsscanf(const char *, const char *, va_list);
+#endif
+
+#endif /* NCURSES_NOMACROS */
+
+/*
+ * Pseudo-character tokens outside ASCII range. The curses wgetch() function
+ * will return any given one of these only if the corresponding k- capability
+ * is defined in your terminal's terminfo entry.
+ *
+ * Some keys (KEY_A1, etc) are arranged like this:
+ * a1 up a3
+ * left b2 right
+ * c1 down c3
+ *
+ * A few key codes do not depend upon the terminfo entry.
+ */
+#define KEY_CODE_YES 0400 /* A wchar_t contains a key code */
+#define KEY_MIN 0401 /* Minimum curses key */
+#define KEY_BREAK 0401 /* Break key (unreliable) */
+#define KEY_SRESET 0530 /* Soft (partial) reset (unreliable) */
+#define KEY_RESET 0531 /* Reset or hard reset (unreliable) */
+/*
+ * These definitions were generated by /home/user/ncurses-5.6/include/MKkey_defs.sh /home/user/ncurses-5.6/include/Caps
+ */
+#define KEY_DOWN 0402 /* down-arrow key */
+#define KEY_UP 0403 /* up-arrow key */
+#define KEY_LEFT 0404 /* left-arrow key */
+#define KEY_RIGHT 0405 /* right-arrow key */
+#define KEY_HOME 0406 /* home key */
+#define KEY_BACKSPACE 0407 /* backspace key */
+#define KEY_F0 0410 /* Function keys. Space for 64 */
+#define KEY_F(n) (KEY_F0+(n)) /* Value of function key n */
+#define KEY_DL 0510 /* delete-line key */
+#define KEY_IL 0511 /* insert-line key */
+#define KEY_DC 0512 /* delete-character key */
+#define KEY_IC 0513 /* insert-character key */
+#define KEY_EIC 0514 /* sent by rmir or smir in insert mode */
+#define KEY_CLEAR 0515 /* clear-screen or erase key */
+#define KEY_EOS 0516 /* clear-to-end-of-screen key */
+#define KEY_EOL 0517 /* clear-to-end-of-line key */
+#define KEY_SF 0520 /* scroll-forward key */
+#define KEY_SR 0521 /* scroll-backward key */
+#define KEY_NPAGE 0522 /* next-page key */
+#define KEY_PPAGE 0523 /* previous-page key */
+#define KEY_STAB 0524 /* set-tab key */
+#define KEY_CTAB 0525 /* clear-tab key */
+#define KEY_CATAB 0526 /* clear-all-tabs key */
+#define KEY_ENTER 0527 /* enter/send key */
+#define KEY_PRINT 0532 /* print key */
+#define KEY_LL 0533 /* lower-left key (home down) */
+#define KEY_A1 0534 /* upper left of keypad */
+#define KEY_A3 0535 /* upper right of keypad */
+#define KEY_B2 0536 /* center of keypad */
+#define KEY_C1 0537 /* lower left of keypad */
+#define KEY_C3 0540 /* lower right of keypad */
+#define KEY_BTAB 0541 /* back-tab key */
+#define KEY_BEG 0542 /* begin key */
+#define KEY_CANCEL 0543 /* cancel key */
+#define KEY_CLOSE 0544 /* close key */
+#define KEY_COMMAND 0545 /* command key */
+#define KEY_COPY 0546 /* copy key */
+#define KEY_CREATE 0547 /* create key */
+#define KEY_END 0550 /* end key */
+#define KEY_EXIT 0551 /* exit key */
+#define KEY_FIND 0552 /* find key */
+#define KEY_HELP 0553 /* help key */
+#define KEY_MARK 0554 /* mark key */
+#define KEY_MESSAGE 0555 /* message key */
+#define KEY_MOVE 0556 /* move key */
+#define KEY_NEXT 0557 /* next key */
+#define KEY_OPEN 0560 /* open key */
+#define KEY_OPTIONS 0561 /* options key */
+#define KEY_PREVIOUS 0562 /* previous key */
+#define KEY_REDO 0563 /* redo key */
+#define KEY_REFERENCE 0564 /* reference key */
+#define KEY_REFRESH 0565 /* refresh key */
+#define KEY_REPLACE 0566 /* replace key */
+#define KEY_RESTART 0567 /* restart key */
+#define KEY_RESUME 0570 /* resume key */
+#define KEY_SAVE 0571 /* save key */
+#define KEY_SBEG 0572 /* shifted begin key */
+#define KEY_SCANCEL 0573 /* shifted cancel key */
+#define KEY_SCOMMAND 0574 /* shifted command key */
+#define KEY_SCOPY 0575 /* shifted copy key */
+#define KEY_SCREATE 0576 /* shifted create key */
+#define KEY_SDC 0577 /* shifted delete-character key */
+#define KEY_SDL 0600 /* shifted delete-line key */
+#define KEY_SELECT 0601 /* select key */
+#define KEY_SEND 0602 /* shifted end key */
+#define KEY_SEOL 0603 /* shifted clear-to-end-of-line key */
+#define KEY_SEXIT 0604 /* shifted exit key */
+#define KEY_SFIND 0605 /* shifted find key */
+#define KEY_SHELP 0606 /* shifted help key */
+#define KEY_SHOME 0607 /* shifted home key */
+#define KEY_SIC 0610 /* shifted insert-character key */
+#define KEY_SLEFT 0611 /* shifted left-arrow key */
+#define KEY_SMESSAGE 0612 /* shifted message key */
+#define KEY_SMOVE 0613 /* shifted move key */
+#define KEY_SNEXT 0614 /* shifted next key */
+#define KEY_SOPTIONS 0615 /* shifted options key */
+#define KEY_SPREVIOUS 0616 /* shifted previous key */
+#define KEY_SPRINT 0617 /* shifted print key */
+#define KEY_SREDO 0620 /* shifted redo key */
+#define KEY_SREPLACE 0621 /* shifted replace key */
+#define KEY_SRIGHT 0622 /* shifted right-arrow key */
+#define KEY_SRSUME 0623 /* shifted resume key */
+#define KEY_SSAVE 0624 /* shifted save key */
+#define KEY_SSUSPEND 0625 /* shifted suspend key */
+#define KEY_SUNDO 0626 /* shifted undo key */
+#define KEY_SUSPEND 0627 /* suspend key */
+#define KEY_UNDO 0630 /* undo key */
+#define KEY_MOUSE 0631 /* Mouse event has occurred */
+#define KEY_RESIZE 0632 /* Terminal resize event */
+#define KEY_EVENT 0633 /* We were interrupted by an event */
+
+#define KEY_MAX 0777 /* Maximum key value is 0633 */
+/*
+ * This file is part of ncurses, designed to be appended after curses.h.in
+ * (see that file for the relevant copyright).
+ */
+#ifdef _XOPEN_SOURCE_EXTENDED
+
+/* $Id: curses.wide,v 1.32 2006/05/27 19:44:23 tom Exp $ */
+
+extern NCURSES_EXPORT_VAR(cchar_t *) _nc_wacs;
+
+#define NCURSES_WACS(c) (&_nc_wacs[(unsigned char)c])
+
+#define WACS_BSSB NCURSES_WACS('l')
+#define WACS_SSBB NCURSES_WACS('m')
+#define WACS_BBSS NCURSES_WACS('k')
+#define WACS_SBBS NCURSES_WACS('j')
+#define WACS_SBSS NCURSES_WACS('u')
+#define WACS_SSSB NCURSES_WACS('t')
+#define WACS_SSBS NCURSES_WACS('v')
+#define WACS_BSSS NCURSES_WACS('w')
+#define WACS_BSBS NCURSES_WACS('q')
+#define WACS_SBSB NCURSES_WACS('x')
+#define WACS_SSSS NCURSES_WACS('n')
+
+#define WACS_ULCORNER WACS_BSSB
+#define WACS_LLCORNER WACS_SSBB
+#define WACS_URCORNER WACS_BBSS
+#define WACS_LRCORNER WACS_SBBS
+#define WACS_RTEE WACS_SBSS
+#define WACS_LTEE WACS_SSSB
+#define WACS_BTEE WACS_SSBS
+#define WACS_TTEE WACS_BSSS
+#define WACS_HLINE WACS_BSBS
+#define WACS_VLINE WACS_SBSB
+#define WACS_PLUS WACS_SSSS
+
+#define WACS_S1 NCURSES_WACS('o') /* scan line 1 */
+#define WACS_S9 NCURSES_WACS('s') /* scan line 9 */
+#define WACS_DIAMOND NCURSES_WACS('`') /* diamond */
+#define WACS_CKBOARD NCURSES_WACS('a') /* checker board */
+#define WACS_DEGREE NCURSES_WACS('f') /* degree symbol */
+#define WACS_PLMINUS NCURSES_WACS('g') /* plus/minus */
+#define WACS_BULLET NCURSES_WACS('~') /* bullet */
+
+ /* Teletype 5410v1 symbols */
+#define WACS_LARROW NCURSES_WACS(',') /* arrow left */
+#define WACS_RARROW NCURSES_WACS('+') /* arrow right */
+#define WACS_DARROW NCURSES_WACS('.') /* arrow down */
+#define WACS_UARROW NCURSES_WACS('-') /* arrow up */
+#define WACS_BOARD NCURSES_WACS('h') /* board of squares */
+#define WACS_LANTERN NCURSES_WACS('i') /* lantern symbol */
+#define WACS_BLOCK NCURSES_WACS('0') /* solid square block */
+
+ /* ncurses extensions */
+#define WACS_S3 NCURSES_WACS('p') /* scan line 3 */
+#define WACS_S7 NCURSES_WACS('r') /* scan line 7 */
+#define WACS_LEQUAL NCURSES_WACS('y') /* less/equal */
+#define WACS_GEQUAL NCURSES_WACS('z') /* greater/equal */
+#define WACS_PI NCURSES_WACS('{') /* Pi */
+#define WACS_NEQUAL NCURSES_WACS('|') /* not equal */
+#define WACS_STERLING NCURSES_WACS('}') /* UK pound sign */
+
+/*
+ * Function prototypes for wide-character operations.
+ *
+ * "generated" comments should include ":WIDEC" to make the corresponding
+ * functions ifdef'd in lib_gen.c
+ *
+ * "implemented" comments do not need this marker.
+ */
+
+extern NCURSES_EXPORT(int) add_wch (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) add_wchnstr (const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) add_wchstr (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) addnwstr (const wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) addwstr (const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) bkgrnd (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(void) bkgrndset (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) border_set (const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) box_set (WINDOW *, const cchar_t *, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) echo_wchar (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) erasewchar (wchar_t*); /* implemented */
+extern NCURSES_EXPORT(int) get_wch (wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) get_wstr (wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) getbkgrnd (cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) getcchar (const cchar_t *, wchar_t*, attr_t*, short*, void*); /* implemented */
+extern NCURSES_EXPORT(int) getn_wstr (wint_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) hline_set (const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) in_wch (cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) in_wchnstr (cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) in_wchstr (cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) innwstr (wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) ins_nwstr (const wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) ins_wch (const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) ins_wstr (const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) inwstr (wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(NCURSES_CONST char*) key_name (wchar_t); /* implemented */
+extern NCURSES_EXPORT(int) killwchar (wchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) mvadd_wch (int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvadd_wchnstr (int, int, const cchar_t *, int);/* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvadd_wchstr (int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvaddnwstr (int, int, const wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvaddwstr (int, int, const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvget_wch (int, int, wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvget_wstr (int, int, wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvgetn_wstr (int, int, wint_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvhline_set (int, int, const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvin_wch (int, int, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvin_wchnstr (int, int, cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvin_wchstr (int, int, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvinnwstr (int, int, wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvins_nwstr (int, int, const wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvins_wch (int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvins_wstr (int, int, const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvinwstr (int, int, wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvvline_set (int, int, const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwadd_wch (WINDOW *, int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwadd_wchnstr (WINDOW *, int, int, const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwadd_wchstr (WINDOW *, int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwaddnwstr (WINDOW *, int, int, const wchar_t *, int);/* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwaddwstr (WINDOW *, int, int, const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwget_wch (WINDOW *, int, int, wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwget_wstr (WINDOW *, int, int, wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwgetn_wstr (WINDOW *, int, int, wint_t *, int);/* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwhline_set (WINDOW *, int, int, const cchar_t *, int);/* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwin_wch (WINDOW *, int, int, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwin_wchnstr (WINDOW *, int,int, cchar_t *,int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwin_wchstr (WINDOW *, int, int, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwinnwstr (WINDOW *, int, int, wchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwins_nwstr (WINDOW *, int,int, const wchar_t *,int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwins_wch (WINDOW *, int, int, const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwins_wstr (WINDOW *, int, int, const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwinwstr (WINDOW *, int, int, wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) mvwvline_set (WINDOW *, int,int, const cchar_t *,int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) pecho_wchar (WINDOW *, const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) setcchar (cchar_t *, const wchar_t *, const attr_t, short, const void *); /* implemented */
+extern NCURSES_EXPORT(int) slk_wset (int, const wchar_t *, int); /* implemented */
+extern NCURSES_EXPORT(attr_t) term_attrs (void); /* implemented */
+extern NCURSES_EXPORT(int) unget_wch (const wchar_t); /* implemented */
+extern NCURSES_EXPORT(int) vid_attr (attr_t, short, void *); /* implemented */
+extern NCURSES_EXPORT(int) vid_puts (attr_t, short, void *, int (*)(int)); /* implemented */
+extern NCURSES_EXPORT(int) vline_set (const cchar_t *, int); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) wadd_wch (WINDOW *,const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) wadd_wchnstr (WINDOW *,const cchar_t *,int); /* implemented */
+extern NCURSES_EXPORT(int) wadd_wchstr (WINDOW *,const cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) waddnwstr (WINDOW *,const wchar_t *,int); /* implemented */
+extern NCURSES_EXPORT(int) waddwstr (WINDOW *,const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) wbkgrnd (WINDOW *,const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(void) wbkgrndset (WINDOW *,const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) wborder_set (WINDOW *,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*,const cchar_t*); /* implemented */
+extern NCURSES_EXPORT(int) wecho_wchar (WINDOW *, const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) wget_wch (WINDOW *, wint_t *); /* implemented */
+extern NCURSES_EXPORT(int) wget_wstr (WINDOW *, wint_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) wgetbkgrnd (WINDOW *, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) wgetn_wstr (WINDOW *,wint_t *, int); /* implemented */
+extern NCURSES_EXPORT(int) whline_set (WINDOW *, const cchar_t *, int); /* implemented */
+extern NCURSES_EXPORT(int) win_wch (WINDOW *, cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) win_wchnstr (WINDOW *, cchar_t *, int); /* implemented */
+extern NCURSES_EXPORT(int) win_wchstr (WINDOW *, cchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) winnwstr (WINDOW *, wchar_t *, int); /* implemented */
+extern NCURSES_EXPORT(int) wins_nwstr (WINDOW *, const wchar_t *, int); /* implemented */
+extern NCURSES_EXPORT(int) wins_wch (WINDOW *, const cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) wins_wstr (WINDOW *, const wchar_t *); /* generated:WIDEC */
+extern NCURSES_EXPORT(int) winwstr (WINDOW *, wchar_t *); /* implemented */
+extern NCURSES_EXPORT(wchar_t*) wunctrl (cchar_t *); /* implemented */
+extern NCURSES_EXPORT(int) wvline_set (WINDOW *, const cchar_t *, int); /* implemented */
+
+#ifndef NCURSES_NOMACROS
+
+/*
+ * XSI curses macros for XPG4 conformance.
+ */
+#define add_wch(c) wadd_wch(stdscr,c)
+#define add_wchnstr(str,n) wadd_wchnstr(stdscr,str,n)
+#define add_wchstr(str) wadd_wchstr(stdscr,str)
+#define addnwstr(wstr,n) waddnwstr(stdscr,wstr,n)
+#define addwstr(wstr) waddwstr(stdscr,wstr)
+#define bkgrnd(c) wbkgrnd(stdscr,c)
+#define bkgrndset(c) wbkgrndset(stdscr,c)
+#define border_set(l,r,t,b,tl,tr,bl,br) wborder_set(stdscr,l,r,t,b,tl,tr,bl,br)
+#define box_set(w,v,h) wborder_set(w,v,v,h,h,0,0,0,0)
+#define echo_wchar(c) wecho_wchar(stdscr,c)
+#define get_wch(c) wget_wch(stdscr,c)
+#define get_wstr(t) wget_wstr(stdscr,t)
+#define getbkgrnd(wch) wgetbkgrnd(stdscr,wch)
+#define getn_wstr(t,n) wgetn_wstr(stdscr,t,n)
+#define hline_set(c,n) whline_set(stdscr,c,n)
+#define in_wch(c) win_wch(stdscr,c)
+#define in_wchnstr(c,n) win_wchnstr(stdscr,c,n)
+#define in_wchstr(c) win_wchstr(stdscr,c)
+#define innwstr(c,n) winnwstr(stdscr,c,n)
+#define ins_nwstr(t,n) wins_nwstr(stdscr,t,n)
+#define ins_wch(c) wins_wch(stdscr,c)
+#define ins_wstr(t) wins_wstr(stdscr,t)
+#define inwstr(c) winwstr(stdscr,c)
+#define vline_set(c,n) wvline_set(stdscr,c,n)
+#define wadd_wchstr(win,str) wadd_wchnstr(win,str,-1)
+#define waddwstr(win,wstr) waddnwstr(win,wstr,-1)
+#define wget_wstr(w,t) wgetn_wstr(w,t,-1)
+//// #define wgetbkgrnd(win,wch) (*wch = win->_bkgrnd, OK)
+#define win_wchstr(w,c) win_wchnstr(w,c,-1)
+#define wins_wstr(w,t) wins_nwstr(w,t,-1)
+
+#define mvadd_wch(y,x,c) mvwadd_wch(stdscr,y,x,c)
+#define mvadd_wchnstr(y,x,s,n) mvwadd_wchnstr(stdscr,y,x,s,n)
+#define mvadd_wchstr(y,x,s) mvwadd_wchstr(stdscr,y,x,s)
+#define mvaddnwstr(y,x,wstr,n) mvwaddnwstr(stdscr,y,x,wstr,n)
+#define mvaddwstr(y,x,wstr) mvwaddwstr(stdscr,y,x,wstr)
+#define mvget_wch(y,x,c) mvwget_wch(stdscr,y,x,c)
+#define mvget_wstr(y,x,t) mvwget_wstr(stdscr,y,x,t)
+#define mvgetn_wstr(y,x,t,n) mvwgetn_wstr(stdscr,y,x,t,n)
+#define mvhline_set(y,x,c,n) mvwhline_set(stdscr,y,x,c,n)
+#define mvin_wch(y,x,c) mvwin_wch(stdscr,y,x,c)
+#define mvin_wchnstr(y,x,c,n) mvwin_wchnstr(stdscr,y,x,c,n)
+#define mvin_wchstr(y,x,c) mvwin_wchstr(stdscr,y,x,c)
+#define mvinnwstr(y,x,c,n) mvwinnwstr(stdscr,y,x,c,n)
+#define mvins_nwstr(y,x,t,n) mvwins_nwstr(stdscr,y,x,t,n)
+#define mvins_wch(y,x,c) mvwins_wch(stdscr,y,x,c)
+#define mvins_wstr(y,x,t) mvwins_wstr(stdscr,y,x,t)
+#define mvinwstr(y,x,c) mvwinwstr(stdscr,y,x,c)
+#define mvvline_set(y,x,c,n) mvwvline_set(stdscr,y,x,c,n)
+
+#define mvwadd_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : wadd_wch(win,c))
+#define mvwadd_wchnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : wadd_wchnstr(win,s,n))
+#define mvwadd_wchstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : wadd_wchstr(win,s))
+#define mvwaddnwstr(win,y,x,wstr,n) (wmove(win,y,x) == ERR ? ERR : waddnwstr(win,wstr,n))
+#define mvwaddwstr(win,y,x,wstr) (wmove(win,y,x) == ERR ? ERR : waddwstr(win,wstr))
+#define mvwget_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : wget_wch(win,c))
+#define mvwget_wstr(win,y,x,t) (wmove(win,y,x) == ERR ? ERR : wget_wstr(win,t))
+#define mvwgetn_wstr(win,y,x,t,n) (wmove(win,y,x) == ERR ? ERR : wgetn_wstr(win,t,n))
+#define mvwhline_set(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline_set(win,c,n))
+#define mvwin_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : win_wch(win,c))
+#define mvwin_wchnstr(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : win_wchnstr(win,c,n))
+#define mvwin_wchstr(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : win_wchstr(win,c))
+#define mvwinnwstr(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : winnwstr(win,c,n))
+#define mvwins_nwstr(win,y,x,t,n) (wmove(win,y,x) == ERR ? ERR : wins_nwstr(win,t,n))
+#define mvwins_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : wins_wch(win,c))
+#define mvwins_wstr(win,y,x,t) (wmove(win,y,x) == ERR ? ERR : wins_wstr(win,t))
+#define mvwinwstr(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winwstr(win,c))
+#define mvwvline_set(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline_set(win,c,n))
+
+#endif /* NCURSES_NOMACROS */
+
+#if defined(TRACE) || defined(NCURSES_TEST)
+extern NCURSES_EXPORT(const char *) _nc_viswbuf(const wchar_t *);
+extern NCURSES_EXPORT(const char *) _nc_viswibuf(const wint_t *);
+#endif
+
+#endif /* _XOPEN_SOURCE_EXTENDED */
+/*
+ * This file is part of ncurses, designed to be appended after curses.h.in
+ * (see that file for the relevant copyright).
+ */
+/* $Id: curses.tail,v 1.14 2006/05/27 16:28:29 tom Exp $ */
+
+/* mouse interface */
+
+#ifdef NCURSES_MOUSE_VERSION
+#if NCURSES_MOUSE_VERSION > 1
+#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 5))
+#else
+#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 6))
+#endif
+
+#define NCURSES_BUTTON_RELEASED 001L
+#define NCURSES_BUTTON_PRESSED 002L
+#define NCURSES_BUTTON_CLICKED 004L
+#define NCURSES_DOUBLE_CLICKED 010L
+#define NCURSES_TRIPLE_CLICKED 020L
+#define NCURSES_RESERVED_EVENT 040L
+
+/* event masks */
+#define BUTTON1_RELEASED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_RELEASED)
+#define BUTTON1_PRESSED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_PRESSED)
+#define BUTTON1_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_CLICKED)
+#define BUTTON1_DOUBLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_DOUBLE_CLICKED)
+#define BUTTON1_TRIPLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_TRIPLE_CLICKED)
+
+#define BUTTON2_RELEASED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_RELEASED)
+#define BUTTON2_PRESSED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED)
+#define BUTTON2_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_CLICKED)
+#define BUTTON2_DOUBLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_DOUBLE_CLICKED)
+#define BUTTON2_TRIPLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_TRIPLE_CLICKED)
+
+#define BUTTON3_RELEASED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_RELEASED)
+#define BUTTON3_PRESSED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_PRESSED)
+#define BUTTON3_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_CLICKED)
+#define BUTTON3_DOUBLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_DOUBLE_CLICKED)
+#define BUTTON3_TRIPLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_TRIPLE_CLICKED)
+
+#define BUTTON4_RELEASED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_RELEASED)
+#define BUTTON4_PRESSED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_PRESSED)
+#define BUTTON4_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_CLICKED)
+#define BUTTON4_DOUBLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_DOUBLE_CLICKED)
+#define BUTTON4_TRIPLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_TRIPLE_CLICKED)
+
+/*
+ * In 32 bits the version-1 scheme does not provide enough space for a 5th
+ * button, unless we choose to change the ABI by omitting the reserved-events.
+ */
+#if NCURSES_MOUSE_VERSION > 1
+
+#define BUTTON5_RELEASED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_RELEASED)
+#define BUTTON5_PRESSED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_PRESSED)
+#define BUTTON5_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_CLICKED)
+#define BUTTON5_DOUBLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_DOUBLE_CLICKED)
+#define BUTTON5_TRIPLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_TRIPLE_CLICKED)
+
+#define BUTTON_CTRL NCURSES_MOUSE_MASK(6, 0001L)
+#define BUTTON_SHIFT NCURSES_MOUSE_MASK(6, 0002L)
+#define BUTTON_ALT NCURSES_MOUSE_MASK(6, 0004L)
+#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(6, 0010L)
+
+#else
+
+#define BUTTON1_RESERVED_EVENT NCURSES_MOUSE_MASK(1, NCURSES_RESERVED_EVENT)
+#define BUTTON2_RESERVED_EVENT NCURSES_MOUSE_MASK(2, NCURSES_RESERVED_EVENT)
+#define BUTTON3_RESERVED_EVENT NCURSES_MOUSE_MASK(3, NCURSES_RESERVED_EVENT)
+#define BUTTON4_RESERVED_EVENT NCURSES_MOUSE_MASK(4, NCURSES_RESERVED_EVENT)
+
+#define BUTTON_CTRL NCURSES_MOUSE_MASK(5, 0001L)
+#define BUTTON_SHIFT NCURSES_MOUSE_MASK(5, 0002L)
+#define BUTTON_ALT NCURSES_MOUSE_MASK(5, 0004L)
+#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(5, 0010L)
+
+#endif
+
+#define ALL_MOUSE_EVENTS (REPORT_MOUSE_POSITION - 1)
+
+/* macros to extract single event-bits from masks */
+#define BUTTON_RELEASE(e, x) ((e) & (001 << (6 * ((x) - 1))))
+#define BUTTON_PRESS(e, x) ((e) & (002 << (6 * ((x) - 1))))
+#define BUTTON_CLICK(e, x) ((e) & (004 << (6 * ((x) - 1))))
+#define BUTTON_DOUBLE_CLICK(e, x) ((e) & (010 << (6 * ((x) - 1))))
+#define BUTTON_TRIPLE_CLICK(e, x) ((e) & (020 << (6 * ((x) - 1))))
+#define BUTTON_RESERVED_EVENT(e, x) ((e) & (040 << (6 * ((x) - 1))))
+
+typedef struct
+{
+ short id; /* ID to distinguish multiple devices */
+ int x, y, z; /* event coordinates (character-cell) */
+ mmask_t bstate; /* button state bits */
+}
+MEVENT;
+
+extern NCURSES_EXPORT(int) getmouse (MEVENT *);
+extern NCURSES_EXPORT(int) ungetmouse (MEVENT *);
+extern NCURSES_EXPORT(mmask_t) mousemask (mmask_t, mmask_t *);
+extern NCURSES_EXPORT(bool) wenclose (const WINDOW *, int, int);
+extern NCURSES_EXPORT(int) mouseinterval (int);
+extern NCURSES_EXPORT(bool) wmouse_trafo (const WINDOW*, int*, int*, bool);
+extern NCURSES_EXPORT(bool) mouse_trafo (int*, int*, bool); /* generated */
+
+#define mouse_trafo(y,x,to_screen) wmouse_trafo(stdscr,y,x,to_screen)
+#endif
+
+/* other non-XSI functions */
+
+extern NCURSES_EXPORT(int) mcprint (char *, int); /* direct data to printer */
+extern NCURSES_EXPORT(int) has_key (int); /* do we have given key? */
+
+/* Debugging : use with libncurses_g.a */
+
+extern NCURSES_EXPORT(void) _tracef (const char *, ...) GCC_PRINTFLIKE(1,2);
+extern NCURSES_EXPORT(void) _tracedump (const char *, WINDOW *);
+extern NCURSES_EXPORT(char *) _traceattr (attr_t);
+extern NCURSES_EXPORT(char *) _traceattr2 (int, chtype);
+extern NCURSES_EXPORT(char *) _nc_tracebits (void);
+extern NCURSES_EXPORT(char *) _tracechar (int);
+extern NCURSES_EXPORT(char *) _tracechtype (chtype);
+extern NCURSES_EXPORT(char *) _tracechtype2 (int, chtype);
+#ifdef _XOPEN_SOURCE_EXTENDED
+#define _tracech_t _tracecchar_t
+extern NCURSES_EXPORT(char *) _tracecchar_t (const cchar_t *);
+#define _tracech_t2 _tracecchar_t2
+extern NCURSES_EXPORT(char *) _tracecchar_t2 (int, const cchar_t *);
+#else
+#define _tracech_t _tracechtype
+#define _tracech_t2 _tracechtype2
+#endif
+#ifdef NCURSES_MOUSE_VERSION
+extern NCURSES_EXPORT(char *) _tracemouse (const MEVENT *);
+#endif
+extern NCURSES_EXPORT(void) trace (const unsigned int);
+
+/* trace masks */
+#define TRACE_DISABLE 0x0000 /* turn off tracing */
+#define TRACE_TIMES 0x0001 /* trace user and system times of updates */
+#define TRACE_TPUTS 0x0002 /* trace tputs calls */
+#define TRACE_UPDATE 0x0004 /* trace update actions, old & new screens */
+#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */
+#define TRACE_CHARPUT 0x0010 /* trace all character outputs */
+#define TRACE_ORDINARY 0x001F /* trace all update actions */
+#define TRACE_CALLS 0x0020 /* trace all curses calls */
+#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */
+#define TRACE_IEVENT 0x0080 /* trace low-level input processing */
+#define TRACE_BITS 0x0100 /* trace state of TTY control bits */
+#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */
+#define TRACE_CCALLS 0x0400 /* trace per-character calls */
+#define TRACE_DATABASE 0x0800 /* trace read/write of terminfo/termcap data */
+#define TRACE_ATTRS 0x1000 /* trace attribute updates */
+
+#define TRACE_SHIFT 13 /* number of bits in the trace masks */
+#define TRACE_MAXIMUM ((1 << TRACE_SHIFT) - 1) /* maximum trace level */
+
+#if defined(TRACE) || defined(NCURSES_TEST)
+extern NCURSES_EXPORT_VAR(int) _nc_optimize_enable; /* enable optimizations */
+extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *);
+#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */
+#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */
+#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */
+#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */
+#endif
+
+#ifdef __cplusplus
+
+#ifndef NCURSES_NOMACROS
+
+/* these names conflict with STL */
+#undef box
+#undef clear
+#undef erase
+#undef move
+#undef refresh
+
+#endif /* NCURSES_NOMACROS */
+
+}
+#endif
+
+/* Local functions not defined in normal curses */
+
+void curses_enable_vga(int);
+void curses_enable_serial(int);
+
+int curses_vga_enabled(void);
+int curses_serial_enabled(void);
+
+#endif /* _CURSES_H */
diff --git a/apps/lib/curses/tinycurses/curses.priv.h b/apps/lib/curses/tinycurses/curses.priv.h
new file mode 100644
index 0000000..78b7ff3
--- /dev/null
+++ b/apps/lib/curses/tinycurses/curses.priv.h
@@ -0,0 +1,1317 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
+ * and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
+ ****************************************************************************/
+
+
+/*
+ * $Id: curses.priv.h,v 1.314 2006/12/10 00:55:14 tom Exp $
+ *
+ * curses.priv.h
+ *
+ * Header file for curses library objects which are private to
+ * the library.
+ *
+ */
+
+#ifndef _CURSES_PRIV_H
+#define _CURSES_PRIV_H 1
+
+//// #include <ncurses_dll.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//// #include <ncurses_cfg.h>
+
+#if USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+//// #if HAVE_SYS_BSDTYPES_H
+//// #include <sys/bsdtypes.h> /* needed for ISC */
+//// #endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+//// #elif HAVE_SYS_PARAM_H
+//// # include <sys/param.h>
+#endif
+////
+//// #include <assert.h>
+#include <stdio.h>
+
+#include <errno.h>
+
+#if DECL_ERRNO
+extern int errno;
+#endif
+
+//// #include <nc_panel.h>
+////
+//// /* Some systems have a broken 'select()', but workable 'poll()'. Use that */
+//// #if HAVE_WORKING_POLL
+//// #define USE_FUNC_POLL 1
+//// #if HAVE_POLL_H
+//// #include <poll.h>
+//// #else
+//// #include <sys/poll.h>
+//// #endif
+//// #else
+//// #define USE_FUNC_POLL 0
+//// #endif
+////
+//// /* include signal.h before curses.h to work-around defect in glibc 2.1.3 */
+//// #include <signal.h>
+
+/* Alessandro Rubini's GPM (general-purpose mouse) */
+#if HAVE_LIBGPM && HAVE_GPM_H
+#define USE_GPM_SUPPORT 1
+#else
+#define USE_GPM_SUPPORT 0
+#endif
+
+/* QNX mouse support */
+#if defined(__QNX__) && !defined(__QNXNTO__)
+#define USE_QNX_MOUSE 1
+#else
+#define USE_QNX_MOUSE 0
+#endif
+
+/* EMX mouse support */
+#ifdef __EMX__
+#define USE_EMX_MOUSE 1
+#else
+#define USE_EMX_MOUSE 0
+#endif
+
+#define DEFAULT_MAXCLICK 166
+#define EV_MAX 8 /* size of mouse circular event queue */
+
+/*
+ * If we don't have signals to support it, don't add a sigwinch handler.
+ * In any case, resizing is an extended feature. Use it if we've got it.
+ */
+#if !NCURSES_EXT_FUNCS
+#undef HAVE_SIZECHANGE
+#define HAVE_SIZECHANGE 0
+#endif
+
+#if HAVE_SIZECHANGE && defined(SIGWINCH)
+#define USE_SIZECHANGE 1
+#else
+#define USE_SIZECHANGE 0
+#undef USE_SIGWINCH
+#define USE_SIGWINCH 0
+#endif
+
+/*
+ * If desired, one can configure this, disabling environment variables that
+ * point to custom terminfo/termcap locations.
+ */
+#ifdef USE_ROOT_ENVIRON
+#define use_terminfo_vars() 1
+#else
+#define use_terminfo_vars() _nc_env_access()
+extern NCURSES_EXPORT(int) _nc_env_access (void);
+#endif
+
+/*
+ * Not all platforms have memmove; some have an equivalent bcopy. (Some may
+ * have neither).
+ */
+#if USE_OK_BCOPY
+#define memmove(d,s,n) bcopy(s,d,n)
+#elif USE_MY_MEMMOVE
+#define memmove(d,s,n) _nc_memmove(d,s,n)
+extern NCURSES_EXPORT(void *) _nc_memmove (void *, const void *, size_t);
+#endif
+
+/*
+ * Scroll hints are useless when hashmap is used
+ */
+//// #if !USE_SCROLL_HINTS
+//// #if !USE_HASHMAP
+//// #define USE_SCROLL_HINTS 1
+//// #else
+//// #define USE_SCROLL_HINTS 0
+//// #endif
+//// #endif
+
+#if USE_SCROLL_HINTS
+#define if_USE_SCROLL_HINTS(stmt) stmt
+#else
+#define if_USE_SCROLL_HINTS(stmt) /*nothing*/
+#endif
+
+/*
+ * Note: ht/cbt expansion flakes out randomly under Linux 1.1.47, but only
+ * when we're throwing control codes at the screen at high volume. To see
+ * this, re-enable USE_HARD_TABS and run worm for a while. Other systems
+ * probably don't want to define this either due to uncertainties about tab
+ * delays and expansion in raw mode.
+ */
+
+struct tries {
+ struct tries *child; /* ptr to child. NULL if none */
+ struct tries *sibling; /* ptr to sibling. NULL if none */
+ unsigned char ch; /* character at this node */
+ unsigned short value; /* code of string so far. 0 if none. */
+};
+
+/*
+ * Common/troublesome character definitions
+ */
+#define L_BRACE '{'
+#define R_BRACE '}'
+#define S_QUOTE '\''
+#define D_QUOTE '"'
+
+#define VT_ACSC "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~"
+
+/*
+ * Structure for palette tables
+ */
+
+typedef struct
+{
+ short red, green, blue; /* what color_content() returns */
+ short r, g, b; /* params to init_color() */
+ int init; /* true if we called init_color() */
+}
+color_t;
+
+#define MAXCOLUMNS 135
+#define MAXLINES 66
+#define FIFO_SIZE MAXCOLUMNS+2 /* for nocbreak mode input */
+
+#define ACS_LEN 128
+
+#define WINDOWLIST struct _win_list
+
+#if USE_WIDEC_SUPPORT
+#define _nc_bkgd _bkgrnd
+#else
+#undef _XOPEN_SOURCE_EXTENDED
+#define _nc_bkgd _bkgd
+#define wgetbkgrnd(win, wch) *wch = win->_bkgd
+#define wbkgrnd wbkgd
+#endif
+
+//// #include <curses.h> /* we'll use -Ipath directive to get the right one! */
+//// #include <term.h>
+//// #include <term_entry.h>
+//// #include <nc_tparm.h>
+
+#if NCURSES_EXT_COLORS && USE_WIDEC_SUPPORT
+#define if_EXT_COLORS(stmt) stmt
+#define NetPair(value,p) (value).ext_color = (p), \
+ AttrOf(value) &= ALL_BUT_COLOR, \
+ AttrOf(value) |= (A_COLOR & COLOR_PAIR((p > 255) ? 255 : p))
+#define SetPair(value,p) (value).ext_color = (p)
+#define GetPair(value) (value).ext_color
+#define unColor(n) (AttrOf(n) & ALL_BUT_COLOR)
+#define GET_WINDOW_PAIR(w) (w)->_color
+#define SET_WINDOW_PAIR(w,p) (w)->_color = (p)
+#define SameAttrOf(a,b) (AttrOf(a) == AttrOf(b) && GetPair(a) == GetPair(b))
+#define VIDATTR(attr, pair) vid_attr(attr, pair, 0)
+#else
+#define if_EXT_COLORS(stmt) /* nothing */
+#define SetPair(value,p) RemAttr(value, A_COLOR), \
+ SetAttr(value, AttrOf(value) | (A_COLOR & COLOR_PAIR(p)))
+#define GetPair(value) PAIR_NUMBER(AttrOf(value))
+#define unColor(n) (AttrOf(n) & ALL_BUT_COLOR)
+#define GET_WINDOW_PAIR(w) PAIR_NUMBER(WINDOW_ATTRS(w))
+#define SET_WINDOW_PAIR(w,p) WINDOW_ATTRS(w) &= ALL_BUT_COLOR, \
+ WINDOW_ATTRS(w) |= (A_COLOR & COLOR_PAIR(p))
+#define SameAttrOf(a,b) (AttrOf(a) == AttrOf(b))
+#define VIDATTR(attr, pair) vidattr(attr)
+#endif
+
+#define WINDOW_ATTRS(w) ((w)->_attrs)
+
+#define SCREEN_ATTRS(s) (*((s)->_current_attr))
+#define GET_SCREEN_PAIR(s) GetPair(SCREEN_ATTRS(s))
+#define SET_SCREEN_PAIR(s,p) SetPair(SCREEN_ATTRS(s), p)
+
+/*
+ * Definitions for color pairs
+ */
+typedef unsigned colorpair_t; /* type big enough to store PAIR_OF() */
+#define C_SHIFT 9 /* we need more bits than there are colors */
+#define C_MASK ((1 << C_SHIFT) - 1)
+#define PAIR_OF(fg, bg) ((((fg) & C_MASK) << C_SHIFT) | ((bg) & C_MASK))
+#define isDefaultColor(c) ((c) >= COLOR_DEFAULT || (c) < 0)
+
+#define COLOR_DEFAULT C_MASK
+
+#if defined(USE_TERMLIB) && !defined(NEED_NCURSES_CH_T)
+
+#undef NCURSES_CH_T /* this is not a termlib feature */
+#define NCURSES_CH_T void /* ...but we need a pointer in SCREEN */
+
+#endif /* USE_TERMLIB */
+
+#ifndef USE_TERMLIB
+struct ldat
+{
+ NCURSES_CH_T *text; /* text of the line */
+ NCURSES_SIZE_T firstchar; /* first changed character in the line */
+ NCURSES_SIZE_T lastchar; /* last changed character in the line */
+ NCURSES_SIZE_T oldindex; /* index of the line at last update */
+};
+#endif /* USE_TERMLIB */
+
+typedef enum {
+ M_XTERM = -1 /* use xterm's mouse tracking? */
+ ,M_NONE = 0 /* no mouse device */
+#if USE_GPM_SUPPORT
+ ,M_GPM /* use GPM */
+#endif
+#if USE_SYSMOUSE
+ ,M_SYSMOUSE /* FreeBSD sysmouse on console */
+#endif
+} MouseType;
+
+/*
+ * Structures for scrolling.
+ */
+
+typedef struct {
+ unsigned long hashval;
+ int oldcount, newcount;
+ int oldindex, newindex;
+} HASHMAP;
+
+/*
+ * Structures for soft labels.
+ */
+
+struct _SLK;
+
+#ifndef USE_TERMLIB
+
+typedef struct
+{
+ char *ent_text; /* text for the label */
+ char *form_text; /* formatted text (left/center/...) */
+ int ent_x; /* x coordinate of this field */
+ char dirty; /* this label has changed */
+ char visible; /* field is visible */
+} slk_ent;
+
+typedef struct _SLK {
+ char dirty; /* all labels have changed */
+ char hidden; /* soft labels are hidden */
+ WINDOW *win;
+ slk_ent *ent;
+ short maxlab; /* number of available labels */
+ short labcnt; /* number of allocated labels */
+ short maxlen; /* length of labels */
+ NCURSES_CH_T attr; /* soft label attribute */
+} SLK;
+
+#endif /* USE_TERMLIB */
+
+typedef struct {
+ int line; /* lines to take, < 0 => from bottom*/
+ int (*hook)(WINDOW *, int); /* callback for user */
+ WINDOW *w; /* maybe we need this for cleanup */
+} ripoff_t;
+
+#if USE_GPM_SUPPORT
+#undef buttons /* term.h defines this, and gpm uses it! */
+#include <gpm.h>
+
+#ifdef HAVE_LIBDL
+/* link dynamically to GPM */
+typedef int *TYPE_gpm_fd;
+typedef int (*TYPE_Gpm_Open) (Gpm_Connect *, int);
+typedef int (*TYPE_Gpm_Close) (void);
+typedef int (*TYPE_Gpm_GetEvent) (Gpm_Event *);
+
+#define my_gpm_fd SP->_mouse_gpm_fd
+#define my_Gpm_Open SP->_mouse_Gpm_Open
+#define my_Gpm_Close SP->_mouse_Gpm_Close
+#define my_Gpm_GetEvent SP->_mouse_Gpm_GetEvent
+#else
+/* link statically to GPM */
+#define my_gpm_fd &gpm_fd
+#define my_Gpm_Open Gpm_Open
+#define my_Gpm_Close Gpm_Close
+#define my_Gpm_GetEvent Gpm_GetEvent
+#endif /* HAVE_LIBDL */
+#endif /* USE_GPM_SUPPORT */
+
+/*
+ * The SCREEN structure.
+ */
+
+struct screen {
+ int _ifd; /* input file ptr for screen */
+ FILE *_ofp; /* output file ptr for screen */
+ char *_setbuf; /* buffered I/O for output */
+ bool _filtered; /* filter() was called */
+ bool _buffered; /* setvbuf uses _setbuf data */
+ int _checkfd; /* filedesc for typeahead check */
+ //// TERMINAL *_term; /* terminal type information */
+ short _lines; /* screen lines */
+ short _columns; /* screen columns */
+
+ short _lines_avail; /* lines available for stdscr */
+ short _topstolen; /* lines stolen from top */
+ ripoff_t _rippedoff[5]; /* list of lines stolen */
+ int _rip_count; /* ...and total lines stolen */
+
+ WINDOW *_curscr; /* current screen */
+ WINDOW *_newscr; /* virtual screen to be updated to */
+ WINDOW *_stdscr; /* screen's full-window context */
+
+ struct tries *_keytry; /* "Try" for use with keypad mode */
+ struct tries *_key_ok; /* Disabled keys via keyok(,FALSE) */
+ bool _tried; /* keypad mode was initialized */
+ bool _keypad_on; /* keypad mode is currently on */
+
+ bool _called_wgetch; /* check for recursion in wgetch() */
+ int _fifo[FIFO_SIZE]; /* input push-back buffer */
+ short _fifohead, /* head of fifo queue */
+ _fifotail, /* tail of fifo queue */
+ _fifopeek, /* where to peek for next char */
+ _fifohold; /* set if breakout marked */
+
+ int _endwin; /* are we out of window mode? */
+ NCURSES_CH_T *_current_attr; /* holds current attributes set */
+ int _coloron; /* is color enabled? */
+ int _color_defs; /* are colors modified */
+ int _cursor; /* visibility of the cursor */
+ int _cursrow; /* physical cursor row */
+ int _curscol; /* physical cursor column */
+ bool _notty; /* true if we cannot switch non-tty */
+ int _nl; /* True if NL -> CR/NL is on */
+ int _raw; /* True if in raw mode */
+ int _cbreak; /* 1 if in cbreak mode */
+ /* > 1 if in halfdelay mode */
+ int _echo; /* True if echo on */
+ int _use_meta; /* use the meta key? */
+ struct _SLK *_slk; /* ptr to soft key struct / NULL */
+ int slk_format; /* selected format for this screen */
+ /* cursor movement costs; units are 10ths of milliseconds */
+#if NCURSES_NO_PADDING
+ int _no_padding; /* flag to set if padding disabled */
+#endif
+ int _char_padding; /* cost of character put */
+ int _cr_cost; /* cost of (carriage_return) */
+ int _cup_cost; /* cost of (cursor_address) */
+ int _home_cost; /* cost of (cursor_home) */
+ int _ll_cost; /* cost of (cursor_to_ll) */
+#if USE_HARD_TABS
+ int _ht_cost; /* cost of (tab) */
+ int _cbt_cost; /* cost of (backtab) */
+#endif /* USE_HARD_TABS */
+ int _cub1_cost; /* cost of (cursor_left) */
+ int _cuf1_cost; /* cost of (cursor_right) */
+ int _cud1_cost; /* cost of (cursor_down) */
+ int _cuu1_cost; /* cost of (cursor_up) */
+ int _cub_cost; /* cost of (parm_cursor_left) */
+ int _cuf_cost; /* cost of (parm_cursor_right) */
+ int _cud_cost; /* cost of (parm_cursor_down) */
+ int _cuu_cost; /* cost of (parm_cursor_up) */
+ int _hpa_cost; /* cost of (column_address) */
+ int _vpa_cost; /* cost of (row_address) */
+ /* used in tty_update.c, must be chars */
+ int _ed_cost; /* cost of (clr_eos) */
+ int _el_cost; /* cost of (clr_eol) */
+ int _el1_cost; /* cost of (clr_bol) */
+ int _dch1_cost; /* cost of (delete_character) */
+ int _ich1_cost; /* cost of (insert_character) */
+ int _dch_cost; /* cost of (parm_dch) */
+ int _ich_cost; /* cost of (parm_ich) */
+ int _ech_cost; /* cost of (erase_chars) */
+ int _rep_cost; /* cost of (repeat_char) */
+ int _hpa_ch_cost; /* cost of (column_address) */
+ int _cup_ch_cost; /* cost of (cursor_address) */
+ int _cuf_ch_cost; /* cost of (parm_cursor_right) */
+ int _inline_cost; /* cost of inline-move */
+ int _smir_cost; /* cost of (enter_insert_mode) */
+ int _rmir_cost; /* cost of (exit_insert_mode) */
+ int _ip_cost; /* cost of (insert_padding) */
+ /* used in lib_mvcur.c */
+ char * _address_cursor;
+ /* used in tty_update.c */
+ int _scrolling; /* 1 if terminal's smart enough to */
+
+ /* used in lib_color.c */
+ color_t *_color_table; /* screen's color palette */
+ int _color_count; /* count of colors in palette */
+ colorpair_t *_color_pairs; /* screen's color pair list */
+ int _pair_count; /* count of color pairs */
+#if NCURSES_EXT_FUNCS
+ bool _default_color; /* use default colors */
+ bool _has_sgr_39_49; /* has ECMA default color support */
+ int _default_fg; /* assumed default foreground */
+ int _default_bg; /* assumed default background */
+#endif
+ chtype _ok_attributes; /* valid attributes for terminal */
+ chtype _xmc_suppress; /* attributes to suppress if xmc */
+ chtype _xmc_triggers; /* attributes to process if xmc */
+ chtype * _acs_map; /* the real alternate-charset map */
+ bool * _screen_acs_map;
+
+
+ /* used in lib_vidattr.c */
+ bool _use_rmso; /* true if we may use 'rmso' */
+ bool _use_rmul; /* true if we may use 'rmul' */
+
+ /*
+ * These data correspond to the state of the idcok() and idlok()
+ * functions. A caveat is in order here: the XSI and SVr4
+ * documentation specify that these functions apply to the window which
+ * is given as an argument. However, ncurses implements this logic
+ * only for the newscr/curscr update process, _not_ per-window.
+ */
+ bool _nc_sp_idlok;
+ bool _nc_sp_idcok;
+#define _nc_idlok SP->_nc_sp_idlok
+#define _nc_idcok SP->_nc_sp_idcok
+
+#ifdef NCURSES_MOUSE_VERSION
+ /*
+ * These are the data that support the mouse interface.
+ */
+ bool _mouse_initialized;
+ MouseType _mouse_type;
+ int _maxclick;
+ bool (*_mouse_event) (SCREEN *);
+ bool (*_mouse_inline)(SCREEN *);
+ bool (*_mouse_parse) (int);
+ void (*_mouse_resume)(SCREEN *);
+ void (*_mouse_wrap) (SCREEN *);
+ int _mouse_fd; /* file-descriptor, if any */
+ bool _mouse_active; /* true if initialized */
+ mmask_t _mouse_mask;
+ NCURSES_CONST char *_mouse_xtermcap; /* string to enable/disable mouse */
+ MEVENT _mouse_events[EV_MAX]; /* hold the last mouse event seen */
+ MEVENT *_mouse_eventp; /* next free slot in event queue */
+#endif
+
+#if USE_GPM_SUPPORT
+ bool _mouse_gpm_loaded;
+ bool _mouse_gpm_found;
+#ifdef HAVE_LIBDL
+ TYPE_gpm_fd _mouse_gpm_fd;
+ TYPE_Gpm_Open _mouse_Gpm_Open;
+ TYPE_Gpm_Close _mouse_Gpm_Close;
+ TYPE_Gpm_GetEvent _mouse_Gpm_GetEvent;
+#endif
+ Gpm_Connect _mouse_gpm_connect;
+#endif /* USE_GPM_SUPPORT */
+
+#if USE_EMX_MOUSE
+ int _emxmouse_wfd;
+ int _emxmouse_thread;
+ int _emxmouse_activated;
+ char _emxmouse_buttons[4];
+#endif
+
+#if USE_SYSMOUSE
+ MEVENT _sysmouse_fifo[FIFO_SIZE];
+ int _sysmouse_head;
+ int _sysmouse_tail;
+ int _sysmouse_char_width; /* character width */
+ int _sysmouse_char_height; /* character height */
+ int _sysmouse_old_buttons;
+ int _sysmouse_new_buttons;
+#endif
+
+ /*
+ * This supports automatic resizing
+ */
+#if USE_SIZECHANGE
+ int (*_resize)(int,int);
+#endif
+
+ /*
+ * These are data that support the proper handling of the panel stack on an
+ * per screen basis.
+ */
+ //// struct panelhook _panelHook;
+ /*
+ * Linked-list of all windows, to support '_nc_resizeall()' and
+ * '_nc_freeall()'
+ */
+ WINDOWLIST *_nc_sp_windows;
+#define _nc_windows SP->_nc_sp_windows
+
+ bool _sig_winch;
+ SCREEN *_next_screen;
+
+ /* hashes for old and new lines */
+ unsigned long *oldhash, *newhash;
+ HASHMAP *hashtab;
+ int hashtab_len;
+
+ bool _cleanup; /* cleanup after int/quit signal */
+ int (*_outch)(int); /* output handler if not putc */
+
+ int _legacy_coding; /* see use_legacy_coding() */
+
+ /*
+ * ncurses/ncursesw are the same up to this point.
+ */
+#if USE_WIDEC_SUPPORT
+ /* recent versions of 'screen' have partially-working support for
+ * UTF-8, but do not permit ACS at the same time (see tty_update.c).
+ */
+ bool _screen_acs_fix;
+#endif
+};
+
+extern NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain;
+
+ WINDOWLIST {
+ WINDOW win; /* first, so WINDOW_EXT() works */
+ WINDOWLIST *next;
+#ifdef _XOPEN_SOURCE_EXTENDED
+ char addch_work[(MB_LEN_MAX * 9) + 1];
+ unsigned addch_used; /* number of bytes in addch_work[] */
+ int addch_x; /* x-position for addch_work[] */
+ int addch_y; /* y-position for addch_work[] */
+#endif
+};
+
+#define WINDOW_EXT(win,field) (((WINDOWLIST *)(win))->field)
+
+/* usually in <limits.h> */
+#ifndef UCHAR_MAX
+#define UCHAR_MAX 255
+#endif
+
+/* The terminfo source is assumed to be 7-bit ASCII */
+#define is7bits(c) ((unsigned)(c) < 128)
+
+/* Checks for isprint() should be done on 8-bit characters (non-wide) */
+#define is8bits(c) ((unsigned)(c) <= UCHAR_MAX)
+
+#ifndef min
+#define min(a,b) ((a) > (b) ? (b) : (a))
+#endif
+
+#ifndef max
+#define max(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+/* usually in <unistd.h> */
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+#ifndef R_OK
+#define R_OK 4 /* Test for read permission. */
+#endif
+#ifndef W_OK
+#define W_OK 2 /* Test for write permission. */
+#endif
+#ifndef X_OK
+#define X_OK 1 /* Test for execute permission. */
+#endif
+#ifndef F_OK
+#define F_OK 0 /* Test for existence. */
+#endif
+
+#if HAVE_FCNTL_H
+//// #include <fcntl.h> /* may define O_BINARY */
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifdef TRACE
+#define TRACE_OUTCHARS(n) _nc_outchars += (n);
+#else
+#define TRACE_OUTCHARS(n) /* nothing */
+#endif
+
+#define UChar(c) ((unsigned char)(c))
+#define ChCharOf(c) ((c) & (chtype)A_CHARTEXT)
+#define ChAttrOf(c) ((c) & (chtype)A_ATTRIBUTES)
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 8 /* should be >= MB_CUR_MAX, but that may be a function */
+#endif
+
+#if USE_WIDEC_SUPPORT /* { */
+#define isEILSEQ(status) ((status == (size_t)-1) && (errno == EILSEQ))
+
+#define init_mb(state) memset(&state, 0, sizeof(state))
+
+#if NCURSES_EXT_COLORS
+#define NulColor , 0
+#else
+#define NulColor /* nothing */
+#endif
+
+#define NulChar 0,0,0,0 /* FIXME: see CCHARW_MAX */
+#define CharOf(c) ((c).chars[0])
+#define AttrOf(c) ((c).attr)
+#define AddAttr(c,a) AttrOf(c) |= ((a) & A_ATTRIBUTES)
+#define RemAttr(c,a) AttrOf(c) &= ~((a) & A_ATTRIBUTES)
+#define SetAttr(c,a) AttrOf(c) = ((a) & A_ATTRIBUTES)
+#define NewChar2(c,a) { a, { c, NulChar } NulColor }
+#define NewChar(ch) NewChar2(ChCharOf(ch), ChAttrOf(ch))
+#define CharEq(a,b) (!memcmp(&(a), &(b), sizeof(a)))
+#define SetChar(ch,c,a) do { \
+ NCURSES_CH_T *_cp = &ch; \
+ memset(_cp, 0, sizeof(ch)); \
+ _cp->chars[0] = (c); \
+ _cp->attr = (a); \
+ if_EXT_COLORS(SetPair(ch, PAIR_NUMBER(a))); \
+ } while (0)
+#define CHREF(wch) (&wch)
+#define CHDEREF(wch) (*wch)
+#define ARG_CH_T NCURSES_CH_T *
+#define CARG_CH_T const NCURSES_CH_T *
+#define PUTC_DATA char PUTC_buf[MB_LEN_MAX]; int PUTC_i, PUTC_n; \
+ mbstate_t PUT_st; wchar_t PUTC_ch
+#define PUTC_INIT init_mb (PUT_st)
+#define PUTC(ch,b) do { if(!isWidecExt(ch)) { \
+ if (Charable(ch)) { \
+ fputc(CharOf(ch), b); \
+ TRACE_OUTCHARS(1); \
+ } else { \
+ PUTC_INIT; \
+ for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { \
+ PUTC_ch = (ch).chars[PUTC_i]; \
+ if (PUTC_ch == L'\0') \
+ break; \
+ PUTC_n = wcrtomb(PUTC_buf, \
+ (ch).chars[PUTC_i], &PUT_st); \
+ if (PUTC_n <= 0) { \
+ if (PUTC_ch && is8bits(PUTC_ch) && PUTC_i == 0) \
+ putc(PUTC_ch,b); \
+ break; \
+ } \
+ fwrite(PUTC_buf, (unsigned) PUTC_n, 1, b); \
+ } \
+ TRACE_OUTCHARS(PUTC_i); \
+ } } } while (0)
+
+#define BLANK { WA_NORMAL, {' '} NulColor }
+#define ZEROS { WA_NORMAL, {'\0'} NulColor }
+#define ISBLANK(ch) ((ch).chars[0] == L' ' && (ch).chars[1] == L'\0')
+
+ /*
+ * Wide characters cannot be represented in the A_CHARTEXT mask of
+ * attr_t's but an application might have set a narrow character there.
+ * But even in that case, it would only be a printable character, or
+ * zero. Otherwise we can use those bits to tell if a cell is the
+ * first or extension part of a wide character.
+ */
+#define WidecExt(ch) (AttrOf(ch) & A_CHARTEXT)
+#define isWidecBase(ch) (WidecExt(ch) == 1)
+#define isWidecExt(ch) (WidecExt(ch) > 1 && WidecExt(ch) < 32)
+#define SetWidecExt(dst, ext) AttrOf(dst) &= ~A_CHARTEXT, \
+ AttrOf(dst) |= (ext + 1)
+
+#define if_WIDEC(code) code
+#define Charable(ch) ((SP != 0 && SP->_legacy_coding) \
+ || (AttrOf(ch) & A_ALTCHARSET) \
+ || (!isWidecExt(ch) && \
+ (ch).chars[1] == L'\0' && \
+ _nc_is_charable(CharOf(ch))))
+
+#define L(ch) L ## ch
+#else /* }{ */
+#define CharOf(c) ChCharOf(c)
+#define AttrOf(c) ChAttrOf(c)
+#define AddAttr(c,a) c |= (a)
+#define RemAttr(c,a) c &= ~((a) & A_ATTRIBUTES)
+#define SetAttr(c,a) c = ((c) & ~A_ATTRIBUTES) | (a)
+#define NewChar(ch) (ch)
+#define NewChar2(c,a) ((c) | (a))
+#define CharEq(a,b) ((a) == (b))
+#define SetChar(ch,c,a) ch = (c) | (a)
+#define CHREF(wch) wch
+#define CHDEREF(wch) wch
+#define ARG_CH_T NCURSES_CH_T
+#define CARG_CH_T NCURSES_CH_T
+#define PUTC_DATA int data = 0
+#define PUTC(ch,b) do { data = CharOf(ch); putc(data,b); } while (0)
+
+#define BLANK (' '|A_NORMAL)
+#define ZEROS ('\0'|A_NORMAL)
+#define ISBLANK(ch) (CharOf(ch) == ' ')
+
+#define isWidecExt(ch) (0)
+#define if_WIDEC(code) /* nothing */
+
+#define L(ch) ch
+#endif /* } */
+
+#define AttrOfD(ch) AttrOf(CHDEREF(ch))
+#define CharOfD(ch) CharOf(CHDEREF(ch))
+#define SetChar2(wch,ch) SetChar(wch,ChCharOf(ch),ChAttrOf(ch))
+
+#define BLANK_ATTR A_NORMAL
+#define BLANK_TEXT L(' ')
+
+#define CHANGED -1
+
+#define LEGALYX(w, y, x) \
+ ((w) != 0 && \
+ ((x) >= 0 && (x) <= (w)->_maxx && \
+ (y) >= 0 && (y) <= (w)->_maxy))
+
+#define CHANGED_CELL(line,col) \
+ if (line->firstchar == _NOCHANGE) \
+ line->firstchar = line->lastchar = col; \
+ else if ((col) < line->firstchar) \
+ line->firstchar = col; \
+ else if ((col) > line->lastchar) \
+ line->lastchar = col
+
+#define CHANGED_RANGE(line,start,end) \
+ if (line->firstchar == _NOCHANGE \
+ || line->firstchar > (start)) \
+ line->firstchar = start; \
+ if (line->lastchar == _NOCHANGE \
+ || line->lastchar < (end)) \
+ line->lastchar = end
+
+#define CHANGED_TO_EOL(line,start,end) \
+ if (line->firstchar == _NOCHANGE \
+ || line->firstchar > (start)) \
+ line->firstchar = start; \
+ line->lastchar = end
+
+#define SIZEOF(v) (sizeof(v)/sizeof(v[0]))
+
+#define FreeIfNeeded(p) if ((p) != 0) free(p)
+
+/* FreeAndNull() is not a comma-separated expression because some compilers
+ * do not accept a mixture of void with values.
+ */
+#define FreeAndNull(p) free(p); p = 0
+
+//// #include <nc_alloc.h>
+
+/*
+ * TTY bit definition for converting tabs to spaces.
+ */
+#ifdef TAB3
+# define OFLAGS_TABS TAB3 /* POSIX specifies TAB3 */
+#else
+# ifdef XTABS
+# define OFLAGS_TABS XTABS /* XTABS is usually the "same" */
+# else
+# ifdef OXTABS
+# define OFLAGS_TABS OXTABS /* the traditional BSD equivalent */
+# else
+# define OFLAGS_TABS 0
+# endif
+# endif
+#endif
+
+/*
+ * Prefixes for call/return points of library function traces. We use these to
+ * instrument the public functions so that the traces can be easily transformed
+ * into regression scripts.
+ */
+#define T_CALLED(fmt) "called {" fmt
+#define T_CREATE(fmt) "create :" fmt
+#define T_RETURN(fmt) "return }" fmt
+
+#ifdef TRACE
+
+#define START_TRACE() \
+ if ((_nc_tracing & TRACE_MAXIMUM) == 0) { \
+ int t = _nc_getenv_num("NCURSES_TRACE"); \
+ if (t >= 0) \
+ trace((unsigned) t); \
+ }
+
+#define TR(n, a) if (_nc_tracing & (n)) _tracef a
+#define T(a) TR(TRACE_CALLS, a)
+#define TPUTS_TRACE(s) _nc_tputs_trace = s;
+#define TRACE_RETURN(value,type) return _nc_retrace_##type(value)
+
+#define returnAttr(code) TRACE_RETURN(code,attr_t)
+#define returnBits(code) TRACE_RETURN(code,unsigned)
+#define returnBool(code) TRACE_RETURN(code,bool)
+#define returnCPtr(code) TRACE_RETURN(code,cptr)
+#define returnCVoidPtr(code) TRACE_RETURN(code,cvoid_ptr)
+#define returnChar(code) TRACE_RETURN(code,chtype)
+#define returnCode(code) TRACE_RETURN(code,int)
+#define returnPtr(code) TRACE_RETURN(code,ptr)
+#define returnSP(code) TRACE_RETURN(code,sp)
+#define returnVoid T((T_RETURN(""))); return
+#define returnVoidPtr(code) TRACE_RETURN(code,void_ptr)
+#define returnWin(code) TRACE_RETURN(code,win)
+
+extern NCURSES_EXPORT(NCURSES_BOOL) _nc_retrace_bool (NCURSES_BOOL);
+extern NCURSES_EXPORT(NCURSES_CONST void *) _nc_retrace_cvoid_ptr (NCURSES_CONST void *);
+extern NCURSES_EXPORT(SCREEN *) _nc_retrace_sp (SCREEN *);
+extern NCURSES_EXPORT(WINDOW *) _nc_retrace_win (WINDOW *);
+extern NCURSES_EXPORT(attr_t) _nc_retrace_attr_t (attr_t);
+extern NCURSES_EXPORT(char *) _nc_retrace_ptr (char *);
+extern NCURSES_EXPORT(char *) _nc_trace_ttymode(TTY *tty);
+extern NCURSES_EXPORT(char *) _nc_varargs (const char *, va_list);
+extern NCURSES_EXPORT(chtype) _nc_retrace_chtype (chtype);
+extern NCURSES_EXPORT(const char *) _nc_altcharset_name(attr_t, chtype);
+extern NCURSES_EXPORT(const char *) _nc_retrace_cptr (const char *);
+extern NCURSES_EXPORT(int) _nc_retrace_int (int);
+extern NCURSES_EXPORT(unsigned) _nc_retrace_unsigned (unsigned);
+extern NCURSES_EXPORT(void *) _nc_retrace_void_ptr (void *);
+extern NCURSES_EXPORT(void) _nc_fifo_dump (void);
+extern NCURSES_EXPORT_VAR(const char *) _nc_tputs_trace;
+extern NCURSES_EXPORT_VAR(long) _nc_outchars;
+extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing;
+
+#if USE_WIDEC_SUPPORT
+extern NCURSES_EXPORT(const char *) _nc_viswbuf2 (int, const wchar_t *);
+extern NCURSES_EXPORT(const char *) _nc_viswbufn (const wchar_t *, int);
+#endif
+
+extern NCURSES_EXPORT(const char *) _nc_viscbuf2 (int, const NCURSES_CH_T *, int);
+extern NCURSES_EXPORT(const char *) _nc_viscbuf (const NCURSES_CH_T *, int);
+
+#else /* !TRACE */
+
+#define START_TRACE() /* nothing */
+
+#define T(a)
+#define TR(n, a)
+#define TPUTS_TRACE(s)
+
+#define returnAttr(code) return code
+#define returnBits(code) return code
+#define returnBool(code) return code
+#define returnCPtr(code) return code
+#define returnCVoidPtr(code) return code
+#define returnChar(code) return code
+#define returnCode(code) return code
+#define returnPtr(code) return code
+#define returnSP(code) return code
+#define returnVoid return
+#define returnVoidPtr(code) return code
+#define returnWin(code) return code
+
+#endif /* TRACE/!TRACE */
+
+/*
+ * Return-codes for tgetent() and friends.
+ */
+#define TGETENT_YES 1 /* entry is found */
+#define TGETENT_NO 0 /* entry is not found */
+#define TGETENT_ERR -1 /* an error occurred */
+
+extern NCURSES_EXPORT(const char *) _nc_visbuf2 (int, const char *);
+extern NCURSES_EXPORT(const char *) _nc_visbufn (const char *, int);
+
+#define empty_module(name) \
+extern NCURSES_EXPORT(void) name (void); \
+ NCURSES_EXPORT(void) name (void) { }
+
+#define ALL_BUT_COLOR ((chtype)~(A_COLOR))
+#define NONBLANK_ATTR (A_NORMAL|A_BOLD|A_DIM|A_BLINK)
+#define XMC_CHANGES(c) ((c) & SP->_xmc_suppress)
+
+#define toggle_attr_on(S,at) {\
+ if (PAIR_NUMBER(at) > 0) {\
+ (S) = ((S) & ALL_BUT_COLOR) | (at);\
+ } else {\
+ (S) |= (at);\
+ }\
+ TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));}
+
+
+#define toggle_attr_off(S,at) {\
+ if (PAIR_NUMBER(at) > 0) {\
+ (S) &= ~(at|A_COLOR);\
+ } else {\
+ (S) &= ~(at);\
+ }\
+ TR(TRACE_ATTRS, ("new attribute is %s", _traceattr((S))));}
+
+#define DelCharCost(count) \
+ ((parm_dch != 0) \
+ ? SP->_dch_cost \
+ : ((delete_character != 0) \
+ ? (SP->_dch1_cost * count) \
+ : INFINITY))
+
+#define InsCharCost(count) \
+ ((parm_ich != 0) \
+ ? SP->_ich_cost \
+ : ((enter_insert_mode && exit_insert_mode) \
+ ? SP->_smir_cost + SP->_rmir_cost + (SP->_ip_cost * count) \
+ : ((insert_character != 0) \
+ ? ((SP->_ich1_cost + SP->_ip_cost) * count) \
+ : INFINITY)))
+
+#if USE_XMC_SUPPORT
+#define UpdateAttrs(c) if (!SameAttrOf(SCREEN_ATTRS(SP), c)) { \
+ attr_t chg = AttrOf(SCREEN_ATTRS(SP)); \
+ VIDATTR(AttrOf(c), GetPair(c)); \
+ if (magic_cookie_glitch > 0 \
+ && XMC_CHANGES((chg ^ AttrOf(SCREEN_ATTRS(SP))))) { \
+ T(("%s @%d before glitch %d,%d", \
+ __FILE__, __LINE__, \
+ SP->_cursrow, \
+ SP->_curscol)); \
+ _nc_do_xmc_glitch(chg); \
+ } \
+ }
+#else
+#define UpdateAttrs(c) if (!SameAttrOf(SCREEN_ATTRS(SP), c)) \
+ VIDATTR(AttrOf(c), GetPair(c));
+#endif
+
+/*
+ * Macros to make additional parameter to implement wgetch_events()
+ */
+#ifdef NCURSES_WGETCH_EVENTS
+#define EVENTLIST_0th(param) param
+#define EVENTLIST_1st(param) param
+#define EVENTLIST_2nd(param) , param
+#else
+#define EVENTLIST_0th(param) void
+#define EVENTLIST_1st(param) /* nothing */
+#define EVENTLIST_2nd(param) /* nothing */
+#endif
+
+#if NCURSES_EXPANDED && NCURSES_EXT_FUNCS
+
+#undef toggle_attr_on
+#define toggle_attr_on(S,at) _nc_toggle_attr_on(&(S), at)
+extern NCURSES_EXPORT(void) _nc_toggle_attr_on (attr_t *, attr_t);
+
+#undef toggle_attr_off
+#define toggle_attr_off(S,at) _nc_toggle_attr_off(&(S), at)
+extern NCURSES_EXPORT(void) _nc_toggle_attr_off (attr_t *, attr_t);
+
+#undef DelCharCost
+#define DelCharCost(count) _nc_DelCharCost(count)
+extern NCURSES_EXPORT(int) _nc_DelCharCost (int);
+
+#undef InsCharCost
+#define InsCharCost(count) _nc_InsCharCost(count)
+extern NCURSES_EXPORT(int) _nc_InsCharCost (int);
+
+#undef UpdateAttrs
+#define UpdateAttrs(c) _nc_UpdateAttrs(c)
+extern NCURSES_EXPORT(void) _nc_UpdateAttrs (NCURSES_CH_T);
+
+#else
+
+extern NCURSES_EXPORT(void) _nc_expanded (void);
+
+#endif
+
+#if !HAVE_GETCWD
+#define getcwd(buf,len) getwd(buf)
+#endif
+
+/* charable.c */
+#if USE_WIDEC_SUPPORT
+extern NCURSES_EXPORT(bool) _nc_is_charable(wchar_t);
+extern NCURSES_EXPORT(int) _nc_to_char(wint_t);
+extern NCURSES_EXPORT(wint_t) _nc_to_widechar(int);
+#endif
+
+/* doupdate.c */
+#if USE_XMC_SUPPORT
+extern NCURSES_EXPORT(void) _nc_do_xmc_glitch (attr_t);
+#endif
+
+/* hardscroll.c */
+#if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG)
+extern NCURSES_EXPORT(void) _nc_linedump (void);
+#endif
+
+/* lib_acs.c */
+extern NCURSES_EXPORT(void) _nc_init_acs (void); /* corresponds to traditional 'init_acs()' */
+extern NCURSES_EXPORT(int) _nc_msec_cost (const char *const, int); /* used by 'tack' program */
+
+/* lib_addch.c */
+#if USE_WIDEC_SUPPORT
+NCURSES_EXPORT(int) _nc_build_wch(WINDOW *win, ARG_CH_T ch);
+#endif
+
+/* lib_addstr.c */
+#if USE_WIDEC_SUPPORT && !defined(USE_TERMLIB)
+extern NCURSES_EXPORT(int) _nc_wchstrlen(const cchar_t *);
+#endif
+
+/* lib_color.c */
+extern NCURSES_EXPORT(bool) _nc_reset_colors(void);
+
+/* lib_getch.c */
+extern NCURSES_EXPORT(int) _nc_wgetch(WINDOW *, unsigned long *, int EVENTLIST_2nd(_nc_eventlist *));
+
+/* lib_insch.c */
+extern NCURSES_EXPORT(int) _nc_insert_ch(WINDOW *, chtype);
+
+/* lib_mvcur.c */
+#define INFINITY 1000000 /* cost: too high to use */
+
+extern NCURSES_EXPORT(void) _nc_mvcur_init (void);
+extern NCURSES_EXPORT(void) _nc_mvcur_resume (void);
+extern NCURSES_EXPORT(void) _nc_mvcur_wrap (void);
+
+extern NCURSES_EXPORT(int) _nc_scrolln (int, int, int, int);
+
+extern NCURSES_EXPORT(void) _nc_screen_init (void);
+extern NCURSES_EXPORT(void) _nc_screen_resume (void);
+extern NCURSES_EXPORT(void) _nc_screen_wrap (void);
+
+/* lib_mouse.c */
+extern NCURSES_EXPORT(int) _nc_has_mouse (void);
+
+/* lib_mvcur.c */
+#define INFINITY 1000000 /* cost: too high to use */
+#define BAUDBYTE 9 /* 9 = 7 bits + 1 parity + 1 stop */
+
+/* lib_setup.c */
+extern NCURSES_EXPORT(char *) _nc_get_locale(void);
+extern NCURSES_EXPORT(int) _nc_unicode_locale(void);
+extern NCURSES_EXPORT(int) _nc_locale_breaks_acs(void);
+extern NCURSES_EXPORT(int) _nc_setupterm(NCURSES_CONST char *, int, int *, bool);
+
+/* lib_tstp.c */
+#if USE_SIGWINCH
+extern NCURSES_EXPORT(int) _nc_handle_sigwinch(int);
+#else
+#define _nc_handle_sigwinch(a) /* nothing */
+#endif
+
+/* lib_wacs.c */
+#if USE_WIDEC_SUPPORT
+extern NCURSES_EXPORT(void) _nc_init_wacs(void);
+#endif
+
+typedef struct {
+ char *s_head; /* beginning of the string (may be null) */
+ char *s_tail; /* end of the string (may be null) */
+ size_t s_size; /* current remaining size available */
+ size_t s_init; /* total size available */
+} string_desc;
+
+/* strings.c */
+extern NCURSES_EXPORT(string_desc *) _nc_str_init (string_desc *, char *, size_t);
+extern NCURSES_EXPORT(string_desc *) _nc_str_null (string_desc *, size_t);
+extern NCURSES_EXPORT(string_desc *) _nc_str_copy (string_desc *, string_desc *);
+extern NCURSES_EXPORT(bool) _nc_safe_strcat (string_desc *, const char *);
+extern NCURSES_EXPORT(bool) _nc_safe_strcpy (string_desc *, const char *);
+
+#if !HAVE_STRSTR
+#define strstr _nc_strstr
+extern NCURSES_EXPORT(char *) _nc_strstr (const char *, const char *);
+#endif
+
+/* safe_sprintf.c */
+extern NCURSES_EXPORT(char *) _nc_printf_string (const char *, va_list);
+
+/* tries.c */
+extern NCURSES_EXPORT(void) _nc_add_to_try (struct tries **, const char *, unsigned);
+extern NCURSES_EXPORT(char *) _nc_expand_try (struct tries *, unsigned, int *, size_t);
+extern NCURSES_EXPORT(int) _nc_remove_key (struct tries **, unsigned);
+extern NCURSES_EXPORT(int) _nc_remove_string (struct tries **, const char *);
+
+/* elsewhere ... */
+//// extern NCURSES_EXPORT(ENTRY *) _nc_delink_entry(ENTRY *, TERMTYPE *);
+extern NCURSES_EXPORT(WINDOW *) _nc_makenew (int, int, int, int, int);
+extern NCURSES_EXPORT(char *) _nc_trace_buf (int, size_t);
+extern NCURSES_EXPORT(char *) _nc_trace_bufcat (int, const char *);
+extern NCURSES_EXPORT(int) _nc_access (const char *, int);
+extern NCURSES_EXPORT(int) _nc_baudrate (int);
+extern NCURSES_EXPORT(int) _nc_freewin (WINDOW *);
+extern NCURSES_EXPORT(int) _nc_getenv_num (const char *);
+extern NCURSES_EXPORT(int) _nc_keypad (bool);
+extern NCURSES_EXPORT(int) _nc_ospeed (int);
+extern NCURSES_EXPORT(int) _nc_outch (int);
+//// extern NCURSES_EXPORT(int) _nc_read_termcap_entry (const char *const, TERMTYPE *const);
+extern NCURSES_EXPORT(int) _nc_setupscreen (int, int, FILE *, bool, int);
+extern NCURSES_EXPORT(int) _nc_timed_wait(int, int, int * EVENTLIST_2nd(_nc_eventlist *));
+extern NCURSES_EXPORT(void) _nc_do_color (short, short, bool, int (*)(int));
+extern NCURSES_EXPORT(void) _nc_flush (void);
+//// extern NCURSES_EXPORT(void) _nc_free_entry(ENTRY *, TERMTYPE *);
+extern NCURSES_EXPORT(void) _nc_freeall (void);
+extern NCURSES_EXPORT(void) _nc_hash_map (void);
+extern NCURSES_EXPORT(void) _nc_init_keytry (void);
+extern NCURSES_EXPORT(void) _nc_keep_tic_dir (const char *);
+extern NCURSES_EXPORT(void) _nc_make_oldhash (int i);
+extern NCURSES_EXPORT(void) _nc_scroll_oldhash (int n, int top, int bot);
+extern NCURSES_EXPORT(void) _nc_scroll_optimize (void);
+extern NCURSES_EXPORT(void) _nc_set_buffer (FILE *, bool);
+extern NCURSES_EXPORT(void) _nc_signal_handler (bool);
+extern NCURSES_EXPORT(void) _nc_synchook (WINDOW *);
+extern NCURSES_EXPORT(void) _nc_trace_tries (struct tries *);
+
+#if NO_LEAKS
+extern NCURSES_EXPORT(void) _nc_alloc_entry_leaks(void);
+extern NCURSES_EXPORT(void) _nc_captoinfo_leaks(void);
+extern NCURSES_EXPORT(void) _nc_comp_scan_leaks(void);
+extern NCURSES_EXPORT(void) _nc_keyname_leaks(void);
+extern NCURSES_EXPORT(void) _nc_tgetent_leaks(void);
+#endif
+
+#ifndef USE_TERMLIB
+extern NCURSES_EXPORT(NCURSES_CH_T) _nc_render (WINDOW *, NCURSES_CH_T);
+extern NCURSES_EXPORT(int) _nc_waddch_nosync (WINDOW *, const NCURSES_CH_T);
+extern NCURSES_EXPORT(void) _nc_scroll_window (WINDOW *, int const, NCURSES_SIZE_T const, NCURSES_SIZE_T const, NCURSES_CH_T);
+#endif
+
+#if USE_WIDEC_SUPPORT && !defined(USE_TERMLIB)
+#ifdef linux
+extern NCURSES_EXPORT(size_t) _nc_wcrtomb (char *, wchar_t, mbstate_t *);
+#else
+#define _nc_wcrtomb(s,wc,ps) wcrtomb(s,wc,ps)
+#endif
+#endif
+
+#if USE_SIZECHANGE
+extern NCURSES_EXPORT(void) _nc_update_screensize (void);
+#endif
+
+#if HAVE_RESIZETERM
+extern NCURSES_EXPORT(void) _nc_resize_margins (WINDOW *);
+#else
+#define _nc_resize_margins(wp) /* nothing */
+#endif
+
+#ifdef NCURSES_WGETCH_EVENTS
+extern NCURSES_EXPORT(int) _nc_eventlist_timeout(_nc_eventlist *);
+#else
+#define wgetch_events(win, evl) wgetch(win)
+#define wgetnstr_events(win, str, maxlen, evl) wgetnstr(win, str, maxlen)
+#endif
+
+/*
+ * Not everyone has vsscanf(), but we'd like to use it for scanw().
+ */
+#if !HAVE_VSSCANF
+extern int vsscanf(const char *str, const char *format, va_list __arg);
+#endif
+
+/* scroll indices */
+extern NCURSES_EXPORT_VAR(int *) _nc_oldnums;
+
+#define USE_SETBUF_0 0
+
+#define NC_BUFFERED(flag) _nc_set_buffer(SP->_ofp, flag)
+
+#define NC_OUTPUT ((SP != 0) ? SP->_ofp : stdout)
+
+/*
+ * On systems with a broken linker, define 'SP' as a function to force the
+ * linker to pull in the data-only module with 'SP'.
+ */
+#if BROKEN_LINKER
+#define SP _nc_screen()
+extern NCURSES_EXPORT(SCREEN *) _nc_screen (void);
+extern NCURSES_EXPORT(int) _nc_alloc_screen (void);
+extern NCURSES_EXPORT(void) _nc_set_screen (SCREEN *);
+#else
+/* current screen is private data; avoid possible linking conflicts too */
+extern NCURSES_EXPORT_VAR(SCREEN *) SP;
+#define _nc_alloc_screen() ((SP = typeCalloc(SCREEN, 1)) != 0)
+#define _nc_set_screen(sp) SP = sp
+#endif
+
+/*
+ * We don't want to use the lines or columns capabilities internally, because
+ * if the application is running multiple screens under X, it's quite possible
+ * they could all have type xterm but have different sizes! So...
+ */
+#define screen_lines SP->_lines
+#define screen_columns SP->_columns
+
+extern NCURSES_EXPORT_VAR(int) _nc_slk_format; /* != 0 if slk_init() called */
+extern NCURSES_EXPORT(int) _nc_slk_initialize (WINDOW *, int);
+
+/*
+ * Some constants related to SLK's
+ */
+#define MAX_SKEY_OLD 8 /* count of soft keys */
+#define MAX_SKEY_LEN_OLD 8 /* max length of soft key text */
+#define MAX_SKEY_PC 12 /* This is what most PC's have */
+#define MAX_SKEY_LEN_PC 5
+
+/* Macro to check whether or not we use a standard format */
+#define SLK_STDFMT(fmt) (fmt < 3)
+/* Macro to determine height of label window */
+#define SLK_LINES(fmt) (SLK_STDFMT(fmt) ? 1 : ((fmt) - 2))
+
+#define MAX_SKEY(fmt) (SLK_STDFMT(fmt)? MAX_SKEY_OLD : MAX_SKEY_PC)
+#define MAX_SKEY_LEN(fmt) (SLK_STDFMT(fmt)? MAX_SKEY_LEN_OLD : MAX_SKEY_LEN_PC)
+
+extern NCURSES_EXPORT(int) _nc_ripoffline (int line, int (*init)(WINDOW *,int));
+
+/*
+ * Common error messages
+ */
+#define MSG_NO_MEMORY "Out of memory"
+#define MSG_NO_INPUTS "Premature EOF"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CURSES_PRIV_H */
diff --git a/apps/lib/curses/tinycurses/keyboard.c b/apps/lib/curses/tinycurses/keyboard.c
new file mode 100644
index 0000000..2122d86
--- /dev/null
+++ b/apps/lib/curses/tinycurses/keyboard.c
@@ -0,0 +1,247 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This file handles reading keystrokes from serial and the console
+ * and "cooking" them so that they are correct for curses.
+ * Also, implement key related functions (mainly wgetch)
+ *
+ * TODO:
+ * Actually cook the serial (handle special keys)
+ */
+
+#include "local.h"
+#include <unistd.h>
+
+static int _halfdelay = 0;
+
+/* ============== Serial ==================== */
+
+#ifdef CONFIG_SERIAL_CONSOLE
+/* We treat serial like a vt100 terminal. For now we
+ do the cooking in here, but we should probably eventually
+ pass it to dedicated vt100 code */
+
+static int getkeyseq(char *buffer, int len, int max)
+{
+ int i;
+
+ while (1) {
+ for(i = 0; i < 75; i++) {
+ if (tstc())
+ break;
+ usleep(100);
+ }
+
+ if (i == 75)
+ return len;
+
+ buffer[len++] = getchar();
+ if (len == max)
+ return len;
+ }
+}
+
+static struct {
+ const char *seq;
+ int key;
+} escape_codes[] = {
+ { "[A", KEY_UP },
+ { "[B", KEY_DOWN },
+ { "[C", KEY_RIGHT },
+ { "[D", KEY_LEFT },
+ { "[F", KEY_END },
+ { "[H", KEY_HOME },
+ { "[2~", KEY_IC },
+ { "[3~", KEY_DC },
+ { "[5~", KEY_PPAGE },
+ { "[6~", KEY_NPAGE },
+ { "OP", KEY_F(1) },
+ { "OQ", KEY_F(2) },
+ { "OR", KEY_F(3) },
+ { "OS", KEY_F(4) },
+ { "[15~", KEY_F(5) },
+ { "[17~", KEY_F(6) },
+ { "[18~", KEY_F(7) },
+ { "[19~", KEY_F(8) },
+ { "[20~", KEY_F(9) },
+ { "[21~", KEY_F(10) },
+ { "[23~", KEY_F(11) },
+ { "[24~", KEY_F(12) },
+ { NULL },
+};
+
+static int handle_escape(void)
+{
+ char buffer[5];
+ int len = getkeyseq(buffer, 0, sizeof(buffer));
+ int i, t;
+
+ if (len == 0)
+ return 27;
+
+ for(i = 0; escape_codes[i].seq != NULL; i++) {
+ const char *p = escape_codes[i].seq;
+
+ for(t = 0; t < len; t++) {
+ if (!*p || *p != buffer[t])
+ break;
+ p++;
+ }
+
+ if (t == len)
+ return escape_codes[i].key;
+ }
+
+ return 0;
+}
+
+static int cook_serial(unsigned char ch)
+{
+ switch(ch) {
+ case 8:
+ return KEY_BACKSPACE;
+
+ case 13:
+ return KEY_ENTER;
+
+ case 27:
+ return handle_escape();
+
+ default:
+ return ch;
+ }
+}
+#endif
+
+/* ================ Keyboard ================ */
+
+static int curses_getchar(int _delay)
+{
+#if defined(CONFIG_SERIAL_CONSOLE)
+ unsigned short c;
+#endif
+
+ do {
+#ifdef CONFIG_SERIAL_CONSOLE
+ if ((curses_flags & F_ENABLE_SERIAL) &&
+ tstc()) {
+ c = getchar();
+ return cook_serial(c);
+ }
+#endif
+
+ if (_delay == 0)
+ break;
+
+ if (_delay > 0) {
+ usleep(1000);
+ _delay--;
+ }
+
+
+ } while (1);
+
+ return ERR;
+}
+
+/* === Public functions === */
+
+int wgetch(WINDOW *win)
+{
+ int _delay = -1;
+
+ if (_halfdelay)
+ _delay = _halfdelay;
+ else
+ _delay = win->_delay;
+
+ return curses_getchar(_delay);
+}
+
+int nodelay(WINDOW *win, NCURSES_BOOL flag)
+{
+ win->_delay = flag ? 0 : -1;
+ return 0;
+}
+
+int halfdelay(int tenths)
+{
+ if (tenths > 255)
+ return ERR;
+
+ _halfdelay = tenths;
+ return 0;
+}
+
+int nocbreak(void)
+{
+ /* Remove half delay timeout. */
+ _halfdelay = 0;
+ return 0;
+}
+
+#ifdef CONFIG_VGA_VIDEO_CONSOLE
+void curses_enable_vga(int state)
+{
+ if (state)
+ curses_flags |= F_ENABLE_CONSOLE;
+ else
+ curses_flags &= ~F_ENABLE_CONSOLE;
+}
+
+int curses_vga_enabled(void)
+{
+ return (curses_flags & F_ENABLE_CONSOLE) != 0;
+}
+#else
+void curses_enable_vga(int state) { }
+int curses_vga_enabled(void) { return 0; }
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+void curses_enable_serial(int state)
+{
+ if (state)
+ curses_flags |= F_ENABLE_SERIAL;
+ else
+ curses_flags &= ~F_ENABLE_SERIAL;
+}
+
+int curses_serial_enabled(void)
+{
+ return (curses_flags & F_ENABLE_SERIAL) != 0;
+}
+
+#else
+void curses_enable_serial(int state) { }
+int curses_serial_enabled(void) { return 0; }
+#endif
+
diff --git a/apps/lib/curses/tinycurses/local.h b/apps/lib/curses/tinycurses/local.h
new file mode 100644
index 0000000..42ea152
--- /dev/null
+++ b/apps/lib/curses/tinycurses/local.h
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CURSES_LOCAL_H
+#define _CURSES_LOCAL_H
+
+/* For curses.priv.h: */
+#define USE_RCS_IDS 0
+#define DECL_ERRNO 0
+#define HAVE_LIBGPM 0
+#define NCURSES_EXT_FUNCS 0
+#define USE_OK_BCOPY 0
+#define USE_MY_MEMMOVE 0
+#define USE_SCROLL_HINTS 0
+#define USE_HASHMAP 0
+#define USE_WIDEC_SUPPORT 0 /* We do _not_ want wide character support. */
+// #define NCURSES_EXT_COLORS 1
+#define NCURSES_EXT_COLORS 0
+#define USE_SYSMOUSE 0
+#define NCURSES_NO_PADDING 0
+#define USE_HARD_TABS 0
+#define HAVE_FCNTL_H 0
+#define HAVE_LIMITS_H 1
+#define HAVE_UNISTD_H 1
+#define USE_XMC_SUPPORT 0
+#define NCURSES_EXPANDED 0
+#define HAVE_GETCWD 0
+#define USE_XMC_SUPPORT 0
+#define HAVE_STRSTR 1
+#define NO_LEAKS 0
+#define HAVE_RESIZETERM 0
+#define HAVE_VSSCANF 0
+#define BROKEN_LINKER 0
+
+#undef USE_TERMLIB
+
+#include <curses.h>
+#include <curses.priv.h>
+
+#define SCREEN_X 80
+#define SCREEN_Y 25
+
+/* Flags used to determine what output methods are available */
+
+#ifdef CONFIG_VIDEO_CONSOLE
+#define F_ENABLE_CONSOLE 0x01
+#else
+#define F_ENABLE_CONSOLE 0x00
+#endif
+
+#define CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_CONSOLE
+#define F_ENABLE_SERIAL 0x02
+#else
+#define F_ENABLE_SERIAL 0x00
+#endif
+
+extern int curses_flags;
+
+/* Share the color table for easy lookup */
+extern unsigned char color_pairs[256];
+
+#endif
diff --git a/apps/lib/curses/tinycurses/tinycurses.c b/apps/lib/curses/tinycurses/tinycurses.c
new file mode 100644
index 0000000..e09c0a5
--- /dev/null
+++ b/apps/lib/curses/tinycurses/tinycurses.c
@@ -0,0 +1,1016 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Ulf Jordan <jordan@chalmers.se>
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This is a tiny implementation of the (n)curses library intended to be
+ * used in embedded/firmware/BIOS code where no libc or operating system
+ * environment is available and code size is very important.
+ *
+ * Design goals:
+ * - Small object code.
+ * - Self-contained.
+ * - Doesn't require a libc (no glibc/uclibc/dietlibc/klibc/newlib).
+ * - Works without any other external libraries or header files.
+ * - Works without an underlying operating system.
+ * - Doesn't use files, signals, syscalls, ttys, library calls, etc.
+ * - Doesn't do any dynamic memory allocation (no malloc() and friends).
+ * - All data structures are statically allocated.
+ * - Supports standard VGA console (80x25) and serial port console.
+ * - This includes character output and keyboard input over serial.
+ * - Supports beep() through a minimal PC speaker driver.
+ *
+ * Limitations:
+ * - Only implements a small subset of the (n)curses functions.
+ * - Only implements very few sanity checks (for smaller code).
+ * - Thus: Don't do obviously stupid things in your code.
+ * - Doesn't implement the 'form', 'panel', and 'menu' extensions.
+ * - Only implements C bindings (no C++, Ada95, or others).
+ * - Doesn't include wide character support.
+ */
+
+#include <utils/ansi.h>
+
+#include "local.h"
+
+#undef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#define CONFIG_SERIAL_ACS_FALLBACK
+
+#define MAX_WINDOWS 3
+
+/* Statically allocate all structures (no malloc())! */
+static WINDOW window_list[MAX_WINDOWS];
+static int window_count = 1;
+
+// struct ldat foo;
+static struct ldat ldat_list[MAX_WINDOWS][SCREEN_Y];
+static int ldat_count = 0;
+
+/* One item bigger than SCREEN_X to reserve space for a NUL byte. */
+static NCURSES_CH_T linebuf_list[SCREEN_Y * MAX_WINDOWS][SCREEN_X + 1];
+static int linebuf_count = 0;
+
+/* Globals */
+int COLORS; /* Currently unused? */
+int COLOR_PAIRS = 255;
+WINDOW *stdscr;
+WINDOW *curscr;
+WINDOW *newscr;
+int LINES = 25;
+int COLS = 80;
+int TABSIZE;
+int ESCDELAY;
+// char ttytype[];
+// cchar_t *_nc_wacs;
+SCREEN *SP;
+chtype acs_map[128];
+
+/* See terminfo(5). */
+chtype fallback_acs_map[128] =
+ {
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', '>', '<', '^', 'v', ' ',
+ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ '+', ':', ' ', ' ', ' ', ' ', '\\', '#',
+ '#', '#', '+', '+', '+', '+', '+', '~',
+ '-', '-', '-', '_', '+', '+', '+', '+',
+ '|', '<', '>', '*', '!', 'f', 'o', ' ',
+ };
+
+#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_ACS_FALLBACK
+chtype serial_acs_map[128];
+#else
+/* See acsc of vt100. */
+chtype serial_acs_map[128] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ '`', 'a', 0, 0, 0, 0, 'f', 'g',
+ 0, 0, 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '{', '|', '}', '~', 0,
+ };
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_CONSOLE
+/* See acsc of linux. */
+chtype console_acs_map[128] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, '\020', '\021', '\030', '\031', 0,
+ '\333', 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ '\004', '\261', 0, 0, 0, 0, '\370', '\361',
+ '\260', '\316', '\331', '\277', '\332', '\300', '\305', '~',
+ '\304', '\304', '\304', '_', '\303', '\264', '\301', '\302',
+ '\263', '\363', '\362', '\343', '\330', '\234', '\376', 0,
+ };
+#endif
+
+// FIXME: Ugly (and insecure!) hack!
+char sprintf_tmp[1024];
+
+
+int curses_flags = (F_ENABLE_CONSOLE | F_ENABLE_SERIAL);
+
+/* Return bit mask for clearing color pair number if given ch has color */
+#define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))
+
+/* Compute a rendition of the given char correct for the current context. */
+static inline NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch)
+{
+ /* TODO. */
+ return ch;
+}
+
+/* Make render_char() visible while still allowing us to inline it below. */
+NCURSES_CH_T _nc_render(WINDOW *win, NCURSES_CH_T ch)
+{
+ return render_char(win, ch);
+}
+
+/*
+ * Implementations of most functions marked 'implemented' in include/curses.h:
+ */
+
+// int baudrate(void) {}
+int beep(void)
+{
+ /* TODO: Flash the screen if beeping fails? */
+#ifdef CONFIG_SPEAKER
+ speaker_tone(1760, 500); /* 1760 == note A6 */
+#endif
+ return OK;
+}
+// bool can_change_color(void) {}
+int cbreak(void) { /* TODO */ return 0; }
+/* D */ int clearok(WINDOW *win, bool flag) { win->_clear = flag; return OK; }
+// int color_content(short color, short *r, short *g, short *b) {}
+int curs_set(int on)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (curses_flags & F_ENABLE_SERIAL) {
+ ansi_cursor_enable(on);
+ }
+#endif
+#ifdef CONFIG_VIDEO_CONSOLE
+ if (curses_flags & F_ENABLE_CONSOLE) {
+ video_console_cursor_enable(on);
+ }
+#endif
+
+ return OK;
+}
+// int def_prog_mode(void) {}
+// int def_shell_mode(void) {}
+// int delay_output(int) {}
+// void delscreen(SCREEN *) {}
+int delwin(WINDOW *win)
+{
+ /* TODO: Don't try to delete stdscr. */
+ /* TODO: Don't delete parent windows before subwindows. */
+
+ // if (win->_flags & _SUBWIN)
+ // touchwin(win->_parent);
+ // else if (curscr != 0)
+ // touchwin(curscr);
+
+ // return _nc_freewin(win);
+ return OK;
+}
+WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
+{
+#if 0
+ WINDOW *win = NULL;
+ int i;
+ int flags = _SUBWIN;
+
+ /* Make sure window fits inside the original one. */
+ if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0
+ || num_columns < 0)
+ return NULL;
+
+ if (begy + num_lines > orig->_maxy + 1
+ || begx + num_columns > orig->_maxx + 1)
+ return NULL;
+
+ if (num_lines == 0)
+ num_lines = orig->_maxy + 1 - begy;
+
+ if (num_columns == 0)
+ num_columns = orig->_maxx + 1 - begx;
+
+ if (orig->_flags & _ISPAD)
+ flags |= _ISPAD;
+
+ // FIXME
+ if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
+ orig->_begx + begx, flags)) == 0)
+ return NULL;
+
+ win->_pary = begy;
+ win->_parx = begx;
+ WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
+ win->_nc_bkgd = orig->_nc_bkgd;
+
+ for (i = 0; i < num_lines; i++)
+ win->_line[i].text = &orig->_line[begy++].text[begx];
+
+ win->_parent = orig;
+
+ return win;
+#else
+ return NULL;
+#endif
+}
+int doupdate(void) { /* TODO */ return(0); }
+// WINDOW * dupwin (WINDOW *) {}
+/* D */ int echo(void) { SP->_echo = TRUE; return OK; }
+int endwin(void)
+{
+ if (!SP)
+ return ERR;
+
+ SP->_endwin = TRUE;
+#ifdef NCURSES_MOUSE_VERSION
+ SP->_mouse_wrap(SP);
+#endif
+ // _nc_screen_wrap();
+ // _nc_mvcur_wrap(); /* wrap up cursor addressing */
+ // return reset_shell_mode();
+ return OK; // FIXME
+}
+// char erasechar (void) {}
+// void filter (void) {}
+// int flash(void) {}
+int flushinp(void) { /* TODO */ return 0; }
+// WINDOW *getwin (FILE *) {}
+bool has_colors (void) { return(TRUE); }
+// bool has_ic (void) {}
+// bool has_il (void) {}
+// void idcok (WINDOW *, bool) {}
+// int idlok (WINDOW *, bool) {}
+void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
+/** Note: Must _not_ be called twice! */
+WINDOW *initscr(void)
+{
+ int i;
+
+ // newterm(name, stdout, stdin);
+ // def_prog_mode();
+
+ for (i = 0; i < 128; i++)
+ acs_map[i] = (chtype) i | A_ALTCHARSET;
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (curses_flags & F_ENABLE_SERIAL) {
+ ansi_clear();
+ }
+#endif
+#ifdef CONFIG_VIDEO_CONSOLE
+ if (curses_flags & F_ENABLE_CONSOLE) {
+ /* Clear the screen and kill the cursor */
+
+ video_console_clear();
+ video_console_cursor_enable(0);
+ }
+#endif
+
+ // Speaker init?
+
+ stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
+ // TODO: curscr, newscr?
+
+ werase(stdscr);
+
+ return stdscr;
+}
+// int intrflush (WINDOW *,bool) {}
+/* D */ bool isendwin(void) { return ((SP == NULL) ? FALSE : SP->_endwin); }
+// bool is_linetouched (WINDOW *,int) {}
+// bool is_wintouched (WINDOW *) {}
+// NCURSES_CONST char * keyname (int) {}
+int keypad (WINDOW *win, bool flag) { /* TODO */ return 0; }
+// char killchar (void) {}
+/* D */ int leaveok(WINDOW *win, bool flag) { win->_leaveok = flag; return OK; }
+// char *longname (void) {}
+// int meta (WINDOW *,bool) {}
+// int mvcur (int,int,int,int) {}
+// int mvderwin (WINDOW *, int, int) {}
+int mvprintw(int y, int x, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ va_start(argp, fmt);
+ code = vwprintw(stdscr, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int mvscanw (int,int, NCURSES_CONST char *,...) {}
+// int mvwin (WINDOW *,int,int) {}
+int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ va_start(argp, fmt);
+ code = vwprintw(win, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) {}
+// int napms (int) {}
+// WINDOW *newpad (int,int) {}
+// SCREEN *newterm (NCURSES_CONST char *,FILE *,FILE *) {}
+WINDOW *newwin(int num_lines, int num_columns, int begy, int begx)
+{
+ int i;
+
+ /* Use next statically allocated window. */
+ // TODO: Error handling.
+ // TODO: WINDOWLIST?
+ WINDOW *win = &window_list[window_count++];
+
+ // bool is_pad = (flags & _ISPAD);
+
+ // TODO: Checks.
+
+ win->_cury = 0;
+ win->_curx = 0;
+ win->_maxy = num_lines - 1;
+ win->_maxx = num_columns - 1;
+ win->_begy = begy;
+ win->_begx = begx;
+ // win->_yoffset = SP->_topstolen;
+
+ win->_line = ldat_list[ldat_count++];
+
+ /* FIXME: Is this right? Should the window attributes be normal? */
+ win->_color = PAIR_NUMBER(0);
+ win->_attrs = A_NORMAL;
+
+ for (i = 0; i < num_lines; i++)
+ win->_line[i].text =
+ (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
+
+ return win;
+}
+/* D */ int nl(void) { SP->_nl = TRUE; return OK; }
+/* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
+/* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
+// void noqiflush (void) {}
+// int noraw (void) {}
+/* D */ int notimeout (WINDOW *win, bool f) { win->_notimeout = f; return OK; }
+// int overlay (const WINDOW*,WINDOW *) {}
+// int overwrite (const WINDOW*,WINDOW *) {}
+// int pair_content (short,short*,short*) {}
+// int pechochar (WINDOW *, const chtype) {}
+// int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
+// int prefresh (WINDOW *,int,int,int,int,int,int) {}
+int printw(const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ va_start(argp, fmt);
+ code = vwprintw(stdscr, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int putwin (WINDOW *, FILE *) {}
+// void qiflush (void) {}
+// int raw (void) {}
+// int resetty (void) {}
+// int reset_prog_mode (void) {}
+// int reset_shell_mode (void) {}
+// int ripoffline (int, int (*)(WINDOW *, int)) {}
+// int savetty (void) {}
+// int scanw (NCURSES_CONST char *,...) {}
+// int scr_dump (const char *) {}
+// int scr_init (const char *) {}
+/* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
+// int scr_restore (const char *) {}
+// int scr_set (const char *) {}
+// SCREEN *set_term (SCREEN *) {}
+// int slk_attroff (const chtype) {}
+// int slk_attron (const chtype) {}
+// int slk_attrset (const chtype) {}
+// attr_t slk_attr (void) {}
+// int slk_attr_set (const attr_t,short,void*) {}
+// int slk_clear (void) {}
+// int slk_color (short) {}
+// int slk_init (int) {}
+/* D */ char *slk_label(int n)
+{
+ // TODO: Needed?
+ // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
+ // return NULL;
+ return SP->_slk->ent[n - 1].ent_text;
+}
+// int slk_noutrefresh (void) {}
+// int slk_refresh (void) {}
+// int slk_restore (void) {}
+// int slk_set (int,const char *,int) {}
+// int slk_touch (void) {}
+
+// WINDOW *subpad (WINDOW *, int, int, int, int) {}
+WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
+{
+ return derwin(w, l, c, y - w->_begy, x - w->_begx);
+}
+// int syncok (WINDOW *, bool) {}
+// chtype termattrs (void) {}
+// char *termname (void) {}
+// int typeahead (int) {}
+int ungetch(int ch) { /* TODO */ return ERR; }
+// void use_env (bool) {}
+// int vidattr (chtype) {}
+// int vidputs (chtype, int (*)(int)) {}
+int vwprintw(WINDOW *win, const char *fmt, va_list argp)
+{
+ vsprintf((char *)&sprintf_tmp, fmt, argp);
+
+ /* TODO: Error handling? */
+ return waddstr(win, (char *)&sprintf_tmp);
+}
+// int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
+int waddch(WINDOW *win, const chtype ch)
+{
+ int code = ERR;
+ // NCURSES_CH_T wch;
+ // SetChar2(wch, ch);
+
+ if (win->_line[win->_cury].firstchar == _NOCHANGE ||
+ win->_line[win->_cury].firstchar > win->_curx)
+ win->_line[win->_cury].firstchar = win->_curx;
+
+ win->_line[win->_cury].text[win->_curx].chars[0] =
+ ((ch) & (chtype)A_CHARTEXT);
+
+ win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
+ win->_line[win->_cury].text[win->_curx].attr |=
+ ((ch) & (chtype)A_ATTRIBUTES);
+
+ if (win->_line[win->_cury].lastchar == _NOCHANGE ||
+ win->_line[win->_cury].lastchar < win->_curx)
+ win->_line[win->_cury].lastchar = win->_curx;
+
+ win->_curx++; // FIXME
+
+ // if (win && (waddch_nosync(win, wch) != ERR)) {
+ // _nc_synchook(win);
+ // code = OK;
+ // }
+
+ return code;
+}
+// int waddchnstr (WINDOW *,const chtype *,int) {}
+int waddnstr(WINDOW *win, const char *astr, int n)
+{
+ int code = OK;
+ const char *str = astr;
+
+ if (!str)
+ return ERR;
+
+ if (n < 0)
+ n = strlen(astr);
+
+ if (win->_line[win->_cury].firstchar == _NOCHANGE ||
+ win->_line[win->_cury].firstchar > win->_curx)
+ win->_line[win->_cury].firstchar = win->_curx;
+
+ while ((n-- > 0) && (*str != '\0')) {
+ // while (*str != '\0') {
+ win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
+ win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
+;
+ win->_curx++; // FIXME
+
+ // NCURSES_CH_T ch;
+ // SetChar(ch, UChar(*str++), A_NORMAL);
+ // if (_nc_waddch_nosync(win, ch) == ERR) {
+ // code = ERR;
+ // break;
+ // }
+ }
+
+ if (win->_line[win->_cury].lastchar == _NOCHANGE ||
+ win->_line[win->_cury].lastchar < win->_curx)
+ win->_line[win->_cury].lastchar = win->_curx;
+
+ return code;
+}
+int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
+{
+ if (at & A_COLOR)
+ win->_color = PAIR_NUMBER(at);
+ // toggle_attr_on(WINDOW_ATTRS(win), at);
+ return OK;
+}
+int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
+{
+ if (at & A_COLOR)
+ win->_color = 0;
+ // toggle_attr_off(WINDOW_ATTRS(win), at);
+ return 0;
+}
+int wbkgd (WINDOW *win, chtype ch) { /* TODO */ return 0; }
+void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
+
+int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
+ chtype tl, chtype tr, chtype bl, chtype br)
+{
+ int x, y;
+
+ if (ls == 0) ls = ACS_VLINE;
+ if (rs == 0) rs = ACS_VLINE;
+ if (ts == 0) ts = ACS_HLINE;
+ if (bs == 0) bs = ACS_HLINE;
+ if (tl == 0) tl = ACS_ULCORNER;
+ if (tr == 0) tr = ACS_URCORNER;
+ if (bl == 0) bl = ACS_LLCORNER;
+ if (br == 0) br = ACS_LRCORNER;
+
+ for(y = 0; y <= win->_maxy; y++) {
+
+ if (y == 0) {
+ mvwaddch(win, y, 0, tl);
+
+ for(x = 1; x < win->_maxx; x++)
+ mvwaddch(win, y, x, ts);
+
+ mvwaddch(win, y, win->_maxx, tr);
+ }
+ else if (y == win->_maxy) {
+ mvwaddch(win, y, 0, bl);
+
+ for(x = 1; x < win->_maxx; x++)
+ mvwaddch(win, y, x, bs);
+
+ mvwaddch(win, y, win->_maxx, br);
+ }
+ else {
+ mvwaddch(win, y, 0, ls);
+ mvwaddch(win, y, win->_maxx, rs);
+ }
+ }
+
+ return OK;
+}
+
+// int wchgat (WINDOW *, int, attr_t, short, const void *) {}
+/* D */ int wclear(WINDOW *win)
+{
+ if (werase(win) == ERR)
+ return ERR;
+ win->_clear = TRUE;
+ return OK;
+}
+// int wclrtobot (WINDOW *) {}
+int wclrtoeol(WINDOW *win) { /* TODO */ return ERR; }
+int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
+{
+ if (!opts && (color_pair_number >= 0)
+ && (color_pair_number < COLOR_PAIRS)) {
+ SET_WINDOW_PAIR(win, color_pair_number);
+ if_EXT_COLORS(win->_color = color_pair_number);
+ return OK;
+ }
+ return ERR;
+}
+// void wcursyncup (WINDOW *) {}
+// int wdelch (WINDOW *) {}
+// int wechochar (WINDOW *, const chtype) {}
+int werase(WINDOW *win)
+{
+ int x, y;
+ for (y = 0; y <= win->_maxy; y++) {
+ for (x = 0; x <= win->_maxx; x++) {
+ win->_line[y].text[x].chars[0] = ' ';
+ win->_line[y].text[x].attr = WINDOW_ATTRS(win);
+ }
+ // Should we check instead?
+ win->_line[y].firstchar = 0;
+ win->_line[y].lastchar = win->_maxx;
+ }
+ return OK;
+}
+// int wgetnstr (WINDOW *,char *,int) {}
+int whline(WINDOW *win, chtype ch, int n)
+{
+ NCURSES_SIZE_T start, end;
+ struct ldat *line = &(win->_line[win->_cury]);
+ NCURSES_CH_T wch;
+
+ start = win->_curx;
+ end = start + n - 1;
+ if (end > win->_maxx)
+ end = win->_maxx;
+
+ CHANGED_RANGE(line, start, end);
+
+ //// TODO:
+ //// if (ch == 0)
+ //// SetChar2(wch, ACS_HLINE);
+ //// else
+ //// SetChar2(wch, ch);
+ // Ugly hack:
+ wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
+ wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
+ wch = _nc_render(win, wch);
+
+ while (end >= start) {
+ line->text[end] = wch;
+ end--;
+ }
+
+ //// _nc_synchook(win);
+
+ return OK;
+}
+/* D */ chtype winch(WINDOW *win)
+{
+ //// TODO
+ // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
+ // AttrOf(win->_line[win->_cury].text[win->_curx]));
+ return OK; // FIXME
+}
+// int winchnstr (WINDOW *, chtype *, int) {}
+// int winnstr (WINDOW *, char *, int) {}
+// int winsch (WINDOW *, chtype) {}
+// int winsdelln (WINDOW *,int) {}
+// int winsnstr (WINDOW *, const char *,int) {}
+/* D */ int wmove(WINDOW *win, int y, int x)
+{
+ if (!LEGALYX(win, y, x))
+ return ERR;
+ win->_curx = (NCURSES_SIZE_T) x;
+ win->_cury = (NCURSES_SIZE_T) y;
+ win->_flags &= ~_WRAPPED;
+ win->_flags |= _HASMOVED;
+ return OK;
+}
+
+#define SWAP_RED_BLUE(c) \
+ (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
+int wnoutrefresh(WINDOW *win)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+ // FIXME.
+ int serial_is_bold = 0;
+ int serial_is_reverse = 0;
+ int serial_is_altcharset = 0;
+ int serial_cur_pair = 0;
+
+ int need_altcharset;
+ short fg, bg;
+#endif
+ int x, y;
+ chtype ch;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+ ansi_end_bold();
+ ansi_end_altcharset();
+#endif
+
+ for (y = 0; y <= win->_maxy; y++) {
+
+ if (win->_line[y].firstchar == _NOCHANGE)
+ continue;
+
+ /* Position the serial cursor */
+
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (curses_flags & F_ENABLE_SERIAL)
+ ansi_set_cursor(win->_begy + y, win->_begx +
+ win->_line[y].firstchar);
+#endif
+
+ for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
+ attr_t attr = win->_line[y].text[x].attr;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (curses_flags & F_ENABLE_SERIAL) {
+ ch = win->_line[y].text[x].chars[0];
+
+ if (attr & A_BOLD) {
+ if (!serial_is_bold) {
+ ansi_start_bold();
+ serial_is_bold = 1;
+ }
+ } else {
+ if (serial_is_bold) {
+ ansi_end_bold();
+ serial_is_bold = 0;
+ /* work around serial.c
+ * shortcoming:
+ */
+ serial_is_reverse = 0;
+ serial_cur_pair = 0;
+ }
+ }
+
+ if (attr & A_REVERSE) {
+ if (!serial_is_reverse) {
+ ansi_start_reverse();
+ serial_is_reverse = 1;
+ }
+ } else {
+ if (serial_is_reverse) {
+ ansi_end_reverse();
+ serial_is_reverse = 0;
+ /* work around serial.c
+ * shortcoming:
+ */
+ serial_is_bold = 0;
+ serial_cur_pair = 0;
+ }
+ }
+
+ need_altcharset = 0;
+ if (attr & A_ALTCHARSET) {
+ if (serial_acs_map[ch & 0x7f]) {
+ ch = serial_acs_map[ch & 0x7f];
+ need_altcharset = 1;
+ } else
+ ch = fallback_acs_map[ch & 0x7f];
+ }
+ if (need_altcharset && !serial_is_altcharset) {
+ ansi_start_altcharset();
+ serial_is_altcharset = 1;
+ }
+ if (!need_altcharset && serial_is_altcharset) {
+ ansi_end_altcharset();
+ serial_is_altcharset = 0;
+ }
+
+ if (serial_cur_pair != PAIR_NUMBER(attr)) {
+ pair_content(PAIR_NUMBER(attr),
+ &fg, &bg);
+ ansi_set_color(fg + 30, bg + 40);
+ serial_cur_pair = PAIR_NUMBER(attr);
+ }
+
+ putchar(ch);
+
+ }
+#endif
+#ifdef CONFIG_VIDEO_CONSOLE
+ unsigned int c =
+ ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
+
+ c = SWAP_RED_BLUE(c);
+
+ if (curses_flags & F_ENABLE_CONSOLE) {
+ ch = win->_line[y].text[x].chars[0];
+
+ /* Handle some of the attributes. */
+ if (attr & A_BOLD)
+ c |= 0x0800;
+ if (attr & A_DIM)
+ c &= ~0x800;
+ if (attr & A_REVERSE) {
+ unsigned char tmp = (c >> 8) & 0xf;
+ c = (c >> 4) & 0xf00;
+ c |= tmp << 12;
+ }
+ if (attr & A_ALTCHARSET) {
+ if (console_acs_map[ch & 0x7f])
+ ch = console_acs_map[ch & 0x7f];
+ else
+ ch = fallback_acs_map[ch & 0x7f];
+ }
+
+ /*
+ * FIXME: Somewhere along the line, the
+ * character value is getting sign-extented.
+ * For now grab just the 8 bit character,
+ * but this will break wide characters!
+ */
+ c |= (chtype) (ch & 0xff);
+ video_console_putc(win->_begy + y, win->_begx + x, c);
+ }
+#endif
+ }
+ win->_line[y].firstchar = _NOCHANGE;
+ win->_line[y].lastchar = _NOCHANGE;
+ }
+
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (curses_flags & F_ENABLE_SERIAL)
+ ansi_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
+#endif
+
+#ifdef CONFIG_VIDEO_CONSOLE
+ if (curses_flags & F_ENABLE_CONSOLE)
+ video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
+#endif
+
+ return OK;
+}
+int wprintw(WINDOW *win, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ va_start(argp, fmt);
+ code = vwprintw(win, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+
+int wredrawln (WINDOW *win, int beg_line, int num_lines)
+{
+ int i;
+
+ for (i = beg_line; i < beg_line + num_lines; i++) {
+ win->_line[i].firstchar = 0;
+ win->_line[i].lastchar = win->_maxx;
+ }
+
+ return OK;
+}
+
+int wrefresh(WINDOW *win)
+{
+ int code;
+
+ // FIXME
+ return wnoutrefresh(win);
+
+ // XXX
+
+ if (win == curscr) {
+ curscr->_clear = TRUE;
+ // code = doupdate();
+ } else if ((code = wnoutrefresh(win)) == OK) {
+ if (win->_clear)
+ newscr->_clear = TRUE;
+ // code = doupdate();
+ /*
+ * Reset the clearok() flag in case it was set for the special
+ * case in hardscroll.c (if we don't reset it here, we'll get 2
+ * refreshes because the flag is copied from stdscr to newscr).
+ * Resetting the flag shouldn't do any harm, anyway.
+ */
+ win->_clear = FALSE;
+ }
+
+ return code;
+}
+// int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
+int wscrl(WINDOW *win, int n)
+{
+ int x, y;
+
+ if (!win->_scroll)
+ return ERR;
+
+ if (n == 0)
+ return OK;
+
+ for (y = 0; y <= (win->_maxy - n); y++) {
+ win->_line[y].firstchar = win->_line[y + n].firstchar;
+ win->_line[y].lastchar = win->_line[y + n].lastchar;
+ for (x = 0; x <= win->_maxx; x++) {
+ if ((win->_line[y].text[x].chars[0] != win->_line[y + n].text[x].chars[0]) ||
+ (win->_line[y].text[x].attr != win->_line[y + n].text[x].attr)) {
+ if (win->_line[y].firstchar == _NOCHANGE)
+ win->_line[y].firstchar = x;
+
+ win->_line[y].lastchar = x;
+
+ win->_line[y].text[x].chars[0] = win->_line[y + n].text[x].chars[0];
+ win->_line[y].text[x].attr = win->_line[y + n].text[x].attr;
+ }
+ }
+ }
+
+ for (y = (win->_maxy+1 - n); y <= win->_maxy; y++) {
+ for (x = 0; x <= win->_maxx; x++) {
+ if ((win->_line[y].text[x].chars[0] != ' ') ||
+ (win->_line[y].text[x].attr != A_NORMAL)) {
+ if (win->_line[y].firstchar == _NOCHANGE)
+ win->_line[y].firstchar = x;
+
+ win->_line[y].lastchar = x;
+
+ win->_line[y].text[x].chars[0] = ' ';
+ win->_line[y].text[x].attr = A_NORMAL;
+ }
+ }
+ }
+
+ // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
+ // _nc_synchook(win);
+
+ return OK;
+}
+int wsetscrreg(WINDOW *win, int top, int bottom)
+{
+ if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
+ bottom <= win->_maxy && bottom > top) {
+ win->_regtop = (NCURSES_SIZE_T) top;
+ win->_regbottom = (NCURSES_SIZE_T) bottom;
+ return OK;
+ }
+ return ERR;
+}
+// void wsyncdown (WINDOW *) {}
+// void wsyncup (WINDOW *) {}
+/* D */ void wtimeout(WINDOW *win, int _delay) { win->_delay = _delay; }
+/* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
+{
+ int i;
+
+ // if ((n < 0) || (y < 0) || (y > win->_maxy))
+ // return ERR;
+
+ for (i = y; i < y + n; i++) {
+ if (i > win->_maxy)
+ break;
+ win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
+ win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
+ }
+ return OK;
+}
+// int wvline (WINDOW *,chtype,int) {}
+// int tigetflag (NCURSES_CONST char *) {}
+// int tigetnum (NCURSES_CONST char *) {}
+// char *tigetstr (NCURSES_CONST char *) {}
+// int putp (const char *) {}
+// #if NCURSES_TPARM_VARARGS
+// char *tparm (NCURSES_CONST char *, ...) {}
+// #else
+// char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
+// char *tparm_varargs (NCURSES_CONST char *, ...) {}
+// #endif
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 12/20] app: add tinycurses support
2013-03-06 9:29 ` [PATCH 12/20] app: add tinycurses support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 11:31 ` Sascha Hauer
2013-03-06 13:04 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 31+ messages in thread
From: Sascha Hauer @ 2013-03-06 11:31 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Wed, Mar 06, 2013 at 10:29:41AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> take from corboot and upated to use ansi
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Drop the curses stuff from the series. It will take time to get the
application stuff reviewed and merged, so concentrate on the basic stuff
and do not dump this unrelated stuff on the list.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 12/20] app: add tinycurses support
2013-03-06 11:31 ` Sascha Hauer
@ 2013-03-06 13:04 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 13:04 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 12:31 Wed 06 Mar , Sascha Hauer wrote:
> On Wed, Mar 06, 2013 at 10:29:41AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > take from corboot and upated to use ansi
> >
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
>
> Drop the curses stuff from the series. It will take time to get the
> application stuff reviewed and merged, so concentrate on the basic stuff
> and do not dump this unrelated stuff on the list.
this will be presented this friday at CEWG so I choose to send it together and
it's a good example how to use the application implemetation
for the other version of this patch serie I'll not include it
Best Regards,
J.
>
> Sascha
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 13/20] app: curses: add pdcurses
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (10 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 12/20] app: add tinycurses support Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 14/20] app: add test curses Jean-Christophe PLAGNIOL-VILLARD
` (6 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
backend inspided by coreboot core but with ansi support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/lib/curses/Kconfig | 7 +
apps/lib/curses/Makefile | 1 +
apps/lib/curses/Makefile.include | 1 +
apps/lib/curses/pdcurses/Makefile | 89 ++
apps/lib/curses/pdcurses/Makefile.include | 1 +
apps/lib/curses/pdcurses/backend/Makefile | 6 +
apps/lib/curses/pdcurses/backend/barebox.h | 21 +
apps/lib/curses/pdcurses/backend/config.h | 136 +++
apps/lib/curses/pdcurses/backend/pdcdisp.c | 107 ++
apps/lib/curses/pdcurses/backend/pdcgetsc.c | 47 +
apps/lib/curses/pdcurses/backend/pdckbd.c | 161 +++
apps/lib/curses/pdcurses/backend/pdcscrn.c | 162 +++
apps/lib/curses/pdcurses/backend/pdcsetsc.c | 35 +
apps/lib/curses/pdcurses/backend/pdcutil.c | 26 +
apps/lib/curses/pdcurses/include/curses.h | 1378 ++++++++++++++++++++++++++
apps/lib/curses/pdcurses/include/panel.h | 58 ++
apps/lib/curses/pdcurses/pdcurses/Makefile | 39 +
apps/lib/curses/pdcurses/pdcurses/README | 25 +
apps/lib/curses/pdcurses/pdcurses/addch.c | 408 ++++++++
apps/lib/curses/pdcurses/pdcurses/addchstr.c | 242 +++++
apps/lib/curses/pdcurses/pdcurses/addstr.c | 237 +++++
apps/lib/curses/pdcurses/pdcurses/attr.c | 349 +++++++
apps/lib/curses/pdcurses/pdcurses/beep.c | 65 ++
apps/lib/curses/pdcurses/pdcurses/bkgd.c | 220 ++++
apps/lib/curses/pdcurses/pdcurses/border.c | 408 ++++++++
apps/lib/curses/pdcurses/pdcurses/clear.c | 154 +++
apps/lib/curses/pdcurses/pdcurses/color.c | 295 ++++++
apps/lib/curses/pdcurses/pdcurses/curspriv.h | 146 +++
apps/lib/curses/pdcurses/pdcurses/debug.c | 81 ++
apps/lib/curses/pdcurses/pdcurses/delch.c | 93 ++
apps/lib/curses/pdcurses/pdcurses/deleteln.c | 208 ++++
apps/lib/curses/pdcurses/pdcurses/deprec.c | 29 +
apps/lib/curses/pdcurses/pdcurses/getch.c | 410 ++++++++
apps/lib/curses/pdcurses/pdcurses/getstr.c | 471 +++++++++
apps/lib/curses/pdcurses/pdcurses/getyx.c | 143 +++
apps/lib/curses/pdcurses/pdcurses/inch.c | 125 +++
apps/lib/curses/pdcurses/pdcurses/inchstr.c | 211 ++++
apps/lib/curses/pdcurses/pdcurses/initscr.c | 339 +++++++
apps/lib/curses/pdcurses/pdcurses/inopts.c | 321 ++++++
apps/lib/curses/pdcurses/pdcurses/insch.c | 268 +++++
apps/lib/curses/pdcurses/pdcurses/insstr.c | 261 +++++
apps/lib/curses/pdcurses/pdcurses/instr.c | 243 +++++
apps/lib/curses/pdcurses/pdcurses/kernel.c | 256 +++++
apps/lib/curses/pdcurses/pdcurses/keyname.c | 125 +++
apps/lib/curses/pdcurses/pdcurses/mouse.c | 429 ++++++++
apps/lib/curses/pdcurses/pdcurses/move.c | 54 +
apps/lib/curses/pdcurses/pdcurses/outopts.c | 156 +++
apps/lib/curses/pdcurses/pdcurses/overlay.c | 256 +++++
apps/lib/curses/pdcurses/pdcurses/pad.c | 259 +++++
apps/lib/curses/pdcurses/pdcurses/panel.c | 630 ++++++++++++
apps/lib/curses/pdcurses/pdcurses/printw.c | 123 +++
apps/lib/curses/pdcurses/pdcurses/refresh.c | 276 ++++++
apps/lib/curses/pdcurses/pdcurses/scanw.c | 575 +++++++++++
apps/lib/curses/pdcurses/pdcurses/scr_dump.c | 210 ++++
apps/lib/curses/pdcurses/pdcurses/scroll.c | 98 ++
apps/lib/curses/pdcurses/pdcurses/slk.c | 643 ++++++++++++
apps/lib/curses/pdcurses/pdcurses/term.h | 57 ++
apps/lib/curses/pdcurses/pdcurses/termattr.c | 176 ++++
apps/lib/curses/pdcurses/pdcurses/terminfo.c | 215 ++++
apps/lib/curses/pdcurses/pdcurses/touch.c | 160 +++
apps/lib/curses/pdcurses/pdcurses/util.c | 309 ++++++
apps/lib/curses/pdcurses/pdcurses/window.c | 562 +++++++++++
62 files changed, 13596 insertions(+)
create mode 100644 apps/lib/curses/pdcurses/Makefile
create mode 100644 apps/lib/curses/pdcurses/Makefile.include
create mode 100644 apps/lib/curses/pdcurses/backend/Makefile
create mode 100644 apps/lib/curses/pdcurses/backend/barebox.h
create mode 100644 apps/lib/curses/pdcurses/backend/config.h
create mode 100644 apps/lib/curses/pdcurses/backend/pdcdisp.c
create mode 100644 apps/lib/curses/pdcurses/backend/pdcgetsc.c
create mode 100644 apps/lib/curses/pdcurses/backend/pdckbd.c
create mode 100644 apps/lib/curses/pdcurses/backend/pdcscrn.c
create mode 100644 apps/lib/curses/pdcurses/backend/pdcsetsc.c
create mode 100644 apps/lib/curses/pdcurses/backend/pdcutil.c
create mode 100644 apps/lib/curses/pdcurses/include/curses.h
create mode 100644 apps/lib/curses/pdcurses/include/panel.h
create mode 100644 apps/lib/curses/pdcurses/pdcurses/Makefile
create mode 100644 apps/lib/curses/pdcurses/pdcurses/README
create mode 100644 apps/lib/curses/pdcurses/pdcurses/addch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/addchstr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/addstr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/attr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/beep.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/bkgd.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/border.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/clear.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/color.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/curspriv.h
create mode 100644 apps/lib/curses/pdcurses/pdcurses/debug.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/delch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/deleteln.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/deprec.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/getch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/getstr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/getyx.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/inch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/inchstr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/initscr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/inopts.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/insch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/insstr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/instr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/kernel.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/keyname.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/mouse.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/move.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/outopts.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/overlay.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/pad.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/panel.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/printw.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/refresh.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/scanw.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/scr_dump.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/scroll.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/slk.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/term.h
create mode 100644 apps/lib/curses/pdcurses/pdcurses/termattr.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/terminfo.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/touch.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/util.c
create mode 100644 apps/lib/curses/pdcurses/pdcurses/window.c
diff --git a/apps/lib/curses/Kconfig b/apps/lib/curses/Kconfig
index c6bc573..7852afb 100644
--- a/apps/lib/curses/Kconfig
+++ b/apps/lib/curses/Kconfig
@@ -6,9 +6,16 @@ if APP_LIB_CURSES
choice
prompt "curses implementation"
+config APP_LIB_PDCURSES
+ bool "pdcurses"
+
config APP_LIB_TINYCURSES
bool "tiny"
endchoice
+config APP_LIB_PANEL
+ bool "panel"
+ depends on APP_LIB_PDCURSES
+
endif
diff --git a/apps/lib/curses/Makefile b/apps/lib/curses/Makefile
index aeebdd5..ca094a0 100644
--- a/apps/lib/curses/Makefile
+++ b/apps/lib/curses/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_APP_LIB_TINYCURSES) += tinycurses/
+obj-$(CONFIG_APP_LIB_PDCURSES) += pdcurses/
diff --git a/apps/lib/curses/Makefile.include b/apps/lib/curses/Makefile.include
index 8cf9d52..a694fe1 100644
--- a/apps/lib/curses/Makefile.include
+++ b/apps/lib/curses/Makefile.include
@@ -1,3 +1,4 @@
+inc-$(CONFIG_APP_LIB_PDCURSES) += $(srctree)/apps/lib/curses/pdcurses/Makefile.include
inc-$(CONFIG_APP_LIB_TINYCURSES) += $(srctree)/apps/lib/curses/tinycurses/Makefile.include
include $(inc-y)
diff --git a/apps/lib/curses/pdcurses/Makefile b/apps/lib/curses/pdcurses/Makefile
new file mode 100644
index 0000000..3707947
--- /dev/null
+++ b/apps/lib/curses/pdcurses/Makefile
@@ -0,0 +1,89 @@
+#ifeq (y,y)
+#INCLUDES += -D_LP64=0 -Icurses/PDCurses-3.4 -Icurses/pdcurses-backend -Icurses/menu -Icurses/form
+#endif
+
+
+obj-y += pdcurses/
+obj-y += backend/
+
+includes-y += pdcurses-backend/nc_alloc.h
+includes-y += pdcurses-backend/ncurses_cfg.h
+includes-y += PDCurses-3.4/curses.h
+includes-y += PDCurses-3.4/term.h
+includes-y += PDCurses-3.4/panel.h
+includes-y += menu/eti.h
+includes-y += menu/menu.h
+includes-y += menu/mf_common.h
+includes-y += form/form.h
+
+libpanel-y += PDCurses-3.4/pdcurses/panel.o
+
+libmenu-y += menu/m_req_name.o
+libmenu-y += menu/m_item_nam.o
+libmenu-y += menu/m_pad.o
+libmenu-y += menu/m_cursor.o
+libmenu-y += menu/m_item_new.o
+libmenu-y += menu/m_attribs.o
+libmenu-y += menu/m_item_opt.o
+libmenu-y += menu/m_format.o
+libmenu-y += menu/m_post.o
+libmenu-y += menu/m_userptr.o
+libmenu-y += menu/m_item_cur.o
+libmenu-y += menu/m_driver.o
+libmenu-y += menu/m_sub.o
+libmenu-y += menu/m_win.o
+libmenu-y += menu/m_global.o
+libmenu-y += menu/m_item_vis.o
+libmenu-y += menu/m_new.o
+libmenu-y += menu/m_scale.o
+libmenu-y += menu/m_spacing.o
+libmenu-y += menu/m_opts.o
+libmenu-y += menu/m_pattern.o
+libmenu-y += menu/m_item_val.o
+libmenu-y += menu/m_hook.o
+libmenu-y += menu/m_item_use.o
+libmenu-y += menu/m_items.o
+libmenu-y += menu/m_item_top.o
+libform-y += form/frm_page.o
+libform-y += form/frm_opts.o
+libform-y += form/frm_def.o
+libform-y += form/frm_req_name.o
+libform-y += form/fty_alpha.o
+libform-y += form/frm_driver.o
+libform-y += form/fld_user.o
+libform-y += form/frm_win.o
+libform-y += form/fld_newftyp.o
+#libform-y += form/fty_regex.o
+libform-y += form/fld_stat.o
+libform-y += form/fld_pad.o
+libform-y += form/fld_current.o
+libform-y += form/frm_post.o
+#libform-y += form/f_trace.o
+libform-y += form/fty_generic.o
+libform-y += form/fld_page.o
+libform-y += form/frm_hook.o
+libform-y += form/frm_scale.o
+libform-y += form/fty_int.o
+libform-y += form/fty_alnum.o
+libform-y += form/frm_cursor.o
+#libform-y += form/fty_ipv4.o
+libform-y += form/fld_link.o
+libform-y += form/fld_arg.o
+libform-y += form/fld_move.o
+libform-y += form/fld_def.o
+libform-y += form/fld_type.o
+libform-y += form/fld_max.o
+libform-y += form/fld_ftlink.o
+libform-y += form/fld_ftchoice.o
+libform-y += form/fld_info.o
+libform-y += form/frm_user.o
+#libform-y += form/fty_num.o
+libform-y += form/frm_sub.o
+libform-y += form/fty_enum.o
+libform-y += form/frm_data.o
+libform-y += form/fld_opts.o
+libform-y += form/fld_attr.o
+libform-y += form/fld_dup.o
+libform-y += form/fld_just.o
+
+app-y += $(curses-y)
diff --git a/apps/lib/curses/pdcurses/Makefile.include b/apps/lib/curses/pdcurses/Makefile.include
new file mode 100644
index 0000000..822f12f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/Makefile.include
@@ -0,0 +1 @@
+APP_CPPFLAGS-y += -I$(srctree)/apps/lib/curses/pdcurses/include/ -D_LP64=0
diff --git a/apps/lib/curses/pdcurses/backend/Makefile b/apps/lib/curses/pdcurses/backend/Makefile
new file mode 100644
index 0000000..cf6eb3f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/Makefile
@@ -0,0 +1,6 @@
+app-y += pdcdisp.o
+app-y += pdcgetsc.o
+app-y += pdckbd.o
+app-y += pdcscrn.o
+app-y += pdcsetsc.o
+app-y += pdcutil.o
diff --git a/apps/lib/curses/pdcurses/backend/barebox.h b/apps/lib/curses/pdcurses/backend/barebox.h
new file mode 100644
index 0000000..2a16c7e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/barebox.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include <curses.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include "../pdcurses/curspriv.h"
+
+extern unsigned char *pdc_atrtab;
+extern short curstoreal[16], realtocurs[16];
+
+#ifdef DEBUG
+#define debug(fmt, arg...) printf(fmt, ## arg)
+#else
+#define debug(fmt, arg...)
+#endif
diff --git a/apps/lib/curses/pdcurses/backend/config.h b/apps/lib/curses/pdcurses/backend/config.h
new file mode 100644
index 0000000..e08c710
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/config.h
@@ -0,0 +1,136 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+#define PDC_RGB
+
+/* Define if you have the <DECkeySym.h> header file */
+/* #undef HAVE_DECKEYSYM_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+/* #undef HAVE_FCNTL_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+/* #undef HAVE_MEMORY_H */
+
+/* Define to 1 if you have the `poll' function. */
+/* #undef HAVE_POLL */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+/* #undef HAVE_STRINGS_H */
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <Sunkeysym.h> header file */
+/* #undef HAVE_SUNKEYSYM_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+/* #undef HAVE_SYS_STAT_H */
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+/* #undef HAVE_SYS_TIME_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `vsscanf' function. */
+/* #undef HAVE_VSSCANF */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_BEGIN */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_DELETE */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_DOWN */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_END */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_HOME */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_INSERT */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_LEFT */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_NEXT */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_PRIOR */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_RIGHT */
+
+/* Define if you have this defined in <keysym.h> */
+/* #undef HAVE_XK_KP_UP */
+
+/* Define if you have the <xpm.h> header file */
+/* #undef HAVE_XPM_H */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "barebox@@lists.infradead.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "PDCurses"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "PDCurses 3.4"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "PDCurses"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.4"
+
+/* Define as the system defined limit for number of signals */
+#define PDC_MAX_SIGNALS NSIG
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+//#define TIME_WITH_SYS_TIME 1
+
+/* Define if you want to use neXtaw library */
+/* #undef USE_NEXTAW */
+
+/* Define if you want to use Xaw3d library */
+/* #undef USE_XAW3D */
+
+/* Define XPointer is typedefed in X11/Xlib.h */
+/* #undef XPOINTER_TYPEDEFED */
diff --git a/apps/lib/curses/pdcurses/backend/pdcdisp.c b/apps/lib/curses/pdcurses/backend/pdcdisp.c
new file mode 100644
index 0000000..9d629d0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdcdisp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include "barebox.h"
+#include <utils/ansi.h>
+
+chtype acs_map[128] =
+ {
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', '>', '<', '^', 'v', ' ',
+ '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ '+', ':', ' ', ' ', ' ', ' ', '\\', '#',
+ '#', '#', '+', '+', '+', '+', '+', '~',
+ '-', '-', '-', '_', '+', '+', '+', '+',
+ '|', '<', '>', '*', '!', 'f', 'o', ' ',
+ };
+
+/* position hardware cursor at (y, x) */
+void PDC_gotoyx(int row, int col)
+{
+ PDC_LOG(("PDC_gotoyx() - called: row %d col %d\n", row, col));
+
+ ansi_set_cursor(row, col);
+}
+
+struct ansi_set {
+ bool is_bold;
+ bool is_blink;
+ short cur_pair;
+};
+
+static void set_attr(chtype attr, struct ansi_set *s)
+{
+ short fg;
+ short bg;
+ short cur_pair = PAIR_NUMBER(attr);
+ bool is_bold = attr & A_BOLD;
+ bool is_reverse = FALSE;
+ bool is_blink = attr & A_BLINK;
+
+ if (s->cur_pair != cur_pair) {
+ PDC_pair_content(cur_pair, &fg, &bg );
+ ansi_set_color(fg + 30, bg + 40);
+ s->cur_pair = cur_pair;
+ }
+
+ /* Reverse flag = highlighted selection XOR A_REVERSE set */
+ is_reverse ^= !!(attr & A_REVERSE);
+
+ if (s->is_bold != is_bold) {
+ ansi_bold(is_bold);
+ s->is_bold = is_bold;
+ }
+
+ if (s->is_blink != is_blink) {
+ ansi_blink(is_blink);
+ s->is_blink = is_blink;
+ }
+
+ /* always set it ansi issue with bold */
+ ansi_reverse(is_reverse);
+}
+/* update the given physical line to look like the corresponding line in
+ curscr */
+
+void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
+{
+ int j, ch;
+ chtype attr = srcp[0] & A_ATTRIBUTES;
+ chtype prev_attr = attr;
+ struct ansi_set s;
+
+ /* ensure different */
+ s.cur_pair = PAIR_NUMBER(attr) + 1;
+
+ PDC_LOG(("PDC_transform_line() - called: line %d, len %d\n", lineno, len));
+
+ ansi_set_cursor(lineno, x);
+ set_attr(attr, &s);
+
+ for (j = 0; j < len; j++) {
+ ch = srcp[j];
+ attr = ch & A_ATTRIBUTES;
+
+ if (attr != prev_attr) {
+ set_attr(attr, &s);
+ prev_attr = attr;
+ }
+
+ if (ch & A_ALTCHARSET && !(ch & 0xff80))
+ ch = acs_map[ch & 0x7f];
+
+ putchar(ch & A_CHARTEXT);
+ }
+}
diff --git a/apps/lib/curses/pdcurses/backend/pdcgetsc.c b/apps/lib/curses/pdcurses/backend/pdcgetsc.c
new file mode 100644
index 0000000..e09a268
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdcgetsc.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include "barebox.h"
+#include <utils/termcap.h>
+
+/* return width of screen/viewport */
+int PDC_get_columns(void)
+{
+ int cols = 80;
+ int rows;
+
+ PDC_LOG(("PDC_get_columns() - called\n"));
+
+ term_get_size(&rows, &cols);
+
+ PDC_LOG(("PDC_get_columns() - returned: cols %d\n", cols));
+
+ return cols;
+}
+
+/* get the cursor size/shape */
+int PDC_get_cursor_mode(void)
+{
+ PDC_LOG(("PDC_get_cursor_mode() - called\n"));
+
+ /* only have one cursor type */
+ return SP->visibility;
+}
+
+/* return number of screen rows */
+int PDC_get_rows(void)
+{
+ int cols;
+ int rows = 25;
+
+ PDC_LOG(("PDC_get_rows() - called\n"));
+
+ term_get_size(&rows, &cols);
+
+ PDC_LOG(("PDC_get_rows() - returned: rows %d\n", rows));
+
+ return rows;
+}
diff --git a/apps/lib/curses/pdcurses/backend/pdckbd.c b/apps/lib/curses/pdcurses/backend/pdckbd.c
new file mode 100644
index 0000000..b9030a2
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdckbd.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include "barebox.h"
+#include <utils/getchar.h>
+
+unsigned long pdc_key_modifiers = 0L;
+
+static struct {
+ const char *seq;
+ int val;
+} escape_codes[] = {
+ { "OA", KEY_UP },
+ { "OB", KEY_DOWN },
+ { "OC", KEY_RIGHT },
+ { "OD", KEY_LEFT },
+ { "[A", KEY_UP },
+ { "[B", KEY_DOWN },
+ { "[C", KEY_RIGHT },
+ { "[D", KEY_LEFT },
+ { "[F", KEY_END },
+ { "[H", KEY_HOME },
+ { "[1~", KEY_HOME },
+ { "[2~", KEY_IC },
+ { "[3~", KEY_DC },
+ { "[5~", KEY_PPAGE },
+ { "[6~", KEY_NPAGE },
+ { "OP", KEY_F(1) },
+ { "OQ", KEY_F(2) },
+ { "OR", KEY_F(3) },
+ { "OS", KEY_F(4) },
+ { "[15~", KEY_F(5) },
+ { "[17~", KEY_F(6) },
+ { "[18~", KEY_F(7) },
+ { "[19~", KEY_F(8) },
+ { "[20~", KEY_F(9) },
+ { "[21~", KEY_F(10) },
+ { "[23~", KEY_F(11) },
+ { "[24~", KEY_F(12) },
+ { NULL },
+};
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static int read_escape(void)
+{
+ char buf[6];
+ int i = 0;
+
+ buf[i++] = getchar_timeout(10);
+ buf[i++] = getchar_timeout(10);
+
+ if (isdigit(buf[1])) {
+ for (; i < ARRAY_SIZE(buf); i++) {
+ buf[i] = getchar_timeout(10);
+ if (buf[i] < 0)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(buf))
+ goto err;
+ }
+
+ buf[i] = 0;
+ debug("buf = ");
+ for (i = 0; i < ARRAY_SIZE(buf); i++)
+ debug("%02x", buf[i]);
+ debug("\n");
+
+ for (i = 0; i < ARRAY_SIZE(escape_codes); i++) {
+ if (!strcmp(buf, escape_codes[i].seq)) {
+ debug("found 0x%x\n", escape_codes[i].val);
+ return escape_codes[i].val;
+ }
+ }
+
+err:
+ debug("buf = ");
+ for (i = 0; i < ARRAY_SIZE(buf); i++)
+ debug("%02x ", buf[i]);
+ debug("\n");
+
+ return 0;
+}
+
+static int readkey(void)
+{
+ int ch = getchar();
+
+ debug("buf = %x\n", ch);
+ switch(ch) {
+ case '\r':
+ return KEY_ENTER;
+ case '\n':
+ return KEY_ENTER;
+ case 8:
+ return KEY_BACKSPACE;
+ case 27:
+ return read_escape();
+
+ default:
+ return ch;
+ }
+}
+
+void PDC_set_keyboard_binary(bool on)
+{
+ PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
+}
+
+/* check if a key event is waiting */
+
+bool PDC_check_key(void)
+{
+ if (tstc())
+ return TRUE;
+
+ return FALSE;
+}
+
+/* return the next available key event */
+
+int PDC_get_key(void)
+{
+ int c = 0;
+
+ if (tstc())
+ c = readkey();
+
+ if (c == 0)
+ c = ERR;
+
+ SP->key_code = c >= KEY_MIN;
+
+ debug("key buf = 0x%x\n", c);
+
+ return c;
+}
+
+/* discard any pending keyboard input -- this is the core
+ routine for flushinp() */
+
+void PDC_flushinp(void)
+{
+ PDC_LOG(("PDC_flushinp() - called\n"));
+
+ while (PDC_check_key()) PDC_get_key();
+}
+
+int PDC_mouse_set(void)
+{
+ return ERR;
+}
+
+int PDC_modifiers_set(void)
+{
+ return OK;
+}
diff --git a/apps/lib/curses/pdcurses/backend/pdcscrn.c b/apps/lib/curses/pdcurses/backend/pdcscrn.c
new file mode 100644
index 0000000..904d573
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdcscrn.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include <utils/termcap.h>
+#include <utils/ansi.h>
+#include "barebox.h"
+
+#ifdef CHTYPE_LONG
+# define PDC_OFFSET 32
+#else
+# define PDC_OFFSET 8
+#endif
+
+/* COLOR_PAIR to attribute encoding table. */
+
+unsigned char *pdc_atrtab = (unsigned char *)NULL;
+
+short curstoreal[16], realtocurs[16] =
+{
+ COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
+ COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
+ COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
+ COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
+};
+
+/* close the physical screen -- may restore the screen to its state
+ before PDC_scr_open(); miscellaneous cleanup */
+
+void PDC_scr_close(void)
+{
+ PDC_LOG(("PDC_scr_close() - called\n"));
+
+ reset_shell_mode();
+
+ if (SP->visibility != 1)
+ curs_set(1);
+
+ ansi_set_cursor(0, 0);
+ ansi_set_color(39, 49);
+ ansi_clear();
+}
+
+void PDC_scr_free(void)
+{
+ free(SP);
+ free(pdc_atrtab);
+ pdc_atrtab = (unsigned char *)NULL;
+}
+
+/* open the physical screen -- allocate SP, miscellaneous intialization,
+ and may save the existing screen for later restoration */
+
+int PDC_scr_open(int argc, char **argv)
+{
+ int i;
+ int cols = 80;
+ int rows = 25;
+
+ PDC_LOG(("PDC_scr_open() - called\n"));
+
+
+ SP = calloc(1, sizeof(SCREEN));
+ pdc_atrtab = calloc(PDC_COLOR_PAIRS * PDC_OFFSET, 1);
+
+ if (!SP || !pdc_atrtab)
+ return ERR;
+
+ for (i = 0; i < 16; i++)
+ curstoreal[realtocurs[i]] = i;
+
+ SP->orig_attr = FALSE;
+
+ term_get_size(&rows, &cols);
+ SP->lines = rows;
+ SP->cols = cols;
+
+ ansi_clear();
+
+ return OK;
+}
+
+/* the core of resize_term() */
+
+int PDC_resize_screen(int nlines, int ncols)
+{
+ PDC_LOG(("PDC_resize_screen() - called. Lines: %d Cols: %d\n",
+ nlines, ncols));
+
+ return ERR;
+}
+
+void PDC_reset_prog_mode(void)
+{
+ PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
+}
+
+void PDC_reset_shell_mode(void)
+{
+ PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
+}
+
+void PDC_restore_screen_mode(int i)
+{
+}
+
+void PDC_save_screen_mode(int i)
+{
+}
+
+void PDC_init_pair(short pair, short fg, short bg)
+{
+ unsigned char att, temp_bg;
+ chtype i;
+
+ fg = curstoreal[fg];
+ bg = curstoreal[bg];
+
+ for (i = 0; i < PDC_OFFSET; i++) {
+ att = fg | (bg << 4);
+
+ if (i & (A_REVERSE >> PDC_ATTR_SHIFT))
+ att = bg | (fg << 4);
+ if (i & (A_UNDERLINE >> PDC_ATTR_SHIFT))
+ att = 1;
+ if (i & (A_INVIS >> PDC_ATTR_SHIFT)) {
+ temp_bg = att >> 4;
+ att = temp_bg << 4 | temp_bg;
+ }
+ if (i & (A_BOLD >> PDC_ATTR_SHIFT))
+ att |= 8;
+ if (i & (A_BLINK >> PDC_ATTR_SHIFT))
+ att |= 128;
+
+ pdc_atrtab[pair * PDC_OFFSET + i] = att;
+ }
+}
+
+int PDC_pair_content(short pair, short *fg, short *bg)
+{
+ *fg = realtocurs[pdc_atrtab[pair * PDC_OFFSET] & 0x0F];
+ *bg = realtocurs[(pdc_atrtab[pair * PDC_OFFSET] & 0xF0) >> 4];
+
+ return OK;
+}
+
+bool PDC_can_change_color(void)
+{
+ return FALSE;
+}
+
+int PDC_color_content(short color, short *red, short *green, short *blue)
+{
+ return ERR;
+}
+
+int PDC_init_color(short color, short red, short green, short blue)
+{
+ return ERR;
+}
diff --git a/apps/lib/curses/pdcurses/backend/pdcsetsc.c b/apps/lib/curses/pdcurses/backend/pdcsetsc.c
new file mode 100644
index 0000000..79db8fb
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdcsetsc.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include <utils/ansi.h>
+#include "barebox.h"
+
+int PDC_curs_set(int visibility)
+{
+ int ret_vis;
+
+ PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility));
+
+ ret_vis = SP->visibility;
+ SP->visibility = visibility;
+
+ ansi_cursor_enable(visibility);
+
+ return ret_vis;
+}
+
+int PDC_set_blink(bool blinkon)
+{
+ if (pdc_color_started)
+ COLORS = 16;
+
+ return ERR;
+}
+
+void PDC_set_title(const char *title)
+{
+ printf("\033]0;%s", title);
+}
diff --git a/apps/lib/curses/pdcurses/backend/pdcutil.c b/apps/lib/curses/pdcurses/backend/pdcutil.c
new file mode 100644
index 0000000..d171c01
--- /dev/null
+++ b/apps/lib/curses/pdcurses/backend/pdcutil.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Under BSD
+ */
+
+#include "barebox.h"
+
+void PDC_beep(void)
+{
+ PDC_LOG(("PDC_beep() - called\n"));
+
+ printf("\a");
+}
+
+void PDC_napms(int ms)
+{
+ PDC_LOG(("PDC_napms() - called: ms=%d\n", ms));
+
+ usleep(ms * 1000);
+}
+
+const char *PDC_sysname(void)
+{
+ return "barebox";
+}
diff --git a/apps/lib/curses/pdcurses/include/curses.h b/apps/lib/curses/pdcurses/include/curses.h
new file mode 100644
index 0000000..234c5fe
--- /dev/null
+++ b/apps/lib/curses/pdcurses/include/curses.h
@@ -0,0 +1,1378 @@
+/* Public Domain Curses */
+
+/* $Id: curses.h,v 1.295 2008/07/15 17:13:25 wmcbrine Exp $ */
+
+/*----------------------------------------------------------------------*
+ * PDCurses *
+ *----------------------------------------------------------------------*/
+
+#ifndef __PDCURSES__
+#define __PDCURSES__ 1
+
+/*man-start**************************************************************
+
+PDCurses definitions list: (Only define those needed)
+
+ XCURSES True if compiling for X11.
+ PDC_RGB True if you want to use RGB color definitions
+ (Red = 1, Green = 2, Blue = 4) instead of BGR.
+ PDC_WIDE True if building wide-character support.
+ PDC_DLL_BUILD True if building a Win32 DLL.
+ NCURSES_MOUSE_VERSION Use the ncurses mouse API instead
+ of PDCurses' traditional mouse API.
+
+PDCurses portable platform definitions list:
+
+ PDC_BUILD Defines API build version.
+ PDCURSES Enables access to PDCurses-only routines.
+ XOPEN Always true.
+ SYSVcurses True if you are compiling for SYSV portability.
+ BSDcurses True if you are compiling for BSD portability.
+
+**man-end****************************************************************/
+
+#define PDC_BUILD 3401
+#define PDCURSES 1 /* PDCurses-only routines */
+#define XOPEN 1 /* X/Open Curses routines */
+#define SYSVcurses 1 /* System V Curses routines */
+#define BSDcurses 1 /* BSD Curses routines */
+#define CHTYPE_LONG 1 /* size of chtype; long */
+#define PDC_RGB /* RGB mode ansi terminal */
+
+/*----------------------------------------------------------------------*/
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h> /* Required by X/Open usage below */
+
+#ifdef PDC_WIDE
+# include <wchar.h>
+#endif
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+extern "C"
+{
+# define bool _bool
+#endif
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses Manifest Constants
+ *
+ */
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef NULL
+# define NULL (void *)0
+#endif
+#ifndef ERR
+# define ERR (-1)
+#endif
+#ifndef OK
+# define OK 0
+#endif
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses Type Declarations
+ *
+ */
+
+//typedef unsigned char bool; /* PDCurses Boolean type */
+
+#ifdef CHTYPE_LONG
+# if _LP64
+typedef unsigned int chtype;
+# else
+typedef unsigned long chtype; /* 16-bit attr + 16-bit char */
+# endif
+#else
+typedef unsigned short chtype; /* 8-bit attr + 8-bit char */
+#endif
+
+#ifdef PDC_WIDE
+typedef chtype cchar_t;
+#endif
+
+typedef chtype attr_t;
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses Mouse Interface -- SYSVR4, with extensions
+ *
+ */
+
+typedef struct
+{
+ int x; /* absolute column, 0 based, measured in characters */
+ int y; /* absolute row, 0 based, measured in characters */
+ short button[3]; /* state of each button */
+ int changes; /* flags indicating what has changed with the mouse */
+} MOUSE_STATUS;
+
+#define BUTTON_RELEASED 0x0000
+#define BUTTON_PRESSED 0x0001
+#define BUTTON_CLICKED 0x0002
+#define BUTTON_DOUBLE_CLICKED 0x0003
+#define BUTTON_TRIPLE_CLICKED 0x0004
+#define BUTTON_MOVED 0x0005 /* PDCurses */
+#define WHEEL_SCROLLED 0x0006 /* PDCurses */
+#define BUTTON_ACTION_MASK 0x0007 /* PDCurses */
+
+#define PDC_BUTTON_SHIFT 0x0008 /* PDCurses */
+#define PDC_BUTTON_CONTROL 0x0010 /* PDCurses */
+#define PDC_BUTTON_ALT 0x0020 /* PDCurses */
+#define BUTTON_MODIFIER_MASK 0x0038 /* PDCurses */
+
+#define MOUSE_X_POS (Mouse_status.x)
+#define MOUSE_Y_POS (Mouse_status.y)
+
+/*
+ * Bits associated with the .changes field:
+ * 3 2 1 0
+ * 210987654321098765432109876543210
+ * 1 <- button 1 has changed
+ * 10 <- button 2 has changed
+ * 100 <- button 3 has changed
+ * 1000 <- mouse has moved
+ * 10000 <- mouse position report
+ * 100000 <- mouse wheel up
+ * 1000000 <- mouse wheel down
+ */
+
+#define PDC_MOUSE_MOVED 0x0008
+#define PDC_MOUSE_POSITION 0x0010
+#define PDC_MOUSE_WHEEL_UP 0x0020
+#define PDC_MOUSE_WHEEL_DOWN 0x0040
+
+#define A_BUTTON_CHANGED (Mouse_status.changes & 7)
+#define MOUSE_MOVED (Mouse_status.changes & PDC_MOUSE_MOVED)
+#define MOUSE_POS_REPORT (Mouse_status.changes & PDC_MOUSE_POSITION)
+#define BUTTON_CHANGED(x) (Mouse_status.changes & (1 << ((x) - 1)))
+#define BUTTON_STATUS(x) (Mouse_status.button[(x) - 1])
+#define MOUSE_WHEEL_UP (Mouse_status.changes & PDC_MOUSE_WHEEL_UP)
+#define MOUSE_WHEEL_DOWN (Mouse_status.changes & PDC_MOUSE_WHEEL_DOWN)
+
+/* mouse bit-masks */
+
+#define BUTTON1_RELEASED 0x00000001L
+#define BUTTON1_PRESSED 0x00000002L
+#define BUTTON1_CLICKED 0x00000004L
+#define BUTTON1_DOUBLE_CLICKED 0x00000008L
+#define BUTTON1_TRIPLE_CLICKED 0x00000010L
+#define BUTTON1_MOVED 0x00000010L /* PDCurses */
+
+#define BUTTON2_RELEASED 0x00000020L
+#define BUTTON2_PRESSED 0x00000040L
+#define BUTTON2_CLICKED 0x00000080L
+#define BUTTON2_DOUBLE_CLICKED 0x00000100L
+#define BUTTON2_TRIPLE_CLICKED 0x00000200L
+#define BUTTON2_MOVED 0x00000200L /* PDCurses */
+
+#define BUTTON3_RELEASED 0x00000400L
+#define BUTTON3_PRESSED 0x00000800L
+#define BUTTON3_CLICKED 0x00001000L
+#define BUTTON3_DOUBLE_CLICKED 0x00002000L
+#define BUTTON3_TRIPLE_CLICKED 0x00004000L
+#define BUTTON3_MOVED 0x00004000L /* PDCurses */
+
+/* For the ncurses-compatible functions only, BUTTON4_PRESSED and
+ BUTTON5_PRESSED are returned for mouse scroll wheel up and down;
+ otherwise PDCurses doesn't support buttons 4 and 5 */
+
+#define BUTTON4_RELEASED 0x00008000L
+#define BUTTON4_PRESSED 0x00010000L
+#define BUTTON4_CLICKED 0x00020000L
+#define BUTTON4_DOUBLE_CLICKED 0x00040000L
+#define BUTTON4_TRIPLE_CLICKED 0x00080000L
+
+#define BUTTON5_RELEASED 0x00100000L
+#define BUTTON5_PRESSED 0x00200000L
+#define BUTTON5_CLICKED 0x00400000L
+#define BUTTON5_DOUBLE_CLICKED 0x00800000L
+#define BUTTON5_TRIPLE_CLICKED 0x01000000L
+
+#define MOUSE_WHEEL_SCROLL 0x02000000L /* PDCurses */
+#define BUTTON_MODIFIER_SHIFT 0x04000000L /* PDCurses */
+#define BUTTON_MODIFIER_CONTROL 0x08000000L /* PDCurses */
+#define BUTTON_MODIFIER_ALT 0x10000000L /* PDCurses */
+
+#define ALL_MOUSE_EVENTS 0x1fffffffL
+#define REPORT_MOUSE_POSITION 0x20000000L
+
+/* ncurses mouse interface */
+
+typedef unsigned long mmask_t;
+
+typedef struct
+{
+ short id; /* unused, always 0 */
+ int x, y, z; /* x, y same as MOUSE_STATUS; z unused */
+ mmask_t bstate; /* equivalent to changes + button[], but
+ in the same format as used for mousemask() */
+} MEVENT;
+
+#ifdef NCURSES_MOUSE_VERSION
+# define BUTTON_SHIFT BUTTON_MODIFIER_SHIFT
+# define BUTTON_CONTROL BUTTON_MODIFIER_CONTROL
+# define BUTTON_CTRL BUTTON_MODIFIER_CONTROL
+# define BUTTON_ALT BUTTON_MODIFIER_ALT
+#else
+# define BUTTON_SHIFT PDC_BUTTON_SHIFT
+# define BUTTON_CONTROL PDC_BUTTON_CONTROL
+# define BUTTON_ALT PDC_BUTTON_ALT
+#endif
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses Structure Definitions
+ *
+ */
+
+typedef struct _win /* definition of a window */
+{
+ int _cury; /* current pseudo-cursor */
+ int _curx;
+ int _maxy; /* max window coordinates */
+ int _maxx;
+ int _begy; /* origin on screen */
+ int _begx;
+ int _flags; /* window properties */
+ chtype _attrs; /* standard attributes and colors */
+ chtype _bkgd; /* background, normally blank */
+ bool _clear; /* causes clear at next refresh */
+ bool _leaveit; /* leaves cursor where it is */
+ bool _scroll; /* allows window scrolling */
+ bool _nodelay; /* input character wait flag */
+ bool _immed; /* immediate update flag */
+ bool _sync; /* synchronise window ancestors */
+ bool _use_keypad; /* flags keypad key mode active */
+ chtype **_y; /* pointer to line pointer array */
+ int *_firstch; /* first changed character in line */
+ int *_lastch; /* last changed character in line */
+ int _tmarg; /* top of scrolling region */
+ int _bmarg; /* bottom of scrolling region */
+ int _delayms; /* milliseconds of delay for getch() */
+ int _parx, _pary; /* coords relative to parent (0,0) */
+ struct _win *_parent; /* subwin's pointer to parent win */
+} WINDOW;
+
+/* Avoid using the SCREEN struct directly -- use the corresponding
+ functions if possible. This struct may eventually be made private. */
+
+typedef struct
+{
+ bool alive; /* if initscr() called, and not endwin() */
+ bool autocr; /* if cr -> lf */
+ bool cbreak; /* if terminal unbuffered */
+ bool echo; /* if terminal echo */
+ bool raw_inp; /* raw input mode (v. cooked input) */
+ bool raw_out; /* raw output mode (7 v. 8 bits) */
+ bool audible; /* FALSE if the bell is visual */
+ bool mono; /* TRUE if current screen is mono */
+ bool resized; /* TRUE if TERM has been resized */
+ bool orig_attr; /* TRUE if we have the original colors */
+ short orig_fore; /* original screen foreground color */
+ short orig_back; /* original screen foreground color */
+ int cursrow; /* position of physical cursor */
+ int curscol; /* position of physical cursor */
+ int visibility; /* visibility of cursor */
+ int orig_cursor; /* original cursor size */
+ int lines; /* new value for LINES */
+ int cols; /* new value for COLS */
+ unsigned long _trap_mbe; /* trap these mouse button events */
+ unsigned long _map_mbe_to_key; /* map mouse buttons to slk */
+ int mouse_wait; /* time to wait (in ms) for a
+ button release after a press, in
+ order to count it as a click */
+ int slklines; /* lines in use by slk_init() */
+ WINDOW *slk_winptr; /* window for slk */
+ int linesrippedoff; /* lines ripped off via ripoffline() */
+ int linesrippedoffontop; /* lines ripped off on
+ top via ripoffline() */
+ int delaytenths; /* 1/10ths second to wait block
+ getch() for */
+ bool _preserve; /* TRUE if screen background
+ to be preserved */
+ int _restore; /* specifies if screen background
+ to be restored, and how */
+ bool save_key_modifiers; /* TRUE if each key modifiers saved
+ with each key press */
+ bool return_key_modifiers; /* TRUE if modifier keys are
+ returned as "real" keys */
+ bool key_code; /* TRUE if last key is a special key;
+ used internally by get_wch() */
+#ifdef XCURSES
+ int XcurscrSize; /* size of Xcurscr shared memory block */
+ bool sb_on;
+ int sb_viewport_y;
+ int sb_viewport_x;
+ int sb_total_y;
+ int sb_total_x;
+ int sb_cur_y;
+ int sb_cur_x;
+#endif
+ short line_color; /* color of line attributes - default -1 */
+} SCREEN;
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses External Variables
+ *
+ */
+
+#ifdef PDC_DLL_BUILD
+# ifdef CURSES_LIBRARY
+# define PDCEX __declspec(dllexport) extern
+# else
+# define PDCEX __declspec(dllimport)
+# endif
+#else
+# define PDCEX extern
+#endif
+
+PDCEX int LINES; /* terminal height */
+PDCEX int COLS; /* terminal width */
+PDCEX WINDOW *stdscr; /* the default screen window */
+PDCEX WINDOW *curscr; /* the current screen image */
+PDCEX SCREEN *SP; /* curses variables */
+PDCEX MOUSE_STATUS Mouse_status;
+PDCEX int COLORS;
+PDCEX int COLOR_PAIRS;
+PDCEX int TABSIZE;
+PDCEX chtype acs_map[]; /* alternate character set map */
+PDCEX char ttytype[]; /* terminal name/description */
+
+/*man-start**************************************************************
+
+PDCurses Text Attributes
+========================
+
+Originally, PDCurses used a short (16 bits) for its chtype. To include
+color, a number of things had to be sacrificed from the strict Unix and
+System V support. The main problem was fitting all character attributes
+and color into an unsigned char (all 8 bits!).
+
+Today, PDCurses by default uses a long (32 bits) for its chtype, as in
+System V. The short chtype is still available, by undefining CHTYPE_LONG
+and rebuilding the library.
+
+The following is the structure of a win->_attrs chtype:
+
+short form:
+
+-------------------------------------------------
+|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+-------------------------------------------------
+ color number | attrs | character eg 'a'
+
+The available non-color attributes are bold, reverse and blink. Others
+have no effect. The high order char is an index into an array of
+physical colors (defined in color.c) -- 32 foreground/background color
+pairs (5 bits) plus 3 bits for other attributes.
+
+long form:
+
+----------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|..| 3| 2| 1| 0|
+----------------------------------------------------------------------------
+ color number | modifiers | character eg 'a'
+
+The available non-color attributes are bold, underline, invisible,
+right-line, left-line, protect, reverse and blink. 256 color pairs (8
+bits), 8 bits for other attributes, and 16 bits for character data.
+
+**man-end****************************************************************/
+
+/*** Video attribute macros ***/
+
+#define A_NORMAL (chtype)0
+
+#ifdef CHTYPE_LONG
+# define A_ALTCHARSET (chtype)0x00010000
+# define A_RIGHTLINE (chtype)0x00020000
+# define A_LEFTLINE (chtype)0x00040000
+# define A_INVIS (chtype)0x00080000
+# define A_UNDERLINE (chtype)0x00100000
+# define A_REVERSE (chtype)0x00200000
+# define A_BLINK (chtype)0x00400000
+# define A_BOLD (chtype)0x00800000
+
+# define A_ATTRIBUTES (chtype)0xffff0000
+# define A_CHARTEXT (chtype)0x0000ffff
+# define A_COLOR (chtype)0xff000000
+
+# define A_ITALIC A_INVIS
+# define A_PROTECT (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE)
+
+# define PDC_ATTR_SHIFT 19
+# define PDC_COLOR_SHIFT 24
+#else
+# define A_BOLD (chtype)0x0100 /* X/Open */
+# define A_REVERSE (chtype)0x0200 /* X/Open */
+# define A_BLINK (chtype)0x0400 /* X/Open */
+
+# define A_ATTRIBUTES (chtype)0xff00 /* X/Open */
+# define A_CHARTEXT (chtype)0x00ff /* X/Open */
+# define A_COLOR (chtype)0xf800 /* System V */
+
+# define A_ALTCHARSET A_NORMAL /* X/Open */
+# define A_PROTECT A_NORMAL /* X/Open */
+# define A_UNDERLINE A_NORMAL /* X/Open */
+
+# define A_LEFTLINE A_NORMAL
+# define A_RIGHTLINE A_NORMAL
+# define A_ITALIC A_NORMAL
+# define A_INVIS A_NORMAL
+
+# define PDC_ATTR_SHIFT 8
+# define PDC_COLOR_SHIFT 11
+#endif
+
+#define A_STANDOUT (A_REVERSE | A_BOLD) /* X/Open */
+#define A_DIM A_NORMAL
+
+#define CHR_MSK A_CHARTEXT /* Obsolete */
+#define ATR_MSK A_ATTRIBUTES /* Obsolete */
+#define ATR_NRM A_NORMAL /* Obsolete */
+
+/* For use with attr_t -- X/Open says, "these shall be distinct", so
+ this is a non-conforming implementation. */
+
+#define WA_ALTCHARSET A_ALTCHARSET
+#define WA_BLINK A_BLINK
+#define WA_BOLD A_BOLD
+#define WA_DIM A_DIM
+#define WA_INVIS A_INVIS
+#define WA_LEFT A_LEFTLINE
+#define WA_PROTECT A_PROTECT
+#define WA_REVERSE A_REVERSE
+#define WA_RIGHT A_RIGHTLINE
+#define WA_STANDOUT A_STANDOUT
+#define WA_UNDERLINE A_UNDERLINE
+
+#define WA_HORIZONTAL A_NORMAL
+#define WA_LOW A_NORMAL
+#define WA_TOP A_NORMAL
+#define WA_VERTICAL A_NORMAL
+
+/*** Alternate character set macros ***/
+
+/* 'w' = 32-bit chtype; acs_map[] index | A_ALTCHARSET
+ 'n' = 16-bit chtype; it gets the fallback set because no bit is
+ available for A_ALTCHARSET */
+
+#ifdef CHTYPE_LONG
+# define ACS_PICK(w, n) ((chtype)w | A_ALTCHARSET)
+#else
+# define ACS_PICK(w, n) ((chtype)n)
+#endif
+
+/* VT100-compatible symbols -- box chars */
+
+#define ACS_ULCORNER ACS_PICK('l', '+')
+#define ACS_LLCORNER ACS_PICK('m', '+')
+#define ACS_URCORNER ACS_PICK('k', '+')
+#define ACS_LRCORNER ACS_PICK('j', '+')
+#define ACS_RTEE ACS_PICK('u', '+')
+#define ACS_LTEE ACS_PICK('t', '+')
+#define ACS_BTEE ACS_PICK('v', '+')
+#define ACS_TTEE ACS_PICK('w', '+')
+#define ACS_HLINE ACS_PICK('q', '-')
+#define ACS_VLINE ACS_PICK('x', '|')
+#define ACS_PLUS ACS_PICK('n', '+')
+
+/* VT100-compatible symbols -- other */
+
+#define ACS_S1 ACS_PICK('o', '-')
+#define ACS_S9 ACS_PICK('s', '_')
+#define ACS_DIAMOND ACS_PICK('`', '+')
+#define ACS_CKBOARD ACS_PICK('a', ':')
+#define ACS_DEGREE ACS_PICK('f', '\'')
+#define ACS_PLMINUS ACS_PICK('g', '#')
+#define ACS_BULLET ACS_PICK('~', 'o')
+
+/* Teletype 5410v1 symbols -- these are defined in SysV curses, but
+ are not well-supported by most terminals. Stick to VT100 characters
+ for optimum portability. */
+
+#define ACS_LARROW ACS_PICK(',', '<')
+#define ACS_RARROW ACS_PICK('+', '>')
+#define ACS_DARROW ACS_PICK('.', 'v')
+#define ACS_UARROW ACS_PICK('-', '^')
+#define ACS_BOARD ACS_PICK('h', '#')
+#define ACS_LANTERN ACS_PICK('i', '*')
+#define ACS_BLOCK ACS_PICK('0', '#')
+
+/* That goes double for these -- undocumented SysV symbols. Don't use
+ them. */
+
+#define ACS_S3 ACS_PICK('p', '-')
+#define ACS_S7 ACS_PICK('r', '-')
+#define ACS_LEQUAL ACS_PICK('y', '<')
+#define ACS_GEQUAL ACS_PICK('z', '>')
+#define ACS_PI ACS_PICK('{', 'n')
+#define ACS_NEQUAL ACS_PICK('|', '+')
+#define ACS_STERLING ACS_PICK('}', 'L')
+
+/* Box char aliases */
+
+#define ACS_BSSB ACS_ULCORNER
+#define ACS_SSBB ACS_LLCORNER
+#define ACS_BBSS ACS_URCORNER
+#define ACS_SBBS ACS_LRCORNER
+#define ACS_SBSS ACS_RTEE
+#define ACS_SSSB ACS_LTEE
+#define ACS_SSBS ACS_BTEE
+#define ACS_BSSS ACS_TTEE
+#define ACS_BSBS ACS_HLINE
+#define ACS_SBSB ACS_VLINE
+#define ACS_SSSS ACS_PLUS
+
+/* cchar_t aliases */
+
+#ifdef PDC_WIDE
+# define WACS_ULCORNER (&(acs_map['l']))
+# define WACS_LLCORNER (&(acs_map['m']))
+# define WACS_URCORNER (&(acs_map['k']))
+# define WACS_LRCORNER (&(acs_map['j']))
+# define WACS_RTEE (&(acs_map['u']))
+# define WACS_LTEE (&(acs_map['t']))
+# define WACS_BTEE (&(acs_map['v']))
+# define WACS_TTEE (&(acs_map['w']))
+# define WACS_HLINE (&(acs_map['q']))
+# define WACS_VLINE (&(acs_map['x']))
+# define WACS_PLUS (&(acs_map['n']))
+
+# define WACS_S1 (&(acs_map['o']))
+# define WACS_S9 (&(acs_map['s']))
+# define WACS_DIAMOND (&(acs_map['`']))
+# define WACS_CKBOARD (&(acs_map['a']))
+# define WACS_DEGREE (&(acs_map['f']))
+# define WACS_PLMINUS (&(acs_map['g']))
+# define WACS_BULLET (&(acs_map['~']))
+
+# define WACS_LARROW (&(acs_map[',']))
+# define WACS_RARROW (&(acs_map['+']))
+# define WACS_DARROW (&(acs_map['.']))
+# define WACS_UARROW (&(acs_map['-']))
+# define WACS_BOARD (&(acs_map['h']))
+# define WACS_LANTERN (&(acs_map['i']))
+# define WACS_BLOCK (&(acs_map['0']))
+
+# define WACS_S3 (&(acs_map['p']))
+# define WACS_S7 (&(acs_map['r']))
+# define WACS_LEQUAL (&(acs_map['y']))
+# define WACS_GEQUAL (&(acs_map['z']))
+# define WACS_PI (&(acs_map['{']))
+# define WACS_NEQUAL (&(acs_map['|']))
+# define WACS_STERLING (&(acs_map['}']))
+
+# define WACS_BSSB WACS_ULCORNER
+# define WACS_SSBB WACS_LLCORNER
+# define WACS_BBSS WACS_URCORNER
+# define WACS_SBBS WACS_LRCORNER
+# define WACS_SBSS WACS_RTEE
+# define WACS_SSSB WACS_LTEE
+# define WACS_SSBS WACS_BTEE
+# define WACS_BSSS WACS_TTEE
+# define WACS_BSBS WACS_HLINE
+# define WACS_SBSB WACS_VLINE
+# define WACS_SSSS WACS_PLUS
+#endif
+
+/*** Color macros ***/
+
+#define COLOR_BLACK 0
+
+#ifdef PDC_RGB /* RGB */
+# define COLOR_RED 1
+# define COLOR_GREEN 2
+# define COLOR_BLUE 4
+#else /* BGR */
+# define COLOR_BLUE 1
+# define COLOR_GREEN 2
+# define COLOR_RED 4
+#endif
+
+#define COLOR_CYAN (COLOR_BLUE | COLOR_GREEN)
+#define COLOR_MAGENTA (COLOR_RED | COLOR_BLUE)
+#define COLOR_YELLOW (COLOR_RED | COLOR_GREEN)
+
+#define COLOR_WHITE 7
+
+/*----------------------------------------------------------------------
+ *
+ * Function and Keypad Key Definitions.
+ * Many are just for compatibility.
+ *
+ */
+
+#define KEY_CODE_YES 0x100 /* If get_wch() gives a key code */
+
+#define KEY_BREAK 0x101 /* Not on PC KBD */
+#define KEY_DOWN 0x102 /* Down arrow key */
+#define KEY_UP 0x103 /* Up arrow key */
+#define KEY_LEFT 0x104 /* Left arrow key */
+#define KEY_RIGHT 0x105 /* Right arrow key */
+#define KEY_HOME 0x106 /* home key */
+#define KEY_BACKSPACE 0x107 /* not on pc */
+#define KEY_F0 0x108 /* function keys; 64 reserved */
+
+#define KEY_DL 0x148 /* delete line */
+#define KEY_IL 0x149 /* insert line */
+#define KEY_DC 0x14a /* delete character */
+#define KEY_IC 0x14b /* insert char or enter ins mode */
+#define KEY_EIC 0x14c /* exit insert char mode */
+#define KEY_CLEAR 0x14d /* clear screen */
+#define KEY_EOS 0x14e /* clear to end of screen */
+#define KEY_EOL 0x14f /* clear to end of line */
+#define KEY_SF 0x150 /* scroll 1 line forward */
+#define KEY_SR 0x151 /* scroll 1 line back (reverse) */
+#define KEY_NPAGE 0x152 /* next page */
+#define KEY_PPAGE 0x153 /* previous page */
+#define KEY_STAB 0x154 /* set tab */
+#define KEY_CTAB 0x155 /* clear tab */
+#define KEY_CATAB 0x156 /* clear all tabs */
+#define KEY_ENTER 0x157 /* enter or send (unreliable) */
+#define KEY_SRESET 0x158 /* soft/reset (partial/unreliable) */
+#define KEY_RESET 0x159 /* reset/hard reset (unreliable) */
+#define KEY_PRINT 0x15a /* print/copy */
+#define KEY_LL 0x15b /* home down/bottom (lower left) */
+#define KEY_ABORT 0x15c /* abort/terminate key (any) */
+#define KEY_SHELP 0x15d /* short help */
+#define KEY_LHELP 0x15e /* long help */
+#define KEY_BTAB 0x15f /* Back tab key */
+#define KEY_BEG 0x160 /* beg(inning) key */
+#define KEY_CANCEL 0x161 /* cancel key */
+#define KEY_CLOSE 0x162 /* close key */
+#define KEY_COMMAND 0x163 /* cmd (command) key */
+#define KEY_COPY 0x164 /* copy key */
+#define KEY_CREATE 0x165 /* create key */
+#define KEY_END 0x166 /* end key */
+#define KEY_EXIT 0x167 /* exit key */
+#define KEY_FIND 0x168 /* find key */
+#define KEY_HELP 0x169 /* help key */
+#define KEY_MARK 0x16a /* mark key */
+#define KEY_MESSAGE 0x16b /* message key */
+#define KEY_MOVE 0x16c /* move key */
+#define KEY_NEXT 0x16d /* next object key */
+#define KEY_OPEN 0x16e /* open key */
+#define KEY_OPTIONS 0x16f /* options key */
+#define KEY_PREVIOUS 0x170 /* previous object key */
+#define KEY_REDO 0x171 /* redo key */
+#define KEY_REFERENCE 0x172 /* ref(erence) key */
+#define KEY_REFRESH 0x173 /* refresh key */
+#define KEY_REPLACE 0x174 /* replace key */
+#define KEY_RESTART 0x175 /* restart key */
+#define KEY_RESUME 0x176 /* resume key */
+#define KEY_SAVE 0x177 /* save key */
+#define KEY_SBEG 0x178 /* shifted beginning key */
+#define KEY_SCANCEL 0x179 /* shifted cancel key */
+#define KEY_SCOMMAND 0x17a /* shifted command key */
+#define KEY_SCOPY 0x17b /* shifted copy key */
+#define KEY_SCREATE 0x17c /* shifted create key */
+#define KEY_SDC 0x17d /* shifted delete char key */
+#define KEY_SDL 0x17e /* shifted delete line key */
+#define KEY_SELECT 0x17f /* select key */
+#define KEY_SEND 0x180 /* shifted end key */
+#define KEY_SEOL 0x181 /* shifted clear line key */
+#define KEY_SEXIT 0x182 /* shifted exit key */
+#define KEY_SFIND 0x183 /* shifted find key */
+#define KEY_SHOME 0x184 /* shifted home key */
+#define KEY_SIC 0x185 /* shifted input key */
+
+#define KEY_SLEFT 0x187 /* shifted left arrow key */
+#define KEY_SMESSAGE 0x188 /* shifted message key */
+#define KEY_SMOVE 0x189 /* shifted move key */
+#define KEY_SNEXT 0x18a /* shifted next key */
+#define KEY_SOPTIONS 0x18b /* shifted options key */
+#define KEY_SPREVIOUS 0x18c /* shifted prev key */
+#define KEY_SPRINT 0x18d /* shifted print key */
+#define KEY_SREDO 0x18e /* shifted redo key */
+#define KEY_SREPLACE 0x18f /* shifted replace key */
+#define KEY_SRIGHT 0x190 /* shifted right arrow */
+#define KEY_SRSUME 0x191 /* shifted resume key */
+#define KEY_SSAVE 0x192 /* shifted save key */
+#define KEY_SSUSPEND 0x193 /* shifted suspend key */
+#define KEY_SUNDO 0x194 /* shifted undo key */
+#define KEY_SUSPEND 0x195 /* suspend key */
+#define KEY_UNDO 0x196 /* undo key */
+
+/* PDCurses-specific key definitions -- PC only */
+
+#define ALT_0 0x197
+#define ALT_1 0x198
+#define ALT_2 0x199
+#define ALT_3 0x19a
+#define ALT_4 0x19b
+#define ALT_5 0x19c
+#define ALT_6 0x19d
+#define ALT_7 0x19e
+#define ALT_8 0x19f
+#define ALT_9 0x1a0
+#define ALT_A 0x1a1
+#define ALT_B 0x1a2
+#define ALT_C 0x1a3
+#define ALT_D 0x1a4
+#define ALT_E 0x1a5
+#define ALT_F 0x1a6
+#define ALT_G 0x1a7
+#define ALT_H 0x1a8
+#define ALT_I 0x1a9
+#define ALT_J 0x1aa
+#define ALT_K 0x1ab
+#define ALT_L 0x1ac
+#define ALT_M 0x1ad
+#define ALT_N 0x1ae
+#define ALT_O 0x1af
+#define ALT_P 0x1b0
+#define ALT_Q 0x1b1
+#define ALT_R 0x1b2
+#define ALT_S 0x1b3
+#define ALT_T 0x1b4
+#define ALT_U 0x1b5
+#define ALT_V 0x1b6
+#define ALT_W 0x1b7
+#define ALT_X 0x1b8
+#define ALT_Y 0x1b9
+#define ALT_Z 0x1ba
+
+#define CTL_LEFT 0x1bb /* Control-Left-Arrow */
+#define CTL_RIGHT 0x1bc
+#define CTL_PGUP 0x1bd
+#define CTL_PGDN 0x1be
+#define CTL_HOME 0x1bf
+#define CTL_END 0x1c0
+
+#define KEY_A1 0x1c1 /* upper left on Virtual keypad */
+#define KEY_A2 0x1c2 /* upper middle on Virt. keypad */
+#define KEY_A3 0x1c3 /* upper right on Vir. keypad */
+#define KEY_B1 0x1c4 /* middle left on Virt. keypad */
+#define KEY_B2 0x1c5 /* center on Virt. keypad */
+#define KEY_B3 0x1c6 /* middle right on Vir. keypad */
+#define KEY_C1 0x1c7 /* lower left on Virt. keypad */
+#define KEY_C2 0x1c8 /* lower middle on Virt. keypad */
+#define KEY_C3 0x1c9 /* lower right on Vir. keypad */
+
+#define PADSLASH 0x1ca /* slash on keypad */
+#define PADENTER 0x1cb /* enter on keypad */
+#define CTL_PADENTER 0x1cc /* ctl-enter on keypad */
+#define ALT_PADENTER 0x1cd /* alt-enter on keypad */
+#define PADSTOP 0x1ce /* stop on keypad */
+#define PADSTAR 0x1cf /* star on keypad */
+#define PADMINUS 0x1d0 /* minus on keypad */
+#define PADPLUS 0x1d1 /* plus on keypad */
+#define CTL_PADSTOP 0x1d2 /* ctl-stop on keypad */
+#define CTL_PADCENTER 0x1d3 /* ctl-enter on keypad */
+#define CTL_PADPLUS 0x1d4 /* ctl-plus on keypad */
+#define CTL_PADMINUS 0x1d5 /* ctl-minus on keypad */
+#define CTL_PADSLASH 0x1d6 /* ctl-slash on keypad */
+#define CTL_PADSTAR 0x1d7 /* ctl-star on keypad */
+#define ALT_PADPLUS 0x1d8 /* alt-plus on keypad */
+#define ALT_PADMINUS 0x1d9 /* alt-minus on keypad */
+#define ALT_PADSLASH 0x1da /* alt-slash on keypad */
+#define ALT_PADSTAR 0x1db /* alt-star on keypad */
+#define ALT_PADSTOP 0x1dc /* alt-stop on keypad */
+#define CTL_INS 0x1dd /* ctl-insert */
+#define ALT_DEL 0x1de /* alt-delete */
+#define ALT_INS 0x1df /* alt-insert */
+#define CTL_UP 0x1e0 /* ctl-up arrow */
+#define CTL_DOWN 0x1e1 /* ctl-down arrow */
+#define CTL_TAB 0x1e2 /* ctl-tab */
+#define ALT_TAB 0x1e3
+#define ALT_MINUS 0x1e4
+#define ALT_EQUAL 0x1e5
+#define ALT_HOME 0x1e6
+#define ALT_PGUP 0x1e7
+#define ALT_PGDN 0x1e8
+#define ALT_END 0x1e9
+#define ALT_UP 0x1ea /* alt-up arrow */
+#define ALT_DOWN 0x1eb /* alt-down arrow */
+#define ALT_RIGHT 0x1ec /* alt-right arrow */
+#define ALT_LEFT 0x1ed /* alt-left arrow */
+#define ALT_ENTER 0x1ee /* alt-enter */
+#define ALT_ESC 0x1ef /* alt-escape */
+#define ALT_BQUOTE 0x1f0 /* alt-back quote */
+#define ALT_LBRACKET 0x1f1 /* alt-left bracket */
+#define ALT_RBRACKET 0x1f2 /* alt-right bracket */
+#define ALT_SEMICOLON 0x1f3 /* alt-semi-colon */
+#define ALT_FQUOTE 0x1f4 /* alt-forward quote */
+#define ALT_COMMA 0x1f5 /* alt-comma */
+#define ALT_STOP 0x1f6 /* alt-stop */
+#define ALT_FSLASH 0x1f7 /* alt-forward slash */
+#define ALT_BKSP 0x1f8 /* alt-backspace */
+#define CTL_BKSP 0x1f9 /* ctl-backspace */
+#define PAD0 0x1fa /* keypad 0 */
+
+#define CTL_PAD0 0x1fb /* ctl-keypad 0 */
+#define CTL_PAD1 0x1fc
+#define CTL_PAD2 0x1fd
+#define CTL_PAD3 0x1fe
+#define CTL_PAD4 0x1ff
+#define CTL_PAD5 0x200
+#define CTL_PAD6 0x201
+#define CTL_PAD7 0x202
+#define CTL_PAD8 0x203
+#define CTL_PAD9 0x204
+
+#define ALT_PAD0 0x205 /* alt-keypad 0 */
+#define ALT_PAD1 0x206
+#define ALT_PAD2 0x207
+#define ALT_PAD3 0x208
+#define ALT_PAD4 0x209
+#define ALT_PAD5 0x20a
+#define ALT_PAD6 0x20b
+#define ALT_PAD7 0x20c
+#define ALT_PAD8 0x20d
+#define ALT_PAD9 0x20e
+
+#define CTL_DEL 0x20f /* clt-delete */
+#define ALT_BSLASH 0x210 /* alt-back slash */
+#define CTL_ENTER 0x211 /* ctl-enter */
+
+#define SHF_PADENTER 0x212 /* shift-enter on keypad */
+#define SHF_PADSLASH 0x213 /* shift-slash on keypad */
+#define SHF_PADSTAR 0x214 /* shift-star on keypad */
+#define SHF_PADPLUS 0x215 /* shift-plus on keypad */
+#define SHF_PADMINUS 0x216 /* shift-minus on keypad */
+#define SHF_UP 0x217 /* shift-up on keypad */
+#define SHF_DOWN 0x218 /* shift-down on keypad */
+#define SHF_IC 0x219 /* shift-insert on keypad */
+#define SHF_DC 0x21a /* shift-delete on keypad */
+
+#define KEY_MOUSE 0x21b /* "mouse" key */
+#define KEY_SHIFT_L 0x21c /* Left-shift */
+#define KEY_SHIFT_R 0x21d /* Right-shift */
+#define KEY_CONTROL_L 0x21e /* Left-control */
+#define KEY_CONTROL_R 0x21f /* Right-control */
+#define KEY_ALT_L 0x220 /* Left-alt */
+#define KEY_ALT_R 0x221 /* Right-alt */
+#define KEY_RESIZE 0x222 /* Window resize */
+#define KEY_SUP 0x223 /* Shifted up arrow */
+#define KEY_SDOWN 0x224 /* Shifted down arrow */
+
+#define KEY_MIN KEY_BREAK /* Minimum curses key value */
+#define KEY_MAX KEY_SDOWN /* Maximum curses key */
+
+#define KEY_F(n) (KEY_F0 + (n))
+
+/*----------------------------------------------------------------------
+ *
+ * PDCurses Function Declarations
+ *
+ */
+
+/* Standard */
+
+int addch(const chtype);
+int addchnstr(const chtype *, int);
+int addchstr(const chtype *);
+int addnstr(const char *, int);
+int addstr(const char *);
+int attroff(chtype);
+int attron(chtype);
+int attrset(chtype);
+int attr_get(attr_t *, short *, void *);
+int attr_off(attr_t, void *);
+int attr_on(attr_t, void *);
+int attr_set(attr_t, short, void *);
+int baudrate(void);
+int beep(void);
+int bkgd(chtype);
+void bkgdset(chtype);
+int border(chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype);
+int box(WINDOW *, chtype, chtype);
+bool can_change_color(void);
+int cbreak(void);
+int chgat(int, attr_t, short, const void *);
+int clearok(WINDOW *, bool);
+int clear(void);
+int clrtobot(void);
+int clrtoeol(void);
+int color_content(short, short *, short *, short *);
+int color_set(short, void *);
+int copywin(const WINDOW *, WINDOW *, int, int, int, int, int, int, int);
+int curs_set(int);
+int def_prog_mode(void);
+int def_shell_mode(void);
+int delay_output(int);
+int delch(void);
+int deleteln(void);
+void delscreen(SCREEN *);
+int delwin(WINDOW *);
+WINDOW *derwin(WINDOW *, int, int, int, int);
+int doupdate(void);
+WINDOW *dupwin(WINDOW *);
+int echochar(const chtype);
+int echo(void);
+int endwin(void);
+char erasechar(void);
+int erase(void);
+void filter(void);
+int flash(void);
+int flushinp(void);
+chtype getbkgd(WINDOW *);
+int getnstr(char *, int);
+int getstr(char *);
+WINDOW *getwin(FILE *);
+int halfdelay(int);
+bool has_colors(void);
+bool has_ic(void);
+bool has_il(void);
+int hline(chtype, int);
+void idcok(WINDOW *, bool);
+int idlok(WINDOW *, bool);
+void immedok(WINDOW *, bool);
+int inchnstr(chtype *, int);
+int inchstr(chtype *);
+chtype inch(void);
+int init_color(short, short, short, short);
+int init_pair(short, short, short);
+WINDOW *initscr(void);
+int innstr(char *, int);
+int insch(chtype);
+int insdelln(int);
+int insertln(void);
+int insnstr(const char *, int);
+int insstr(const char *);
+int instr(char *);
+int intrflush(WINDOW *, bool);
+bool isendwin(void);
+bool is_linetouched(WINDOW *, int);
+bool is_wintouched(WINDOW *);
+char *keyname(int);
+int keypad(WINDOW *, bool);
+char killchar(void);
+int leaveok(WINDOW *, bool);
+char *longname(void);
+int meta(WINDOW *, bool);
+int move(int, int);
+int mvaddch(int, int, const chtype);
+int mvaddchnstr(int, int, const chtype *, int);
+int mvaddchstr(int, int, const chtype *);
+int mvaddnstr(int, int, const char *, int);
+int mvaddstr(int, int, const char *);
+int mvchgat(int, int, int, attr_t, short, const void *);
+int mvcur(int, int, int, int);
+int mvdelch(int, int);
+int mvderwin(WINDOW *, int, int);
+int mvgetch(int, int);
+int mvgetnstr(int, int, char *, int);
+int mvgetstr(int, int, char *);
+int mvhline(int, int, chtype, int);
+chtype mvinch(int, int);
+int mvinchnstr(int, int, chtype *, int);
+int mvinchstr(int, int, chtype *);
+int mvinnstr(int, int, char *, int);
+int mvinsch(int, int, chtype);
+int mvinsnstr(int, int, const char *, int);
+int mvinsstr(int, int, const char *);
+int mvinstr(int, int, char *);
+int mvprintw(int, int, const char *, ...);
+int mvscanw(int, int, const char *, ...);
+int mvvline(int, int, chtype, int);
+int mvwaddchnstr(WINDOW *, int, int, const chtype *, int);
+int mvwaddchstr(WINDOW *, int, int, const chtype *);
+int mvwaddch(WINDOW *, int, int, const chtype);
+int mvwaddnstr(WINDOW *, int, int, const char *, int);
+int mvwaddstr(WINDOW *, int, int, const char *);
+int mvwchgat(WINDOW *, int, int, int, attr_t, short, const void *);
+int mvwdelch(WINDOW *, int, int);
+int mvwgetch(WINDOW *, int, int);
+int mvwgetnstr(WINDOW *, int, int, char *, int);
+int mvwgetstr(WINDOW *, int, int, char *);
+int mvwhline(WINDOW *, int, int, chtype, int);
+int mvwinchnstr(WINDOW *, int, int, chtype *, int);
+int mvwinchstr(WINDOW *, int, int, chtype *);
+chtype mvwinch(WINDOW *, int, int);
+int mvwinnstr(WINDOW *, int, int, char *, int);
+int mvwinsch(WINDOW *, int, int, chtype);
+int mvwinsnstr(WINDOW *, int, int, const char *, int);
+int mvwinsstr(WINDOW *, int, int, const char *);
+int mvwinstr(WINDOW *, int, int, char *);
+int mvwin(WINDOW *, int, int);
+int mvwprintw(WINDOW *, int, int, const char *, ...);
+int mvwscanw(WINDOW *, int, int, const char *, ...);
+int mvwvline(WINDOW *, int, int, chtype, int);
+int napms(int);
+WINDOW *newpad(int, int);
+SCREEN *newterm(const char *, FILE *, FILE *);
+WINDOW *newwin(int, int, int, int);
+int nl(void);
+int nocbreak(void);
+int nodelay(WINDOW *, bool);
+int noecho(void);
+int nonl(void);
+void noqiflush(void);
+int noraw(void);
+int notimeout(WINDOW *, bool);
+int overlay(const WINDOW *, WINDOW *);
+int overwrite(const WINDOW *, WINDOW *);
+int pair_content(short, short *, short *);
+int pechochar(WINDOW *, chtype);
+int pnoutrefresh(WINDOW *, int, int, int, int, int, int);
+int prefresh(WINDOW *, int, int, int, int, int, int);
+int printw(const char *, ...);
+int putwin(WINDOW *, FILE *);
+void qiflush(void);
+int raw(void);
+int redrawwin(WINDOW *);
+int refresh(void);
+int reset_prog_mode(void);
+int reset_shell_mode(void);
+int resetty(void);
+int ripoffline(int, int (*)(WINDOW *, int));
+int savetty(void);
+int scanw(const char *, ...);
+int scr_dump(const char *);
+int scr_init(const char *);
+int scr_restore(const char *);
+int scr_set(const char *);
+int scrl(int);
+int scroll(WINDOW *);
+int scrollok(WINDOW *, bool);
+SCREEN *set_term(SCREEN *);
+int setscrreg(int, int);
+int slk_attroff(const chtype);
+int slk_attr_off(const attr_t, void *);
+int slk_attron(const chtype);
+int slk_attr_on(const attr_t, void *);
+int slk_attrset(const chtype);
+int slk_attr_set(const attr_t, short, void *);
+int slk_clear(void);
+int slk_color(short);
+int slk_init(int);
+char *slk_label(int);
+int slk_noutrefresh(void);
+int slk_refresh(void);
+int slk_restore(void);
+int slk_set(int, const char *, int);
+int slk_touch(void);
+int standend(void);
+int standout(void);
+int start_color(void);
+WINDOW *subpad(WINDOW *, int, int, int, int);
+WINDOW *subwin(WINDOW *, int, int, int, int);
+int syncok(WINDOW *, bool);
+chtype termattrs(void);
+attr_t term_attrs(void);
+char *termname(void);
+void timeout(int);
+int touchline(WINDOW *, int, int);
+int touchwin(WINDOW *);
+int typeahead(int);
+int untouchwin(WINDOW *);
+void use_env(bool);
+int vidattr(chtype);
+int vid_attr(attr_t, short, void *);
+int vidputs(chtype, int (*)(int));
+int vid_puts(attr_t, short, void *, int (*)(int));
+int vline(chtype, int);
+int vw_printw(WINDOW *, const char *, va_list);
+int vwprintw(WINDOW *, const char *, va_list);
+int vw_scanw(WINDOW *, const char *, va_list);
+int vwscanw(WINDOW *, const char *, va_list);
+int waddchnstr(WINDOW *, const chtype *, int);
+int waddchstr(WINDOW *, const chtype *);
+int waddch(WINDOW *, const chtype);
+int waddnstr(WINDOW *, const char *, int);
+int waddstr(WINDOW *, const char *);
+int wattroff(WINDOW *, chtype);
+int wattron(WINDOW *, chtype);
+int wattrset(WINDOW *, chtype);
+int wattr_get(WINDOW *, attr_t *, short *, void *);
+int wattr_off(WINDOW *, attr_t, void *);
+int wattr_on(WINDOW *, attr_t, void *);
+int wattr_set(WINDOW *, attr_t, short, void *);
+void wbkgdset(WINDOW *, chtype);
+int wbkgd(WINDOW *, chtype);
+int wborder(WINDOW *, chtype, chtype, chtype, chtype,
+ chtype, chtype, chtype, chtype);
+int wchgat(WINDOW *, int, attr_t, short, const void *);
+int wclear(WINDOW *);
+int wclrtobot(WINDOW *);
+int wclrtoeol(WINDOW *);
+int wcolor_set(WINDOW *, short, void *);
+void wcursyncup(WINDOW *);
+int wdelch(WINDOW *);
+int wdeleteln(WINDOW *);
+int wechochar(WINDOW *, const chtype);
+int werase(WINDOW *);
+int wgetch(WINDOW *);
+int wgetnstr(WINDOW *, char *, int);
+int wgetstr(WINDOW *, char *);
+int whline(WINDOW *, chtype, int);
+int winchnstr(WINDOW *, chtype *, int);
+int winchstr(WINDOW *, chtype *);
+chtype winch(WINDOW *);
+int winnstr(WINDOW *, char *, int);
+int winsch(WINDOW *, chtype);
+int winsdelln(WINDOW *, int);
+int winsertln(WINDOW *);
+int winsnstr(WINDOW *, const char *, int);
+int winsstr(WINDOW *, const char *);
+int winstr(WINDOW *, char *);
+int wmove(WINDOW *, int, int);
+int wnoutrefresh(WINDOW *);
+int wprintw(WINDOW *, const char *, ...);
+int wredrawln(WINDOW *, int, int);
+int wrefresh(WINDOW *);
+int wscanw(WINDOW *, const char *, ...);
+int wscrl(WINDOW *, int);
+int wsetscrreg(WINDOW *, int, int);
+int wstandend(WINDOW *);
+int wstandout(WINDOW *);
+void wsyncdown(WINDOW *);
+void wsyncup(WINDOW *);
+void wtimeout(WINDOW *, int);
+int wtouchln(WINDOW *, int, int, int);
+int wvline(WINDOW *, chtype, int);
+
+/* Wide-character functions */
+
+#ifdef PDC_WIDE
+int addnwstr(const wchar_t *, int);
+int addwstr(const wchar_t *);
+int add_wch(const cchar_t *);
+int add_wchnstr(const cchar_t *, int);
+int add_wchstr(const cchar_t *);
+int border_set(const cchar_t *, const cchar_t *, const cchar_t *,
+ const cchar_t *, const cchar_t *, const cchar_t *,
+ const cchar_t *, const cchar_t *);
+int box_set(WINDOW *, const cchar_t *, const cchar_t *);
+int echo_wchar(const cchar_t *);
+int erasewchar(wchar_t *);
+int getbkgrnd(cchar_t *);
+int getcchar(const cchar_t *, wchar_t *, attr_t *, short *, void *);
+int getn_wstr(wint_t *, int);
+int get_wch(wint_t *);
+int get_wstr(wint_t *);
+int hline_set(const cchar_t *, int);
+int innwstr(wchar_t *, int);
+int ins_nwstr(const wchar_t *, int);
+int ins_wch(const cchar_t *);
+int ins_wstr(const wchar_t *);
+int inwstr(wchar_t *);
+int in_wch(cchar_t *);
+int in_wchnstr(cchar_t *, int);
+int in_wchstr(cchar_t *);
+char *key_name(wchar_t);
+int killwchar(wchar_t *);
+int mvaddnwstr(int, int, const wchar_t *, int);
+int mvaddwstr(int, int, const wchar_t *);
+int mvadd_wch(int, int, const cchar_t *);
+int mvadd_wchnstr(int, int, const cchar_t *, int);
+int mvadd_wchstr(int, int, const cchar_t *);
+int mvgetn_wstr(int, int, wint_t *, int);
+int mvget_wch(int, int, wint_t *);
+int mvget_wstr(int, int, wint_t *);
+int mvhline_set(int, int, const cchar_t *, int);
+int mvinnwstr(int, int, wchar_t *, int);
+int mvins_nwstr(int, int, const wchar_t *, int);
+int mvins_wch(int, int, const cchar_t *);
+int mvins_wstr(int, int, const wchar_t *);
+int mvinwstr(int, int, wchar_t *);
+int mvin_wch(int, int, cchar_t *);
+int mvin_wchnstr(int, int, cchar_t *, int);
+int mvin_wchstr(int, int, cchar_t *);
+int mvvline_set(int, int, const cchar_t *, int);
+int mvwaddnwstr(WINDOW *, int, int, const wchar_t *, int);
+int mvwaddwstr(WINDOW *, int, int, const wchar_t *);
+int mvwadd_wch(WINDOW *, int, int, const cchar_t *);
+int mvwadd_wchnstr(WINDOW *, int, int, const cchar_t *, int);
+int mvwadd_wchstr(WINDOW *, int, int, const cchar_t *);
+int mvwgetn_wstr(WINDOW *, int, int, wint_t *, int);
+int mvwget_wch(WINDOW *, int, int, wint_t *);
+int mvwget_wstr(WINDOW *, int, int, wint_t *);
+int mvwhline_set(WINDOW *, int, int, const cchar_t *, int);
+int mvwinnwstr(WINDOW *, int, int, wchar_t *, int);
+int mvwins_nwstr(WINDOW *, int, int, const wchar_t *, int);
+int mvwins_wch(WINDOW *, int, int, const cchar_t *);
+int mvwins_wstr(WINDOW *, int, int, const wchar_t *);
+int mvwin_wch(WINDOW *, int, int, cchar_t *);
+int mvwin_wchnstr(WINDOW *, int, int, cchar_t *, int);
+int mvwin_wchstr(WINDOW *, int, int, cchar_t *);
+int mvwinwstr(WINDOW *, int, int, wchar_t *);
+int mvwvline_set(WINDOW *, int, int, const cchar_t *, int);
+int pecho_wchar(WINDOW *, const cchar_t*);
+int setcchar(cchar_t*, const wchar_t*, const attr_t, short, const void*);
+int slk_wset(int, const wchar_t *, int);
+int unget_wch(const wchar_t);
+int vline_set(const cchar_t *, int);
+int waddnwstr(WINDOW *, const wchar_t *, int);
+int waddwstr(WINDOW *, const wchar_t *);
+int wadd_wch(WINDOW *, const cchar_t *);
+int wadd_wchnstr(WINDOW *, const cchar_t *, int);
+int wadd_wchstr(WINDOW *, const cchar_t *);
+int wbkgrnd(WINDOW *, const cchar_t *);
+void wbkgrndset(WINDOW *, const cchar_t *);
+int wborder_set(WINDOW *, const cchar_t *, const cchar_t *,
+ const cchar_t *, const cchar_t *, const cchar_t *,
+ const cchar_t *, const cchar_t *, const cchar_t *);
+int wecho_wchar(WINDOW *, const cchar_t *);
+int wgetbkgrnd(WINDOW *, cchar_t *);
+int wgetn_wstr(WINDOW *, wint_t *, int);
+int wget_wch(WINDOW *, wint_t *);
+int wget_wstr(WINDOW *, wint_t *);
+int whline_set(WINDOW *, const cchar_t *, int);
+int winnwstr(WINDOW *, wchar_t *, int);
+int wins_nwstr(WINDOW *, const wchar_t *, int);
+int wins_wch(WINDOW *, const cchar_t *);
+int wins_wstr(WINDOW *, const wchar_t *);
+int winwstr(WINDOW *, wchar_t *);
+int win_wch(WINDOW *, cchar_t *);
+int win_wchnstr(WINDOW *, cchar_t *, int);
+int win_wchstr(WINDOW *, cchar_t *);
+wchar_t *wunctrl(cchar_t *);
+int wvline_set(WINDOW *, const cchar_t *, int);
+#endif
+
+/* Quasi-standard */
+
+chtype getattrs(WINDOW *);
+int getbegx(WINDOW *);
+int getbegy(WINDOW *);
+int getmaxx(WINDOW *);
+int getmaxy(WINDOW *);
+int getparx(WINDOW *);
+int getpary(WINDOW *);
+int getcurx(WINDOW *);
+int getcury(WINDOW *);
+void traceoff(void);
+void traceon(void);
+char *unctrl(chtype);
+
+int crmode(void);
+int nocrmode(void);
+int draino(int);
+int resetterm(void);
+int fixterm(void);
+int saveterm(void);
+int setsyx(int, int);
+
+int mouse_set(unsigned long);
+int mouse_on(unsigned long);
+int mouse_off(unsigned long);
+int request_mouse_pos(void);
+int map_button(unsigned long);
+void wmouse_position(WINDOW *, int *, int *);
+unsigned long getmouse(void);
+unsigned long getbmap(void);
+
+/* ncurses */
+
+int assume_default_colors(int, int);
+const char *curses_version(void);
+bool has_key(int);
+int use_default_colors(void);
+int wresize(WINDOW *, int, int);
+
+int mouseinterval(int);
+mmask_t mousemask(mmask_t, mmask_t *);
+bool mouse_trafo(int *, int *, bool);
+int nc_getmouse(MEVENT *);
+int ungetmouse(MEVENT *);
+bool wenclose(const WINDOW *, int, int);
+bool wmouse_trafo(const WINDOW *, int *, int *, bool);
+
+/* PDCurses */
+
+int addrawch(chtype);
+int insrawch(chtype);
+bool is_termresized(void);
+int mvaddrawch(int, int, chtype);
+int mvdeleteln(int, int);
+int mvinsertln(int, int);
+int mvinsrawch(int, int, chtype);
+int mvwaddrawch(WINDOW *, int, int, chtype);
+int mvwdeleteln(WINDOW *, int, int);
+int mvwinsertln(WINDOW *, int, int);
+int mvwinsrawch(WINDOW *, int, int, chtype);
+int raw_output(bool);
+int resize_term(int, int);
+WINDOW *resize_window(WINDOW *, int, int);
+int waddrawch(WINDOW *, chtype);
+int winsrawch(WINDOW *, chtype);
+char wordchar(void);
+
+#ifdef PDC_WIDE
+wchar_t *slk_wlabel(int);
+#endif
+
+void PDC_debug(const char *, ...);
+int PDC_ungetch(int);
+int PDC_set_blink(bool);
+int PDC_set_line_color(short);
+void PDC_set_title(const char *);
+
+int PDC_clearclipboard(void);
+int PDC_freeclipboard(char *);
+int PDC_getclipboard(char **, long *);
+int PDC_setclipboard(const char *, long);
+
+unsigned long PDC_get_input_fd(void);
+unsigned long PDC_get_key_modifiers(void);
+int PDC_return_key_modifiers(bool);
+int PDC_save_key_modifiers(bool);
+
+#ifdef XCURSES
+WINDOW *Xinitscr(int, char **);
+void XCursesExit(void);
+int sb_init(void);
+int sb_set_horz(int, int, int);
+int sb_set_vert(int, int, int);
+int sb_get_horz(int *, int *, int *);
+int sb_get_vert(int *, int *, int *);
+int sb_refresh(void);
+#endif
+
+/*** Functions defined as macros ***/
+
+/* getch() and ungetch() conflict with some DOS libraries */
+
+#define getch() wgetch(stdscr)
+#define ungetch(ch) PDC_ungetch(ch)
+
+#define COLOR_PAIR(n) (((chtype)(n) << PDC_COLOR_SHIFT) & A_COLOR)
+#define PAIR_NUMBER(n) (((n) & A_COLOR) >> PDC_COLOR_SHIFT)
+
+/* These will _only_ work as macros */
+
+#define getbegyx(w, y, x) (y = getbegy(w), x = getbegx(w))
+#define getmaxyx(w, y, x) (y = getmaxy(w), x = getmaxx(w))
+#define getparyx(w, y, x) (y = getpary(w), x = getparx(w))
+#define getyx(w, y, x) (y = getcury(w), x = getcurx(w))
+
+#define getsyx(y, x) { if (curscr->_leaveit) (y)=(x)=-1; \
+ else getyx(curscr,(y),(x)); }
+
+#ifdef NCURSES_MOUSE_VERSION
+# define getmouse(x) nc_getmouse(x)
+#endif
+
+/* return codes from PDC_getclipboard() and PDC_setclipboard() calls */
+
+#define PDC_CLIP_SUCCESS 0
+#define PDC_CLIP_ACCESS_ERROR 1
+#define PDC_CLIP_EMPTY 2
+#define PDC_CLIP_MEMORY_ERROR 3
+
+/* PDCurses key modifier masks */
+
+#define PDC_KEY_MODIFIER_SHIFT 1
+#define PDC_KEY_MODIFIER_CONTROL 2
+#define PDC_KEY_MODIFIER_ALT 4
+#define PDC_KEY_MODIFIER_NUMLOCK 8
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+# undef bool
+}
+#endif
+
+#endif /* __PDCURSES__ */
diff --git a/apps/lib/curses/pdcurses/include/panel.h b/apps/lib/curses/pdcurses/include/panel.h
new file mode 100644
index 0000000..1d7cace
--- /dev/null
+++ b/apps/lib/curses/pdcurses/include/panel.h
@@ -0,0 +1,58 @@
+/* Public Domain Curses */
+
+/* $Id: panel.h,v 1.19 2008/07/13 16:08:16 wmcbrine Exp $ */
+
+/*----------------------------------------------------------------------*
+ * Panels for PDCurses *
+ *----------------------------------------------------------------------*/
+
+#ifndef __PDCURSES_PANEL_H__
+#define __PDCURSES_PANEL_H__ 1
+
+#include <curses.h>
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+extern "C"
+{
+#endif
+
+typedef struct panelobs
+{
+ struct panelobs *above;
+ struct panel *pan;
+} PANELOBS;
+
+typedef struct panel
+{
+ WINDOW *win;
+ int wstarty;
+ int wendy;
+ int wstartx;
+ int wendx;
+ struct panel *below;
+ struct panel *above;
+ const void *user;
+ struct panelobs *obscure;
+} PANEL;
+
+int bottom_panel(PANEL *pan);
+int del_panel(PANEL *pan);
+int hide_panel(PANEL *pan);
+int move_panel(PANEL *pan, int starty, int startx);
+PANEL *new_panel(WINDOW *win);
+PANEL *panel_above(const PANEL *pan);
+PANEL *panel_below(const PANEL *pan);
+int panel_hidden(const PANEL *pan);
+const void *panel_userptr(const PANEL *pan);
+WINDOW *panel_window(const PANEL *pan);
+int replace_panel(PANEL *pan, WINDOW *win);
+int set_panel_userptr(PANEL *pan, const void *uptr);
+int show_panel(PANEL *pan);
+int top_panel(PANEL *pan);
+void update_panels(void);
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+}
+#endif
+
+#endif /* __PDCURSES_PANEL_H__ */
diff --git a/apps/lib/curses/pdcurses/pdcurses/Makefile b/apps/lib/curses/pdcurses/pdcurses/Makefile
new file mode 100644
index 0000000..5bae5c6
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/Makefile
@@ -0,0 +1,39 @@
+app-$(CONFIG_APP_LIB_PANEL) += panel.o
+app-y += addch.o
+app-y += move.o
+app-y += overlay.o
+app-y += refresh.o
+app-y += terminfo.o
+app-y += window.o
+app-y += util.o
+app-y += inopts.o
+app-y += addstr.o
+app-y += keyname.o
+app-y += instr.o
+app-y += clear.o
+app-y += addchstr.o
+app-y += kernel.o
+app-y += pad.o
+app-y += insstr.o
+app-y += border.o
+app-y += getyx.o
+app-y += getstr.o
+app-y += getch.o
+app-y += termattr.o
+app-y += outopts.o
+app-y += color.o
+app-y += deleteln.o
+app-y += initscr.o
+app-y += slk.o
+app-y += delch.o
+app-y += touch.o
+app-y += mouse.o
+app-y += scanw.o
+app-y += scroll.o
+app-y += printw.o
+app-y += bkgd.o
+app-y += inch.o
+app-y += attr.o
+app-y += insch.o
+app-y += inchstr.o
+app-y += beep.o
diff --git a/apps/lib/curses/pdcurses/pdcurses/README b/apps/lib/curses/pdcurses/pdcurses/README
new file mode 100644
index 0000000..bef1c4c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/README
@@ -0,0 +1,25 @@
+PDCurses Portable Core
+======================
+
+This directory contains core PDCurses source code files common to all
+platforms.
+
+
+Building
+--------
+
+These modules are built by the platform-specific makefiles, in the
+platform directories.
+
+
+Distribution Status
+-------------------
+
+The files in this directory are released to the Public Domain.
+
+
+Acknowledgements
+----------------
+
+The panel library was originally provided by
+Warren Tucker <wht@n4hgf.mt-park.ga.us>
diff --git a/apps/lib/curses/pdcurses/pdcurses/addch.c b/apps/lib/curses/pdcurses/pdcurses/addch.c
new file mode 100644
index 0000000..586d1a7
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/addch.c
@@ -0,0 +1,408 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: addch.c,v 1.54 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: addch
+
+ Synopsis:
+ int addch(const chtype ch);
+ int waddch(WINDOW *win, const chtype ch);
+ int mvaddch(int y, int x, const chtype ch);
+ int mvwaddch(WINDOW *win, int y, int x, const chtype ch);
+ int echochar(const chtype ch);
+ int wechochar(WINDOW *win, const chtype ch);
+
+ int addrawch(chtype ch);
+ int waddrawch(WINDOW *win, chtype ch);
+ int mvaddrawch(int y, int x, chtype ch);
+ int mvwaddrawch(WINDOW *win, int y, int x, chtype ch);
+
+ int add_wch(const cchar_t *wch);
+ int wadd_wch(WINDOW *win, const cchar_t *wch);
+ int mvadd_wch(int y, int x, const cchar_t *wch);
+ int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch);
+ int echo_wchar(const cchar_t *wch);
+ int wecho_wchar(WINDOW *win, const cchar_t *wch);
+
+ Description:
+ addch() adds the chtype ch to the default window (stdscr) at the
+ current cursor position, and advances the cursor. Note that
+ chtypes can convey both text (a single character) and
+ attributes, including a color pair. add_wch() is the wide-
+ character version of this function, taking a pointer to a
+ cchar_t instead of a chtype.
+
+ waddch() is like addch(), but also lets you specify the window.
+ (This is in fact the core output routine.) wadd_wch() is the
+ wide version.
+
+ mvaddch() moves the cursor to the specified (y, x) position, and
+ adds ch to stdscr. mvadd_wch() is the wide version.
+
+ mvwaddch() moves the cursor to the specified position and adds
+ ch to the specified window. mvwadd_wch() is the wide version.
+
+ echochar() adds ch to stdscr at the current cursor position and
+ calls refresh(). echo_wchar() is the wide version.
+
+ wechochar() adds ch to the specified window and calls
+ wrefresh(). wecho_wchar() is the wide version.
+
+ addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are
+ PDCurses-specific wrappers for addch() etc. that disable the
+ translation of control characters.
+
+ The following applies to all these functions:
+
+ If the cursor moves on to the right margin, an automatic newline
+ is performed. If scrollok is enabled, and a character is added
+ to the bottom right corner of the window, the scrolling region
+ will be scrolled up one line. If scrolling is not allowed, ERR
+ will be returned.
+
+ If ch is a tab, newline, or backspace, the cursor will be moved
+ appropriately within the window. If ch is a newline, the
+ clrtoeol routine is called before the cursor is moved to the
+ beginning of the next line. If newline mapping is off, the
+ cursor will be moved to the next line, but the x coordinate will
+ be unchanged. If ch is a tab the cursor is moved to the next
+ tab position within the window. If ch is another control
+ character, it will be drawn in the ^X notation. Calling the
+ inch() routine after adding a control character returns the
+ representation of the control character, not the control
+ character.
+
+ Video attributes can be combined with a character by ORing them
+ into the parameter. Text, including attributes, can be copied
+ from one place to another by using inch() and addch().
+
+ Note that in PDCurses, for now, a cchar_t and a chtype are the
+ same. The text field is 16 bits wide, and is treated as Unicode
+ (UCS-2) when PDCurses is built with wide-character support
+ (define PDC_WIDE). So, in functions that take a chtype, like
+ addch(), both the wide and narrow versions will handle Unicode.
+ But for portability, you should use the wide functions.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ addch Y Y Y
+ waddch Y Y Y
+ mvaddch Y Y Y
+ mvwaddch Y Y Y
+ echochar Y - 3.0
+ wechochar Y - 3.0
+ addrawch - - -
+ waddrawch - - -
+ mvaddrawch - - -
+ mvwaddrawch - - -
+ add_wch Y
+ wadd_wch Y
+ mvadd_wch Y
+ mvwadd_wch Y
+ echo_wchar Y
+ wecho_wchar Y
+
+**man-end****************************************************************/
+
+int waddch(WINDOW *win, const chtype ch)
+{
+ int x, y;
+ chtype text, attr;
+ bool xlat;
+
+ PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
+ win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+ if (!win)
+ return ERR;
+
+ x = win->_curx;
+ y = win->_cury;
+
+ if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
+ return ERR;
+
+ xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
+ text = ch & A_CHARTEXT;
+ attr = ch & A_ATTRIBUTES;
+
+ if (xlat && (text < ' ' || text == 0x7f))
+ {
+ int x2;
+
+ switch (text)
+ {
+ case '\t':
+ for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
+ {
+ if (waddch(win, attr | ' ') == ERR)
+ return ERR;
+
+ /* if tab to next line, exit the loop */
+
+ if (!win->_curx)
+ break;
+ }
+ return OK;
+
+ case '\n':
+ /* if lf -> crlf */
+
+ if (!SP->raw_out)
+ x = 0;
+
+ wclrtoeol(win);
+
+ if (++y > win->_bmarg)
+ {
+ y--;
+
+ if (wscrl(win, 1) == ERR)
+ return ERR;
+ }
+
+ break;
+
+ case '\b':
+ /* don't back over left margin */
+
+ if (--x < 0)
+ case '\r':
+ x = 0;
+
+ break;
+
+ case 0x7f:
+ if (waddch(win, attr | '^') == ERR)
+ return ERR;
+
+ return waddch(win, attr | '?');
+
+ default:
+ /* handle control chars */
+
+ if (waddch(win, attr | '^') == ERR)
+ return ERR;
+
+ return waddch(win, ch + '@');
+ }
+ }
+ else
+ {
+ /* If the incoming character doesn't have its own attribute,
+ then use the current attributes for the window. If it has
+ attributes but not a color component, OR the attributes to
+ the current attributes for the window. If it has a color
+ component, use the attributes solely from the incoming
+ character. */
+
+ if (!(attr & A_COLOR))
+ attr |= win->_attrs;
+
+ /* wrs (4/10/93): Apply the same sort of logic for the window
+ background, in that it only takes precedence if other color
+ attributes are not there and that the background character
+ will only print if the printing character is blank. */
+
+ if (!(attr & A_COLOR))
+ attr |= win->_bkgd & A_ATTRIBUTES;
+ else
+ attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
+
+ if (text == ' ')
+ text = win->_bkgd & A_CHARTEXT;
+
+ /* Add the attribute back into the character. */
+
+ text |= attr;
+
+ /* Only change _firstch/_lastch if the character to be added is
+ different from the character/attribute that is already in
+ that position in the window. */
+
+ if (win->_y[y][x] != text)
+ {
+ if (win->_firstch[y] == _NO_CHANGE)
+ win->_firstch[y] = win->_lastch[y] = x;
+ else
+ if (x < win->_firstch[y])
+ win->_firstch[y] = x;
+ else
+ if (x > win->_lastch[y])
+ win->_lastch[y] = x;
+
+ win->_y[y][x] = text;
+ }
+
+ if (++x >= win->_maxx)
+ {
+ /* wrap around test */
+
+ x = 0;
+
+ if (++y > win->_bmarg)
+ {
+ y--;
+
+ if (wscrl(win, 1) == ERR)
+ {
+ PDC_sync(win);
+ return ERR;
+ }
+ }
+ }
+ }
+
+ win->_curx = x;
+ win->_cury = y;
+
+ if (win->_immed)
+ wrefresh(win);
+ if (win->_sync)
+ wsyncup(win);
+
+ return OK;
+}
+
+int addch(const chtype ch)
+{
+ PDC_LOG(("addch() - called: ch=%x\n", ch));
+
+ return waddch(stdscr, ch);
+}
+
+int mvaddch(int y, int x, const chtype ch)
+{
+ PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));
+
+ if (move(y,x) == ERR)
+ return ERR;
+
+ return waddch(stdscr, ch);
+}
+
+int mvwaddch(WINDOW *win, int y, int x, const chtype ch)
+{
+ PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddch(win, ch);
+}
+
+int echochar(const chtype ch)
+{
+ PDC_LOG(("echochar() - called: ch=%x\n", ch));
+
+ return wechochar(stdscr, ch);
+}
+
+int wechochar(WINDOW *win, const chtype ch)
+{
+ PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));
+
+ if (waddch(win, ch) == ERR)
+ return ERR;
+
+ return wrefresh(win);
+}
+
+int waddrawch(WINDOW *win, chtype ch)
+{
+ PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
+ win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+ if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
+ ch |= A_ALTCHARSET;
+
+ return waddch(win, ch);
+}
+
+int addrawch(chtype ch)
+{
+ PDC_LOG(("addrawch() - called: ch=%x\n", ch));
+
+ return waddrawch(stdscr, ch);
+}
+
+int mvaddrawch(int y, int x, chtype ch)
+{
+ PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddrawch(stdscr, ch);
+}
+
+int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)
+{
+ PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",
+ win, y, x, ch));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddrawch(win, ch);
+}
+
+#ifdef PDC_WIDE
+int wadd_wch(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));
+
+ return wch ? waddch(win, *wch) : ERR;
+}
+
+int add_wch(const cchar_t *wch)
+{
+ PDC_LOG(("add_wch() - called: wch=%x\n", *wch));
+
+ return wadd_wch(stdscr, wch);
+}
+
+int mvadd_wch(int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));
+
+ if (move(y,x) == ERR)
+ return ERR;
+
+ return wadd_wch(stdscr, wch);
+}
+
+int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",
+ win, y, x, *wch));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wadd_wch(win, wch);
+}
+
+int echo_wchar(const cchar_t *wch)
+{
+ PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));
+
+ return wecho_wchar(stdscr, wch);
+}
+
+int wecho_wchar(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));
+
+ if (!wch || (wadd_wch(win, wch) == ERR))
+ return ERR;
+
+ return wrefresh(win);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/addchstr.c b/apps/lib/curses/pdcurses/pdcurses/addchstr.c
new file mode 100644
index 0000000..0eea85a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/addchstr.c
@@ -0,0 +1,242 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: addchstr.c,v 1.43 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: addchstr
+
+ Synopsis:
+ int addchstr(const chtype *ch);
+ int addchnstr(const chtype *ch, int n);
+ int waddchstr(WINDOW *win, const chtype *ch);
+ int waddchnstr(WINDOW *win, const chtype *ch, int n);
+ int mvaddchstr(int y, int x, const chtype *ch);
+ int mvaddchnstr(int y, int x, const chtype *ch, int n);
+ int mvwaddchstr(WINDOW *, int y, int x, const chtype *ch);
+ int mvwaddchnstr(WINDOW *, int y, int x, const chtype *ch, int n);
+
+ int add_wchstr(const cchar_t *wch);
+ int add_wchnstr(const cchar_t *wch, int n);
+ int wadd_wchstr(WINDOW *win, const cchar_t *wch);
+ int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n);
+ int mvadd_wchstr(int y, int x, const cchar_t *wch);
+ int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n);
+ int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch);
+ int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch,
+ int n);
+
+ Description:
+ These routines write a chtype or cchar_t string directly into
+ the window structure, starting at the current or specified
+ position. The four routines with n as the last argument copy at
+ most n elements, but no more than will fit on the line. If n =
+ -1 then the whole string is copied, up to the maximum number
+ that will fit on the line.
+
+ The cursor position is not advanced. These routines do not check
+ for newline or other special characters, nor does any line
+ wrapping occur.
+
+ Return Value:
+ All functions return OK or ERR.
+
+ Portability X/Open BSD SYS V
+ addchstr Y - 4.0
+ waddchstr Y - 4.0
+ mvaddchstr Y - 4.0
+ mvwaddchstr Y - 4.0
+ addchnstr Y - 4.0
+ waddchnstr Y - 4.0
+ mvaddchnstr Y - 4.0
+ mvwaddchnstr Y - 4.0
+ add_wchstr Y
+ wadd_wchstr Y
+ mvadd_wchstr Y
+ mvwadd_wchstr Y
+ add_wchnstr Y
+ wadd_wchnstr Y
+ mvadd_wchnstr Y
+ mvwadd_wchnstr Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int waddchnstr(WINDOW *win, const chtype *ch, int n)
+{
+ int y, x, maxx, minx;
+ chtype *ptr;
+
+ PDC_LOG(("waddchnstr() - called: win=%p n=%d\n", win, n));
+
+ if (!win || !ch || !n || n < -1)
+ return ERR;
+
+ x = win->_curx;
+ y = win->_cury;
+ ptr = &(win->_y[y][x]);
+
+ if (n == -1 || n > win->_maxx - x)
+ n = win->_maxx - x;
+
+ minx = win->_firstch[y];
+ maxx = win->_lastch[y];
+
+ for (; n && *ch; n--, x++, ptr++, ch++)
+ {
+ if (*ptr != *ch)
+ {
+ if (x < minx || minx == _NO_CHANGE)
+ minx = x;
+
+ if (x > maxx)
+ maxx = x;
+
+ PDC_LOG(("y %d x %d minx %d maxx %d *ptr %x *ch"
+ " %x firstch: %d lastch: %d\n",
+ y, x, minx, maxx, *ptr, *ch,
+ win->_firstch[y], win->_lastch[y]));
+
+ *ptr = *ch;
+ }
+ }
+
+ win->_firstch[y] = minx;
+ win->_lastch[y] = maxx;
+
+ return OK;
+}
+
+int addchstr(const chtype *ch)
+{
+ PDC_LOG(("addchstr() - called\n"));
+
+ return waddchnstr(stdscr, ch, -1);
+}
+
+int addchnstr(const chtype *ch, int n)
+{
+ PDC_LOG(("addchnstr() - called\n"));
+
+ return waddchnstr(stdscr, ch, n);
+}
+
+int waddchstr(WINDOW *win, const chtype *ch)
+{
+ PDC_LOG(("waddchstr() - called: win=%p\n", win));
+
+ return waddchnstr(win, ch, -1);
+}
+
+int mvaddchstr(int y, int x, const chtype *ch)
+{
+ PDC_LOG(("mvaddchstr() - called: y %d x %d\n", y, x));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddchnstr(stdscr, ch, -1);
+}
+
+int mvaddchnstr(int y, int x, const chtype *ch, int n)
+{
+ PDC_LOG(("mvaddchnstr() - called: y %d x %d n %d\n", y, x, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddchnstr(stdscr, ch, n);
+}
+
+int mvwaddchstr(WINDOW *win, int y, int x, const chtype *ch)
+{
+ PDC_LOG(("mvwaddchstr() - called:\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddchnstr(win, ch, -1);
+}
+
+int mvwaddchnstr(WINDOW *win, int y, int x, const chtype *ch, int n)
+{
+ PDC_LOG(("mvwaddchnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddchnstr(win, ch, n);
+}
+
+#ifdef PDC_WIDE
+int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n)
+{
+ PDC_LOG(("wadd_wchnstr() - called: win=%p n=%d\n", win, n));
+
+ return waddchnstr(win, wch, n);
+}
+
+int add_wchstr(const cchar_t *wch)
+{
+ PDC_LOG(("add_wchstr() - called\n"));
+
+ return wadd_wchnstr(stdscr, wch, -1);
+}
+
+int add_wchnstr(const cchar_t *wch, int n)
+{
+ PDC_LOG(("add_wchnstr() - called\n"));
+
+ return wadd_wchnstr(stdscr, wch, n);
+}
+
+int wadd_wchstr(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wadd_wchstr() - called: win=%p\n", win));
+
+ return wadd_wchnstr(win, wch, -1);
+}
+
+int mvadd_wchstr(int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvadd_wchstr() - called: y %d x %d\n", y, x));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wadd_wchnstr(stdscr, wch, -1);
+}
+
+int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvadd_wchnstr() - called: y %d x %d n %d\n", y, x, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wadd_wchnstr(stdscr, wch, n);
+}
+
+int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvwadd_wchstr() - called:\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wadd_wchnstr(win, wch, -1);
+}
+
+int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvwadd_wchnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wadd_wchnstr(win, wch, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/addstr.c b/apps/lib/curses/pdcurses/pdcurses/addstr.c
new file mode 100644
index 0000000..ca19fd0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/addstr.c
@@ -0,0 +1,237 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: addstr.c,v 1.44 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: addstr
+
+ Synopsis:
+ int addstr(const char *str);
+ int addnstr(const char *str, int n);
+ int waddstr(WINDOW *win, const char *str);
+ int waddnstr(WINDOW *win, const char *str, int n);
+ int mvaddstr(int y, int x, const char *str);
+ int mvaddnstr(int y, int x, const char *str, int n);
+ int mvwaddstr(WINDOW *win, int y, int x, const char *str);
+ int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n);
+
+ int addwstr(const wchar_t *wstr);
+ int addnwstr(const wchar_t *wstr, int n);
+ int waddwstr(WINDOW *win, const wchar_t *wstr);
+ int waddnwstr(WINDOW *win, const wchar_t *wstr, int n);
+ int mvaddwstr(int y, int x, const wchar_t *wstr);
+ int mvaddnwstr(int y, int x, const wchar_t *wstr, int n);
+ int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr);
+ int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n);
+
+ Description:
+ These routines write all the characters of the null-terminated
+ string str or wide-character string wstr to the given window.
+ The functionality is similar to calling waddch() once for each
+ character in the string; except that, when PDCurses is built
+ with wide-character support enabled, the narrow-character
+ functions treat the string as a multibyte string in the current
+ locale, and convert it. The routines with n as the last
+ argument write at most n characters; if n is negative, then the
+ entire string will be added.
+
+ Return Value:
+ All functions return OK or ERR.
+
+ Portability X/Open BSD SYS V
+ addstr Y Y Y
+ waddstr Y Y Y
+ mvaddstr Y Y Y
+ mvwaddstr Y Y Y
+ addnstr Y - 4.0
+ waddnstr Y - 4.0
+ mvaddnstr Y - 4.0
+ mvwaddnstr Y - 4.0
+ addwstr Y
+ waddwstr Y
+ mvaddwstr Y
+ mvwaddwstr Y
+ addnwstr Y
+ waddnwstr Y
+ mvaddnwstr Y
+ mvwaddnwstr Y
+
+**man-end****************************************************************/
+
+int waddnstr(WINDOW *win, const char *str, int n)
+{
+ int i = 0;
+
+ PDC_LOG(("waddnstr() - called: string=\"%s\" n %d \n", str, n));
+
+ if (!win || !str)
+ return ERR;
+
+ while (str[i] && (i < n || n < 0))
+ {
+#ifdef PDC_WIDE
+ wchar_t wch;
+ int retval = PDC_mbtowc(&wch, str + i, n >= 0 ? n - i : 6);
+
+ if (retval <= 0)
+ return OK;
+
+ i += retval;
+#else
+ chtype wch = (unsigned char)(str[i++]);
+#endif
+ if (waddch(win, wch) == ERR)
+ return ERR;
+ }
+
+ return OK;
+}
+
+int addstr(const char *str)
+{
+ PDC_LOG(("addstr() - called: string=\"%s\"\n", str));
+
+ return waddnstr(stdscr, str, -1);
+}
+
+int addnstr(const char *str, int n)
+{
+ PDC_LOG(("addnstr() - called: string=\"%s\" n %d \n", str, n));
+
+ return waddnstr(stdscr, str, n);
+}
+
+int waddstr(WINDOW *win, const char *str)
+{
+ PDC_LOG(("waddstr() - called: string=\"%s\"\n", str));
+
+ return waddnstr(win, str, -1);
+}
+
+int mvaddstr(int y, int x, const char *str)
+{
+ PDC_LOG(("mvaddstr() - called: y %d x %d string=\"%s\"\n", y, x, str));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddnstr(stdscr, str, -1);
+}
+
+int mvaddnstr(int y, int x, const char *str, int n)
+{
+ PDC_LOG(("mvaddnstr() - called: y %d x %d string=\"%s\" n %d \n",
+ y, x, str, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddnstr(stdscr, str, n);
+}
+
+int mvwaddstr(WINDOW *win, int y, int x, const char *str)
+{
+ PDC_LOG(("mvwaddstr() - called: string=\"%s\"\n", str));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddnstr(win, str, -1);
+}
+
+int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n)
+{
+ PDC_LOG(("mvwaddnstr() - called: y %d x %d string=\"%s\" n %d \n",
+ y, x, str, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddnstr(win, str, n);
+}
+
+#ifdef PDC_WIDE
+int waddnwstr(WINDOW *win, const wchar_t *wstr, int n)
+{
+ int i = 0;
+
+ PDC_LOG(("waddnwstr() - called\n"));
+
+ if (!win || !wstr)
+ return ERR;
+
+ while (wstr[i] && (i < n || n < 0))
+ {
+ chtype wch = wstr[i++];
+
+ if (waddch(win, wch) == ERR)
+ return ERR;
+ }
+
+ return OK;
+}
+
+int addwstr(const wchar_t *wstr)
+{
+ PDC_LOG(("addwstr() - called\n"));
+
+ return waddnwstr(stdscr, wstr, -1);
+}
+
+int addnwstr(const wchar_t *wstr, int n)
+{
+ PDC_LOG(("addnwstr() - called\n"));
+
+ return waddnwstr(stdscr, wstr, n);
+}
+
+int waddwstr(WINDOW *win, const wchar_t *wstr)
+{
+ PDC_LOG(("waddwstr() - called\n"));
+
+ return waddnwstr(win, wstr, -1);
+}
+
+int mvaddwstr(int y, int x, const wchar_t *wstr)
+{
+ PDC_LOG(("mvaddstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddnwstr(stdscr, wstr, -1);
+}
+
+int mvaddnwstr(int y, int x, const wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvaddnstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return waddnwstr(stdscr, wstr, n);
+}
+
+int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr)
+{
+ PDC_LOG(("mvwaddstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddnwstr(win, wstr, -1);
+}
+
+int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvwaddnstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return waddnwstr(win, wstr, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/attr.c b/apps/lib/curses/pdcurses/pdcurses/attr.c
new file mode 100644
index 0000000..532384b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/attr.c
@@ -0,0 +1,349 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: attr.c,v 1.41 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: attr
+
+ Synopsis:
+ int attroff(chtype attrs);
+ int wattroff(WINDOW *win, chtype attrs);
+ int attron(chtype attrs);
+ int wattron(WINDOW *win, chtype attrs);
+ int attrset(chtype attrs);
+ int wattrset(WINDOW *win, chtype attrs);
+ int standend(void);
+ int wstandend(WINDOW *win);
+ int standout(void);
+ int wstandout(WINDOW *win);
+
+ int color_set(short color_pair, void *opts);
+ int wcolor_set(WINDOW *win, short color_pair, void *opts);
+
+ int attr_get(attr_t *attrs, short *color_pair, void *opts);
+ int attr_off(attr_t attrs, void *opts);
+ int attr_on(attr_t attrs, void *opts);
+ int attr_set(attr_t attrs, short color_pair, void *opts);
+ int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair,
+ void *opts);
+ int wattr_off(WINDOW *win, attr_t attrs, void *opts);
+ int wattr_on(WINDOW *win, attr_t attrs, void *opts);
+ int wattr_set(WINDOW *win, attr_t attrs, short color_pair,
+ void *opts);
+
+ int chgat(int n, attr_t attr, short color, const void *opts);
+ int mvchgat(int y, int x, int n, attr_t attr, short color,
+ const void *opts);
+ int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr,
+ short color, const void *opts);
+ int wchgat(WINDOW *win, int n, attr_t attr, short color,
+ const void *opts);
+
+ chtype getattrs(WINDOW *win);
+
+ Description:
+ These functions manipulate the current attributes and/or colors
+ of the named window. These attributes can be any combination
+ of A_STANDOUT, A_REVERSE, A_BOLD, A_DIM, A_BLINK, A_UNDERLINE.
+
+ These constants are defined in <curses.h> and can be combined
+ with the bitwise-OR operator (|).
+
+ The current attributes of a window are applied to all chtypes
+ that are written into the window with waddch(). Attributes are
+ a property of the chtype, and move with the character through
+ any scrolling or insert/delete operations.
+
+ attrset() sets the current attributes of the given window to
+ attrs. attroff() turns off the named attributes without
+ affecting any other attributes; attron() turns them on.
+ color_set() sets the window color to the value of color_pair.
+
+ standout() is the same as attron(A_STANDOUT). standend() is the
+ same as attrset(A_NORMAL); that is, it turns off all attributes.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ attroff Y Y Y
+ wattroff Y Y Y
+ attron Y Y Y
+ wattron Y Y Y
+ attrset Y Y Y
+ wattrset Y Y Y
+ standend Y Y Y
+ wstandend Y Y Y
+ standout Y Y Y
+ wstandout Y Y Y
+ color_set Y
+ wcolor_set Y
+ attr_get Y
+ wattr_get Y
+ attr_on Y
+ wattr_on Y
+ attr_off Y
+ wattr_off Y
+ attr_set Y
+ wattr_set Y
+ chgat Y
+ wchgat Y
+ mvchgat Y
+ mvwchgat Y
+ getattrs -
+
+**man-end****************************************************************/
+
+int wattroff(WINDOW *win, chtype attrs)
+{
+ PDC_LOG(("wattroff() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_attrs &= (~attrs & A_ATTRIBUTES);
+
+ return OK;
+}
+
+int attroff(chtype attrs)
+{
+ PDC_LOG(("attroff() - called\n"));
+
+ return wattroff(stdscr, attrs);
+}
+
+int wattron(WINDOW *win, chtype attrs)
+{
+ chtype newcolr, oldcolr, newattr, oldattr;
+
+ PDC_LOG(("wattron() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ if ((win->_attrs & A_COLOR) && (attrs & A_COLOR))
+ {
+ oldcolr = win->_attrs & A_COLOR;
+ oldattr = win->_attrs ^ oldcolr;
+ newcolr = attrs & A_COLOR;
+ newattr = (attrs & A_ATTRIBUTES) ^ newcolr;
+ newattr |= oldattr;
+ win->_attrs = newattr | newcolr;
+ }
+ else
+ win->_attrs |= (attrs & A_ATTRIBUTES);
+
+ return OK;
+}
+
+int attron(chtype attrs)
+{
+ PDC_LOG(("attron() - called\n"));
+
+ return wattron(stdscr, attrs);
+}
+
+int wattrset(WINDOW *win, chtype attrs)
+{
+ PDC_LOG(("wattrset() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_attrs = attrs & A_ATTRIBUTES;
+
+ return OK;
+}
+
+int attrset(chtype attrs)
+{
+ PDC_LOG(("attrset() - called\n"));
+
+ return wattrset(stdscr, attrs);
+}
+
+int standend(void)
+{
+ PDC_LOG(("standend() - called\n"));
+
+ return wattrset(stdscr, A_NORMAL);
+}
+
+int standout(void)
+{
+ PDC_LOG(("standout() - called\n"));
+
+ return wattrset(stdscr, A_STANDOUT);
+}
+
+int wstandend(WINDOW *win)
+{
+ PDC_LOG(("wstandend() - called\n"));
+
+ return wattrset(win, A_NORMAL);
+}
+
+int wstandout(WINDOW *win)
+{
+ PDC_LOG(("wstandout() - called\n"));
+
+ return wattrset(win, A_STANDOUT);
+}
+
+chtype getattrs(WINDOW *win)
+{
+ return win ? win->_attrs : 0;
+}
+
+int wcolor_set(WINDOW *win, short color_pair, void *opts)
+{
+ PDC_LOG(("wcolor_set() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_attrs = (win->_attrs & ~A_COLOR) | COLOR_PAIR(color_pair);
+
+ return OK;
+}
+
+int color_set(short color_pair, void *opts)
+{
+ PDC_LOG(("color_set() - called\n"));
+
+ return wcolor_set(stdscr, color_pair, opts);
+}
+
+int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, void *opts)
+{
+ PDC_LOG(("wattr_get() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ if (attrs)
+ *attrs = win->_attrs & (A_ATTRIBUTES & ~A_COLOR);
+
+ if (color_pair)
+ *color_pair = PAIR_NUMBER(win->_attrs);
+
+ return OK;
+}
+
+int attr_get(attr_t *attrs, short *color_pair, void *opts)
+{
+ PDC_LOG(("attr_get() - called\n"));
+
+ return wattr_get(stdscr, attrs, color_pair, opts);
+}
+
+int wattr_off(WINDOW *win, attr_t attrs, void *opts)
+{
+ PDC_LOG(("wattr_off() - called\n"));
+
+ return wattroff(win, attrs);
+}
+
+int attr_off(attr_t attrs, void *opts)
+{
+ PDC_LOG(("attr_off() - called\n"));
+
+ return wattroff(stdscr, attrs);
+}
+
+int wattr_on(WINDOW *win, attr_t attrs, void *opts)
+{
+ PDC_LOG(("wattr_off() - called\n"));
+
+ return wattron(win, attrs);
+}
+
+int attr_on(attr_t attrs, void *opts)
+{
+ PDC_LOG(("attr_on() - called\n"));
+
+ return wattron(stdscr, attrs);
+}
+
+int wattr_set(WINDOW *win, attr_t attrs, short color_pair, void *opts)
+{
+ PDC_LOG(("wattr_set() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_attrs = (attrs & (A_ATTRIBUTES & ~A_COLOR)) | COLOR_PAIR(color_pair);
+
+ return OK;
+}
+
+int attr_set(attr_t attrs, short color_pair, void *opts)
+{
+ PDC_LOG(("attr_get() - called\n"));
+
+ return wattr_set(stdscr, attrs, color_pair, opts);
+}
+
+int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts)
+{
+ chtype *dest, newattr;
+ int startpos, endpos;
+
+ PDC_LOG(("wchgat() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ newattr = (attr & A_ATTRIBUTES) | COLOR_PAIR(color);
+
+ startpos = win->_curx;
+ endpos = ((n < 0) ? win->_maxx : min(startpos + n, win->_maxx)) - 1;
+ dest = win->_y[win->_cury];
+
+ for (n = startpos; n <= endpos; n++)
+ dest[n] = (dest[n] & A_CHARTEXT) | newattr;
+
+ n = win->_cury;
+
+ if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE)
+ win->_firstch[n] = startpos;
+
+ if (endpos > win->_lastch[n])
+ win->_lastch[n] = endpos;
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int chgat(int n, attr_t attr, short color, const void *opts)
+{
+ PDC_LOG(("chgat() - called\n"));
+
+ return wchgat(stdscr, n, attr, color, opts);
+}
+
+int mvchgat(int y, int x, int n, attr_t attr, short color, const void *opts)
+{
+ PDC_LOG(("mvchgat() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wchgat(stdscr, n, attr, color, opts);
+}
+
+int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr, short color,
+ const void *opts)
+{
+ PDC_LOG(("mvwchgat() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wchgat(win, n, attr, color, opts);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/beep.c b/apps/lib/curses/pdcurses/pdcurses/beep.c
new file mode 100644
index 0000000..9e92f45
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/beep.c
@@ -0,0 +1,65 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: beep.c,v 1.34 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: beep
+
+ Synopsis:
+ int beep(void);
+ int flash(void);
+
+ Description:
+ beep() sounds the audible bell on the terminal, if possible;
+ if not, it calls flash().
+
+ flash() "flashes" the screen, by inverting the foreground and
+ background of every cell, pausing, and then restoring the
+ original attributes.
+
+ Return Value:
+ These functions return OK.
+
+ Portability X/Open BSD SYS V
+ beep Y Y Y
+ flash Y Y Y
+
+**man-end****************************************************************/
+
+int beep(void)
+{
+ PDC_LOG(("beep() - called\n"));
+
+ if (SP->audible)
+ PDC_beep();
+ else
+ flash();
+
+ return OK;
+}
+
+int flash(void)
+{
+ int z, y, x;
+
+ PDC_LOG(("flash() - called\n"));
+
+ /* Reverse each cell; wait; restore the screen */
+
+ for (z = 0; z < 2; z++)
+ {
+ for (y = 0; y < LINES; y++)
+ for (x = 0; x < COLS; x++)
+ curscr->_y[y][x] ^= A_REVERSE;
+
+ wrefresh(curscr);
+
+ if (!z)
+ napms(50);
+ }
+
+ return OK;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/bkgd.c b/apps/lib/curses/pdcurses/pdcurses/bkgd.c
new file mode 100644
index 0000000..083239e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/bkgd.c
@@ -0,0 +1,220 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: bkgd.c,v 1.39 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: bkgd
+
+ Synopsis:
+ int bkgd(chtype ch);
+ void bkgdset(chtype ch);
+ chtype getbkgd(WINDOW *win);
+ int wbkgd(WINDOW *win, chtype ch);
+ void wbkgdset(WINDOW *win, chtype ch);
+
+ int bkgrnd(const cchar_t *wch);
+ void bkgrndset(const cchar_t *wch);
+ int getbkgrnd(cchar_t *wch);
+ int wbkgrnd(WINDOW *win, const cchar_t *wch);
+ void wbkgrndset(WINDOW *win, const cchar_t *wch);
+ int wgetbkgrnd(WINDOW *win, cchar_t *wch);
+
+ Description:
+ bkgdset() and wbkgdset() manipulate the background of a window.
+ The background is a chtype consisting of any combination of
+ attributes and a character; it is combined with each chtype
+ added or inserted to the window by waddch() or winsch(). Only
+ the attribute part is used to set the background of non-blank
+ characters, while both character and attributes are used for
+ blank positions.
+
+ bkgd() and wbkgd() not only change the background, but apply it
+ immediately to every cell in the window.
+
+ The attributes that are defined with the attrset()/attron() set
+ of functions take precedence over the background attributes if
+ there is a conflict (e.g., different color pairs).
+
+ Return Value:
+ bkgd() and wbkgd() return OK, unless the window is NULL, in
+ which case they return ERR.
+
+ Portability X/Open BSD SYS V
+ bkgd Y - 4.0
+ bkgdset Y - 4.0
+ getbkgd Y
+ wbkgd Y - 4.0
+ wbkgdset Y - 4.0
+ bkgrnd Y
+ bkgrndset Y
+ getbkgrnd Y
+ wbkgrnd Y
+ wbkgrndset Y
+ wgetbkgrnd Y
+
+**man-end****************************************************************/
+
+int wbkgd(WINDOW *win, chtype ch)
+{
+ int x, y;
+ chtype oldcolr, oldch, newcolr, newch, colr, attr;
+ chtype oldattr = 0, newattr = 0;
+ chtype *winptr;
+
+ PDC_LOG(("wbkgd() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ if (win->_bkgd == ch)
+ return OK;
+
+ oldcolr = win->_bkgd & A_COLOR;
+ if (oldcolr)
+ oldattr = (win->_bkgd & A_ATTRIBUTES) ^ oldcolr;
+
+ oldch = win->_bkgd & A_CHARTEXT;
+
+ wbkgdset(win, ch);
+
+ newcolr = win->_bkgd & A_COLOR;
+ if (newcolr)
+ newattr = (win->_bkgd & A_ATTRIBUTES) ^ newcolr;
+
+ newch = win->_bkgd & A_CHARTEXT;
+
+ /* what follows is what seems to occur in the System V
+ implementation of this routine */
+
+ for (y = 0; y < win->_maxy; y++)
+ {
+ for (x = 0; x < win->_maxx; x++)
+ {
+ winptr = win->_y[y] + x;
+
+ ch = *winptr;
+
+ /* determine the colors and attributes of the character read
+ from the window */
+
+ colr = ch & A_COLOR;
+ attr = ch & (A_ATTRIBUTES ^ A_COLOR);
+
+ /* if the color is the same as the old background color,
+ then make it the new background color, otherwise leave it */
+
+ if (colr == oldcolr)
+ colr = newcolr;
+
+ /* remove any attributes (non color) from the character that
+ were part of the old background, then combine the
+ remaining ones with the new background */
+
+ attr ^= oldattr;
+ attr |= newattr;
+
+ /* change character if it is there because it was the old
+ background character */
+
+ ch &= A_CHARTEXT;
+ if (ch == oldch)
+ ch = newch;
+
+ ch |= (attr | colr);
+
+ *winptr = ch;
+
+ }
+ }
+
+ touchwin(win);
+ PDC_sync(win);
+ return OK;
+}
+
+int bkgd(chtype ch)
+{
+ PDC_LOG(("bkgd() - called\n"));
+
+ return wbkgd(stdscr, ch);
+}
+
+void wbkgdset(WINDOW *win, chtype ch)
+{
+ PDC_LOG(("wbkgdset() - called\n"));
+
+ if (win)
+ {
+ if (!(ch & A_CHARTEXT))
+ ch |= ' ';
+
+ win->_bkgd = ch;
+ }
+}
+
+void bkgdset(chtype ch)
+{
+ PDC_LOG(("bkgdset() - called\n"));
+
+ wbkgdset(stdscr, ch);
+}
+
+chtype getbkgd(WINDOW *win)
+{
+ PDC_LOG(("getbkgd() - called\n"));
+
+ return win ? win->_bkgd : (chtype)ERR;
+}
+
+#ifdef PDC_WIDE
+int wbkgrnd(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wbkgrnd() - called\n"));
+
+ return wch ? wbkgd(win, *wch) : ERR;
+}
+
+int bkgrnd(const cchar_t *wch)
+{
+ PDC_LOG(("bkgrnd() - called\n"));
+
+ return wbkgrnd(stdscr, wch);
+}
+
+void wbkgrndset(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wbkgdset() - called\n"));
+
+ if (wch)
+ wbkgdset(win, *wch);
+}
+
+void bkgrndset(const cchar_t *wch)
+{
+ PDC_LOG(("bkgrndset() - called\n"));
+
+ wbkgrndset(stdscr, wch);
+}
+
+int wgetbkgrnd(WINDOW *win, cchar_t *wch)
+{
+ PDC_LOG(("wgetbkgrnd() - called\n"));
+
+ if (!win || !wch)
+ return ERR;
+
+ *wch = win->_bkgd;
+
+ return OK;
+}
+
+int getbkgrnd(cchar_t *wch)
+{
+ PDC_LOG(("getbkgrnd() - called\n"));
+
+ return wgetbkgrnd(stdscr, wch);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/border.c b/apps/lib/curses/pdcurses/pdcurses/border.c
new file mode 100644
index 0000000..ec86aaf
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/border.c
@@ -0,0 +1,408 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: border.c,v 1.53 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: border
+
+ Synopsis:
+ int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl,
+ chtype tr, chtype bl, chtype br);
+ int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts,
+ chtype bs, chtype tl, chtype tr, chtype bl, chtype br);
+ int box(WINDOW *win, chtype verch, chtype horch);
+ int hline(chtype ch, int n);
+ int vline(chtype ch, int n);
+ int whline(WINDOW *win, chtype ch, int n);
+ int wvline(WINDOW *win, chtype ch, int n);
+ int mvhline(int y, int x, chtype ch, int n);
+ int mvvline(int y, int x, chtype ch, int n);
+ int mvwhline(WINDOW *win, int y, int x, chtype ch, int n);
+ int mvwvline(WINDOW *win, int y, int x, chtype ch, int n);
+
+ int border_set(const cchar_t *ls, const cchar_t *rs,
+ const cchar_t *ts, const cchar_t *bs,
+ const cchar_t *tl, const cchar_t *tr,
+ const cchar_t *bl, const cchar_t *br);
+ int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs,
+ const cchar_t *ts, const cchar_t *bs,
+ const cchar_t *tl, const cchar_t *tr,
+ const cchar_t *bl, const cchar_t *br);
+ int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch);
+ int hline_set(const cchar_t *wch, int n);
+ int vline_set(const cchar_t *wch, int n);
+ int whline_set(WINDOW *win, const cchar_t *wch, int n);
+ int wvline_set(WINDOW *win, const cchar_t *wch, int n);
+ int mvhline_set(int y, int x, const cchar_t *wch, int n);
+ int mvvline_set(int y, int x, const cchar_t *wch, int n);
+ int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n);
+ int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n);
+
+ Description:
+ border(), wborder(), and box() draw a border around the edge of
+ the window. If any argument is zero, an appropriate default is
+ used:
+
+ ls left side of border ACS_VLINE
+ rs right side of border ACS_VLINE
+ ts top side of border ACS_HLINE
+ bs bottom side of border ACS_HLINE
+ tl top left corner of border ACS_ULCORNER
+ tr top right corner of border ACS_URCORNER
+ bl bottom left corner of border ACS_LLCORNER
+ br bottom right corner of border ACS_LRCORNER
+
+ hline() and whline() draw a horizontal line, using ch, starting
+ from the current cursor position. The cursor position does not
+ change. The line is at most n characters long, or as many as
+ will fit in the window.
+
+ vline() and wvline() draw a vertical line, using ch, starting
+ from the current cursor position. The cursor position does not
+ change. The line is at most n characters long, or as many as
+ will fit in the window.
+
+ Return Value:
+ These functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ border Y - 4.0
+ wborder Y - 4.0
+ box Y Y Y
+ hline Y - 4.0
+ vline Y - 4.0
+ whline Y - 4.0
+ wvline Y - 4.0
+ mvhline Y
+ mvvline Y
+ mvwhline Y
+ mvwvline Y
+ border_set Y
+ wborder_set Y
+ box_set Y
+ hline_set Y
+ vline_set Y
+ whline_set Y
+ wvline_set Y
+ mvhline_set Y
+ mvvline_set Y
+ mvwhline_set Y
+ mvwvline_set Y
+
+**man-end****************************************************************/
+
+/* _attr_passthru() -- Takes a single chtype 'ch' and checks if the
+ current attribute of window 'win', as set by wattrset(), and/or the
+ current background of win, as set by wbkgd(), should by combined with
+ it. Attributes set explicitly in ch take precedence. */
+
+static chtype _attr_passthru(WINDOW *win, chtype ch)
+{
+ chtype attr;
+
+ /* If the incoming character doesn't have its own attribute, then
+ use the current attributes for the window. If the incoming
+ character has attributes, but not a color component, OR the
+ attributes to the current attributes for the window. If the
+ incoming character has a color component, use only the attributes
+ from the incoming character. */
+
+ attr = ch & A_ATTRIBUTES;
+ if (!(attr & A_COLOR))
+ attr |= win->_attrs;
+
+ /* wrs (4/10/93) -- Apply the same sort of logic for the window
+ background, in that it only takes precedence if other color
+ attributes are not there. */
+
+ if (!(attr & A_COLOR))
+ attr |= win->_bkgd & A_ATTRIBUTES;
+ else
+ attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
+
+ ch = (ch & A_CHARTEXT) | attr;
+
+ return ch;
+}
+
+int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
+ chtype tl, chtype tr, chtype bl, chtype br)
+{
+ int i, ymax, xmax;
+
+ PDC_LOG(("wborder() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ ymax = win->_maxy - 1;
+ xmax = win->_maxx - 1;
+
+ ls = _attr_passthru(win, ls ? ls : ACS_VLINE);
+ rs = _attr_passthru(win, rs ? rs : ACS_VLINE);
+ ts = _attr_passthru(win, ts ? ts : ACS_HLINE);
+ bs = _attr_passthru(win, bs ? bs : ACS_HLINE);
+ tl = _attr_passthru(win, tl ? tl : ACS_ULCORNER);
+ tr = _attr_passthru(win, tr ? tr : ACS_URCORNER);
+ bl = _attr_passthru(win, bl ? bl : ACS_LLCORNER);
+ br = _attr_passthru(win, br ? br : ACS_LRCORNER);
+
+ for (i = 1; i < xmax; i++)
+ {
+ win->_y[0][i] = ts;
+ win->_y[ymax][i] = bs;
+ }
+
+ for (i = 1; i < ymax; i++)
+ {
+ win->_y[i][0] = ls;
+ win->_y[i][xmax] = rs;
+ }
+
+ win->_y[0][0] = tl;
+ win->_y[0][xmax] = tr;
+ win->_y[ymax][0] = bl;
+ win->_y[ymax][xmax] = br;
+
+ for (i = 0; i <= ymax; i++)
+ {
+ win->_firstch[i] = 0;
+ win->_lastch[i] = xmax;
+ }
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl,
+ chtype tr, chtype bl, chtype br)
+{
+ PDC_LOG(("border() - called\n"));
+
+ return wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br);
+}
+
+int box(WINDOW *win, chtype verch, chtype horch)
+{
+ PDC_LOG(("box() - called\n"));
+
+ return wborder(win, verch, verch, horch, horch, 0, 0, 0, 0);
+}
+
+int whline(WINDOW *win, chtype ch, int n)
+{
+ chtype *dest;
+ int startpos, endpos;
+
+ PDC_LOG(("whline() - called\n"));
+
+ if (!win || n < 1)
+ return ERR;
+
+ startpos = win->_curx;
+ endpos = min(startpos + n, win->_maxx) - 1;
+ dest = win->_y[win->_cury];
+ ch = _attr_passthru(win, ch ? ch : ACS_HLINE);
+
+ for (n = startpos; n <= endpos; n++)
+ dest[n] = ch;
+
+ n = win->_cury;
+
+ if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE)
+ win->_firstch[n] = startpos;
+
+ if (endpos > win->_lastch[n])
+ win->_lastch[n] = endpos;
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int hline(chtype ch, int n)
+{
+ PDC_LOG(("hline() - called\n"));
+
+ return whline(stdscr, ch, n);
+}
+
+int mvhline(int y, int x, chtype ch, int n)
+{
+ PDC_LOG(("mvhline() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return whline(stdscr, ch, n);
+}
+
+int mvwhline(WINDOW *win, int y, int x, chtype ch, int n)
+{
+ PDC_LOG(("mvwhline() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return whline(win, ch, n);
+}
+
+int wvline(WINDOW *win, chtype ch, int n)
+{
+ int endpos, x;
+
+ PDC_LOG(("wvline() - called\n"));
+
+ if (!win || n < 1)
+ return ERR;
+
+ endpos = min(win->_cury + n, win->_maxy);
+ x = win->_curx;
+
+ ch = _attr_passthru(win, ch ? ch : ACS_VLINE);
+
+ for (n = win->_cury; n < endpos; n++)
+ {
+ win->_y[n][x] = ch;
+
+ if (x < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE)
+ win->_firstch[n] = x;
+
+ if (x > win->_lastch[n])
+ win->_lastch[n] = x;
+ }
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int vline(chtype ch, int n)
+{
+ PDC_LOG(("vline() - called\n"));
+
+ return wvline(stdscr, ch, n);
+}
+
+int mvvline(int y, int x, chtype ch, int n)
+{
+ PDC_LOG(("mvvline() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wvline(stdscr, ch, n);
+}
+
+int mvwvline(WINDOW *win, int y, int x, chtype ch, int n)
+{
+ PDC_LOG(("mvwvline() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wvline(win, ch, n);
+}
+
+#ifdef PDC_WIDE
+int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs,
+ const cchar_t *ts, const cchar_t *bs, const cchar_t *tl,
+ const cchar_t *tr, const cchar_t *bl, const cchar_t *br)
+{
+ PDC_LOG(("wborder_set() - called\n"));
+
+ return wborder(win, ls ? *ls : 0, rs ? *rs : 0, ts ? *ts : 0,
+ bs ? *bs : 0, tl ? *tl : 0, tr ? *tr : 0,
+ bl ? *bl : 0, br ? *br : 0);
+}
+
+int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts,
+ const cchar_t *bs, const cchar_t *tl, const cchar_t *tr,
+ const cchar_t *bl, const cchar_t *br)
+{
+ PDC_LOG(("border_set() - called\n"));
+
+ return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br);
+}
+
+int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch)
+{
+ PDC_LOG(("box_set() - called\n"));
+
+ return wborder_set(win, verch, verch, horch, horch,
+ (const cchar_t *)NULL, (const cchar_t *)NULL,
+ (const cchar_t *)NULL, (const cchar_t *)NULL);
+}
+
+int whline_set(WINDOW *win, const cchar_t *wch, int n)
+{
+ PDC_LOG(("whline_set() - called\n"));
+
+ return wch ? whline(win, *wch, n) : ERR;
+}
+
+int hline_set(const cchar_t *wch, int n)
+{
+ PDC_LOG(("hline_set() - called\n"));
+
+ return whline_set(stdscr, wch, n);
+}
+
+int mvhline_set(int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvhline_set() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return whline_set(stdscr, wch, n);
+}
+
+int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvwhline_set() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return whline_set(win, wch, n);
+}
+
+int wvline_set(WINDOW *win, const cchar_t *wch, int n)
+{
+ PDC_LOG(("wvline_set() - called\n"));
+
+ return wch ? wvline(win, *wch, n) : ERR;
+}
+
+int vline_set(const cchar_t *wch, int n)
+{
+ PDC_LOG(("vline_set() - called\n"));
+
+ return wvline_set(stdscr, wch, n);
+}
+
+int mvvline_set(int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvvline_set() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wvline_set(stdscr, wch, n);
+}
+
+int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
+{
+ PDC_LOG(("mvwvline_set() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wvline_set(win, wch, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/clear.c b/apps/lib/curses/pdcurses/pdcurses/clear.c
new file mode 100644
index 0000000..eda3385
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/clear.c
@@ -0,0 +1,154 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: clear.c,v 1.35 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: clear
+
+ Synopsis:
+ int clear(void);
+ int wclear(WINDOW *win);
+ int erase(void);
+ int werase(WINDOW *win);
+ int clrtobot(void);
+ int wclrtobot(WINDOW *win);
+ int clrtoeol(void);
+ int wclrtoeol(WINDOW *win);
+
+ Description:
+ erase() and werase() copy blanks (i.e. the background chtype) to
+ every cell of the window.
+
+ clear() and wclear() are similar to erase() and werase(), but
+ they also call clearok() to ensure that the the window is
+ cleared on the next wrefresh().
+
+ clrtobot() and wclrtobot() clear the window from the current
+ cursor position to the end of the window.
+
+ clrtoeol() and wclrtoeol() clear the window from the current
+ cursor position to the end of the current line.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ clear Y Y Y
+ wclear Y Y Y
+ erase Y Y Y
+ werase Y Y Y
+ clrtobot Y Y Y
+ wclrtobot Y Y Y
+ clrtoeol Y Y Y
+ wclrtoeol Y Y Y
+
+**man-end****************************************************************/
+
+int wclrtoeol(WINDOW *win)
+{
+ int x, y, minx;
+ chtype blank, *ptr;
+
+ PDC_LOG(("wclrtoeol() - called: Row: %d Col: %d\n",
+ win->_cury, win->_curx));
+
+ if (!win)
+ return ERR;
+
+ y = win->_cury;
+ x = win->_curx;
+
+ /* wrs (4/10/93) account for window background */
+
+ blank = win->_bkgd;
+
+ for (minx = x, ptr = &win->_y[y][x]; minx < win->_maxx; minx++, ptr++)
+ *ptr = blank;
+
+ if (x < win->_firstch[y] || win->_firstch[y] == _NO_CHANGE)
+ win->_firstch[y] = x;
+
+ win->_lastch[y] = win->_maxx - 1;
+
+ PDC_sync(win);
+ return OK;
+}
+
+int clrtoeol(void)
+{
+ PDC_LOG(("clrtoeol() - called\n"));
+
+ return wclrtoeol(stdscr);
+}
+
+int wclrtobot(WINDOW *win)
+{
+ int savey = win->_cury;
+ int savex = win->_curx;
+
+ PDC_LOG(("wclrtobot() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ /* should this involve scrolling region somehow ? */
+
+ if (win->_cury + 1 < win->_maxy)
+ {
+ win->_curx = 0;
+ win->_cury++;
+ for (; win->_maxy > win->_cury; win->_cury++)
+ wclrtoeol(win);
+ win->_cury = savey;
+ win->_curx = savex;
+ }
+ wclrtoeol(win);
+
+ PDC_sync(win);
+ return OK;
+}
+
+int clrtobot(void)
+{
+ PDC_LOG(("clrtobot() - called\n"));
+
+ return wclrtobot(stdscr);
+}
+
+int werase(WINDOW *win)
+{
+ PDC_LOG(("werase() - called\n"));
+
+ if (wmove(win, 0, 0) == ERR)
+ return ERR;
+
+ return wclrtobot(win);
+}
+
+int erase(void)
+{
+ PDC_LOG(("erase() - called\n"));
+
+ return werase(stdscr);
+}
+
+int wclear(WINDOW *win)
+{
+ PDC_LOG(("wclear() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_clear = TRUE;
+ return werase(win);
+}
+
+int clear(void)
+{
+ PDC_LOG(("clear() - called\n"));
+
+ return wclear(stdscr);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/color.c b/apps/lib/curses/pdcurses/pdcurses/color.c
new file mode 100644
index 0000000..038f760
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/color.c
@@ -0,0 +1,295 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: color.c,v 1.83 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: color
+
+ Synopsis:
+ int start_color(void);
+ int init_pair(short pair, short fg, short bg);
+ int init_color(short color, short red, short green, short blue);
+ bool has_colors(void);
+ bool can_change_color(void);
+ int color_content(short color, short *red, short *green, short *blue);
+ int pair_content(short pair, short *fg, short *bg);
+
+ int assume_default_colors(int f, int b);
+ int use_default_colors(void);
+
+ int PDC_set_line_color(short color);
+
+ Description:
+ To use these routines, start_color() must be called, usually
+ immediately after initscr(). Colors are always used in pairs,
+ referred to as color-pairs. A color-pair consists of a
+ foreground color and a background color. A color-pair is
+ initialized via init_pair(). After initialization, COLOR_PAIR(n)
+ can be used like any other video attribute.
+
+ start_color() initializes eight basic colors (black, red, green,
+ yellow, blue, magenta, cyan, and white), and two global
+ variables; COLORS and COLOR_PAIRS (respectively defining the
+ maximum number of colors and color-pairs the terminal is capable
+ of displaying).
+
+ init_pair() changes the definition of a color-pair. It takes
+ three arguments: the number of the color-pair to be redefined,
+ and the new values of the foreground and background colors. The
+ pair number must be between 0 and COLOR_PAIRS - 1, inclusive.
+ The foreground and background must be between 0 and COLORS - 1,
+ inclusive. If the color pair was previously initialized, the
+ screen is refreshed, and all occurrences of that color-pair are
+ changed to the new definition.
+
+ has_colors() indicates if the terminal supports, and can
+ maniplulate color. It returns TRUE or FALSE.
+
+ can_change_color() indicates if the terminal has the capability
+ to change the definition of its colors.
+
+ pair_content() is used to determine what the colors of a given
+ color-pair consist of.
+
+ assume_default_colors() and use_default_colors() emulate the
+ ncurses extensions of the same names. assume_default_colors(f,
+ b) is essentially the same as init_pair(0, f, b) (which isn't
+ allowed); it redefines the default colors. use_default_colors()
+ allows the use of -1 as a foreground or background color with
+ init_pair(), and calls assume_default_colors(-1, -1); -1
+ represents the foreground or background color that the terminal
+ had at startup. If the environment variable PDC_ORIGINAL_COLORS
+ is set at the time start_color() is called, that's equivalent to
+ calling use_default_colors().
+
+ PDC_set_line_color() is used to set the color, globally, for
+ the color of the lines drawn for the attributes: A_UNDERLINE,
+ A_OVERLINE, A_LEFTLINE and A_RIGHTLINE. A value of -1 (the
+ default) indicates that the current foreground color should be
+ used.
+
+ NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros.
+
+ Return Value:
+ All functions return OK on success and ERR on error, except for
+ has_colors() and can_change_colors(), which return TRUE or FALSE.
+
+ Portability X/Open BSD SYS V
+ start_color Y - 3.2
+ init_pair Y - 3.2
+ init_color Y - 3.2
+ has_colors Y - 3.2
+ can_change_color Y - 3.2
+ color_content Y - 3.2
+ pair_content Y - 3.2
+ assume_default_colors - - -
+ use_default_colors - - -
+ PDC_set_line_color - - -
+
+**man-end****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+int COLORS = 0;
+int COLOR_PAIRS = PDC_COLOR_PAIRS;
+
+bool pdc_color_started = FALSE;
+
+/* pair_set[] tracks whether a pair has been set via init_pair() */
+
+static bool pair_set[PDC_COLOR_PAIRS];
+static bool default_colors = FALSE;
+static short first_col = 0;
+
+int start_color(void)
+{
+ PDC_LOG(("start_color() - called\n"));
+
+ if (SP->mono)
+ return ERR;
+
+ pdc_color_started = TRUE;
+
+ PDC_set_blink(FALSE); /* Also sets COLORS, to 8 or 16 */
+
+ if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS"))
+ default_colors = TRUE;
+
+ PDC_init_atrtab();
+
+ memset(pair_set, 0, PDC_COLOR_PAIRS);
+
+ return OK;
+}
+
+static void _normalize(short *fg, short *bg)
+{
+ if (*fg == -1)
+ *fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE;
+
+ if (*bg == -1)
+ *bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK;
+}
+
+int init_pair(short pair, short fg, short bg)
+{
+ PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg));
+
+ if (!pdc_color_started || pair < 1 || pair >= COLOR_PAIRS ||
+ fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS)
+ return ERR;
+
+ _normalize(&fg, &bg);
+
+ /* To allow the PDC_PRESERVE_SCREEN option to work, we only reset
+ curscr if this call to init_pair() alters a color pair created by
+ the user. */
+
+ if (pair_set[pair])
+ {
+ short oldfg, oldbg;
+
+ PDC_pair_content(pair, &oldfg, &oldbg);
+
+ if (oldfg != fg || oldbg != bg)
+ curscr->_clear = TRUE;
+ }
+
+ PDC_init_pair(pair, fg, bg);
+
+ pair_set[pair] = TRUE;
+
+ return OK;
+}
+
+bool has_colors(void)
+{
+ PDC_LOG(("has_colors() - called\n"));
+
+ return !(SP->mono);
+}
+
+int init_color(short color, short red, short green, short blue)
+{
+ PDC_LOG(("init_color() - called\n"));
+
+ if (color < 0 || color >= COLORS || !PDC_can_change_color() ||
+ red < 0 || red > 1000 || green < 0 || green > 1000 ||
+ blue < 0 || blue > 1000)
+ return ERR;
+
+ return PDC_init_color(color, red, green, blue);
+}
+
+int color_content(short color, short *red, short *green, short *blue)
+{
+ PDC_LOG(("color_content() - called\n"));
+
+ if (color < 0 || color >= COLORS || !red || !green || !blue)
+ return ERR;
+
+ if (PDC_can_change_color())
+ return PDC_color_content(color, red, green, blue);
+ else
+ {
+ /* Simulated values for platforms that don't support palette
+ changing */
+
+ short maxval = (color & 8) ? 1000 : 680;
+
+ *red = (color & COLOR_RED) ? maxval : 0;
+ *green = (color & COLOR_GREEN) ? maxval : 0;
+ *blue = (color & COLOR_BLUE) ? maxval : 0;
+
+ return OK;
+ }
+}
+
+bool can_change_color(void)
+{
+ PDC_LOG(("can_change_color() - called\n"));
+
+ return PDC_can_change_color();
+}
+
+int pair_content(short pair, short *fg, short *bg)
+{
+ PDC_LOG(("pair_content() - called\n"));
+
+ if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg)
+ return ERR;
+
+ return PDC_pair_content(pair, fg, bg);
+}
+
+int assume_default_colors(int f, int b)
+{
+ PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b));
+
+ if (f < -1 || f >= COLORS || b < -1 || b >= COLORS)
+ return ERR;
+
+ if (pdc_color_started)
+ {
+ short fg, bg, oldfg, oldbg;
+
+ fg = f;
+ bg = b;
+
+ _normalize(&fg, &bg);
+
+ PDC_pair_content(0, &oldfg, &oldbg);
+
+ if (oldfg != fg || oldbg != bg)
+ curscr->_clear = TRUE;
+
+ PDC_init_pair(0, fg, bg);
+ }
+
+ return OK;
+}
+
+int use_default_colors(void)
+{
+ PDC_LOG(("use_default_colors() - called\n"));
+
+ default_colors = TRUE;
+ first_col = -1;
+
+ return assume_default_colors(-1, -1);
+}
+
+int PDC_set_line_color(short color)
+{
+ PDC_LOG(("PDC_set_line_color() - called: %d\n", color));
+
+ if (color < -1 || color >= COLORS)
+ return ERR;
+
+ SP->line_color = color;
+
+ return OK;
+}
+
+void PDC_init_atrtab(void)
+{
+ int i;
+ short fg, bg;
+
+ if (pdc_color_started && !default_colors)
+ {
+ fg = COLOR_WHITE;
+ bg = COLOR_BLACK;
+ }
+ else
+ fg = bg = -1;
+
+ _normalize(&fg, &bg);
+
+ for (i = 0; i < PDC_COLOR_PAIRS; i++)
+ PDC_init_pair(i, fg, bg);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/curspriv.h b/apps/lib/curses/pdcurses/pdcurses/curspriv.h
new file mode 100644
index 0000000..734400b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/curspriv.h
@@ -0,0 +1,146 @@
+/* Public Domain Curses */
+
+/* $Id: curspriv.h,v 1.158 2008/07/13 16:08:16 wmcbrine Exp $ */
+
+/* Private definitions and declarations for use within PDCurses.
+ These should generally not be referenced by applications. */
+
+#ifndef __CURSES_INTERNALS__
+#define __CURSES_INTERNALS__ 1
+
+#define HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
+# include "../backend/config.h"
+#endif
+
+#include <stdlib.h>
+#include <malloc.h>
+
+#define CURSES_LIBRARY
+#include <curses.h>
+
+#if defined(__TURBOC__) || defined(__EMX__) || defined(__DJGPP__) || \
+ defined(__CYGWIN32__) || defined(__MINGW32__) || \
+ defined(__WATCOMC__) || defined(__PACIFIC__)
+# ifndef HAVE_VSSCANF
+# define HAVE_VSSCANF /* have vsscanf() */
+# endif
+#endif
+
+#if defined(__CYGWIN32__) || defined(__MINGW32__) || \
+ defined(__LCC__) || defined(__WATCOMC__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF /* have vsnprintf() */
+# endif
+#endif
+
+#if defined(_MSC_VER) && defined(_WIN32) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
+#endif
+
+/*----------------------------------------------------------------------*/
+
+typedef struct /* structure for ripped off lines */
+{
+ int line;
+ int (*init)(WINDOW *, int);
+} RIPPEDOFFLINE;
+
+/* Window properties */
+
+#define _SUBWIN 0x01 /* window is a subwindow */
+#define _PAD 0x10 /* X/Open Pad. */
+#define _SUBPAD 0x20 /* X/Open subpad. */
+
+/* Miscellaneous */
+
+#define _NO_CHANGE -1 /* flags line edge unchanged */
+
+#define _ECHAR 0x08 /* Erase char (^H) */
+#define _DWCHAR 0x17 /* Delete Word char (^W) */
+#define _DLCHAR 0x15 /* Delete Line char (^U) */
+
+extern WINDOW *pdc_lastscr;
+extern bool pdc_trace_on; /* tracing flag */
+extern bool pdc_color_started;
+extern unsigned long pdc_key_modifiers;
+extern MOUSE_STATUS pdc_mouse_status;
+
+/*----------------------------------------------------------------------*/
+
+/* Platform implementation functions */
+
+void PDC_beep(void);
+bool PDC_can_change_color(void);
+int PDC_color_content(short, short *, short *, short *);
+bool PDC_check_key(void);
+int PDC_curs_set(int);
+void PDC_flushinp(void);
+int PDC_get_columns(void);
+int PDC_get_cursor_mode(void);
+int PDC_get_key(void);
+int PDC_get_rows(void);
+void PDC_gotoyx(int, int);
+int PDC_init_color(short, short, short, short);
+void PDC_init_pair(short, short, short);
+int PDC_modifiers_set(void);
+int PDC_mouse_set(void);
+void PDC_napms(int);
+int PDC_pair_content(short, short *, short *);
+void PDC_reset_prog_mode(void);
+void PDC_reset_shell_mode(void);
+int PDC_resize_screen(int, int);
+void PDC_restore_screen_mode(int);
+void PDC_save_screen_mode(int);
+void PDC_scr_close(void);
+void PDC_scr_free(void);
+int PDC_scr_open(int, char **);
+void PDC_set_keyboard_binary(bool);
+void PDC_transform_line(int, int, int, const chtype *);
+const char *PDC_sysname(void);
+
+/* Internal cross-module functions */
+
+void PDC_init_atrtab(void);
+WINDOW *PDC_makelines(WINDOW *);
+WINDOW *PDC_makenew(int, int, int, int);
+int PDC_mouse_in_slk(int, int);
+void PDC_slk_free(void);
+void PDC_slk_initialize(void);
+void PDC_sync(WINDOW *);
+
+#ifdef PDC_WIDE
+int PDC_mbtowc(wchar_t *, const char *, size_t);
+size_t PDC_mbstowcs(wchar_t *, const char *, size_t);
+size_t PDC_wcstombs(char *, const wchar_t *, size_t);
+#endif
+
+#ifdef PDCDEBUG
+# define PDC_LOG(x) if (pdc_trace_on) PDC_debug x
+# define RCSID(x) static const char *rcsid = x;
+#else
+# define PDC_LOG(x)
+# define RCSID(x)
+#endif
+
+/* Internal macros for attributes */
+
+#ifdef CHTYPE_LONG
+# define PDC_COLOR_PAIRS 256
+#else
+# define PDC_COLOR_PAIRS 32
+#endif
+
+#ifndef max
+# define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+# define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define DIVROUND(num, divisor) ((num) + ((divisor) >> 1)) / (divisor)
+
+#define PDC_CLICK_PERIOD 150 /* time to wait for a click, if
+ not set by mouseinterval() */
+
+#endif /* __CURSES_INTERNALS__*/
diff --git a/apps/lib/curses/pdcurses/pdcurses/debug.c b/apps/lib/curses/pdcurses/pdcurses/debug.c
new file mode 100644
index 0000000..5fd9dcc
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/debug.c
@@ -0,0 +1,81 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: debug.c,v 1.7 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: debug
+
+ Synopsis:
+ void traceon(void);
+ void traceoff(void);
+ void PDC_debug(const char *, ...);
+
+ Description:
+ traceon() and traceoff() toggle the recording of debugging
+ information to the file "trace". Although not standard, similar
+ functions are in some other curses implementations.
+
+ PDC_debug() is the function that writes to the file, based on
+ whether traceon() has been called. It's used from the PDC_LOG()
+ macro.
+
+ Portability X/Open BSD SYS V
+ traceon - - -
+ traceoff - - -
+ PDC_debug - - -
+
+**man-end****************************************************************/
+
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+bool pdc_trace_on = TRUE;
+
+void PDC_debug(const char *fmt, ...)
+{
+ va_list args;
+ FILE *dbfp;
+ char hms[9];
+ time_t now;
+
+ if (!pdc_trace_on)
+ return;
+
+ /* open debug log file append */
+
+ dbfp = fopen("trace", "a");
+ if (!dbfp)
+ {
+ fprintf(stderr,
+ "PDC_debug(): Unable to open debug log file\n");
+ return;
+ }
+
+// time(&now);
+// strftime(hms, 9, "%H:%M:%S", localtime(&now));
+// fprintf(dbfp, "At: %8.8ld - %s ", (long) clock(), hms);
+
+ va_start(args, fmt);
+ vfprintf(dbfp, fmt, args);
+ va_end(args);
+
+ fclose(dbfp);
+}
+
+void traceon(void)
+{
+ PDC_LOG(("traceon() - called\n"));
+
+ pdc_trace_on = TRUE;
+}
+
+void traceoff(void)
+{
+ PDC_LOG(("traceoff() - called\n"));
+
+ pdc_trace_on = FALSE;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/delch.c b/apps/lib/curses/pdcurses/pdcurses/delch.c
new file mode 100644
index 0000000..9c2416e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/delch.c
@@ -0,0 +1,93 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: delch.c,v 1.33 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: delch
+
+ Synopsis:
+ int delch(void);
+ int wdelch(WINDOW *win);
+ int mvdelch(int y, int x);
+ int mvwdelch(WINDOW *win, int y, int x);
+
+ Description:
+ The character under the cursor in the window is deleted. All
+ characters to the right on the same line are moved to the left
+ one position and the last character on the line is filled with
+ a blank. The cursor position does not change (after moving to
+ y, x if coordinates are specified).
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ delch Y Y Y
+ wdelch Y Y Y
+ mvdelch Y Y Y
+ mvwdelch Y Y Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int wdelch(WINDOW *win)
+{
+ int y, x, maxx;
+ chtype *temp1;
+
+ PDC_LOG(("wdelch() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ y = win->_cury;
+ x = win->_curx;
+ maxx = win->_maxx - 1;
+ temp1 = &win->_y[y][x];
+
+ memmove(temp1, temp1 + 1, (maxx - x) * sizeof(chtype));
+
+ /* wrs (4/10/93) account for window background */
+
+ win->_y[y][maxx] = win->_bkgd;
+
+ win->_lastch[y] = maxx;
+
+ if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x))
+ win->_firstch[y] = x;
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int delch(void)
+{
+ PDC_LOG(("delch() - called\n"));
+
+ return wdelch(stdscr);
+}
+
+int mvdelch(int y, int x)
+{
+ PDC_LOG(("mvdelch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wdelch(stdscr);
+}
+
+int mvwdelch(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwdelch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wdelch(win);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/deleteln.c b/apps/lib/curses/pdcurses/pdcurses/deleteln.c
new file mode 100644
index 0000000..c856e90
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/deleteln.c
@@ -0,0 +1,208 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: deleteln.c,v 1.35 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: deleteln
+
+ Synopsis:
+ int deleteln(void);
+ int wdeleteln(WINDOW *win);
+ int insdelln(int n);
+ int winsdelln(WINDOW *win, int n);
+ int insertln(void);
+ int winsertln(WINDOW *win);
+
+ int mvdeleteln(int y, int x);
+ int mvwdeleteln(WINDOW *win, int y, int x);
+ int mvinsertln(int y, int x);
+ int mvwinsertln(WINDOW *win, int y, int x);
+
+ Description:
+ With the deleteln() and wdeleteln() functions, the line under
+ the cursor in the window is deleted. All lines below the
+ current line are moved up one line. The bottom line of the
+ window is cleared. The cursor position does not change.
+
+ With the insertln() and winsertn() functions, a blank line is
+ inserted above the current line and the bottom line is lost.
+
+ mvdeleteln(), mvwdeleteln(), mvinsertln() and mvwinsertln()
+ allow moving the cursor and inserting/deleting in one call.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ deleteln Y Y Y
+ wdeleteln Y Y Y
+ mvdeleteln - - -
+ mvwdeleteln - - -
+ insdelln Y - 4.0
+ winsdelln Y - 4.0
+ insertln Y Y Y
+ winsertln Y Y Y
+ mvinsertln - - -
+ mvwinsertln - - -
+
+**man-end****************************************************************/
+
+int wdeleteln(WINDOW *win)
+{
+ chtype blank, *temp, *ptr;
+ int y;
+
+ PDC_LOG(("wdeleteln() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ /* wrs (4/10/93) account for window background */
+
+ blank = win->_bkgd;
+
+ temp = win->_y[win->_cury];
+
+ for (y = win->_cury; y < win->_bmarg; y++)
+ {
+ win->_y[y] = win->_y[y + 1];
+ win->_firstch[y] = 0;
+ win->_lastch[y] = win->_maxx - 1;
+ }
+
+ for (ptr = temp; (ptr - temp < win->_maxx); ptr++)
+ *ptr = blank; /* make a blank line */
+
+ if (win->_cury <= win->_bmarg)
+ {
+ win->_firstch[win->_bmarg] = 0;
+ win->_lastch[win->_bmarg] = win->_maxx - 1;
+ win->_y[win->_bmarg] = temp;
+ }
+
+ return OK;
+}
+
+int deleteln(void)
+{
+ PDC_LOG(("deleteln() - called\n"));
+
+ return wdeleteln(stdscr);
+}
+
+int mvdeleteln(int y, int x)
+{
+ PDC_LOG(("mvdeleteln() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wdeleteln(stdscr);
+}
+
+int mvwdeleteln(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwdeleteln() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wdeleteln(win);
+}
+
+int winsdelln(WINDOW *win, int n)
+{
+ int i;
+
+ PDC_LOG(("winsdelln() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ if (n > 0)
+ {
+ for (i = 0; i < n; i++)
+ if (winsertln(win) == ERR)
+ return ERR;
+ }
+ else if (n < 0)
+ {
+ n = -n;
+ for (i = 0; i < n; i++)
+ if (wdeleteln(win) == ERR)
+ return ERR;
+ }
+
+ return OK;
+}
+
+int insdelln(int n)
+{
+ PDC_LOG(("insdelln() - called\n"));
+
+ return winsdelln(stdscr, n);
+}
+
+int winsertln(WINDOW *win)
+{
+ chtype blank, *temp, *end;
+ int y;
+
+ PDC_LOG(("winsertln() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ /* wrs (4/10/93) account for window background */
+
+ blank = win->_bkgd;
+
+ temp = win->_y[win->_maxy - 1];
+
+ for (y = win->_maxy - 1; y > win->_cury; y--)
+ {
+ win->_y[y] = win->_y[y - 1];
+ win->_firstch[y] = 0;
+ win->_lastch[y] = win->_maxx - 1;
+ }
+
+ win->_y[win->_cury] = temp;
+
+ for (end = &temp[win->_maxx - 1]; temp <= end; temp++)
+ *temp = blank;
+
+ win->_firstch[win->_cury] = 0;
+ win->_lastch[win->_cury] = win->_maxx - 1;
+
+ return OK;
+}
+
+int insertln(void)
+{
+ PDC_LOG(("insertln() - called\n"));
+
+ return winsertln(stdscr);
+}
+
+int mvinsertln(int y, int x)
+{
+ PDC_LOG(("mvinsertln() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winsertln(stdscr);
+}
+
+int mvwinsertln(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwinsertln() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winsertln(win);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/deprec.c b/apps/lib/curses/pdcurses/pdcurses/deprec.c
new file mode 100644
index 0000000..83e6131
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/deprec.c
@@ -0,0 +1,29 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: deprec.c,v 1.6 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/* Deprecated functions. These should not be used, and will eventually
+ be removed. They're here solely for the benefit of applications that
+ linked to them in older versions of PDCurses. */
+
+bool PDC_check_bios_key(void)
+{
+ return PDC_check_key();
+}
+
+int PDC_get_bios_key(void)
+{
+ return PDC_get_key();
+}
+
+bool PDC_get_ctrl_break(void)
+{
+ return !SP->raw_inp;
+}
+
+int PDC_set_ctrl_break(bool setting)
+{
+ return setting ? noraw() : raw();
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/getch.c b/apps/lib/curses/pdcurses/pdcurses/getch.c
new file mode 100644
index 0000000..87677ba
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/getch.c
@@ -0,0 +1,410 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: getch.c,v 1.72 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: getch
+
+ Synopsis:
+ int getch(void);
+ int wgetch(WINDOW *win);
+ int mvgetch(int y, int x);
+ int mvwgetch(WINDOW *win, int y, int x);
+ int ungetch(int ch);
+ int flushinp(void);
+
+ int get_wch(wint_t *wch);
+ int wget_wch(WINDOW *win, wint_t *wch);
+ int mvget_wch(int y, int x, wint_t *wch);
+ int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch);
+ int unget_wch(const wchar_t wch);
+
+ unsigned long PDC_get_key_modifiers(void);
+ int PDC_save_key_modifiers(bool flag);
+ int PDC_return_key_modifiers(bool flag);
+
+ Description:
+ With the getch(), wgetch(), mvgetch(), and mvwgetch() functions,
+ a character is read from the terminal associated with the window.
+ In nodelay mode, if there is no input waiting, the value ERR is
+ returned. In delay mode, the program will hang until the system
+ passes text through to the program. Depending on the setting of
+ cbreak(), this will be after one character or after the first
+ newline. Unless noecho() has been set, the character will also
+ be echoed into the designated window.
+
+ If keypad() is TRUE, and a function key is pressed, the token for
+ that function key will be returned instead of the raw characters.
+ Possible function keys are defined in <curses.h> with integers
+ beginning with 0401, whose names begin with KEY_.
+
+ If nodelay(win, TRUE) has been called on the window and no input
+ is waiting, the value ERR is returned.
+
+ ungetch() places ch back onto the input queue to be returned by
+ the next call to wgetch().
+
+ flushinp() throws away any type-ahead that has been typed by the
+ user and has not yet been read by the program.
+
+ PDC_get_key_modifiers() returns the keyboard modifiers (shift,
+ control, alt, numlock) effective at the time of the last getch()
+ call, if PDC_save_key_modifiers(TRUE) has been called before the
+ getch(). Use the macros PDC_KEY_MODIFIER_* to determine which
+ modifier(s) were set. PDC_return_key_modifiers() tells getch()
+ to return modifier keys pressed alone as keystrokes (KEY_ALT_L,
+ etc.). These may not work on all platforms.
+
+ NOTE: getch() and ungetch() are implemented as macros, to avoid
+ conflict with many DOS compiler's runtime libraries.
+
+ Return Value:
+ These functions return ERR or the value of the character, meta
+ character or function key token.
+
+ Portability X/Open BSD SYS V
+ getch Y Y Y
+ wgetch Y Y Y
+ mvgetch Y Y Y
+ mvwgetch Y Y Y
+ ungetch Y Y Y
+ flushinp Y Y Y
+ get_wch Y
+ wget_wch Y
+ mvget_wch Y
+ mvwget_wch Y
+ unget_wch Y
+ PDC_get_key_modifiers - - -
+
+**man-end****************************************************************/
+
+#define _INBUFSIZ 512 /* size of terminal input buffer */
+#define NUNGETCH 256 /* max # chars to ungetch() */
+
+static int c_pindex = 0; /* putter index */
+static int c_gindex = 1; /* getter index */
+static int c_ungind = 0; /* ungetch() push index */
+static int c_ungch[NUNGETCH]; /* array of ungotten chars */
+
+static int _mouse_key(WINDOW *win)
+{
+ int i, key = KEY_MOUSE;
+ unsigned long mbe = SP->_trap_mbe;
+
+ /* Filter unwanted mouse events */
+
+ for (i = 0; i < 3; i++)
+ {
+ if (pdc_mouse_status.changes & (1 << i))
+ {
+ int shf = i * 5;
+ short button = pdc_mouse_status.button[i] & BUTTON_ACTION_MASK;
+
+ if ( (!(mbe & (BUTTON1_PRESSED << shf)) &&
+ (button == BUTTON_PRESSED))
+
+ || (!(mbe & (BUTTON1_CLICKED << shf)) &&
+ (button == BUTTON_CLICKED))
+
+ || (!(mbe & (BUTTON1_DOUBLE_CLICKED << shf)) &&
+ (button == BUTTON_DOUBLE_CLICKED))
+
+ || (!(mbe & (BUTTON1_MOVED << shf)) &&
+ (button == BUTTON_MOVED))
+
+ || (!(mbe & (BUTTON1_RELEASED << shf)) &&
+ (button == BUTTON_RELEASED))
+ )
+ pdc_mouse_status.changes ^= (1 << i);
+ }
+ }
+
+ if (pdc_mouse_status.changes & PDC_MOUSE_MOVED)
+ {
+ if (!(mbe & (BUTTON1_MOVED|BUTTON2_MOVED|BUTTON3_MOVED)))
+ pdc_mouse_status.changes ^= PDC_MOUSE_MOVED;
+ }
+
+ if (pdc_mouse_status.changes &
+ (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN))
+ {
+ if (!(mbe & MOUSE_WHEEL_SCROLL))
+ pdc_mouse_status.changes &=
+ ~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN);
+ }
+
+ if (!pdc_mouse_status.changes)
+ return -1;
+
+ /* Check for click in slk area */
+
+ i = PDC_mouse_in_slk(pdc_mouse_status.y, pdc_mouse_status.x);
+
+ if (i)
+ {
+ if (pdc_mouse_status.button[0] & (BUTTON_PRESSED|BUTTON_CLICKED))
+ key = KEY_F(i);
+ else
+ key = -1;
+ }
+
+ return key;
+}
+
+int wgetch(WINDOW *win)
+{
+ static int buffer[_INBUFSIZ]; /* character buffer */
+ int key, waitcount;
+
+ PDC_LOG(("wgetch() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ waitcount = 0;
+
+ /* set the number of 1/20th second napms() calls */
+
+ if (SP->delaytenths)
+ waitcount = 2 * SP->delaytenths;
+ else
+ if (win->_delayms)
+ {
+ /* Can't really do millisecond intervals, so delay in
+ 1/20ths of a second (50ms) */
+
+ waitcount = win->_delayms / 50;
+ if (!waitcount)
+ waitcount = 1;
+ }
+
+ /* refresh window when wgetch is called if there have been changes
+ to it and it is not a pad */
+
+ if (!(win->_flags & _PAD) && ((!win->_leaveit &&
+ (win->_begx + win->_curx != SP->curscol ||
+ win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win)))
+ wrefresh(win);
+
+ /* if ungotten char exists, remove and return it */
+
+ if (c_ungind)
+ return c_ungch[--c_ungind];
+
+ /* if normal and data in buffer */
+
+ if ((!SP->raw_inp && !SP->cbreak) && (c_gindex < c_pindex))
+ return buffer[c_gindex++];
+
+ /* prepare to buffer data */
+
+ c_pindex = 0;
+ c_gindex = 0;
+
+ /* to get here, no keys are buffered. go and get one. */
+
+ for (;;) /* loop for any buffering */
+ {
+ /* is there a keystroke ready? */
+
+ if (!PDC_check_key())
+ {
+ /* if not, handle timeout() and halfdelay() */
+
+ if (SP->delaytenths || win->_delayms)
+ {
+ if (!waitcount)
+ return ERR;
+
+ waitcount--;
+ }
+ else
+ if (win->_nodelay)
+ return ERR;
+
+ napms(50); /* sleep for 1/20th second */
+ continue; /* then check again */
+ }
+
+ /* if there is, fetch it */
+
+ key = PDC_get_key();
+
+ if (SP->key_code)
+ {
+ /* filter special keys if not in keypad mode */
+
+ if (!win->_use_keypad)
+ key = -1;
+
+ /* filter mouse events; translate mouse clicks in the slk
+ area to function keys */
+
+ else if (key == KEY_MOUSE)
+ key = _mouse_key(win);
+ }
+
+ /* unwanted key? loop back */
+
+ if (key == -1)
+ continue;
+
+ /* translate CR */
+
+ if (key == '\r' && SP->autocr && !SP->raw_inp)
+ key = '\n';
+
+ /* if echo is enabled */
+
+ if (SP->echo && !SP->key_code)
+ {
+ waddch(win, key);
+ wrefresh(win);
+ }
+
+ /* if no buffering */
+
+ if (SP->raw_inp || SP->cbreak)
+ return key;
+
+ /* if no overflow, put data in buffer */
+
+ if (key == '\b')
+ {
+ if (c_pindex > c_gindex)
+ c_pindex--;
+ }
+ else
+ if (c_pindex < _INBUFSIZ - 2)
+ buffer[c_pindex++] = key;
+
+ /* if we got a line */
+
+ if (key == '\n' || key == '\r')
+ return buffer[c_gindex++];
+ }
+}
+
+int mvgetch(int y, int x)
+{
+ PDC_LOG(("mvgetch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wgetch(stdscr);
+}
+
+int mvwgetch(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwgetch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wgetch(win);
+}
+
+int PDC_ungetch(int ch)
+{
+ PDC_LOG(("ungetch() - called\n"));
+
+ if (c_ungind >= NUNGETCH) /* pushback stack full */
+ return ERR;
+
+ c_ungch[c_ungind++] = ch;
+
+ return OK;
+}
+
+int flushinp(void)
+{
+ PDC_LOG(("flushinp() - called\n"));
+
+ PDC_flushinp();
+
+ c_gindex = 1; /* set indices to kill buffer */
+ c_pindex = 0;
+ c_ungind = 0; /* clear c_ungch array */
+
+ return OK;
+}
+
+unsigned long PDC_get_key_modifiers(void)
+{
+ PDC_LOG(("PDC_get_key_modifiers() - called\n"));
+
+ return pdc_key_modifiers;
+}
+
+int PDC_save_key_modifiers(bool flag)
+{
+ PDC_LOG(("PDC_save_key_modifiers() - called\n"));
+
+ SP->save_key_modifiers = flag;
+ return OK;
+}
+
+int PDC_return_key_modifiers(bool flag)
+{
+ PDC_LOG(("PDC_return_key_modifiers() - called\n"));
+
+ SP->return_key_modifiers = flag;
+ return PDC_modifiers_set();
+}
+
+#ifdef PDC_WIDE
+int wget_wch(WINDOW *win, wint_t *wch)
+{
+ int key;
+
+ PDC_LOG(("wget_wch() - called\n"));
+
+ if (!wch)
+ return ERR;
+
+ key = wgetch(win);
+
+ if (key == ERR)
+ return ERR;
+
+ *wch = key;
+
+ return SP->key_code ? KEY_CODE_YES : OK;
+}
+
+int get_wch(wint_t *wch)
+{
+ PDC_LOG(("get_wch() - called\n"));
+
+ return wget_wch(stdscr, wch);
+}
+
+int mvget_wch(int y, int x, wint_t *wch)
+{
+ PDC_LOG(("mvget_wch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wget_wch(stdscr, wch);
+}
+
+int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch)
+{
+ PDC_LOG(("mvwget_wch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wget_wch(win, wch);
+}
+
+int unget_wch(const wchar_t wch)
+{
+ return PDC_ungetch(wch);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/getstr.c b/apps/lib/curses/pdcurses/pdcurses/getstr.c
new file mode 100644
index 0000000..c6386d3
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/getstr.c
@@ -0,0 +1,471 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: getstr.c,v 1.51 2008/07/14 04:24:51 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: getstr
+
+ Synopsis:
+ int getstr(char *str);
+ int wgetstr(WINDOW *win, char *str);
+ int mvgetstr(int y, int x, char *str);
+ int mvwgetstr(WINDOW *win, int y, int x, char *str);
+ int getnstr(char *str, int n);
+ int wgetnstr(WINDOW *win, char *str, int n);
+ int mvgetnstr(int y, int x, char *str, int n);
+ int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n);
+
+ int get_wstr(wint_t *wstr);
+ int wget_wstr(WINDOW *win, wint_t *wstr);
+ int mvget_wstr(int y, int x, wint_t *wstr);
+ int mvwget_wstr(WINDOW *win, int, int, wint_t *wstr);
+ int getn_wstr(wint_t *wstr, int n);
+ int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
+ int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
+ int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
+
+ Description:
+ These routines call wgetch() repeatedly to build a string,
+ interpreting erase and kill characters along the way, until a
+ newline or carriage return is received. When PDCurses is built
+ with wide-character support enabled, the narrow-character
+ functions convert the wgetch()'d values into a multibyte string
+ in the current locale before returning it. The resulting string
+ is placed in the area pointed to by *str. The routines with n as
+ the last argument read at most n characters.
+
+ Note that there's no way to know how long the buffer passed to
+ wgetstr() is, so use wgetnstr() to avoid buffer overflows.
+
+ Return Value:
+ This functions return ERR on failure or any other value on
+ success.
+
+ Portability X/Open BSD SYS V
+ getstr Y Y Y
+ wgetstr Y Y Y
+ mvgetstr Y Y Y
+ mvwgetstr Y Y Y
+ getnstr Y - 4.0
+ wgetnstr Y - 4.0
+ mvgetnstr Y - -
+ mvwgetnstr Y - -
+ get_wstr Y
+ wget_wstr Y
+ mvget_wstr Y
+ mvwget_wstr Y
+ getn_wstr Y
+ wgetn_wstr Y
+ mvgetn_wstr Y
+ mvwgetn_wstr Y
+
+**man-end****************************************************************/
+
+#define MAXLINE 255
+
+int wgetnstr(WINDOW *win, char *str, int n)
+{
+#ifdef PDC_WIDE
+ wchar_t wstr[MAXLINE + 1];
+
+ if (n < 0 || n > MAXLINE)
+ n = MAXLINE;
+
+ if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR)
+ return ERR;
+
+ return PDC_wcstombs(str, wstr, n);
+#else
+ int ch, i, num, x, chars;
+ char *p;
+ bool stop, oldecho, oldcbreak, oldnodelay;
+
+ PDC_LOG(("wgetnstr() - called\n"));
+
+ if (!win || !str)
+ return ERR;
+
+ chars = 0;
+ p = str;
+ stop = FALSE;
+
+ x = win->_curx;
+
+ oldcbreak = SP->cbreak; /* remember states */
+ oldecho = SP->echo;
+ oldnodelay = win->_nodelay;
+
+ SP->echo = FALSE; /* we do echo ourselves */
+ cbreak(); /* ensure each key is returned immediately */
+ win->_nodelay = FALSE; /* don't return -1 */
+
+ wrefresh(win);
+
+ while (!stop)
+ {
+ ch = wgetch(win);
+
+ switch (ch)
+ {
+
+ case '\t':
+ ch = ' ';
+ num = TABSIZE - (win->_curx - x) % TABSIZE;
+ for (i = 0; i < num; i++)
+ {
+ if (chars < n)
+ {
+ if (oldecho)
+ waddch(win, ch);
+ *p++ = ch;
+ ++chars;
+ }
+ else
+ beep();
+ }
+ break;
+
+ case _ECHAR: /* CTRL-H -- Delete character */
+ if (p > str)
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+ ch = (unsigned char)(*--p);
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ chars--;
+ }
+ break;
+
+ case _DLCHAR: /* CTRL-U -- Delete line */
+ while (p > str)
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+ ch = (unsigned char)(*--p);
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ }
+ chars = 0;
+ break;
+
+ case _DWCHAR: /* CTRL-W -- Delete word */
+
+ while ((p > str) && (*(p - 1) == ' '))
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+
+ --p; /* remove space */
+ chars--;
+ }
+ while ((p > str) && (*(p - 1) != ' '))
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+
+ ch = (unsigned char)(*--p);
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ chars--;
+ }
+ break;
+
+ case '\n':
+ case '\r':
+ stop = TRUE;
+ if (oldecho)
+ waddch(win, '\n');
+ break;
+
+ default:
+ if (chars < n)
+ {
+ if (!SP->key_code && ch < 0x100)
+ {
+ *p++ = ch;
+ if (oldecho)
+ waddch(win, ch);
+ chars++;
+ }
+ }
+ else
+ beep();
+
+ break;
+
+ }
+
+ wrefresh(win);
+ }
+
+ *p = '\0';
+
+ SP->echo = oldecho; /* restore old settings */
+ SP->cbreak = oldcbreak;
+ win->_nodelay = oldnodelay;
+
+ return OK;
+#endif
+}
+
+int getstr(char *str)
+{
+ PDC_LOG(("getstr() - called\n"));
+
+ return wgetnstr(stdscr, str, MAXLINE);
+}
+
+int wgetstr(WINDOW *win, char *str)
+{
+ PDC_LOG(("wgetstr() - called\n"));
+
+ return wgetnstr(win, str, MAXLINE);
+}
+
+int mvgetstr(int y, int x, char *str)
+{
+ PDC_LOG(("mvgetstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wgetnstr(stdscr, str, MAXLINE);
+}
+
+int mvwgetstr(WINDOW *win, int y, int x, char *str)
+{
+ PDC_LOG(("mvwgetstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wgetnstr(win, str, MAXLINE);
+}
+
+int getnstr(char *str, int n)
+{
+ PDC_LOG(("getnstr() - called\n"));
+
+ return wgetnstr(stdscr, str, n);
+}
+
+int mvgetnstr(int y, int x, char *str, int n)
+{
+ PDC_LOG(("mvgetnstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wgetnstr(stdscr, str, n);
+}
+
+int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n)
+{
+ PDC_LOG(("mvwgetnstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wgetnstr(win, str, n);
+}
+
+#ifdef PDC_WIDE
+int wgetn_wstr(WINDOW *win, wint_t *wstr, int n)
+{
+ int ch, i, num, x, chars;
+ wint_t *p;
+ bool stop, oldecho, oldcbreak, oldnodelay;
+
+ PDC_LOG(("wgetn_wstr() - called\n"));
+
+ if (!win || !wstr)
+ return ERR;
+
+ chars = 0;
+ p = wstr;
+ stop = FALSE;
+
+ x = win->_curx;
+
+ oldcbreak = SP->cbreak; /* remember states */
+ oldecho = SP->echo;
+ oldnodelay = win->_nodelay;
+
+ SP->echo = FALSE; /* we do echo ourselves */
+ cbreak(); /* ensure each key is returned immediately */
+ win->_nodelay = FALSE; /* don't return -1 */
+
+ wrefresh(win);
+
+ while (!stop)
+ {
+ ch = wgetch(win);
+
+ switch (ch)
+ {
+
+ case '\t':
+ ch = ' ';
+ num = TABSIZE - (win->_curx - x) % TABSIZE;
+ for (i = 0; i < num; i++)
+ {
+ if (chars < n)
+ {
+ if (oldecho)
+ waddch(win, ch);
+ *p++ = ch;
+ ++chars;
+ }
+ else
+ beep();
+ }
+ break;
+
+ case _ECHAR: /* CTRL-H -- Delete character */
+ if (p > wstr)
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+ ch = *--p;
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ chars--;
+ }
+ break;
+
+ case _DLCHAR: /* CTRL-U -- Delete line */
+ while (p > wstr)
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+ ch = *--p;
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ }
+ chars = 0;
+ break;
+
+ case _DWCHAR: /* CTRL-W -- Delete word */
+
+ while ((p > wstr) && (*(p - 1) == ' '))
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+
+ --p; /* remove space */
+ chars--;
+ }
+ while ((p > wstr) && (*(p - 1) != ' '))
+ {
+ if (oldecho)
+ waddstr(win, "\b \b");
+
+ ch = *--p;
+ if ((ch < ' ') && (oldecho))
+ waddstr(win, "\b \b");
+ chars--;
+ }
+ break;
+
+ case '\n':
+ case '\r':
+ stop = TRUE;
+ if (oldecho)
+ waddch(win, '\n');
+ break;
+
+ default:
+ if (chars < n)
+ {
+ if (!SP->key_code)
+ {
+ *p++ = ch;
+ if (oldecho)
+ waddch(win, ch);
+ chars++;
+ }
+ }
+ else
+ beep();
+
+ break;
+
+ }
+
+ wrefresh(win);
+ }
+
+ *p = '\0';
+
+ SP->echo = oldecho; /* restore old settings */
+ SP->cbreak = oldcbreak;
+ win->_nodelay = oldnodelay;
+
+ return OK;
+}
+
+int get_wstr(wint_t *wstr)
+{
+ PDC_LOG(("get_wstr() - called\n"));
+
+ return wgetn_wstr(stdscr, wstr, MAXLINE);
+}
+
+int wget_wstr(WINDOW *win, wint_t *wstr)
+{
+ PDC_LOG(("wget_wstr() - called\n"));
+
+ return wgetn_wstr(win, wstr, MAXLINE);
+}
+
+int mvget_wstr(int y, int x, wint_t *wstr)
+{
+ PDC_LOG(("mvget_wstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wgetn_wstr(stdscr, wstr, MAXLINE);
+}
+
+int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr)
+{
+ PDC_LOG(("mvwget_wstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wgetn_wstr(win, wstr, MAXLINE);
+}
+
+int getn_wstr(wint_t *wstr, int n)
+{
+ PDC_LOG(("getn_wstr() - called\n"));
+
+ return wgetn_wstr(stdscr, wstr, n);
+}
+
+int mvgetn_wstr(int y, int x, wint_t *wstr, int n)
+{
+ PDC_LOG(("mvgetn_wstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wgetn_wstr(stdscr, wstr, n);
+}
+
+int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n)
+{
+ PDC_LOG(("mvwgetn_wstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wgetn_wstr(win, wstr, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/getyx.c b/apps/lib/curses/pdcurses/pdcurses/getyx.c
new file mode 100644
index 0000000..fd0564d
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/getyx.c
@@ -0,0 +1,143 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: getyx.c,v 1.29 2008/07/15 17:13:26 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: getyx
+
+ Synopsis:
+ void getyx(WINDOW *win, int y, int x);
+ void getparyx(WINDOW *win, int y, int x);
+ void getbegyx(WINDOW *win, int y, int x);
+ void getmaxyx(WINDOW *win, int y, int x);
+
+ void getsyx(int y, int x);
+ int setsyx(int y, int x);
+
+ int getbegy(WINDOW *win);
+ int getbegx(WINDOW *win);
+ int getcury(WINDOW *win);
+ int getcurx(WINDOW *win);
+ int getpary(WINDOW *win);
+ int getparx(WINDOW *win);
+ int getmaxy(WINDOW *win);
+ int getmaxx(WINDOW *win);
+
+ Description:
+ The getyx() macro (defined in curses.h -- the prototypes here
+ are merely illustrative) puts the current cursor position of the
+ specified window into y and x. getbegyx() and getmaxyx() return
+ the starting coordinates and size of the specified window,
+ respectively. getparyx() returns the starting coordinates of the
+ parent's window, if the specified window is a subwindow;
+ otherwise it sets y and x to -1. These are all macros.
+
+ getsyx() gets the coordinates of the virtual screen cursor, and
+ stores them in y and x. If leaveok() is TRUE, it returns -1, -1.
+ If lines have been removed with ripoffline(), then getsyx()
+ includes these lines in its count; so, the returned y and x
+ values should only be used with setsyx().
+
+ setsyx() sets the virtual screen cursor to the y, x coordinates.
+ If y, x are -1, -1, leaveok() is set TRUE.
+
+ getsyx() and setsyx() are meant to be used by a library routine
+ that manipulates curses windows without altering the position of
+ the cursor. Note that getsyx() is defined only as a macro.
+
+ getbegy(), getbegx(), getcurx(), getcury(), getmaxy(),
+ getmaxx(), getpary(), and getparx() return the appropriate
+ coordinate or size values, or ERR in the case of a NULL window.
+
+ Portability X/Open BSD SYS V
+ getyx Y Y Y
+ getparyx - - 4.0
+ getbegyx - - 3.0
+ getmaxyx - - 3.0
+ getsyx - - 3.0
+ setsyx - - 3.0
+ getbegy - - -
+ getbegx - - -
+ getcury - - -
+ getcurx - - -
+ getpary - - -
+ getparx - - -
+ getmaxy - - -
+ getmaxx - - -
+
+**man-end****************************************************************/
+
+int getbegy(WINDOW *win)
+{
+ PDC_LOG(("getbegy() - called\n"));
+
+ return win ? win->_begy : ERR;
+}
+
+int getbegx(WINDOW *win)
+{
+ PDC_LOG(("getbegx() - called\n"));
+
+ return win ? win->_begx : ERR;
+}
+
+int getcury(WINDOW *win)
+{
+ PDC_LOG(("getcury() - called\n"));
+
+ return win ? win->_cury : ERR;
+}
+
+int getcurx(WINDOW *win)
+{
+ PDC_LOG(("getcurx() - called\n"));
+
+ return win ? win->_curx : ERR;
+}
+
+int getpary(WINDOW *win)
+{
+ PDC_LOG(("getpary() - called\n"));
+
+ return win ? win->_pary : ERR;
+}
+
+int getparx(WINDOW *win)
+{
+ PDC_LOG(("getparx() - called\n"));
+
+ return win ? win->_parx : ERR;
+}
+
+int getmaxy(WINDOW *win)
+{
+ PDC_LOG(("getmaxy() - called\n"));
+
+ return win ? win->_maxy : ERR;
+}
+
+int getmaxx(WINDOW *win)
+{
+ PDC_LOG(("getmaxx() - called\n"));
+
+ return win ? win->_maxx : ERR;
+}
+
+int setsyx(int y, int x)
+{
+ PDC_LOG(("setsyx() - called\n"));
+
+ if(y == -1 && x == -1)
+ {
+ curscr->_leaveit = TRUE;
+ return OK;
+ }
+ else
+ {
+ curscr->_leaveit = FALSE;
+ return wmove(curscr, y, x);
+ }
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/inch.c b/apps/lib/curses/pdcurses/pdcurses/inch.c
new file mode 100644
index 0000000..7347e74
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/inch.c
@@ -0,0 +1,125 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: inch.c,v 1.33 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: inch
+
+ Synopsis:
+ chtype inch(void);
+ chtype winch(WINDOW *win);
+ chtype mvinch(int y, int x);
+ chtype mvwinch(WINDOW *win, int y, int x);
+
+ int in_wch(cchar_t *wcval);
+ int win_wch(WINDOW *win, cchar_t *wcval);
+ int mvin_wch(int y, int x, cchar_t *wcval);
+ int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval);
+
+ Description:
+ The inch() functions retrieve the character and attribute from
+ the current or specified window position, in the form of a
+ chtype. If a NULL window is specified, (chtype)ERR is returned.
+
+ The in_wch() functions are the wide-character versions; instead
+ of returning a chtype, they store a cchar_t at the address
+ specified by wcval, and return OK or ERR. (No value is stored
+ when ERR is returned.) Note that in PDCurses, chtype and cchar_t
+ are the same.
+
+ Portability X/Open BSD SYS V
+ inch Y Y Y
+ winch Y Y Y
+ mvinch Y Y Y
+ mvwinch Y Y Y
+ in_wch Y
+ win_wch Y
+ mvin_wch Y
+ mvwin_wch Y
+
+**man-end****************************************************************/
+
+chtype winch(WINDOW *win)
+{
+ PDC_LOG(("winch() - called\n"));
+
+ if (!win)
+ return (chtype)ERR;
+
+ return win->_y[win->_cury][win->_curx];
+}
+
+chtype inch(void)
+{
+ PDC_LOG(("inch() - called\n"));
+
+ return winch(stdscr);
+}
+
+chtype mvinch(int y, int x)
+{
+ PDC_LOG(("mvinch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return (chtype)ERR;
+
+ return stdscr->_y[stdscr->_cury][stdscr->_curx];
+}
+
+chtype mvwinch(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwinch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return (chtype)ERR;
+
+ return win->_y[win->_cury][win->_curx];
+}
+
+#ifdef PDC_WIDE
+int win_wch(WINDOW *win, cchar_t *wcval)
+{
+ PDC_LOG(("win_wch() - called\n"));
+
+ if (!win || !wcval)
+ return ERR;
+
+ *wcval = win->_y[win->_cury][win->_curx];
+
+ return OK;
+}
+
+int in_wch(cchar_t *wcval)
+{
+ PDC_LOG(("in_wch() - called\n"));
+
+ return win_wch(stdscr, wcval);
+}
+
+int mvin_wch(int y, int x, cchar_t *wcval)
+{
+ PDC_LOG(("mvin_wch() - called\n"));
+
+ if (!wcval || (move(y, x) == ERR))
+ return ERR;
+
+ *wcval = stdscr->_y[stdscr->_cury][stdscr->_curx];
+
+ return OK;
+}
+
+int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval)
+{
+ PDC_LOG(("mvwin_wch() - called\n"));
+
+ if (!wcval || (wmove(win, y, x) == ERR))
+ return ERR;
+
+ *wcval = win->_y[win->_cury][win->_curx];
+
+ return OK;
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/inchstr.c b/apps/lib/curses/pdcurses/pdcurses/inchstr.c
new file mode 100644
index 0000000..50b8cf5
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/inchstr.c
@@ -0,0 +1,211 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: inchstr.c,v 1.34 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: inchstr
+
+ Synopsis:
+ int inchstr(chtype *ch);
+ int inchnstr(chtype *ch, int n);
+ int winchstr(WINDOW *win, chtype *ch);
+ int winchnstr(WINDOW *win, chtype *ch, int n);
+ int mvinchstr(int y, int x, chtype *ch);
+ int mvinchnstr(int y, int x, chtype *ch, int n);
+ int mvwinchstr(WINDOW *, int y, int x, chtype *ch);
+ int mvwinchnstr(WINDOW *, int y, int x, chtype *ch, int n);
+
+ int in_wchstr(cchar_t *wch);
+ int in_wchnstr(cchar_t *wch, int n);
+ int win_wchstr(WINDOW *win, cchar_t *wch);
+ int win_wchnstr(WINDOW *win, cchar_t *wch, int n);
+ int mvin_wchstr(int y, int x, cchar_t *wch);
+ int mvin_wchnstr(int y, int x, cchar_t *wch, int n);
+ int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch);
+ int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n);
+
+ Description:
+ These routines read a chtype or cchar_t string from the window,
+ starting at the current or specified position, and ending at the
+ right margin, or after n elements, whichever is less.
+
+ Return Value:
+ All functions return the number of elements read, or ERR on
+ error.
+
+ Portability X/Open BSD SYS V
+ inchstr Y - 4.0
+ winchstr Y - 4.0
+ mvinchstr Y - 4.0
+ mvwinchstr Y - 4.0
+ inchnstr Y - 4.0
+ winchnstr Y - 4.0
+ mvinchnstr Y - 4.0
+ mvwinchnstr Y - 4.0
+ in_wchstr Y
+ win_wchstr Y
+ mvin_wchstr Y
+ mvwin_wchstr Y
+ in_wchnstr Y
+ win_wchnstr Y
+ mvin_wchnstr Y
+ mvwin_wchnstr Y
+
+**man-end****************************************************************/
+
+int winchnstr(WINDOW *win, chtype *ch, int n)
+{
+ chtype *src;
+ int i;
+
+ PDC_LOG(("winchnstr() - called\n"));
+
+ if (!win || !ch || n < 0)
+ return ERR;
+
+ if ((win->_curx + n) > win->_maxx)
+ n = win->_maxx - win->_curx;
+
+ src = win->_y[win->_cury] + win->_curx;
+
+ for (i = 0; i < n; i++)
+ *ch++ = *src++;
+
+ *ch = (chtype)0;
+
+ return OK;
+}
+
+int inchstr(chtype *ch)
+{
+ PDC_LOG(("inchstr() - called\n"));
+
+ return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx);
+}
+
+int winchstr(WINDOW *win, chtype *ch)
+{
+ PDC_LOG(("winchstr() - called\n"));
+
+ return winchnstr(win, ch, win->_maxx - win->_curx);
+}
+
+int mvinchstr(int y, int x, chtype *ch)
+{
+ PDC_LOG(("mvinchstr() - called: y %d x %d\n", y, x));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx);
+}
+
+int mvwinchstr(WINDOW *win, int y, int x, chtype *ch)
+{
+ PDC_LOG(("mvwinchstr() - called:\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winchnstr(win, ch, win->_maxx - win->_curx);
+}
+
+int inchnstr(chtype *ch, int n)
+{
+ PDC_LOG(("inchnstr() - called\n"));
+
+ return winchnstr(stdscr, ch, n);
+}
+
+int mvinchnstr(int y, int x, chtype *ch, int n)
+{
+ PDC_LOG(("mvinchnstr() - called: y %d x %d n %d\n", y, x, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winchnstr(stdscr, ch, n);
+}
+
+int mvwinchnstr(WINDOW *win, int y, int x, chtype *ch, int n)
+{
+ PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winchnstr(win, ch, n);
+}
+
+#ifdef PDC_WIDE
+int win_wchnstr(WINDOW *win, cchar_t *wch, int n)
+{
+ PDC_LOG(("win_wchnstr() - called\n"));
+
+ return winchnstr(win, wch, n);
+}
+
+int in_wchstr(cchar_t *wch)
+{
+ PDC_LOG(("in_wchstr() - called\n"));
+
+ return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx);
+}
+
+int win_wchstr(WINDOW *win, cchar_t *wch)
+{
+ PDC_LOG(("win_wchstr() - called\n"));
+
+ return win_wchnstr(win, wch, win->_maxx - win->_curx);
+}
+
+int mvin_wchstr(int y, int x, cchar_t *wch)
+{
+ PDC_LOG(("mvin_wchstr() - called: y %d x %d\n", y, x));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx);
+}
+
+int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch)
+{
+ PDC_LOG(("mvwin_wchstr() - called:\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return win_wchnstr(win, wch, win->_maxx - win->_curx);
+}
+
+int in_wchnstr(cchar_t *wch, int n)
+{
+ PDC_LOG(("in_wchnstr() - called\n"));
+
+ return win_wchnstr(stdscr, wch, n);
+}
+
+int mvin_wchnstr(int y, int x, cchar_t *wch, int n)
+{
+ PDC_LOG(("mvin_wchnstr() - called: y %d x %d n %d\n", y, x, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return win_wchnstr(stdscr, wch, n);
+}
+
+int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n)
+{
+ PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return win_wchnstr(win, wch, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/initscr.c b/apps/lib/curses/pdcurses/pdcurses/initscr.c
new file mode 100644
index 0000000..d80fa0c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/initscr.c
@@ -0,0 +1,339 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: initscr.c,v 1.114 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: initscr
+
+ Synopsis:
+ WINDOW *initscr(void);
+ WINDOW *Xinitscr(int argc, char *argv[]);
+ int endwin(void);
+ bool isendwin(void);
+ SCREEN *newterm(const char *type, FILE *outfd, FILE *infd);
+ SCREEN *set_term(SCREEN *new);
+ void delscreen(SCREEN *sp);
+
+ int resize_term(int nlines, int ncols);
+ bool is_termresized(void);
+ const char *curses_version(void);
+
+ Description:
+ initscr() should be the first curses routine called. It will
+ initialize all curses data structures, and arrange that the
+ first call to refresh() will clear the screen. In case of
+ error, initscr() will write a message to standard error and end
+ the program.
+
+ endwin() should be called before exiting or escaping from curses
+ mode temporarily. It will restore tty modes, move the cursor to
+ the lower left corner of the screen and reset the terminal into
+ the proper non-visual mode. To resume curses after a temporary
+ escape, call refresh() or doupdate().
+
+ isendwin() returns TRUE if endwin() has been called without a
+ subsequent refresh, unless SP is NULL.
+
+ In some implementations of curses, newterm() allows the use of
+ multiple terminals. Here, it's just an alternative interface for
+ initscr(). It always returns SP, or NULL.
+
+ delscreen() frees the memory allocated by newterm() or
+ initscr(), since it's not freed by endwin(). This function is
+ usually not needed. In PDCurses, the parameter must be the
+ value of SP, and delscreen() sets SP to NULL.
+
+ set_term() does nothing meaningful in PDCurses, but is included
+ for compatibility with other curses implementations.
+
+ resize_term() is effectively two functions: When called with
+ nonzero values for nlines and ncols, it attempts to resize the
+ screen to the given size. When called with (0, 0), it merely
+ adjusts the internal structures to match the current size after
+ the screen is resized by the user. On the currently supported
+ platforms, this functionality is mutually exclusive: X11 allows
+ user resizing, while DOS, OS/2 and Win32 allow programmatic
+ resizing. If you want to support user resizing, you should check
+ for getch() returning KEY_RESIZE, and/or call is_termresized()
+ at appropriate times; if either condition occurs, call
+ resize_term(0, 0). Then, with either user or programmatic
+ resizing, you'll have to resize any windows you've created, as
+ appropriate; resize_term() only handles stdscr and curscr.
+
+ is_termresized() returns TRUE if the curses screen has been
+ resized by the user, and a call to resize_term() is needed.
+ Checking for KEY_RESIZE is generally preferable, unless you're
+ not handling the keyboard.
+
+ curses_version() returns a string describing the version of
+ PDCurses.
+
+ Return Value:
+ All functions return NULL on error, except endwin(), which
+ returns ERR on error.
+
+ Portability X/Open BSD SYS V
+ initscr Y Y Y
+ endwin Y Y Y
+ isendwin Y - 3.0
+ newterm Y - Y
+ set_term Y - Y
+ delscreen Y - 4.0
+ resize_term - - -
+ is_termresized - - -
+ curses_version - - -
+
+**man-end****************************************************************/
+
+#include <stdlib.h>
+
+char ttytype[128];
+
+const char *_curses_notice = "PDCurses 3.4 - Public Domain 2008";
+
+SCREEN *SP = (SCREEN*)NULL; /* curses variables */
+WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */
+WINDOW *stdscr = (WINDOW *)NULL; /* the default screen window */
+WINDOW *pdc_lastscr = (WINDOW *)NULL; /* the last screen image */
+
+int LINES = 0; /* current terminal height */
+int COLS = 0; /* current terminal width */
+int TABSIZE = 8;
+
+MOUSE_STATUS Mouse_status, pdc_mouse_status;
+
+extern RIPPEDOFFLINE linesripped[5];
+extern char linesrippedoff;
+
+WINDOW *Xinitscr(int argc, char *argv[])
+{
+ int i;
+
+ PDC_LOG(("Xinitscr() - called\n"));
+
+ if (SP && SP->alive)
+ return NULL;
+
+ if (PDC_scr_open(argc, argv) == ERR)
+ {
+ fprintf(stderr, "initscr(): Unable to create SP\n");
+ exit(8);
+ }
+
+ SP->autocr = TRUE; /* cr -> lf by default */
+ SP->raw_out = FALSE; /* tty I/O modes */
+ SP->raw_inp = FALSE; /* tty I/O modes */
+ SP->cbreak = TRUE;
+ SP->save_key_modifiers = FALSE;
+ SP->return_key_modifiers = FALSE;
+ SP->echo = TRUE;
+ SP->visibility = 1;
+ SP->resized = FALSE;
+ SP->_trap_mbe = 0L;
+ SP->_map_mbe_to_key = 0L;
+ SP->linesrippedoff = 0;
+ SP->linesrippedoffontop = 0;
+ SP->delaytenths = 0;
+ SP->line_color = -1;
+
+ SP->orig_cursor = PDC_get_cursor_mode();
+
+ LINES = SP->lines;
+ COLS = SP->cols;
+
+ if (LINES < 2 || COLS < 2)
+ {
+ fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
+ LINES, COLS);
+ exit(4);
+ }
+
+ if ((curscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
+ {
+ fprintf(stderr, "initscr(): Unable to create curscr.\n");
+ exit(2);
+ }
+
+ if ((pdc_lastscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
+ {
+ fprintf(stderr, "initscr(): Unable to create pdc_lastscr.\n");
+ exit(2);
+ }
+
+ wattrset(pdc_lastscr, (chtype)(-1));
+ werase(pdc_lastscr);
+
+ PDC_slk_initialize();
+ LINES -= SP->slklines;
+
+ /* We have to sort out ripped off lines here, and reduce the height
+ of stdscr by the number of lines ripped off */
+
+ for (i = 0; i < linesrippedoff; i++)
+ {
+ if (linesripped[i].line < 0)
+ (*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS);
+ else
+ (*linesripped[i].init)(newwin(1, COLS,
+ SP->linesrippedoffontop++, 0), COLS);
+
+ SP->linesrippedoff++;
+ LINES--;
+ }
+
+ linesrippedoff = 0;
+
+ if (!(stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0)))
+ {
+ fprintf(stderr, "initscr(): Unable to create stdscr.\n");
+ exit(1);
+ }
+
+ wclrtobot(stdscr);
+
+ /* If preserving the existing screen, don't allow a screen clear */
+
+ if (SP->_preserve)
+ {
+ untouchwin(curscr);
+ untouchwin(stdscr);
+ stdscr->_clear = FALSE;
+ curscr->_clear = FALSE;
+ }
+ else
+ curscr->_clear = TRUE;
+
+ PDC_init_atrtab(); /* set up default colors */
+
+ MOUSE_X_POS = MOUSE_Y_POS = -1;
+ BUTTON_STATUS(1) = BUTTON_RELEASED;
+ BUTTON_STATUS(2) = BUTTON_RELEASED;
+ BUTTON_STATUS(3) = BUTTON_RELEASED;
+ Mouse_status.changes = 0;
+
+ SP->alive = TRUE;
+
+ def_shell_mode();
+
+ sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname());
+
+ return stdscr;
+}
+
+WINDOW *initscr(void)
+{
+ PDC_LOG(("initscr() - called\n"));
+
+ return Xinitscr(0, NULL);
+}
+
+int endwin(void)
+{
+ PDC_LOG(("endwin() - called\n"));
+
+ /* Allow temporary exit from curses using endwin() */
+
+ def_prog_mode();
+ PDC_scr_close();
+
+ SP->alive = FALSE;
+
+ return OK;
+}
+
+bool isendwin(void)
+{
+ PDC_LOG(("isendwin() - called\n"));
+
+ return SP ? !(SP->alive) : FALSE;
+}
+
+SCREEN *newterm(const char *type, FILE *outfd, FILE *infd)
+{
+ PDC_LOG(("newterm() - called\n"));
+
+ return Xinitscr(0, NULL) ? SP : NULL;
+}
+
+SCREEN *set_term(SCREEN *new)
+{
+ PDC_LOG(("set_term() - called\n"));
+
+ /* We only support one screen */
+
+ return (new == SP) ? SP : NULL;
+}
+
+void delscreen(SCREEN *sp)
+{
+ PDC_LOG(("delscreen() - called\n"));
+
+ if (sp != SP)
+ return;
+
+ PDC_slk_free(); /* free the soft label keys, if needed */
+
+ delwin(stdscr);
+ delwin(curscr);
+ delwin(pdc_lastscr);
+ stdscr = (WINDOW *)NULL;
+ curscr = (WINDOW *)NULL;
+ pdc_lastscr = (WINDOW *)NULL;
+
+ SP->alive = FALSE;
+
+ PDC_scr_free(); /* free SP and pdc_atrtab */
+
+ SP = (SCREEN *)NULL;
+}
+
+int resize_term(int nlines, int ncols)
+{
+ PDC_LOG(("resize_term() - called: nlines %d\n", nlines));
+
+ if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
+ return ERR;
+
+ SP->lines = PDC_get_rows();
+ LINES = SP->lines - SP->linesrippedoff - SP->slklines;
+ SP->cols = COLS = PDC_get_columns();
+
+ if (wresize(curscr, SP->lines, SP->cols) == ERR ||
+ wresize(stdscr, LINES, COLS) == ERR ||
+ wresize(pdc_lastscr, SP->lines, SP->cols) == ERR)
+ return ERR;
+
+ werase(pdc_lastscr);
+ curscr->_clear = TRUE;
+
+ if (SP->slk_winptr)
+ {
+ if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR)
+ return ERR;
+
+ wmove(SP->slk_winptr, 0, 0);
+ wclrtobot(SP->slk_winptr);
+ PDC_slk_initialize();
+ slk_noutrefresh();
+ }
+
+ touchwin(stdscr);
+ wnoutrefresh(stdscr);
+
+ return OK;
+}
+
+bool is_termresized(void)
+{
+ PDC_LOG(("is_termresized() - called\n"));
+
+ return SP->resized;
+}
+
+const char *curses_version(void)
+{
+ return _curses_notice;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/inopts.c b/apps/lib/curses/pdcurses/pdcurses/inopts.c
new file mode 100644
index 0000000..6d33fc2
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/inopts.c
@@ -0,0 +1,321 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: inopts.c,v 1.43 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: inopts
+
+ Synopsis:
+ int cbreak(void);
+ int nocbreak(void);
+ int echo(void);
+ int noecho(void);
+ int halfdelay(int tenths);
+ int intrflush(WINDOW *win, bool bf);
+ int keypad(WINDOW *win, bool bf);
+ int meta(WINDOW *win, bool bf);
+ int nl(void);
+ int nonl(void);
+ int nodelay(WINDOW *win, bool bf);
+ int notimeout(WINDOW *win, bool bf);
+ int raw(void);
+ int noraw(void);
+ void noqiflush(void);
+ void qiflush(void);
+ void timeout(int delay);
+ void wtimeout(WINDOW *win, int delay);
+ int typeahead(int fildes);
+
+ int crmode(void);
+ int nocrmode(void);
+
+ Description:
+ cbreak() and nocbreak() toggle cbreak mode. In cbreak mode,
+ characters typed by the user are made available immediately, and
+ erase/kill character processing is not performed. In nocbreak
+ mode, typed characters are buffered until a newline or carriage
+ return. Interrupt and flow control characters are unaffected by
+ this mode. PDCurses always starts in cbreak mode.
+
+ echo() and noecho() control whether typed characters are echoed
+ by the input routine. Initially, input characters are echoed.
+ Subsequent calls to echo() and noecho() do not flush type-ahead.
+
+ halfdelay() is similar to cbreak(), but allows for a time limit
+ to be specified, in tenths of a second. This causes getch() to
+ block for that period before returning ERR if no key has been
+ received. tenths must be between 1 and 255.
+
+ keypad() controls whether getch() returns function/special keys
+ as single key codes (e.g., the left arrow key as KEY_LEFT). Per
+ X/Open, the default for keypad mode is OFF. You'll probably want
+ it on. With keypad mode off, if a special key is pressed,
+ getch() does nothing or returns ERR.
+
+ nodelay() controls whether wgetch() is a non-blocking call. If
+ the option is enabled, and no input is ready, wgetch() will
+ return ERR. If disabled, wgetch() will hang until input is
+ ready.
+
+ nl() enables the translation of a carriage return into a newline
+ on input. nonl() disables this. Initially, the translation does
+ occur.
+
+ raw() and noraw() toggle raw mode. Raw mode is similar to cbreak
+ mode, in that characters typed are immediately passed through to
+ the user program. The difference is that in raw mode, the INTR,
+ QUIT, SUSP, and STOP characters are passed through without being
+ interpreted, and without generating a signal.
+
+ In PDCurses, the meta() function sets raw mode on or off.
+
+ timeout() and wtimeout() set blocking or non-blocking reads for
+ the specified window. The delay is measured in milliseconds. If
+ it's negative, a blocking read is used; if zero, then non-
+ blocking reads are done -- if no input is waiting, ERR is
+ returned immediately. If the delay is positive, the read blocks
+ for the delay period; if the period expires, ERR is returned.
+
+ intrflush(), notimeout(), noqiflush(), qiflush() and typeahead()
+ do nothing in PDCurses, but are included for compatibility with
+ other curses implementations.
+
+ crmode() and nocrmode() are archaic equivalents to cbreak() and
+ nocbreak(), respectively.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ cbreak Y Y Y
+ nocbreak Y Y Y
+ echo Y Y Y
+ noecho Y Y Y
+ halfdelay Y - Y
+ intrflush Y - Y
+ keypad Y - Y
+ meta Y - Y
+ nl Y Y Y
+ nonl Y Y Y
+ nodelay Y - Y
+ notimeout Y - Y
+ raw Y Y Y
+ noraw Y Y Y
+ noqiflush Y - Y
+ qiflush Y - Y
+ timeout Y - Y
+ wtimeout Y - Y
+ typeahead Y - Y
+ crmode -
+ nocrmode -
+
+**man-end****************************************************************/
+
+int cbreak(void)
+{
+ PDC_LOG(("cbreak() - called\n"));
+
+ SP->cbreak = TRUE;
+
+ return OK;
+}
+
+int nocbreak(void)
+{
+ PDC_LOG(("nocbreak() - called\n"));
+
+ SP->cbreak = FALSE;
+ SP->delaytenths = 0;
+
+ return OK;
+}
+
+int echo(void)
+{
+ PDC_LOG(("echo() - called\n"));
+
+ SP->echo = TRUE;
+
+ return OK;
+}
+
+int noecho(void)
+{
+ PDC_LOG(("noecho() - called\n"));
+
+ SP->echo = FALSE;
+
+ return OK;
+}
+
+int halfdelay(int tenths)
+{
+ PDC_LOG(("halfdelay() - called\n"));
+
+ if (tenths < 1 || tenths > 255)
+ return ERR;
+
+ SP->delaytenths = tenths;
+
+ return OK;
+}
+
+int intrflush(WINDOW *win, bool bf)
+{
+ PDC_LOG(("intrflush() - called\n"));
+
+ return OK;
+}
+
+int keypad(WINDOW *win, bool bf)
+{
+ PDC_LOG(("keypad() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_use_keypad = bf;
+
+ return OK;
+}
+
+int meta(WINDOW *win, bool bf)
+{
+ PDC_LOG(("meta() - called\n"));
+
+ SP->raw_inp = bf;
+
+ return OK;
+}
+
+int nl(void)
+{
+ PDC_LOG(("nl() - called\n"));
+
+ SP->autocr = TRUE;
+
+ return OK;
+}
+
+int nonl(void)
+{
+ PDC_LOG(("nonl() - called\n"));
+
+ SP->autocr = FALSE;
+
+ return OK;
+}
+
+int nodelay(WINDOW *win, bool flag)
+{
+ PDC_LOG(("nodelay() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_nodelay = flag;
+
+ return OK;
+}
+
+int notimeout(WINDOW *win, bool flag)
+{
+ PDC_LOG(("notimeout() - called\n"));
+
+ return OK;
+}
+
+int raw(void)
+{
+ PDC_LOG(("raw() - called\n"));
+
+ PDC_set_keyboard_binary(TRUE);
+ SP->raw_inp = TRUE;
+
+ return OK;
+}
+
+int noraw(void)
+{
+ PDC_LOG(("noraw() - called\n"));
+
+ PDC_set_keyboard_binary(FALSE);
+ SP->raw_inp = FALSE;
+
+ return OK;
+}
+
+void noqiflush(void)
+{
+ PDC_LOG(("noqiflush() - called\n"));
+}
+
+void qiflush(void)
+{
+ PDC_LOG(("qiflush() - called\n"));
+}
+
+int typeahead(int fildes)
+{
+ PDC_LOG(("typeahead() - called\n"));
+
+ return OK;
+}
+
+void wtimeout(WINDOW *win, int delay)
+{
+ PDC_LOG(("wtimeout() - called\n"));
+
+ if (!win)
+ return;
+
+ if (delay < 0)
+ {
+ /* This causes a blocking read on the window, so turn on delay
+ mode */
+
+ win->_nodelay = FALSE;
+ win->_delayms = 0;
+ }
+ else if (!delay)
+ {
+ /* This causes a non-blocking read on the window, so turn off
+ delay mode */
+
+ win->_nodelay = TRUE;
+ win->_delayms = 0;
+ }
+ else
+ {
+ /* This causes the read on the window to delay for the number of
+ milliseconds. Also forces the window into non-blocking read
+ mode */
+
+ /*win->_nodelay = TRUE;*/
+ win->_delayms = delay;
+ }
+}
+
+void timeout(int delay)
+{
+ PDC_LOG(("timeout() - called\n"));
+
+ wtimeout(stdscr, delay);
+}
+
+int crmode(void)
+{
+ PDC_LOG(("crmode() - called\n"));
+
+ return cbreak();
+}
+
+int nocrmode(void)
+{
+ PDC_LOG(("nocrmode() - called\n"));
+
+ return nocbreak();
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/insch.c b/apps/lib/curses/pdcurses/pdcurses/insch.c
new file mode 100644
index 0000000..50527f2
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/insch.c
@@ -0,0 +1,268 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: insch.c,v 1.44 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: insch
+
+ Synopsis:
+ int insch(chtype ch);
+ int winsch(WINDOW *win, chtype ch);
+ int mvinsch(int y, int x, chtype ch);
+ int mvwinsch(WINDOW *win, int y, int x, chtype ch);
+
+ int insrawch(chtype ch);
+ int winsrawch(WINDOW *win, chtype ch);
+ int mvinsrawch(int y, int x, chtype ch);
+ int mvwinsrawch(WINDOW *win, int y, int x, chtype ch);
+
+ int ins_wch(const cchar_t *wch);
+ int wins_wch(WINDOW *win, const cchar_t *wch);
+ int mvins_wch(int y, int x, const cchar_t *wch);
+ int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch);
+
+ Description:
+ The insch() functions insert a chtype into the window at the
+ current or specified cursor position. The cursor is NOT
+ advanced. A newline is equivalent to clrtoeol(); tabs are
+ expanded; other control characters are converted as with
+ unctrl().
+
+ The ins_wch() functions are the wide-character
+ equivalents, taking cchar_t pointers rather than chtypes.
+
+ Video attributes can be combined with a character by ORing
+ them into the parameter. Text, including attributes, can be
+ copied from one place to another using inch() and insch().
+
+ insrawch() etc. are PDCurses-specific wrappers for insch() etc.
+ that disable the translation of control characters.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ insch Y Y Y
+ winsch Y Y Y
+ mvinsch Y Y Y
+ mvwinsch Y Y Y
+ insrawch - - -
+ winsrawch - - -
+ ins_wch Y
+ wins_wch Y
+ mvins_wch Y
+ mvwins_wch Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int winsch(WINDOW *win, chtype ch)
+{
+ int x, y;
+ chtype attr;
+ bool xlat;
+
+ PDC_LOG(("winsch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
+ win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+ if (!win)
+ return ERR;
+
+ x = win->_curx;
+ y = win->_cury;
+
+ if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
+ return ERR;
+
+ xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
+ attr = ch & A_ATTRIBUTES;
+ ch &= A_CHARTEXT;
+
+ if (xlat && (ch < ' ' || ch == 0x7f))
+ {
+ int x2;
+
+ switch (ch)
+ {
+ case '\t':
+ for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
+ {
+ if (winsch(win, attr | ' ') == ERR)
+ return ERR;
+ }
+ return OK;
+
+ case '\n':
+ wclrtoeol(win);
+ break;
+
+ case 0x7f:
+ if (winsch(win, attr | '?') == ERR)
+ return ERR;
+
+ return winsch(win, attr | '^');
+
+ default:
+ /* handle control chars */
+
+ if (winsch(win, attr | (ch + '@')) == ERR)
+ return ERR;
+
+ return winsch(win, attr | '^');
+ }
+ }
+ else
+ {
+ int maxx;
+ chtype *temp;
+
+ /* If the incoming character doesn't have its own attribute,
+ then use the current attributes for the window. If it has
+ attributes but not a color component, OR the attributes to
+ the current attributes for the window. If it has a color
+ component, use the attributes solely from the incoming
+ character. */
+
+ if (!(attr & A_COLOR))
+ attr |= win->_attrs;
+
+ /* wrs (4/10/93): Apply the same sort of logic for the window
+ background, in that it only takes precedence if other color
+ attributes are not there and that the background character
+ will only print if the printing character is blank. */
+
+ if (!(attr & A_COLOR))
+ attr |= win->_bkgd & A_ATTRIBUTES;
+ else
+ attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
+
+ if (ch == ' ')
+ ch = win->_bkgd & A_CHARTEXT;
+
+ /* Add the attribute back into the character. */
+
+ ch |= attr;
+
+ maxx = win->_maxx;
+ temp = &win->_y[y][x];
+
+ memmove(temp + 1, temp, (maxx - x - 1) * sizeof(chtype));
+
+ win->_lastch[y] = maxx - 1;
+
+ if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x))
+ win->_firstch[y] = x;
+
+ *temp = ch;
+ }
+
+ PDC_sync(win);
+
+ return OK;
+}
+
+int insch(chtype ch)
+{
+ PDC_LOG(("insch() - called\n"));
+
+ return winsch(stdscr, ch);
+}
+
+int mvinsch(int y, int x, chtype ch)
+{
+ PDC_LOG(("mvinsch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winsch(stdscr, ch);
+}
+
+int mvwinsch(WINDOW *win, int y, int x, chtype ch)
+{
+ PDC_LOG(("mvwinsch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winsch(win, ch);
+}
+
+int winsrawch(WINDOW *win, chtype ch)
+{
+ PDC_LOG(("winsrawch() - called: win=%p ch=%x "
+ "(char=%c attr=0x%x)\n", win, ch,
+ ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+ if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
+ ch |= A_ALTCHARSET;
+
+ return winsch(win, ch);
+}
+
+int insrawch(chtype ch)
+{
+ PDC_LOG(("insrawch() - called\n"));
+
+ return winsrawch(stdscr, ch);
+}
+
+int mvinsrawch(int y, int x, chtype ch)
+{
+ PDC_LOG(("mvinsrawch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winsrawch(stdscr, ch);
+}
+
+int mvwinsrawch(WINDOW *win, int y, int x, chtype ch)
+{
+ PDC_LOG(("mvwinsrawch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winsrawch(win, ch);
+}
+
+#ifdef PDC_WIDE
+int wins_wch(WINDOW *win, const cchar_t *wch)
+{
+ PDC_LOG(("wins_wch() - called\n"));
+
+ return wch ? winsch(win, *wch) : ERR;
+}
+
+int ins_wch(const cchar_t *wch)
+{
+ PDC_LOG(("ins_wch() - called\n"));
+
+ return wins_wch(stdscr, wch);
+}
+
+int mvins_wch(int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvins_wch() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wins_wch(stdscr, wch);
+}
+
+int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch)
+{
+ PDC_LOG(("mvwins_wch() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wins_wch(win, wch);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/insstr.c b/apps/lib/curses/pdcurses/pdcurses/insstr.c
new file mode 100644
index 0000000..38fa389
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/insstr.c
@@ -0,0 +1,261 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: insstr.c,v 1.46 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: insstr
+
+ Synopsis:
+ int insstr(const char *str);
+ int insnstr(const char *str, int n);
+ int winsstr(WINDOW *win, const char *str);
+ int winsnstr(WINDOW *win, const char *str, int n);
+ int mvinsstr(int y, int x, const char *str);
+ int mvinsnstr(int y, int x, const char *str, int n);
+ int mvwinsstr(WINDOW *win, int y, int x, const char *str);
+ int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n);
+
+ int ins_wstr(const wchar_t *wstr);
+ int ins_nwstr(const wchar_t *wstr, int n);
+ int wins_wstr(WINDOW *win, const wchar_t *wstr);
+ int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n);
+ int mvins_wstr(int y, int x, const wchar_t *wstr);
+ int mvins_nwstr(int y, int x, const wchar_t *wstr, int n);
+ int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr);
+ int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n);
+
+ Description:
+ The insstr() functions insert a character string into a window
+ at the current cursor position, by repeatedly calling winsch().
+ When PDCurses is built with wide-character support enabled, the
+ narrow-character functions treat the string as a multibyte
+ string in the current locale, and convert it first. All
+ characters to the right of the cursor are moved to the right,
+ with the possibility of the rightmost characters on the line
+ being lost. The cursor position does not change (after moving
+ to y, x, if specified). The routines with n as the last
+ argument insert at most n characters; if n is negative, then the
+ entire string is inserted.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ insstr Y - 4.0
+ winsstr Y - 4.0
+ mvinsstr Y - 4.0
+ mvwinsstr Y - 4.0
+ insnstr Y - 4.0
+ winsnstr Y - 4.0
+ mvinsnstr Y - 4.0
+ mvwinsnstr Y - 4.0
+ ins_wstr Y
+ wins_wstr Y
+ mvins_wstr Y
+ mvwins_wstr Y
+ ins_nwstr Y
+ wins_nwstr Y
+ mvins_nwstr Y
+ mvwins_nwstr Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int winsnstr(WINDOW *win, const char *str, int n)
+{
+#ifdef PDC_WIDE
+ wchar_t wstr[513], *p;
+ int i;
+#endif
+ int len;
+
+ PDC_LOG(("winsnstr() - called: string=\"%s\" n %d \n", str, n));
+
+ if (!win || !str)
+ return ERR;
+
+ len = strlen(str);
+
+ if (n < 0 || n < len)
+ n = len;
+
+#ifdef PDC_WIDE
+ if (n > 512)
+ n = 512;
+
+ p = wstr;
+ i = 0;
+
+ while (str[i] && i < n)
+ {
+ int retval = PDC_mbtowc(p, str + i, n - i);
+
+ if (retval <= 0)
+ break;
+ p++;
+ i += retval;
+ }
+
+ while (p > wstr)
+ if (winsch(win, *--p) == ERR)
+#else
+ while (n)
+ if (winsch(win, (unsigned char)(str[--n])) == ERR)
+#endif
+ return ERR;
+
+ return OK;
+}
+
+int insstr(const char *str)
+{
+ PDC_LOG(("insstr() - called: string=\"%s\"\n", str));
+
+ return winsnstr(stdscr, str, -1);
+}
+
+int winsstr(WINDOW *win, const char *str)
+{
+ PDC_LOG(("winsstr() - called: string=\"%s\"\n", str));
+
+ return winsnstr(win, str, -1);
+}
+
+int mvinsstr(int y, int x, const char *str)
+{
+ PDC_LOG(("mvinsstr() - called: y %d x %d string=\"%s\"\n", y, x, str));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winsnstr(stdscr, str, -1);
+}
+
+int mvwinsstr(WINDOW *win, int y, int x, const char *str)
+{
+ PDC_LOG(("mvwinsstr() - called: string=\"%s\"\n", str));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winsnstr(win, str, -1);
+}
+
+int insnstr(const char *str, int n)
+{
+ PDC_LOG(("insnstr() - called: string=\"%s\" n %d \n", str, n));
+
+ return winsnstr(stdscr, str, n);
+}
+
+int mvinsnstr(int y, int x, const char *str, int n)
+{
+ PDC_LOG(("mvinsnstr() - called: y %d x %d string=\"%s\" n %d \n",
+ y, x, str, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winsnstr(stdscr, str, n);
+}
+
+int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n)
+{
+ PDC_LOG(("mvwinsnstr() - called: y %d x %d string=\"%s\" n %d \n",
+ y, x, str, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winsnstr(win, str, n);
+}
+
+#ifdef PDC_WIDE
+int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n)
+{
+ const wchar_t *p;
+ int len;
+
+ PDC_LOG(("wins_nwstr() - called\n"));
+
+ if (!win || !wstr)
+ return ERR;
+
+ for (len = 0, p = wstr; *p; p++)
+ len++;
+
+ if (n < 0 || n < len)
+ n = len;
+
+ while (n)
+ if (winsch(win, wstr[--n]) == ERR)
+ return ERR;
+
+ return OK;
+}
+
+int ins_wstr(const wchar_t *wstr)
+{
+ PDC_LOG(("ins_wstr() - called\n"));
+
+ return wins_nwstr(stdscr, wstr, -1);
+}
+
+int wins_wstr(WINDOW *win, const wchar_t *wstr)
+{
+ PDC_LOG(("wins_wstr() - called\n"));
+
+ return wins_nwstr(win, wstr, -1);
+}
+
+int mvins_wstr(int y, int x, const wchar_t *wstr)
+{
+ PDC_LOG(("mvins_wstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wins_nwstr(stdscr, wstr, -1);
+}
+
+int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr)
+{
+ PDC_LOG(("mvwinsstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wins_nwstr(win, wstr, -1);
+}
+
+int ins_nwstr(const wchar_t *wstr, int n)
+{
+ PDC_LOG(("ins_nwstr() - called\n"));
+
+ return wins_nwstr(stdscr, wstr, n);
+}
+
+int mvins_nwstr(int y, int x, const wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvinsnstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return wins_nwstr(stdscr, wstr, n);
+}
+
+int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvwinsnstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return wins_nwstr(win, wstr, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/instr.c b/apps/lib/curses/pdcurses/pdcurses/instr.c
new file mode 100644
index 0000000..bbf369c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/instr.c
@@ -0,0 +1,243 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: instr.c,v 1.44 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: instr
+
+ Synopsis:
+ int instr(char *str);
+ int innstr(char *str, int n);
+ int winstr(WINDOW *win, char *str);
+ int winnstr(WINDOW *win, char *str, int n);
+ int mvinstr(int y, int x, char *str);
+ int mvinnstr(int y, int x, char *str, int n);
+ int mvwinstr(WINDOW *win, int y, int x, char *str);
+ int mvwinnstr(WINDOW *win, int y, int x, char *str, int n);
+
+ int inwstr(wchar_t *wstr);
+ int innwstr(wchar_t *wstr, int n);
+ int winwstr(WINDOW *win, wchar_t *wstr);
+ int winnwstr(WINDOW *win, wchar_t *wstr, int n);
+ int mvinwstr(int y, int x, wchar_t *wstr);
+ int mvinnwstr(int y, int x, wchar_t *wstr, int n);
+ int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr);
+ int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n);
+
+ Description:
+ These functions take characters (or wide characters) from the
+ current or specified position in the window, and return them as
+ a string in str (or wstr). Attributes are ignored. The functions
+ with n as the last argument return a string at most n characters
+ long.
+
+ Return Value:
+ Upon successful completion, innstr(), mvinnstr(), mvwinnstr()
+ and winnstr() return the number of characters actually read into
+ the string; instr(), mvinstr(), mvwinstr() and winstr() return
+ OK. Otherwise, all these functions return ERR.
+
+ Portability X/Open BSD SYS V
+ instr Y - 4.0
+ winstr Y - 4.0
+ mvinstr Y - 4.0
+ mvwinstr Y - 4.0
+ innstr Y - 4.0
+ winnstr Y - 4.0
+ mvinnstr Y - 4.0
+ mvwinnstr Y - 4.0
+ inwstr Y
+ winwstr Y
+ mvinwstr Y
+ mvwinwstr Y
+ innwstr Y
+ winnwstr Y
+ mvinnwstr Y
+ mvwinnwstr Y
+
+**man-end****************************************************************/
+
+int winnstr(WINDOW *win, char *str, int n)
+{
+#ifdef PDC_WIDE
+ wchar_t wstr[513];
+
+ if (n < 0 || n > 512)
+ n = 512;
+
+ if (winnwstr(win, wstr, n) == ERR)
+ return ERR;
+
+ return PDC_wcstombs(str, wstr, n);
+#else
+ chtype *src;
+ int i;
+
+ PDC_LOG(("winnstr() - called: n %d \n", n));
+
+ if (!win || !str)
+ return ERR;
+
+ if (n < 0 || (win->_curx + n) > win->_maxx)
+ n = win->_maxx - win->_curx;
+
+ src = win->_y[win->_cury] + win->_curx;
+
+ for (i = 0; i < n; i++)
+ str[i] = src[i] & A_CHARTEXT;
+
+ str[i] = '\0';
+
+ return i;
+#endif
+}
+
+int instr(char *str)
+{
+ PDC_LOG(("instr() - called: string=\"%s\"\n", str));
+
+ return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK;
+}
+
+int winstr(WINDOW *win, char *str)
+{
+ PDC_LOG(("winstr() - called: \n"));
+
+ return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK;
+}
+
+int mvinstr(int y, int x, char *str)
+{
+ PDC_LOG(("mvinstr() - called: y %d x %d \n", y, x));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK;
+}
+
+int mvwinstr(WINDOW *win, int y, int x, char *str)
+{
+ PDC_LOG(("mvwinstr() - called: y %d x %d \n", y, x));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK;
+}
+
+int innstr(char *str, int n)
+{
+ PDC_LOG(("innstr() - called: n %d \n", n));
+
+ return winnstr(stdscr, str, n);
+}
+
+int mvinnstr(int y, int x, char *str, int n)
+{
+ PDC_LOG(("mvinnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winnstr(stdscr, str, n);
+}
+
+int mvwinnstr(WINDOW *win, int y, int x, char *str, int n)
+{
+ PDC_LOG(("mvwinnstr() - called: y %d x %d n %d \n", y, x, n));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winnstr(win, str, n);
+}
+
+#ifdef PDC_WIDE
+int winnwstr(WINDOW *win, wchar_t *wstr, int n)
+{
+ chtype *src;
+ int i;
+
+ PDC_LOG(("winnstr() - called: n %d \n", n));
+
+ if (!win || !wstr)
+ return ERR;
+
+ if (n < 0 || (win->_curx + n) > win->_maxx)
+ n = win->_maxx - win->_curx;
+
+ src = win->_y[win->_cury] + win->_curx;
+
+ for (i = 0; i < n; i++)
+ wstr[i] = src[i] & A_CHARTEXT;
+
+ wstr[i] = L'\0';
+
+ return i;
+}
+
+int inwstr(wchar_t *wstr)
+{
+ PDC_LOG(("inwstr() - called\n"));
+
+ return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK;
+}
+
+int winwstr(WINDOW *win, wchar_t *wstr)
+{
+ PDC_LOG(("winwstr() - called\n"));
+
+ return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK;
+}
+
+int mvinwstr(int y, int x, wchar_t *wstr)
+{
+ PDC_LOG(("mvinwstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK;
+}
+
+int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr)
+{
+ PDC_LOG(("mvwinstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK;
+}
+
+int innwstr(wchar_t *wstr, int n)
+{
+ PDC_LOG(("innwstr() - called\n"));
+
+ return winnwstr(stdscr, wstr, n);
+}
+
+int mvinnwstr(int y, int x, wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvinnstr() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ return winnwstr(stdscr, wstr, n);
+}
+
+int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n)
+{
+ PDC_LOG(("mvwinnwstr() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ return winnwstr(win, wstr, n);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/kernel.c b/apps/lib/curses/pdcurses/pdcurses/kernel.c
new file mode 100644
index 0000000..7e41ccf
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/kernel.c
@@ -0,0 +1,256 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: kernel.c,v 1.78 2008/07/15 17:13:26 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: kernel
+
+ Synopsis:
+ int def_prog_mode(void);
+ int def_shell_mode(void);
+ int reset_prog_mode(void);
+ int reset_shell_mode(void);
+ int resetty(void);
+ int savetty(void);
+ int ripoffline(int line, int (*init)(WINDOW *, int));
+ int curs_set(int visibility);
+ int napms(int ms);
+
+ int draino(int ms);
+ int resetterm(void);
+ int fixterm(void);
+ int saveterm(void);
+
+ Description:
+ def_prog_mode() and def_shell_mode() save the current terminal
+ modes as the "program" (in curses) or "shell" (not in curses)
+ state for use by the reset_prog_mode() and reset_shell_mode()
+ functions. This is done automatically by initscr().
+
+ reset_prog_mode() and reset_shell_mode() restore the terminal to
+ "program" (in curses) or "shell" (not in curses) state. These
+ are done automatically by endwin() and doupdate() after an
+ endwin(), so they would normally not be called before these
+ functions.
+
+ savetty() and resetty() save and restore the state of the
+ terminal modes. savetty() saves the current state in a buffer,
+ and resetty() restores the state to what it was at the last call
+ to savetty().
+
+ curs_set() alters the appearance of the cursor. A visibility of
+ 0 makes it disappear; 1 makes it appear "normal" (usually an
+ underline) and 2 makes it "highly visible" (usually a block).
+
+ ripoffline() reduces the size of stdscr by one line. If the
+ "line" parameter is positive, the line is removed from the top
+ of the screen; if negative, from the bottom. Up to 5 lines can
+ be ripped off stdscr by calling ripoffline() repeatedly. The
+ function argument, init, is called from within initscr() or
+ newterm(), so ripoffline() must be called before either of these
+ functions. The init function receives a pointer to a one-line
+ WINDOW, and the width of the window. Calling ripoffline() with a
+ NULL init function pointer is an error.
+
+ napms() suspends the program for the specified number of
+ milliseconds. draino() is an archaic equivalent.
+
+ resetterm(), fixterm() and saveterm() are archaic equivalents
+ for reset_shell_mode(), reset_prog_mode() and def_prog_mode(),
+ respectively.
+
+ Return Value:
+ All functions return OK on success and ERR on error, except
+ curs_set(), which returns the previous visibility.
+
+ Portability X/Open BSD SYS V
+ def_prog_mode Y Y Y
+ def_shell_mode Y Y Y
+ reset_prog_mode Y Y Y
+ reset_shell_mode Y Y Y
+ resetty Y Y Y
+ savetty Y Y Y
+ ripoffline Y - 3.0
+ curs_set Y - 3.0
+ napms Y Y Y
+ draino -
+ resetterm -
+ fixterm -
+ saveterm -
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+RIPPEDOFFLINE linesripped[5];
+char linesrippedoff = 0;
+
+static struct cttyset
+{
+ bool been_set;
+ SCREEN saved;
+} ctty[3];
+
+enum { PDC_SH_TTY, PDC_PR_TTY, PDC_SAVE_TTY };
+
+static void _save_mode(int i)
+{
+ ctty[i].been_set = TRUE;
+
+ memcpy(&(ctty[i].saved), SP, sizeof(SCREEN));
+
+ PDC_save_screen_mode(i);
+}
+
+static int _restore_mode(int i)
+{
+ if (ctty[i].been_set == TRUE)
+ {
+ memcpy(SP, &(ctty[i].saved), sizeof(SCREEN));
+
+ if (ctty[i].saved.raw_out)
+ raw();
+
+ PDC_restore_screen_mode(i);
+
+ if ((LINES != ctty[i].saved.lines) ||
+ (COLS != ctty[i].saved.cols))
+ resize_term(ctty[i].saved.lines, ctty[i].saved.cols);
+
+ PDC_curs_set(ctty[i].saved.visibility);
+
+ PDC_gotoyx(ctty[i].saved.cursrow, ctty[i].saved.curscol);
+ }
+
+ return ctty[i].been_set ? OK : ERR;
+}
+
+int def_prog_mode(void)
+{
+ PDC_LOG(("def_prog_mode() - called\n"));
+
+ _save_mode(PDC_PR_TTY);
+
+ return OK;
+}
+
+int def_shell_mode(void)
+{
+ PDC_LOG(("def_shell_mode() - called\n"));
+
+ _save_mode(PDC_SH_TTY);
+
+ return OK;
+}
+
+int reset_prog_mode(void)
+{
+ PDC_LOG(("reset_prog_mode() - called\n"));
+
+ _restore_mode(PDC_PR_TTY);
+ PDC_reset_prog_mode();
+
+ return OK;
+}
+
+int reset_shell_mode(void)
+{
+ PDC_LOG(("reset_shell_mode() - called\n"));
+
+ _restore_mode(PDC_SH_TTY);
+ PDC_reset_shell_mode();
+
+ return OK;
+}
+
+int resetty(void)
+{
+ PDC_LOG(("resetty() - called\n"));
+
+ return _restore_mode(PDC_SAVE_TTY);
+}
+
+int savetty(void)
+{
+ PDC_LOG(("savetty() - called\n"));
+
+ _save_mode(PDC_SAVE_TTY);
+
+ return OK;
+}
+
+int curs_set(int visibility)
+{
+ int ret_vis;
+
+ PDC_LOG(("curs_set() - called: visibility=%d\n", visibility));
+
+ if ((visibility < 0) || (visibility > 2))
+ return ERR;
+
+ ret_vis = PDC_curs_set(visibility);
+
+ /* If the cursor is changing from invisible to visible, update
+ its position */
+
+ if (visibility && !ret_vis)
+ PDC_gotoyx(SP->cursrow, SP->curscol);
+
+ return ret_vis;
+}
+
+int napms(int ms)
+{
+ PDC_LOG(("napms() - called: ms=%d\n", ms));
+
+ if (ms)
+ PDC_napms(ms);
+
+ return OK;
+}
+
+int ripoffline(int line, int (*init)(WINDOW *, int))
+{
+ PDC_LOG(("ripoffline() - called: line=%d\n", line));
+
+ if (linesrippedoff < 5 && line && init)
+ {
+ linesripped[(int)linesrippedoff].line = line;
+ linesripped[(int)linesrippedoff++].init = init;
+
+ return OK;
+ }
+
+ return ERR;
+}
+
+int draino(int ms)
+{
+ PDC_LOG(("draino() - called\n"));
+
+ return napms(ms);
+}
+
+int resetterm(void)
+{
+ PDC_LOG(("resetterm() - called\n"));
+
+ return reset_shell_mode();
+}
+
+int fixterm(void)
+{
+ PDC_LOG(("fixterm() - called\n"));
+
+ return reset_prog_mode();
+}
+
+int saveterm(void)
+{
+ PDC_LOG(("saveterm() - called\n"));
+
+ return def_prog_mode();
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/keyname.c b/apps/lib/curses/pdcurses/pdcurses/keyname.c
new file mode 100644
index 0000000..6d02cef
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/keyname.c
@@ -0,0 +1,125 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: keyname.c,v 1.8 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: keyname
+
+ Synopsis:
+ char *keyname(int key);
+
+ char *key_name(wchar_t c);
+
+ bool has_key(int key);
+
+ Description:
+ keyname() returns a string corresponding to the argument key.
+ key may be any key returned by wgetch().
+
+ key_name() is the wide-character version. It takes a wchar_t
+ parameter, but still returns a char *.
+
+ has_key() returns TRUE for recognized keys, FALSE otherwise.
+ This function is an ncurses extension.
+
+ Portability X/Open BSD SYS V
+ keyname Y - 3.0
+ key_name Y
+ has_key - - -
+
+**man-end****************************************************************/
+
+char *keyname(int key)
+{
+ /* Key names must be in exactly the same order as in curses.h */
+
+ static char *key_name[] =
+ {
+ "KEY_BREAK", "KEY_DOWN", "KEY_UP", "KEY_LEFT", "KEY_RIGHT",
+ "KEY_HOME", "KEY_BACKSPACE", "KEY_F0", "KEY_F(1)", "KEY_F(2)",
+ "KEY_F(3)", "KEY_F(4)", "KEY_F(5)", "KEY_F(6)", "KEY_F(7)",
+ "KEY_F(8)", "KEY_F(9)", "KEY_F(10)", "KEY_F(11)", "KEY_F(12)",
+ "KEY_F(13)", "KEY_F(14)", "KEY_F(15)", "KEY_F(16)", "KEY_F(17)",
+ "KEY_F(18)", "KEY_F(19)", "KEY_F(20)", "KEY_F(21)", "KEY_F(22)",
+ "KEY_F(23)", "KEY_F(24)", "KEY_F(25)", "KEY_F(26)", "KEY_F(27)",
+ "KEY_F(28)", "KEY_F(29)", "KEY_F(30)", "KEY_F(31)", "KEY_F(32)",
+ "KEY_F(33)", "KEY_F(34)", "KEY_F(35)", "KEY_F(36)", "KEY_F(37)",
+ "KEY_F(38)", "KEY_F(39)", "KEY_F(40)", "KEY_F(41)", "KEY_F(42)",
+ "KEY_F(43)", "KEY_F(44)", "KEY_F(45)", "KEY_F(46)", "KEY_F(47)",
+ "KEY_F(48)", "KEY_F(49)", "KEY_F(50)", "KEY_F(51)", "KEY_F(52)",
+ "KEY_F(53)", "KEY_F(54)", "KEY_F(55)", "KEY_F(56)", "KEY_F(57)",
+ "KEY_F(58)", "KEY_F(59)", "KEY_F(60)", "KEY_F(61)", "KEY_F(62)",
+ "KEY_F(63)", "KEY_DL", "KEY_IL", "KEY_DC", "KEY_IC", "KEY_EIC",
+ "KEY_CLEAR", "KEY_EOS", "KEY_EOL", "KEY_SF", "KEY_SR",
+ "KEY_NPAGE", "KEY_PPAGE", "KEY_STAB", "KEY_CTAB", "KEY_CATAB",
+ "KEY_ENTER", "KEY_SRESET", "KEY_RESET", "KEY_PRINT", "KEY_LL",
+ "KEY_ABORT", "KEY_SHELP", "KEY_LHELP", "KEY_BTAB", "KEY_BEG",
+ "KEY_CANCEL", "KEY_CLOSE", "KEY_COMMAND", "KEY_COPY",
+ "KEY_CREATE", "KEY_END", "KEY_EXIT", "KEY_FIND", "KEY_HELP",
+ "KEY_MARK", "KEY_MESSAGE", "KEY_MOVE", "KEY_NEXT", "KEY_OPEN",
+ "KEY_OPTIONS", "KEY_PREVIOUS", "KEY_REDO", "KEY_REFERENCE",
+ "KEY_REFRESH", "KEY_REPLACE", "KEY_RESTART", "KEY_RESUME",
+ "KEY_SAVE", "KEY_SBEG", "KEY_SCANCEL", "KEY_SCOMMAND",
+ "KEY_SCOPY", "KEY_SCREATE", "KEY_SDC", "KEY_SDL", "KEY_SELECT",
+ "KEY_SEND", "KEY_SEOL", "KEY_SEXIT", "KEY_SFIND", "KEY_SHOME",
+ "KEY_SIC", "UNKNOWN KEY", "KEY_SLEFT", "KEY_SMESSAGE",
+ "KEY_SMOVE", "KEY_SNEXT", "KEY_SOPTIONS", "KEY_SPREVIOUS",
+ "KEY_SPRINT", "KEY_SREDO", "KEY_SREPLACE", "KEY_SRIGHT",
+ "KEY_SRSUME", "KEY_SSAVE", "KEY_SSUSPEND", "KEY_SUNDO",
+ "KEY_SUSPEND", "KEY_UNDO", "ALT_0", "ALT_1", "ALT_2", "ALT_3",
+ "ALT_4", "ALT_5", "ALT_6", "ALT_7", "ALT_8", "ALT_9", "ALT_A",
+ "ALT_B", "ALT_C", "ALT_D", "ALT_E", "ALT_F", "ALT_G", "ALT_H",
+ "ALT_I", "ALT_J", "ALT_K", "ALT_L", "ALT_M", "ALT_N", "ALT_O",
+ "ALT_P", "ALT_Q", "ALT_R", "ALT_S", "ALT_T", "ALT_U", "ALT_V",
+ "ALT_W", "ALT_X", "ALT_Y", "ALT_Z", "CTL_LEFT", "CTL_RIGHT",
+ "CTL_PGUP", "CTL_PGDN", "CTL_HOME", "CTL_END", "KEY_A1",
+ "KEY_A2", "KEY_A3", "KEY_B1", "KEY_B2", "KEY_B3", "KEY_C1",
+ "KEY_C2", "KEY_C3", "PADSLASH", "PADENTER", "CTL_PADENTER",
+ "ALT_PADENTER", "PADSTOP", "PADSTAR", "PADMINUS", "PADPLUS",
+ "CTL_PADSTOP", "CTL_PADCENTER", "CTL_PADPLUS", "CTL_PADMINUS",
+ "CTL_PADSLASH", "CTL_PADSTAR", "ALT_PADPLUS", "ALT_PADMINUS",
+ "ALT_PADSLASH", "ALT_PADSTAR", "ALT_PADSTOP", "CTL_INS",
+ "ALT_DEL", "ALT_INS", "CTL_UP", "CTL_DOWN", "CTL_TAB",
+ "ALT_TAB", "ALT_MINUS", "ALT_EQUAL", "ALT_HOME", "ALT_PGUP",
+ "ALT_PGDN", "ALT_END", "ALT_UP", "ALT_DOWN", "ALT_RIGHT",
+ "ALT_LEFT", "ALT_ENTER", "ALT_ESC", "ALT_BQUOTE",
+ "ALT_LBRACKET", "ALT_RBRACKET", "ALT_SEMICOLON", "ALT_FQUOTE",
+ "ALT_COMMA", "ALT_STOP", "ALT_FSLASH", "ALT_BKSP", "CTL_BKSP",
+ "PAD0", "CTL_PAD0", "CTL_PAD1", "CTL_PAD2", "CTL_PAD3",
+ "CTL_PAD4", "CTL_PAD5", "CTL_PAD6", "CTL_PAD7","CTL_PAD8",
+ "CTL_PAD9", "ALT_PAD0", "ALT_PAD1", "ALT_PAD2", "ALT_PAD3",
+ "ALT_PAD4", "ALT_PAD5", "ALT_PAD6", "ALT_PAD7", "ALT_PAD8",
+ "ALT_PAD9", "CTL_DEL", "ALT_BSLASH", "CTL_ENTER",
+ "SHF_PADENTER", "SHF_PADSLASH", "SHF_PADSTAR", "SHF_PADPLUS",
+ "SHF_PADMINUS", "SHF_UP", "SHF_DOWN", "SHF_IC", "SHF_DC",
+ "KEY_MOUSE", "KEY_SHIFT_L", "KEY_SHIFT_R", "KEY_CONTROL_L",
+ "KEY_CONTROL_R", "KEY_ALT_L", "KEY_ALT_R", "KEY_RESIZE",
+ "KEY_SUP", "KEY_SDOWN"
+ };
+
+ PDC_LOG(("keyname() - called: key %d\n", key));
+
+ if ((key >= 0) && (key < 0x80))
+ return unctrl((chtype)key);
+
+ return has_key(key) ? key_name[key - KEY_MIN] : "UNKNOWN KEY";
+}
+
+bool has_key(int key)
+{
+ PDC_LOG(("has_key() - called: key %d\n", key));
+
+ return (key >= KEY_MIN && key <= KEY_MAX);
+}
+
+#ifdef PDC_WIDE
+char *key_name(wchar_t c)
+{
+ PDC_LOG(("key_name() - called\n"));
+
+ return keyname((int)c);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/mouse.c b/apps/lib/curses/pdcurses/pdcurses/mouse.c
new file mode 100644
index 0000000..1f476dd
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/mouse.c
@@ -0,0 +1,429 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: mouse.c,v 1.45 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: mouse
+
+ Synopsis:
+ int mouse_set(unsigned long mbe);
+ int mouse_on(unsigned long mbe);
+ int mouse_off(unsigned long mbe);
+ int request_mouse_pos(void);
+ int map_button(unsigned long button);
+ void wmouse_position(WINDOW *win, int *y, int *x);
+ unsigned long getmouse(void);
+ unsigned long getbmap(void);
+
+ int mouseinterval(int wait);
+ bool wenclose(const WINDOW *win, int y, int x);
+ bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen);
+ bool mouse_trafo(int *y, int *x, bool to_screen);
+ mmask_t mousemask(mmask_t mask, mmask_t *oldmask);
+ int nc_getmouse(MEVENT *event);
+ int ungetmouse(MEVENT *event);
+
+ Description:
+ As of PDCurses 3.0, there are two separate mouse interfaces: the
+ classic interface, which is based on the undocumented Sys V
+ mouse functions; and an ncurses-compatible interface. Both are
+ active at all times, and you can mix and match functions from
+ each, though it's not recommended. The ncurses interface is
+ essentially an emulation layer built on top of the classic
+ interface; it's here to allow easier porting of ncurses apps.
+
+ The classic interface: mouse_set(), mouse_on(), mouse_off(),
+ request_mouse_pos(), map_button(), wmouse_position(),
+ getmouse(), and getbmap(). An application using this interface
+ would start by calling mouse_set() or mouse_on() with a non-zero
+ value, often ALL_MOUSE_EVENTS. Then it would check for a
+ KEY_MOUSE return from getch(). If found, it would call
+ request_mouse_pos() to get the current mouse status.
+
+ mouse_set(), mouse_on() and mouse_off() are analagous to
+ attrset(), attron() and attroff(). These functions set the
+ mouse button events to trap. The button masks used in these
+ functions are defined in curses.h and can be or'ed together.
+ They are the group of masks starting with BUTTON1_RELEASED.
+
+ request_mouse_pos() requests curses to fill in the Mouse_status
+ structure with the current state of the mouse.
+
+ map_button() enables the specified mouse action to activate the
+ Soft Label Keys if the action occurs over the area of the screen
+ where the Soft Label Keys are displayed. The mouse actions are
+ defined in curses.h in the group that starts with BUTTON_RELEASED.
+
+ wmouse_position() determines if the current mouse position is
+ within the window passed as an argument. If the mouse is
+ outside the current window, -1 is returned in the y and x
+ arguments; otherwise the y and x coordinates of the mouse
+ (relative to the top left corner of the window) are returned in
+ y and x.
+
+ getmouse() returns the current status of the trapped mouse
+ buttons as set by mouse_set() or mouse_on().
+
+ getbmap() returns the current status of the button action used
+ to map a mouse action to the Soft Label Keys as set by the
+ map_button() function.
+
+ The ncurses interface: mouseinterval(), wenclose(),
+ wmouse_trafo(), mouse_trafo(), mousemask(), nc_getmouse(), and
+ ungetmouse(). A typical application using this interface would
+ start by calling mousemask() with a non-zero value, often
+ ALL_MOUSE_EVENTS. Then it would check for a KEY_MOUSE return
+ from getch(). If found, it would call nc_getmouse() to get the
+ current mouse status.
+
+ mouseinterval() sets the timeout for a mouse click. On all
+ current platforms, PDCurses receives mouse button press and
+ release events, but must synthesize click events. It does this
+ by checking whether a release event is queued up after a press
+ event. If it gets a press event, and there are no more events
+ waiting, it will wait for the timeout interval, then check again
+ for a release. A press followed by a release is reported as
+ BUTTON_CLICKED; otherwise it's passed through as BUTTON_PRESSED.
+ The default timeout is 150ms; valid values are 0 (no clicks
+ reported) through 1000ms. In x11, the timeout can also be set
+ via the clickPeriod resource. The return value from
+ mouseinterval() is the old timeout. To check the old value
+ without setting a new one, call it with a parameter of -1. Note
+ that although there's no classic equivalent for this function
+ (apart from the clickPeriod resource), the value set applies in
+ both interfaces.
+
+ wenclose() reports whether the given screen-relative y, x
+ coordinates fall within the given window.
+
+ wmouse_trafo() converts between screen-relative and window-
+ relative coordinates. A to_screen parameter of TRUE means to
+ convert from window to screen; otherwise the reverse. The
+ function returns FALSE if the coordinates aren't within the
+ window, or if any of the parameters are NULL. The coordinates
+ have been converted when the function returns TRUE.
+
+ mouse_trafo() is the stdscr version of wmouse_trafo().
+
+ mousemask() is nearly equivalent to mouse_set(), but instead of
+ OK/ERR, it returns the value of the mask after setting it. (This
+ isn't necessarily the same value passed in, since the mask could
+ be altered on some platforms.) And if the second parameter is a
+ non-null pointer, mousemask() stores the previous mask value
+ there. Also, since the ncurses interface doesn't work with
+ PDCurses' BUTTON_MOVED events, mousemask() filters them out.
+
+ nc_getmouse() returns the current mouse status in an MEVENT
+ struct. This is equivalent to ncurses' getmouse(), renamed to
+ avoid conflict with PDCurses' getmouse(). But if you define
+ NCURSES_MOUSE_VERSION (preferably as 2) before including
+ curses.h, it defines getmouse() to nc_getmouse(), along with a
+ few other redefintions needed for compatibility with ncurses
+ code. nc_getmouse() calls request_mouse_pos(), which (not
+ getmouse()) is the classic equivalent.
+
+ ungetmouse() is the mouse equivalent of ungetch(). However,
+ PDCurses doesn't maintain a queue of mouse events; only one can
+ be pushed back, and it can overwrite or be overwritten by real
+ mouse events.
+
+ Portability X/Open BSD SYS V
+ mouse_set - - 4.0
+ mouse_on - - 4.0
+ mouse_off - - 4.0
+ request_mouse_pos - - 4.0
+ map_button - - 4.0
+ wmouse_position - - 4.0
+ getmouse - - 4.0
+ getbmap - - 4.0
+ mouseinterval - - -
+ wenclose - - -
+ wmouse_trafo - - -
+ mouse_trafo - - -
+ mousemask - - -
+ nc_getmouse - - -
+ ungetmouse - - -
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+static bool ungot = FALSE;
+
+int mouse_set(unsigned long mbe)
+{
+ PDC_LOG(("mouse_set() - called: event %x\n", mbe));
+
+ SP->_trap_mbe = mbe;
+ return PDC_mouse_set();
+}
+
+int mouse_on(unsigned long mbe)
+{
+ PDC_LOG(("mouse_on() - called: event %x\n", mbe));
+
+ SP->_trap_mbe |= mbe;
+ return PDC_mouse_set();
+}
+
+int mouse_off(unsigned long mbe)
+{
+ PDC_LOG(("mouse_off() - called: event %x\n", mbe));
+
+ SP->_trap_mbe &= ~mbe;
+ return PDC_mouse_set();
+}
+
+int map_button(unsigned long button)
+{
+ PDC_LOG(("map_button() - called: button %x\n", button));
+
+/****************** this does nothing at the moment ***************/
+ SP->_map_mbe_to_key = button;
+
+ return OK;
+}
+
+int request_mouse_pos(void)
+{
+ PDC_LOG(("request_mouse_pos() - called\n"));
+
+ Mouse_status = pdc_mouse_status;
+
+ return OK;
+}
+
+void wmouse_position(WINDOW *win, int *y, int *x)
+{
+ PDC_LOG(("wmouse_position() - called\n"));
+
+ if (win && wenclose(win, MOUSE_Y_POS, MOUSE_X_POS))
+ {
+ if (y)
+ *y = MOUSE_Y_POS - win->_begy;
+ if (x)
+ *x = MOUSE_X_POS - win->_begx;
+ }
+ else
+ {
+ if (y)
+ *y = -1;
+ if (x)
+ *x = -1;
+ }
+}
+
+unsigned long getmouse(void)
+{
+ PDC_LOG(("getmouse() - called\n"));
+
+ return SP->_trap_mbe;
+}
+
+unsigned long getbmap(void)
+{
+ PDC_LOG(("getbmap() - called\n"));
+
+ return SP->_map_mbe_to_key;
+}
+
+/* ncurses mouse interface */
+
+int mouseinterval(int wait)
+{
+ int old_wait;
+
+ PDC_LOG(("mouseinterval() - called: %d\n", wait));
+
+ old_wait = SP->mouse_wait;
+
+ if (wait >= 0 && wait <= 1000)
+ SP->mouse_wait = wait;
+
+ return old_wait;
+}
+
+bool wenclose(const WINDOW *win, int y, int x)
+{
+ PDC_LOG(("wenclose() - called: %p %d %d\n", win, y, x));
+
+ return (win && y >= win->_begy && y < win->_begy + win->_maxy
+ && x >= win->_begx && x < win->_begx + win->_maxx);
+}
+
+bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen)
+{
+ int newy, newx;
+
+ PDC_LOG(("wmouse_trafo() - called\n"));
+
+ if (!win || !y || !x)
+ return FALSE;
+
+ newy = *y;
+ newx = *x;
+
+ if (to_screen)
+ {
+ newy += win->_begy;
+ newx += win->_begx;
+
+ if (!wenclose(win, newy, newx))
+ return FALSE;
+ }
+ else
+ {
+ if (wenclose(win, newy, newx))
+ {
+ newy -= win->_begy;
+ newx -= win->_begx;
+ }
+ else
+ return FALSE;
+ }
+
+ *y = newy;
+ *x = newx;
+
+ return TRUE;
+}
+
+bool mouse_trafo(int *y, int *x, bool to_screen)
+{
+ PDC_LOG(("mouse_trafo() - called\n"));
+
+ return wmouse_trafo(stdscr, y, x, to_screen);
+}
+
+mmask_t mousemask(mmask_t mask, mmask_t *oldmask)
+{
+ PDC_LOG(("mousemask() - called\n"));
+
+ if (oldmask)
+ *oldmask = SP->_trap_mbe;
+
+ /* The ncurses interface doesn't work with our move events, so
+ filter them here */
+
+ mask &= ~(BUTTON1_MOVED | BUTTON2_MOVED | BUTTON3_MOVED);
+
+ mouse_set(mask);
+
+ return SP->_trap_mbe;
+}
+
+int nc_getmouse(MEVENT *event)
+{
+ int i;
+ mmask_t bstate = 0;
+
+ PDC_LOG(("nc_getmouse() - called\n"));
+
+ if (!event)
+ return ERR;
+
+ ungot = FALSE;
+
+ request_mouse_pos();
+
+ event->id = 0;
+
+ event->x = Mouse_status.x;
+ event->y = Mouse_status.y;
+ event->z = 0;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (Mouse_status.changes & (1 << i))
+ {
+ int shf = i * 5;
+ short button = Mouse_status.button[i] & BUTTON_ACTION_MASK;
+
+ if (button == BUTTON_RELEASED)
+ bstate |= (BUTTON1_RELEASED << shf);
+ else if (button == BUTTON_PRESSED)
+ bstate |= (BUTTON1_PRESSED << shf);
+ else if (button == BUTTON_CLICKED)
+ bstate |= (BUTTON1_CLICKED << shf);
+ else if (button == BUTTON_DOUBLE_CLICKED)
+ bstate |= (BUTTON1_DOUBLE_CLICKED << shf);
+
+ button = Mouse_status.button[i] & BUTTON_MODIFIER_MASK;
+
+ if (button & PDC_BUTTON_SHIFT)
+ bstate |= BUTTON_MODIFIER_SHIFT;
+ if (button & PDC_BUTTON_CONTROL)
+ bstate |= BUTTON_MODIFIER_CONTROL;
+ if (button & PDC_BUTTON_ALT)
+ bstate |= BUTTON_MODIFIER_ALT;
+ }
+ }
+
+ if (MOUSE_WHEEL_UP)
+ bstate |= BUTTON4_PRESSED;
+ else if (MOUSE_WHEEL_DOWN)
+ bstate |= BUTTON5_PRESSED;
+
+ /* extra filter pass -- mainly for button modifiers */
+
+ event->bstate = bstate & SP->_trap_mbe;
+
+ return OK;
+}
+
+int ungetmouse(MEVENT *event)
+{
+ int i;
+ unsigned long bstate;
+
+ PDC_LOG(("ungetmouse() - called\n"));
+
+ if (!event || ungot)
+ return ERR;
+
+ ungot = TRUE;
+
+ pdc_mouse_status.x = event->x;
+ pdc_mouse_status.y = event->y;
+
+ pdc_mouse_status.changes = 0;
+ bstate = event->bstate;
+
+ for (i = 0; i < 3; i++)
+ {
+ int shf = i * 5;
+ short button = 0;
+
+ if (bstate & ((BUTTON1_RELEASED | BUTTON1_PRESSED |
+ BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED) << shf))
+ {
+ pdc_mouse_status.changes |= 1 << i;
+
+ if (bstate & (BUTTON1_PRESSED << shf))
+ button = BUTTON_PRESSED;
+ if (bstate & (BUTTON1_CLICKED << shf))
+ button = BUTTON_CLICKED;
+ if (bstate & (BUTTON1_DOUBLE_CLICKED << shf))
+ button = BUTTON_DOUBLE_CLICKED;
+
+ if (bstate & BUTTON_MODIFIER_SHIFT)
+ button |= PDC_BUTTON_SHIFT;
+ if (bstate & BUTTON_MODIFIER_CONTROL)
+ button |= PDC_BUTTON_CONTROL;
+ if (bstate & BUTTON_MODIFIER_ALT)
+ button |= PDC_BUTTON_ALT;
+ }
+
+ pdc_mouse_status.button[i] = button;
+ }
+
+ if (bstate & BUTTON4_PRESSED)
+ pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_UP;
+ else if (bstate & BUTTON5_PRESSED)
+ pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN;
+
+ return ungetch(KEY_MOUSE);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/move.c b/apps/lib/curses/pdcurses/pdcurses/move.c
new file mode 100644
index 0000000..30e5908
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/move.c
@@ -0,0 +1,54 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: move.c,v 1.28 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: move
+
+ Synopsis:
+ int move(int y, int x);
+ int wmove(WINDOW *win, int y, int x);
+
+ Description:
+ The cursor associated with the window is moved to the given
+ location. This does not move the physical cursor of the
+ terminal until refresh() is called. The position specified is
+ relative to the upper left corner of the window, which is (0,0).
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ move Y Y Y
+ wmove Y Y Y
+
+**man-end****************************************************************/
+
+int move(int y, int x)
+{
+ PDC_LOG(("move() - called: y=%d x=%d\n", y, x));
+
+ if (!stdscr || x < 0 || y < 0 || x >= stdscr->_maxx || y >= stdscr->_maxy)
+ return ERR;
+
+ stdscr->_curx = x;
+ stdscr->_cury = y;
+
+ return OK;
+}
+
+int wmove(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("wmove() - called: y=%d x=%d\n", y, x));
+
+ if (!win || x < 0 || y < 0 || x >= win->_maxx || y >= win->_maxy)
+ return ERR;
+
+ win->_curx = x;
+ win->_cury = y;
+
+ return OK;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/outopts.c b/apps/lib/curses/pdcurses/pdcurses/outopts.c
new file mode 100644
index 0000000..0a8fd2d
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/outopts.c
@@ -0,0 +1,156 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: outopts.c,v 1.39 2008/07/14 12:22:13 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: outopts
+
+ Synopsis:
+ int clearok(WINDOW *win, bool bf);
+ int idlok(WINDOW *win, bool bf);
+ void idcok(WINDOW *win, bool bf);
+ void immedok(WINDOW *win, bool bf);
+ int leaveok(WINDOW *win, bool bf);
+ int setscrreg(int top, int bot);
+ int wsetscrreg(WINDOW *win, int top, int bot);
+ int scrollok(WINDOW *win, bool bf);
+
+ int raw_output(bool bf);
+
+ Description:
+ With clearok(), if bf is TRUE, the next call to wrefresh() with
+ this window will clear the screen completely and redraw the
+ entire screen.
+
+ immedok(), called with a second argument of TRUE, causes an
+ automatic wrefresh() every time a change is made to the
+ specified window.
+
+ Normally, the hardware cursor is left at the location of the
+ window being refreshed. leaveok() allows the cursor to be
+ left wherever the update happens to leave it. It's useful
+ for applications where the cursor is not used, since it reduces
+ the need for cursor motions. If possible, the cursor is made
+ invisible when this option is enabled.
+
+ wsetscrreg() sets a scrolling region in a window; "top" and
+ "bot" are the line numbers for the top and bottom margins. If
+ this option and scrollok() are enabled, any attempt to move off
+ the bottom margin will cause all lines in the scrolling region
+ to scroll up one line. setscrreg() is the stdscr version.
+
+ idlok() and idcok() do nothing in PDCurses, but are provided for
+ compatibility with other curses implementations.
+
+ raw_output() enables the output of raw characters using the
+ standard *add* and *ins* curses functions (that is, it disables
+ translation of control characters).
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ clearok Y Y Y
+ idlok Y Y Y
+ idcok Y - 4.0
+ immedok Y - 4.0
+ leaveok Y Y Y
+ setscrreg Y Y Y
+ wsetscrreg Y Y Y
+ scrollok Y Y Y
+ raw_output - - -
+
+**man-end****************************************************************/
+
+int clearok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("clearok() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_clear = bf;
+
+ return OK;
+}
+
+int idlok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("idlok() - called\n"));
+
+ return OK;
+}
+
+void idcok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("idcok() - called\n"));
+}
+
+void immedok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("immedok() - called\n"));
+
+ if (win)
+ win->_immed = bf;
+}
+
+int leaveok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("leaveok() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_leaveit = bf;
+
+ curs_set(!bf);
+
+ return OK;
+}
+
+int setscrreg(int top, int bottom)
+{
+ PDC_LOG(("setscrreg() - called: top %d bottom %d\n", top, bottom));
+
+ return wsetscrreg(stdscr, top, bottom);
+}
+
+int wsetscrreg(WINDOW *win, int top, int bottom)
+{
+ PDC_LOG(("wsetscrreg() - called: top %d bottom %d\n", top, bottom));
+
+ if (win && 0 <= top && top <= win->_cury &&
+ win->_cury <= bottom && bottom < win->_maxy)
+ {
+ win->_tmarg = top;
+ win->_bmarg = bottom;
+
+ return OK;
+ }
+ else
+ return ERR;
+}
+
+int scrollok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("scrollok() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_scroll = bf;
+
+ return OK;
+}
+
+int raw_output(bool bf)
+{
+ PDC_LOG(("raw_output() - called\n"));
+
+ SP->raw_out = bf;
+
+ return OK;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/overlay.c b/apps/lib/curses/pdcurses/pdcurses/overlay.c
new file mode 100644
index 0000000..f9bba50
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/overlay.c
@@ -0,0 +1,256 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: overlay.c,v 1.36 2008/07/14 12:35:23 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: overlay
+
+ Synopsis:
+ int overlay(const WINDOW *src_w, WINDOW *dst_w)
+ int overwrite(const WINDOW *src_w, WINDOW *dst_w)
+ int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr,
+ int src_tc, int dst_tr, int dst_tc, int dst_br,
+ int dst_bc, bool overlay)
+
+ Description:
+ overlay() and overwrite() copy all the text from src_w into
+ dst_w. The windows need not be the same size. Those characters
+ in the source window that intersect with the destination window
+ are copied, so that the characters appear in the same physical
+ position on the screen. The difference between the two functions
+ is that overlay() is non-destructive (blanks are not copied)
+ while overwrite() is destructive (blanks are copied).
+
+ copywin() is similar, but doesn't require that the two windows
+ overlap. The arguments src_tc and src_tr specify the top left
+ corner of the region to be copied. dst_tc, dst_tr, dst_br, and
+ dst_bc specify the region within the destination window to copy
+ to. The argument "overlay", if TRUE, indicates that the copy is
+ done non-destructively (as in overlay()); blanks in the source
+ window are not copied to the destination window. When overlay is
+ FALSE, blanks are copied.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ overlay Y Y Y
+ overwrite Y Y Y
+ copywin Y - 3.0
+
+**man-end****************************************************************/
+
+/* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the
+ corrected overlay()/overwrite() behavior. */
+
+static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr,
+ int src_tc, int src_br, int src_bc, int dst_tr,
+ int dst_tc, bool overlay)
+{
+ int col, line, y1, fc, *minchng, *maxchng;
+ chtype *w1ptr, *w2ptr;
+
+ int lc = 0;
+ int xdiff = src_bc - src_tc;
+ int ydiff = src_br - src_tr;
+
+ if (!src_w || !dst_w)
+ return ERR;
+
+ minchng = dst_w->_firstch;
+ maxchng = dst_w->_lastch;
+
+ for (y1 = 0; y1 < dst_tr; y1++)
+ {
+ minchng++;
+ maxchng++;
+ }
+
+ for (line = 0; line < ydiff; line++)
+ {
+ w1ptr = src_w->_y[line + src_tr] + src_tc;
+ w2ptr = dst_w->_y[line + dst_tr] + dst_tc;
+
+ fc = _NO_CHANGE;
+
+ for (col = 0; col < xdiff; col++)
+ {
+ if ((*w1ptr) != (*w2ptr) &&
+ !((*w1ptr & A_CHARTEXT) == ' ' && overlay))
+ {
+ *w2ptr = *w1ptr;
+
+ if (fc == _NO_CHANGE)
+ fc = col + dst_tc;
+
+ lc = col + dst_tc;
+ }
+
+ w1ptr++;
+ w2ptr++;
+ }
+
+ if (*minchng == _NO_CHANGE)
+ {
+ *minchng = fc;
+ *maxchng = lc;
+ }
+ else if (fc != _NO_CHANGE)
+ {
+ if (fc < *minchng)
+ *minchng = fc;
+ if (lc > *maxchng)
+ *maxchng = lc;
+ }
+
+ minchng++;
+ maxchng++;
+ }
+
+ return OK;
+}
+
+int overlay(const WINDOW *src_w, WINDOW *dst_w)
+{
+ int first_line, first_col, last_line, last_col;
+ int src_start_x, src_start_y, dst_start_x, dst_start_y;
+ int xdiff, ydiff;
+
+ PDC_LOG(("overlay() - called\n"));
+
+ if (!src_w || !dst_w)
+ return ERR;
+
+ first_col = max(dst_w->_begx, src_w->_begx);
+ first_line = max(dst_w->_begy, src_w->_begy);
+
+ last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);
+ last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);
+
+ /* determine the overlapping region of the two windows in real
+ coordinates */
+
+ /* if no overlapping region, do nothing */
+
+ if ((last_col < first_col) || (last_line < first_line))
+ return OK;
+
+ /* size of overlapping region */
+
+ xdiff = last_col - first_col;
+ ydiff = last_line - first_line;
+
+ if (src_w->_begx <= dst_w->_begx)
+ {
+ src_start_x = dst_w->_begx - src_w->_begx;
+ dst_start_x = 0;
+ }
+ else
+ {
+ dst_start_x = src_w->_begx - dst_w->_begx;
+ src_start_x = 0;
+ }
+
+ if (src_w->_begy <= dst_w->_begy)
+ {
+ src_start_y = dst_w->_begy - src_w->_begy;
+ dst_start_y = 0;
+ }
+ else
+ {
+ dst_start_y = src_w->_begy - dst_w->_begy;
+ src_start_y = 0;
+ }
+
+ return _copy_win(src_w, dst_w, src_start_y, src_start_x,
+ src_start_y + ydiff, src_start_x + xdiff,
+ dst_start_y, dst_start_x, TRUE);
+}
+
+int overwrite(const WINDOW *src_w, WINDOW *dst_w)
+{
+ int first_line, first_col, last_line, last_col;
+ int src_start_x, src_start_y, dst_start_x, dst_start_y;
+ int xdiff, ydiff;
+
+ PDC_LOG(("overwrite() - called\n"));
+
+ if (!src_w || !dst_w)
+ return ERR;
+
+ first_col = max(dst_w->_begx, src_w->_begx);
+ first_line = max(dst_w->_begy, src_w->_begy);
+
+ last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx);
+ last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy);
+
+ /* determine the overlapping region of the two windows in real
+ coordinates */
+
+ /* if no overlapping region, do nothing */
+
+ if ((last_col < first_col) || (last_line < first_line))
+ return OK;
+
+ /* size of overlapping region */
+
+ xdiff = last_col - first_col;
+ ydiff = last_line - first_line;
+
+ if (src_w->_begx <= dst_w->_begx)
+ {
+ src_start_x = dst_w->_begx - src_w->_begx;
+ dst_start_x = 0;
+ }
+ else
+ {
+ dst_start_x = src_w->_begx - dst_w->_begx;
+ src_start_x = 0;
+ }
+
+ if (src_w->_begy <= dst_w->_begy)
+ {
+ src_start_y = dst_w->_begy - src_w->_begy;
+ dst_start_y = 0;
+ }
+ else
+ {
+ dst_start_y = src_w->_begy - dst_w->_begy;
+ src_start_y = 0;
+ }
+
+ return _copy_win(src_w, dst_w, src_start_y, src_start_x,
+ src_start_y + ydiff, src_start_x + xdiff,
+ dst_start_y, dst_start_x, FALSE);
+}
+
+int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc,
+ int dst_tr, int dst_tc, int dst_br, int dst_bc, int overlay)
+{
+ int src_end_x, src_end_y;
+ int src_rows, src_cols, dst_rows, dst_cols;
+ int min_rows, min_cols;
+
+ PDC_LOG(("copywin() - called\n"));
+
+ if (!src_w || !dst_w || dst_w == curscr || dst_br > dst_w->_maxy
+ || dst_bc > dst_w->_maxx || dst_tr < 0 || dst_tc < 0)
+ return ERR;
+
+ src_rows = src_w->_maxy - src_tr;
+ src_cols = src_w->_maxx - src_tc;
+ dst_rows = dst_br - dst_tr + 1;
+ dst_cols = dst_bc - dst_tc + 1;
+
+ min_rows = min(src_rows, dst_rows);
+ min_cols = min(src_cols, dst_cols);
+
+ src_end_y = src_tr + min_rows;
+ src_end_x = src_tc + min_cols;
+
+ return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x,
+ dst_tr, dst_tc, overlay);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/pad.c b/apps/lib/curses/pdcurses/pdcurses/pad.c
new file mode 100644
index 0000000..ccc5db2
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/pad.c
@@ -0,0 +1,259 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: pad.c,v 1.50 2008/07/14 12:22:13 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: pad
+
+ Synopsis:
+ WINDOW *newpad(int nlines, int ncols);
+ WINDOW *subpad(WINDOW *orig, int nlines, int ncols,
+ int begy, int begx);
+ int prefresh(WINDOW *win, int py, int px, int sy1, int sx1,
+ int sy2, int sx2);
+ int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1,
+ int sy2, int sx2);
+ int pechochar(WINDOW *pad, chtype ch);
+ int pecho_wchar(WINDOW *pad, const cchar_t *wch);
+
+ Description:
+ A pad is a special kind of window, which is not restricted by
+ the screen size, and is not necessarily associated with a
+ particular part of the screen. You can use a pad when you need
+ a large window, and only a part of the window will be on the
+ screen at one time. Pads are not refreshed automatically (e.g.,
+ from scrolling or echoing of input). You can't call wrefresh()
+ with a pad as an argument; use prefresh() or pnoutrefresh()
+ instead. Note that these routines require additional parameters
+ to specify the part of the pad to be displayed, and the location
+ to use on the screen.
+
+ newpad() creates a new pad data structure.
+
+ subpad() creates a new sub-pad within a pad, at position (begy,
+ begx), with dimensions of nlines lines and ncols columns. This
+ position is relative to the pad, and not to the screen as with
+ subwin. Changes to either the parent pad or sub-pad will affect
+ both. When using sub-pads, you may need to call touchwin()
+ before calling prefresh().
+
+ pnoutrefresh() copies the specified pad to the virtual screen.
+
+ prefresh() calls pnoutrefresh(), followed by doupdate().
+
+ These routines are analogous to wnoutrefresh() and wrefresh().
+ (py, px) specifies the upper left corner of the part of the pad
+ to be displayed; (sy1, sx1) and (sy2, sx2) describe the screen
+ rectangle that will contain the selected part of the pad.
+
+ pechochar() is functionally equivalent to addch() followed by
+ a call to prefresh(), with the last-used coordinates and
+ dimensions. pecho_wchar() is the wide-character version.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ newpad Y - Y
+ subpad Y - Y
+ prefresh Y - Y
+ pnoutrefresh Y - Y
+ pechochar Y - 3.0
+ pecho_wchar Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+/* save values for pechochar() */
+
+static int save_pminrow, save_pmincol;
+static int save_sminrow, save_smincol, save_smaxrow, save_smaxcol;
+
+WINDOW *newpad(int nlines, int ncols)
+{
+ WINDOW *win;
+
+ PDC_LOG(("newpad() - called: lines=%d cols=%d\n", nlines, ncols));
+
+ if ( !(win = PDC_makenew(nlines, ncols, -1, -1))
+ || !(win = PDC_makelines(win)) )
+ return (WINDOW *)NULL;
+
+ werase(win);
+
+ win->_flags = _PAD;
+
+ /* save default values in case pechochar() is the first call to
+ prefresh(). */
+
+ save_pminrow = 0;
+ save_pmincol = 0;
+ save_sminrow = 0;
+ save_smincol = 0;
+ save_smaxrow = min(LINES, nlines) - 1;
+ save_smaxcol = min(COLS, ncols) - 1;
+
+ return win;
+}
+
+WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx)
+{
+ WINDOW *win;
+ int i;
+ int j = begy;
+ int k = begx;
+
+ PDC_LOG(("subpad() - called: lines=%d cols=%d begy=%d begx=%d\n",
+ nlines, ncols, begy, begx));
+
+ if (!orig || !(orig->_flags & _PAD))
+ return (WINDOW *)NULL;
+
+ /* make sure window fits inside the original one */
+
+ if ((begy < orig->_begy) || (begx < orig->_begx) ||
+ (begy + nlines) > (orig->_begy + orig->_maxy) ||
+ (begx + ncols) > (orig->_begx + orig->_maxx))
+ return (WINDOW *)NULL;
+
+ if (!nlines)
+ nlines = orig->_maxy - 1 - j;
+
+ if (!ncols)
+ ncols = orig->_maxx - 1 - k;
+
+ if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
+ return (WINDOW *)NULL;
+
+ /* initialize window variables */
+
+ win->_attrs = orig->_attrs;
+ win->_leaveit = orig->_leaveit;
+ win->_scroll = orig->_scroll;
+ win->_nodelay = orig->_nodelay;
+ win->_use_keypad = orig->_use_keypad;
+ win->_parent = orig;
+
+ for (i = 0; i < nlines; i++)
+ win->_y[i] = (orig->_y[j++]) + k;
+
+ win->_flags = _SUBPAD;
+
+ /* save default values in case pechochar() is the first call
+ to prefresh(). */
+
+ save_pminrow = 0;
+ save_pmincol = 0;
+ save_sminrow = 0;
+ save_smincol = 0;
+ save_smaxrow = min(LINES, nlines) - 1;
+ save_smaxcol = min(COLS, ncols) - 1;
+
+ return win;
+}
+
+int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, int sy2, int sx2)
+{
+ PDC_LOG(("prefresh() - called\n"));
+
+ if (pnoutrefresh(win, py, px, sy1, sx1, sy2, sx2) == ERR)
+ return ERR;
+
+ doupdate();
+ return OK;
+}
+
+int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2)
+{
+ int num_cols;
+ int sline = sy1;
+ int pline = py;
+
+ PDC_LOG(("pnoutrefresh() - called\n"));
+
+ if (!w || !(w->_flags & (_PAD|_SUBPAD)) || (sy2 >= LINES) || (sy2 >= COLS))
+ return ERR;
+
+ if (py < 0)
+ py = 0;
+ if (px < 0)
+ px = 0;
+ if (sy1 < 0)
+ sy1 = 0;
+ if (sx1 < 0)
+ sx1 = 0;
+
+ if (sy2 < sy1 || sx2 < sx1)
+ return ERR;
+
+ num_cols = min((sx2 - sx1 + 1), (w->_maxx - px));
+
+ while (sline <= sy2)
+ {
+ if (pline < w->_maxy)
+ {
+ memcpy(curscr->_y[sline] + sx1, w->_y[pline] + px,
+ num_cols * sizeof(chtype));
+
+ if ((curscr->_firstch[sline] == _NO_CHANGE)
+ || (curscr->_firstch[sline] > sx1))
+ curscr->_firstch[sline] = sx1;
+
+ if (sx2 > curscr->_lastch[sline])
+ curscr->_lastch[sline] = sx2;
+
+ w->_firstch[pline] = _NO_CHANGE; /* updated now */
+ w->_lastch[pline] = _NO_CHANGE; /* updated now */
+ }
+
+ sline++;
+ pline++;
+ }
+
+ if (w->_clear)
+ {
+ w->_clear = FALSE;
+ curscr->_clear = TRUE;
+ }
+
+ /* position the cursor to the pad's current position if possible --
+ is the pad current position going to end up displayed? if not,
+ then don't move the cursor; if so, move it to the correct place */
+
+ if (!w->_leaveit && w->_cury >= py && w->_curx >= px &&
+ w->_cury <= py + (sy2 - sy1) && w->_curx <= px + (sx2 - sx1))
+ {
+ curscr->_cury = (w->_cury - py) + sy1;
+ curscr->_curx = (w->_curx - px) + sx1;
+ }
+
+ return OK;
+}
+
+int pechochar(WINDOW *pad, chtype ch)
+{
+ PDC_LOG(("pechochar() - called\n"));
+
+ if (waddch(pad, ch) == ERR)
+ return ERR;
+
+ return prefresh(pad, save_pminrow, save_pmincol, save_sminrow,
+ save_smincol, save_smaxrow, save_smaxcol);
+}
+
+#ifdef PDC_WIDE
+int pecho_wchar(WINDOW *pad, const cchar_t *wch)
+{
+ PDC_LOG(("pecho_wchar() - called\n"));
+
+ if (!wch || (waddch(pad, *wch) == ERR))
+ return ERR;
+
+ return prefresh(pad, save_pminrow, save_pmincol, save_sminrow,
+ save_smincol, save_smaxrow, save_smaxcol);
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/panel.c b/apps/lib/curses/pdcurses/pdcurses/panel.c
new file mode 100644
index 0000000..77028c6
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/panel.c
@@ -0,0 +1,630 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: panel.c,v 1.8 2008/07/14 12:35:23 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: panel
+
+ Synopsis:
+ int bottom_panel(PANEL *pan);
+ int del_panel(PANEL *pan);
+ int hide_panel(PANEL *pan);
+ int move_panel(PANEL *pan, int starty, int startx);
+ PANEL *new_panel(WINDOW *win);
+ PANEL *panel_above(const PANEL *pan);
+ PANEL *panel_below(const PANEL *pan);
+ int panel_hidden(const PANEL *pan);
+ const void *panel_userptr(const PANEL *pan);
+ WINDOW *panel_window(const PANEL *pan);
+ int replace_panel(PANEL *pan, WINDOW *win);
+ int set_panel_userptr(PANEL *pan, const void *uptr);
+ int show_panel(PANEL *pan);
+ int top_panel(PANEL *pan);
+ void update_panels(void);
+
+ Description:
+ The panel library is built using the curses library, and any
+ program using panels routines must call one of the curses
+ initialization routines such as initscr(). A program using these
+ routines must be linked with the panels and curses libraries.
+ The header <panel.h> includes the header <curses.h>.
+
+ The panels package gives the applications programmer a way to
+ have depth relationships between curses windows; a curses window
+ is associated with every panel. The panels routines allow curses
+ windows to overlap without making visible the overlapped
+ portions of underlying windows. The initial curses window,
+ stdscr, lies beneath all panels. The set of currently visible
+ panels is the 'deck' of panels.
+
+ The panels package allows the applications programmer to create
+ panels, fetch and set their associated windows, shuffle panels
+ in the deck, and manipulate panels in other ways.
+
+ bottom_panel() places pan at the bottom of the deck. The size,
+ location and contents of the panel are unchanged.
+
+ del_panel() deletes pan, but not its associated winwow.
+
+ hide_panel() removes a panel from the deck and thus hides it
+ from view.
+
+ move_panel() moves the curses window associated with pan, so
+ that its upper lefthand corner is at the supplied coordinates.
+ (Do not use mvwin() on the window.)
+
+ new_panel() creates a new panel associated with win and returns
+ the panel pointer. The new panel is placed at the top of the
+ deck.
+
+ panel_above() returns a pointer to the panel in the deck above
+ pan, or NULL if pan is the top panel. If the value of pan passed
+ is NULL, this function returns a pointer to the bottom panel in
+ the deck.
+
+ panel_below() returns a pointer to the panel in the deck below
+ pan, or NULL if pan is the bottom panel. If the value of pan
+ passed is NULL, this function returns a pointer to the top panel
+ in the deck.
+
+ panel_hidden() returns OK if pan is hidden and ERR if it is not.
+
+ panel_userptr() - Each panel has a user pointer available for
+ maintaining relevant information. This function returns a
+ pointer to that information previously set up by
+ set_panel_userptr().
+
+ panel_window() returns a pointer to the curses window associated
+ with the panel.
+
+ replace_panel() replaces the current window of pan with win.
+
+ set_panel_userptr() - Each panel has a user pointer available
+ for maintaining relevant information. This function sets the
+ value of that information.
+
+ show_panel() makes a previously hidden panel visible and places
+ it back in the deck on top.
+
+ top_panel() places pan on the top of the deck. The size,
+ location and contents of the panel are unchanged.
+
+ update_panels() refreshes the virtual screen to reflect the
+ depth relationships between the panels in the deck. The user
+ must use doupdate() to refresh the physical screen.
+
+ Return Value:
+ Each routine that returns a pointer to an object returns NULL if
+ an error occurs. Each panel routine that returns an integer,
+ returns OK if it executes successfully and ERR if it does not.
+
+ Portability X/Open BSD SYS V
+ bottom_panel - - Y
+ del_panel - - Y
+ hide_panel - - Y
+ move_panel - - Y
+ new_panel - - Y
+ panel_above - - Y
+ panel_below - - Y
+ panel_hidden - - Y
+ panel_userptr - - Y
+ panel_window - - Y
+ replace_panel - - Y
+ set_panel_userptr - - Y
+ show_panel - - Y
+ top_panel - - Y
+ update_panels - - Y
+
+ Credits:
+ Original Author - Warren Tucker <wht@n4hgf.mt-park.ga.us>
+
+**man-end****************************************************************/
+
+#include <panel.h>
+#include <stdlib.h>
+
+PANEL *_bottom_panel = (PANEL *)0;
+PANEL *_top_panel = (PANEL *)0;
+PANEL _stdscr_pseudo_panel = { (WINDOW *)0 };
+
+#ifdef PANEL_DEBUG
+
+static void dPanel(char *text, PANEL *pan)
+{
+ PDC_LOG(("%s id=%s b=%s a=%s y=%d x=%d", text, pan->user,
+ pan->below ? pan->below->user : "--",
+ pan->above ? pan->above->user : "--",
+ pan->wstarty, pan->wstartx));
+}
+
+static void dStack(char *fmt, int num, PANEL *pan)
+{
+ char s80[80];
+
+ sprintf(s80, fmt, num, pan);
+ PDC_LOG(("%s b=%s t=%s", s80, _bottom_panel ? _bottom_panel->user : "--",
+ _top_panel ? _top_panel->user : "--"));
+
+ if (pan)
+ PDC_LOG(("pan id=%s", pan->user));
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ dPanel("stk", pan);
+ pan = pan->above;
+ }
+}
+
+/* debugging hook for wnoutrefresh */
+
+static void Wnoutrefresh(PANEL *pan)
+{
+ dPanel("wnoutrefresh", pan);
+ wnoutrefresh(pan->win);
+}
+
+static void Touchpan(PANEL *pan)
+{
+ dPanel("Touchpan", pan);
+ touchwin(pan->win);
+}
+
+static void Touchline(PANEL *pan, int start, int count)
+{
+ char s80[80];
+
+ sprintf(s80, "Touchline s=%d c=%d", start, count);
+ dPanel(s80, pan);
+ touchline(pan->win, start, count);
+}
+
+#else /* PANEL_DEBUG */
+
+#define dPanel(text, pan)
+#define dStack(fmt, num, pan)
+#define Wnoutrefresh(pan) wnoutrefresh((pan)->win)
+#define Touchpan(pan) touchwin((pan)->win)
+#define Touchline(pan, start, count) touchline((pan)->win, start, count)
+
+#endif /* PANEL_DEBUG */
+
+static bool _panels_overlapped(PANEL *pan1, PANEL *pan2)
+{
+ if (!pan1 || !pan2)
+ return FALSE;
+
+ return ((pan1->wstarty >= pan2->wstarty && pan1->wstarty < pan2->wendy)
+ || (pan2->wstarty >= pan1->wstarty && pan2->wstarty < pan1->wendy))
+ && ((pan1->wstartx >= pan2->wstartx && pan1->wstartx < pan2->wendx)
+ || (pan2->wstartx >= pan1->wstartx && pan2->wstartx < pan1->wendx));
+}
+
+static void _free_obscure(PANEL *pan)
+{
+ PANELOBS *tobs = pan->obscure; /* "this" one */
+ PANELOBS *nobs; /* "next" one */
+
+ while (tobs)
+ {
+ nobs = tobs->above;
+ free((char *)tobs);
+ tobs = nobs;
+ }
+ pan->obscure = (PANELOBS *)0;
+}
+
+static void _override(PANEL *pan, int show)
+{
+ int y;
+ PANEL *pan2;
+ PANELOBS *tobs = pan->obscure; /* "this" one */
+
+ if (show == 1)
+ Touchpan(pan);
+ else if (!show)
+ {
+ Touchpan(pan);
+ Touchpan(&_stdscr_pseudo_panel);
+ }
+ else if (show == -1)
+ while (tobs && (tobs->pan != pan))
+ tobs = tobs->above;
+
+ while (tobs)
+ {
+ if ((pan2 = tobs->pan) != pan)
+ for (y = pan->wstarty; y < pan->wendy; y++)
+ if ((y >= pan2->wstarty) && (y < pan2->wendy) &&
+ ((is_linetouched(pan->win, y - pan->wstarty)) ||
+ (is_linetouched(stdscr, y))))
+ Touchline(pan2, y - pan2->wstarty, 1);
+
+ tobs = tobs->above;
+ }
+}
+
+static void _calculate_obscure(void)
+{
+ PANEL *pan, *pan2;
+ PANELOBS *tobs; /* "this" one */
+ PANELOBS *lobs; /* last one */
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ if (pan->obscure)
+ _free_obscure(pan);
+
+ lobs = (PANELOBS *)0;
+ pan2 = _bottom_panel;
+
+ while (pan2)
+ {
+ if (_panels_overlapped(pan, pan2))
+ {
+ if ((tobs = malloc(sizeof(PANELOBS))) == NULL)
+ return;
+
+ tobs->pan = pan2;
+ dPanel("obscured", pan2);
+ tobs->above = (PANELOBS *)0;
+
+ if (lobs)
+ lobs->above = tobs;
+ else
+ pan->obscure = tobs;
+
+ lobs = tobs;
+ }
+
+ pan2 = pan2->above;
+ }
+
+ _override(pan, 1);
+ pan = pan->above;
+ }
+}
+
+/* check to see if panel is in the stack */
+
+static bool _panel_is_linked(const PANEL *pan)
+{
+ PANEL *pan2 = _bottom_panel;
+
+ while (pan2)
+ {
+ if (pan2 == pan)
+ return TRUE;
+
+ pan2 = pan2->above;
+ }
+
+ return FALSE;
+}
+
+/* link panel into stack at top */
+
+static void _panel_link_top(PANEL *pan)
+{
+#ifdef PANEL_DEBUG
+ dStack("<lt%d>", 1, pan);
+ if (_panel_is_linked(pan))
+ return;
+#endif
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+
+ if (_top_panel)
+ {
+ _top_panel->above = pan;
+ pan->below = _top_panel;
+ }
+
+ _top_panel = pan;
+
+ if (!_bottom_panel)
+ _bottom_panel = pan;
+
+ _calculate_obscure();
+ dStack("<lt%d>", 9, pan);
+}
+
+/* link panel into stack at bottom */
+
+static void _panel_link_bottom(PANEL *pan)
+{
+#ifdef PANEL_DEBUG
+ dStack("<lb%d>", 1, pan);
+ if (_panel_is_linked(pan))
+ return;
+#endif
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+
+ if (_bottom_panel)
+ {
+ _bottom_panel->below = pan;
+ pan->above = _bottom_panel;
+ }
+
+ _bottom_panel = pan;
+
+ if (!_top_panel)
+ _top_panel = pan;
+
+ _calculate_obscure();
+ dStack("<lb%d>", 9, pan);
+}
+
+static void _panel_unlink(PANEL *pan)
+{
+ PANEL *prev;
+ PANEL *next;
+
+#ifdef PANEL_DEBUG
+ dStack("<u%d>", 1, pan);
+ if (!_panel_is_linked(pan))
+ return;
+#endif
+ _override(pan, 0);
+ _free_obscure(pan);
+
+ prev = pan->below;
+ next = pan->above;
+
+ /* if non-zero, we will not update the list head */
+
+ if (prev)
+ {
+ prev->above = next;
+ if(next)
+ next->below = prev;
+ }
+ else if (next)
+ next->below = prev;
+
+ if (pan == _bottom_panel)
+ _bottom_panel = next;
+
+ if (pan == _top_panel)
+ _top_panel = prev;
+
+ _calculate_obscure();
+
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ dStack("<u%d>", 9, pan);
+
+}
+
+/************************************************************************
+ * The following are the public functions for the panels library. *
+ ************************************************************************/
+
+int bottom_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (pan == _bottom_panel)
+ return OK;
+
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ _panel_link_bottom(pan);
+
+ return OK;
+}
+
+int del_panel(PANEL *pan)
+{
+ if (pan)
+ {
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ free((char *)pan);
+ return OK;
+ }
+
+ return ERR;
+}
+
+int hide_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (!_panel_is_linked(pan))
+ {
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ return ERR;
+ }
+
+ _panel_unlink(pan);
+
+ return OK;
+}
+
+int move_panel(PANEL *pan, int starty, int startx)
+{
+ WINDOW *win;
+ int maxy, maxx;
+
+ if (!pan)
+ return ERR;
+
+ if (_panel_is_linked(pan))
+ _override(pan, 0);
+
+ win = pan->win;
+
+ if (mvwin(win, starty, startx) == ERR)
+ return ERR;
+
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+
+ if (_panel_is_linked(pan))
+ _calculate_obscure();
+
+ return OK;
+}
+
+PANEL *new_panel(WINDOW *win)
+{
+ PANEL *pan = malloc(sizeof(PANEL));
+
+ if (!_stdscr_pseudo_panel.win)
+ {
+ _stdscr_pseudo_panel.win = stdscr;
+ _stdscr_pseudo_panel.wstarty = 0;
+ _stdscr_pseudo_panel.wstartx = 0;
+ _stdscr_pseudo_panel.wendy = LINES;
+ _stdscr_pseudo_panel.wendx = COLS;
+ _stdscr_pseudo_panel.user = "stdscr";
+ _stdscr_pseudo_panel.obscure = (PANELOBS *)0;
+ }
+
+ if (pan)
+ {
+ int maxy, maxx;
+
+ pan->win = win;
+ pan->above = (PANEL *)0;
+ pan->below = (PANEL *)0;
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+#ifdef PANEL_DEBUG
+ pan->user = "new";
+#else
+ pan->user = (char *)0;
+#endif
+ pan->obscure = (PANELOBS *)0;
+ show_panel(pan);
+ }
+
+ return pan;
+}
+
+PANEL *panel_above(const PANEL *pan)
+{
+ return pan ? pan->above : _bottom_panel;
+}
+
+PANEL *panel_below(const PANEL *pan)
+{
+ return pan ? pan->below : _top_panel;
+}
+
+int panel_hidden(const PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ return _panel_is_linked(pan) ? ERR : OK;
+}
+
+const void *panel_userptr(const PANEL *pan)
+{
+ return pan ? pan->user : NULL;
+}
+
+WINDOW *panel_window(const PANEL *pan)
+{
+ PDC_LOG(("panel_window() - called\n"));
+
+ return pan->win;
+}
+
+int replace_panel(PANEL *pan, WINDOW *win)
+{
+ int maxy, maxx;
+
+ if (!pan)
+ return ERR;
+
+ if (_panel_is_linked(pan))
+ _override(pan, 0);
+
+ pan->win = win;
+ getbegyx(win, pan->wstarty, pan->wstartx);
+ getmaxyx(win, maxy, maxx);
+ pan->wendy = pan->wstarty + maxy;
+ pan->wendx = pan->wstartx + maxx;
+
+ if (_panel_is_linked(pan))
+ _calculate_obscure();
+
+ return OK;
+}
+
+int set_panel_userptr(PANEL *pan, const void *uptr)
+{
+ if (!pan)
+ return ERR;
+
+ pan->user = uptr;
+ return OK;
+}
+
+int show_panel(PANEL *pan)
+{
+ if (!pan)
+ return ERR;
+
+ if (pan == _top_panel)
+ return OK;
+
+ if (_panel_is_linked(pan))
+ hide_panel(pan);
+
+ _panel_link_top(pan);
+
+ return OK;
+}
+
+int top_panel(PANEL *pan)
+{
+ return show_panel(pan);
+}
+
+void update_panels(void)
+{
+ PANEL *pan;
+
+ PDC_LOG(("update_panels() - called\n"));
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ _override(pan, -1);
+ pan = pan->above;
+ }
+
+ if (is_wintouched(stdscr))
+ Wnoutrefresh(&_stdscr_pseudo_panel);
+
+ pan = _bottom_panel;
+
+ while (pan)
+ {
+ if (is_wintouched(pan->win) || !pan->above)
+ Wnoutrefresh(pan);
+
+ pan = pan->above;
+ }
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/printw.c b/apps/lib/curses/pdcurses/pdcurses/printw.c
new file mode 100644
index 0000000..9be0c5f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/printw.c
@@ -0,0 +1,123 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: printw.c,v 1.40 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: printw
+
+ Synopsis:
+ int printw(const char *fmt, ...);
+ int wprintw(WINDOW *win, const char *fmt, ...);
+ int mvprintw(int y, int x, const char *fmt, ...);
+ int mvwprintw(WINDOW *win, int y, int x, const char *fmt,...);
+ int vwprintw(WINDOW *win, const char *fmt, va_list varglist);
+ int vw_printw(WINDOW *win, const char *fmt, va_list varglist);
+
+ Description:
+ The printw() functions add a formatted string to the window at
+ the current or specified cursor position. The format strings are
+ the same as used in the standard C library's printf(). (printw()
+ can be used as a drop-in replacement for printf().)
+
+ Return Value:
+ All functions return the number of characters printed, or
+ ERR on error.
+
+ Portability X/Open BSD SYS V
+ printw Y Y Y
+ wprintw Y Y Y
+ mvprintw Y Y Y
+ mvwprintw Y Y Y
+ vwprintw Y - 4.0
+ vw_printw Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int vwprintw(WINDOW *win, const char *fmt, va_list varglist)
+{
+ char printbuf[513];
+ int len;
+
+ PDC_LOG(("vwprintw() - called\n"));
+
+#ifdef HAVE_VSNPRINTF
+ len = vsnprintf(printbuf, 512, fmt, varglist);
+#else
+ len = vsprintf(printbuf, fmt, varglist);
+#endif
+ return (waddstr(win, printbuf) == ERR) ? ERR : len;
+}
+
+int printw(const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("printw() - called\n"));
+
+ va_start(args, fmt);
+ retval = vwprintw(stdscr, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int wprintw(WINDOW *win, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("wprintw() - called\n"));
+
+ va_start(args, fmt);
+ retval = vwprintw(win, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int mvprintw(int y, int x, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("mvprintw() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ va_start(args, fmt);
+ retval = vwprintw(stdscr, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("mvwprintw() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ va_start(args, fmt);
+ retval = vwprintw(win, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int vw_printw(WINDOW *win, const char *fmt, va_list varglist)
+{
+ PDC_LOG(("vw_printw() - called\n"));
+
+ return vwprintw(win, fmt, varglist);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/refresh.c b/apps/lib/curses/pdcurses/pdcurses/refresh.c
new file mode 100644
index 0000000..0b8e1ca
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/refresh.c
@@ -0,0 +1,276 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: refresh.c,v 1.56 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: refresh
+
+ Synopsis:
+ int refresh(void);
+ int wrefresh(WINDOW *win);
+ int wnoutrefresh(WINDOW *win);
+ int doupdate(void);
+ int redrawwin(WINDOW *win);
+ int wredrawln(WINDOW *win, int beg_line, int num_lines);
+
+ Description:
+ wrefresh() copies the named window to the physical terminal
+ screen, taking into account what is already there in order to
+ optimize cursor movement. refresh() does the same, using stdscr.
+ These routines must be called to get any output on the terminal,
+ as other routines only manipulate data structures. Unless
+ leaveok() has been enabled, the physical cursor of the terminal
+ is left at the location of the window's cursor.
+
+ wnoutrefresh() and doupdate() allow multiple updates with more
+ efficiency than wrefresh() alone. wrefresh() works by first
+ calling wnoutrefresh(), which copies the named window to the
+ virtual screen. It then calls doupdate(), which compares the
+ virtual screen to the physical screen and does the actual
+ update. A series of calls to wrefresh() will result in
+ alternating calls to wnoutrefresh() and doupdate(), causing
+ several bursts of output to the screen. By first calling
+ wnoutrefresh() for each window, it is then possible to call
+ doupdate() only once.
+
+ In PDCurses, redrawwin() is equivalent to touchwin(), and
+ wredrawln() is the same as touchline(). In some other curses
+ implementations, there's a subtle distinction, but it has no
+ meaning in PDCurses.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ refresh Y Y Y
+ wrefresh Y Y Y
+ wnoutrefresh Y Y Y
+ doupdate Y Y Y
+ redrawwin Y - 4.0
+ wredrawln Y - 4.0
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+int wnoutrefresh(WINDOW *win)
+{
+ int begy, begx; /* window's place on screen */
+ int i, j;
+
+ PDC_LOG(("wnoutrefresh() - called: win=%p\n", win));
+
+ if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
+ return ERR;
+
+ begy = win->_begy;
+ begx = win->_begx;
+
+ for (i = 0, j = begy; i < win->_maxy; i++, j++)
+ {
+ if (win->_firstch[i] != _NO_CHANGE)
+ {
+ chtype *src = win->_y[i];
+ chtype *dest = curscr->_y[j] + begx;
+
+ int first = win->_firstch[i]; /* first changed */
+ int last = win->_lastch[i]; /* last changed */
+
+ /* ignore areas on the outside that are marked as changed,
+ but really aren't */
+
+ while (first <= last && src[first] == dest[first])
+ first++;
+
+ while (last >= first && src[last] == dest[last])
+ last--;
+
+ /* if any have really changed... */
+
+ if (first <= last)
+ {
+ memcpy(dest + first, src + first,
+ (last - first + 1) * sizeof(chtype));
+
+ first += begx;
+ last += begx;
+
+ if (first < curscr->_firstch[j] ||
+ curscr->_firstch[j] == _NO_CHANGE)
+ curscr->_firstch[j] = first;
+
+ if (last > curscr->_lastch[j])
+ curscr->_lastch[j] = last;
+ }
+
+ win->_firstch[i] = _NO_CHANGE; /* updated now */
+ }
+
+ win->_lastch[i] = _NO_CHANGE; /* updated now */
+ }
+
+ if (win->_clear)
+ win->_clear = FALSE;
+
+ if (!win->_leaveit)
+ {
+ curscr->_cury = win->_cury + begy;
+ curscr->_curx = win->_curx + begx;
+ }
+
+ return OK;
+}
+
+int doupdate(void)
+{
+ int y;
+ bool clearall;
+
+ PDC_LOG(("doupdate() - called\n"));
+
+ if (!curscr)
+ return ERR;
+
+ if (isendwin()) /* coming back after endwin() called */
+ {
+ reset_prog_mode();
+ clearall = TRUE;
+ SP->alive = TRUE; /* so isendwin() result is correct */
+ }
+ else
+ clearall = curscr->_clear;
+
+ for (y = 0; y < SP->lines; y++)
+ {
+ PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n",
+ y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ?
+ "Yes" : "No"));
+
+ if (clearall || curscr->_firstch[y] != _NO_CHANGE)
+ {
+ int first, last;
+
+ chtype *src = curscr->_y[y];
+ chtype *dest = pdc_lastscr->_y[y];
+
+ if (clearall)
+ {
+ first = 0;
+ last = COLS - 1;
+ }
+ else
+ {
+ first = curscr->_firstch[y];
+ last = curscr->_lastch[y];
+ }
+
+ while (first <= last)
+ {
+ int len = 0;
+
+ /* build up a run of changed cells; if two runs are
+ separated by a single unchanged cell, ignore the
+ break */
+
+ if (clearall)
+ len = last - first + 1;
+ else
+ while (first + len <= last &&
+ (src[first + len] != dest[first + len] ||
+ (len && first + len < last &&
+ src[first + len + 1] != dest[first + len + 1])
+ )
+ )
+ len++;
+
+ /* update the screen, and pdc_lastscr */
+
+ if (len)
+ {
+ PDC_transform_line(y, first, len, src + first);
+ memcpy(dest + first, src + first, len * sizeof(chtype));
+ first += len;
+ }
+
+ /* skip over runs of unchanged cells */
+
+ while (first <= last && src[first] == dest[first])
+ first++;
+ }
+
+ curscr->_firstch[y] = _NO_CHANGE;
+ curscr->_lastch[y] = _NO_CHANGE;
+ }
+ }
+
+ curscr->_clear = FALSE;
+
+ if (SP->visibility)
+ PDC_gotoyx(curscr->_cury, curscr->_curx);
+
+ SP->cursrow = curscr->_cury;
+ SP->curscol = curscr->_curx;
+
+ return OK;
+}
+
+int wrefresh(WINDOW *win)
+{
+ bool save_clear;
+
+ PDC_LOG(("wrefresh() - called\n"));
+
+ if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
+ return ERR;
+
+ save_clear = win->_clear;
+
+ if (win == curscr)
+ curscr->_clear = TRUE;
+ else
+ wnoutrefresh(win);
+
+ if (save_clear && win->_maxy == SP->lines && win->_maxx == SP->cols)
+ curscr->_clear = TRUE;
+
+ return doupdate();
+}
+
+int refresh(void)
+{
+ PDC_LOG(("refresh() - called\n"));
+
+ return wrefresh(stdscr);
+}
+
+int wredrawln(WINDOW *win, int start, int num)
+{
+ int i;
+
+ PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n",
+ win, start, num));
+
+ if (!win || start > win->_maxy || start + num > win->_maxy)
+ return ERR;
+
+ for (i = start; i < start + num; i++)
+ {
+ win->_firstch[i] = 0;
+ win->_lastch[i] = win->_maxx - 1;
+ }
+
+ return OK;
+}
+
+int redrawwin(WINDOW *win)
+{
+ PDC_LOG(("redrawwin() - called: win=%p\n", win));
+
+ if (!win)
+ return ERR;
+
+ return wredrawln(win, 0, win->_maxy);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/scanw.c b/apps/lib/curses/pdcurses/pdcurses/scanw.c
new file mode 100644
index 0000000..af2bcb9
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/scanw.c
@@ -0,0 +1,575 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: scanw.c,v 1.42 2008/07/14 12:22:13 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: scanw
+
+ Synopsis:
+ int scanw(const char *fmt, ...);
+ int wscanw(WINDOW *win, const char *fmt, ...);
+ int mvscanw(int y, int x, const char *fmt, ...);
+ int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...);
+ int vwscanw(WINDOW *win, const char *fmt, va_list varglist);
+ int vw_scanw(WINDOW *win, const char *fmt, va_list varglist);
+
+ Description:
+ These routines correspond to the standard C library's scanf()
+ family. Each gets a string from the window via wgetnstr(), and
+ uses the resulting line as input for the scan.
+
+ Return Value:
+ On successful completion, these functions return the number of
+ items successfully matched. Otherwise they return ERR.
+
+ Portability X/Open BSD SYS V
+ scanw Y Y Y
+ wscanw Y Y Y
+ mvscanw Y Y Y
+ mvwscanw Y Y Y
+ vwscanw Y - 4.0
+ vw_scanw Y
+
+**man-end****************************************************************/
+
+#include <string.h>
+
+#ifndef HAVE_VSSCANF
+# include <stdlib.h>
+# include <ctype.h>
+# include <limits.h>
+
+static int _pdc_vsscanf(const char *, const char *, va_list);
+
+# define vsscanf _pdc_vsscanf
+#endif
+
+int vwscanw(WINDOW *win, const char *fmt, va_list varglist)
+{
+ char scanbuf[256];
+
+ PDC_LOG(("vwscanw() - called\n"));
+
+ if (wgetnstr(win, scanbuf, 255) == ERR)
+ return ERR;
+
+ return vsscanf(scanbuf, fmt, varglist);
+}
+
+int scanw(const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("scanw() - called\n"));
+
+ va_start(args, fmt);
+ retval = vwscanw(stdscr, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int wscanw(WINDOW *win, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("wscanw() - called\n"));
+
+ va_start(args, fmt);
+ retval = vwscanw(win, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int mvscanw(int y, int x, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("mvscanw() - called\n"));
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ va_start(args, fmt);
+ retval = vwscanw(stdscr, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...)
+{
+ va_list args;
+ int retval;
+
+ PDC_LOG(("mvscanw() - called\n"));
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ va_start(args, fmt);
+ retval = vwscanw(win, fmt, args);
+ va_end(args);
+
+ return retval;
+}
+
+int vw_scanw(WINDOW *win, const char *fmt, va_list varglist)
+{
+ PDC_LOG(("vw_scanw() - called\n"));
+
+ return vwscanw(win, fmt, varglist);
+}
+
+#ifndef HAVE_VSSCANF
+
+/* _pdc_vsscanf() - Internal routine to parse and format an input
+ buffer. It scans a series of input fields; each field is formatted
+ according to a supplied format string and the formatted input is
+ stored in the variable number of addresses passed. Returns the number
+ of input fields or EOF on error.
+
+ Don't compile this unless required. Some compilers (at least Borland
+ C++ 3.0) have to link with math libraries due to the use of floats.
+
+ Based on vsscanf.c and input.c from emx 0.8f library source,
+ Copyright (c) 1990-1992 by Eberhard Mattes, who has kindly agreed to
+ its inclusion in PDCurses. */
+
+#define WHITE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
+
+#define NEXT(x) \
+ do { \
+ x = *buf++; \
+ if (!x) \
+ return (count ? count : EOF); \
+ ++chars; \
+ } while (0)
+
+#define UNGETC() \
+ do { \
+ --buf; --chars; \
+ } while (0)
+
+static int _pdc_vsscanf(const char *buf, const char *fmt, va_list arg_ptr)
+{
+ int count, chars, c, width, radix, d, i;
+ int *int_ptr;
+ long *long_ptr;
+ short *short_ptr;
+ char *char_ptr;
+ unsigned char f;
+ char neg, assign, ok, size;
+ long n;
+ char map[256], end;
+ double dx, dd, *dbl_ptr;
+ float *flt_ptr;
+ int exp;
+ char eneg;
+
+ count = 0;
+ chars = 0;
+ c = 0;
+ while ((f = *fmt) != 0)
+ {
+ if (WHITE(f))
+ {
+ do
+ {
+ ++fmt;
+ f = *fmt;
+ }
+ while (WHITE(f));
+ do
+ {
+ c = *buf++;
+ if (!c)
+ {
+ if (!f || count)
+ return count;
+ else
+ return EOF;
+ } else
+ ++chars;
+ }
+ while (WHITE(c));
+ UNGETC();
+ } else if (f != '%')
+ {
+ NEXT(c);
+ if (c != f)
+ return count;
+ ++fmt;
+ } else
+ {
+ assign = TRUE;
+ width = INT_MAX;
+ char_ptr = NULL;
+ ++fmt;
+ if (*fmt == '*')
+ {
+ assign = FALSE;
+ ++fmt;
+ }
+ if (isdigit(*fmt))
+ {
+ width = 0;
+ while (isdigit(*fmt))
+ width = width * 10 + (*fmt++ - '0');
+ if (!width)
+ width = INT_MAX;
+ }
+ size = 0;
+ if (*fmt == 'h' || *fmt == 'l')
+ size = *fmt++;
+ f = *fmt;
+ switch (f)
+ {
+ case 'c':
+ if (width == INT_MAX)
+ width = 1;
+ if (assign)
+ char_ptr = va_arg(arg_ptr, char *);
+ while (width > 0)
+ {
+ --width;
+ NEXT(c);
+ if (assign)
+ {
+ *char_ptr++ = (char) c;
+ ++count;
+ }
+ }
+ break;
+ case '[':
+ memset(map, 0, 256);
+ end = 0;
+ ++fmt;
+ if (*fmt == '^')
+ {
+ ++fmt;
+ end = 1;
+ }
+ i = 0;
+ for (;;)
+ {
+ f = (unsigned char) *fmt;
+ switch (f)
+ {
+ case 0:
+ /* avoid skipping past 0 */
+ --fmt;
+ NEXT(c);
+ goto string;
+ case ']':
+ if (i > 0)
+ {
+ NEXT(c);
+ goto string;
+ }
+ /* no break */
+ default:
+ if (fmt[1] == '-' && fmt[2]
+ && f < (unsigned char)fmt[2])
+ {
+ memset(map + f, 1, (unsigned char)fmt[2] - f);
+ fmt += 2;
+ }
+ else
+ map[f] = 1;
+ break;
+ }
+ ++fmt;
+ ++i;
+ }
+ case 's':
+ memset(map, 0, 256);
+ map[' '] = 1;
+ map['\n'] = 1;
+ map['\r'] = 1;
+ map['\t'] = 1;
+ end = 1;
+ do
+ {
+ NEXT(c);
+ }
+ while (WHITE(c));
+ string:
+ if (assign)
+ char_ptr = va_arg(arg_ptr, char *);
+ while (width > 0 && map[(unsigned char) c] != end)
+ {
+ --width;
+ if (assign)
+ *char_ptr++ = (char) c;
+ c = *buf++;
+ if (!c)
+ break;
+ else
+ ++chars;
+ }
+ if (assign)
+ {
+ *char_ptr = 0;
+ ++count;
+ }
+ if (!c)
+ return count;
+ else
+ UNGETC();
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ neg = ok = FALSE;
+ dx = 0.0;
+ do
+ {
+ NEXT(c);
+ }
+ while (WHITE(c));
+ if (c == '+')
+ {
+ NEXT(c);
+ --width;
+ } else if (c == '-')
+ {
+ neg = TRUE;
+ NEXT(c);
+ --width;
+ }
+ while (width > 0 && isdigit(c))
+ {
+ --width;
+ dx = dx * 10.0 + (double) (c - '0');
+ ok = TRUE;
+ c = *buf++;
+ if (!c)
+ break;
+ else
+ ++chars;
+ }
+ if (width > 0 && c == '.')
+ {
+ --width;
+ dd = 10.0;
+ NEXT(c);
+ while (width > 0 && isdigit(c))
+ {
+ --width;
+ dx += (double) (c - '0') / dd;
+ dd *= 10.0;
+ ok = TRUE;
+ c = *buf++;
+ if (!c)
+ break;
+ else
+ ++chars;
+ }
+ }
+ if (!ok)
+ return count;
+ if (width > 0 && (c == 'e' || c == 'E'))
+ {
+ eneg = FALSE;
+ exp = 0;
+ NEXT(c);
+ --width;
+ if (width > 0 && c == '+')
+ {
+ NEXT(c);
+ --width;
+ } else if (width > 0 && c == '-')
+ {
+ eneg = TRUE;
+ NEXT(c);
+ --width;
+ }
+ if (!(width > 0 && isdigit(c)))
+ {
+ UNGETC();
+ return count;
+ }
+ while (width > 0 && isdigit(c))
+ {
+ --width;
+ exp = exp * 10 + (c - '0');
+ c = *buf++;
+ if (!c)
+ break;
+ else
+ ++chars;
+ }
+ if (eneg)
+ exp = -exp;
+ while (exp > 0)
+ {
+ dx *= 10.0;
+ --exp;
+ }
+ while (exp < 0)
+ {
+ dx /= 10.0;
+ ++exp;
+ }
+ }
+ if (assign)
+ {
+ if (neg)
+ dx = -dx;
+ if (size == 'l')
+ {
+ dbl_ptr = va_arg(arg_ptr, double *);
+ *dbl_ptr = dx;
+ }
+ else
+ {
+ flt_ptr = va_arg(arg_ptr, float *);
+ *flt_ptr = (float)dx;
+ }
+ ++count;
+ }
+ if (!c)
+ return count;
+ else
+ UNGETC();
+ break;
+ case 'i':
+ neg = FALSE;
+ radix = 10;
+ do
+ {
+ NEXT(c);
+ }
+ while (WHITE(c));
+ if (!(width > 0 && c == '0'))
+ goto scan_complete_number;
+ NEXT(c);
+ --width;
+ if (width > 0 && (c == 'x' || c == 'X'))
+ {
+ NEXT(c);
+ radix = 16;
+ --width;
+ }
+ else if (width > 0 && (c >= '0' && c <= '7'))
+ radix = 8;
+ goto scan_unsigned_number;
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ do
+ {
+ NEXT(c);
+ }
+ while (WHITE(c));
+ switch (f)
+ {
+ case 'o':
+ radix = 8;
+ break;
+ case 'x':
+ case 'X':
+ radix = 16;
+ break;
+ default:
+ radix = 10;
+ break;
+ }
+ scan_complete_number:
+ neg = FALSE;
+ if (width > 0 && c == '+')
+ {
+ NEXT(c);
+ --width;
+ }
+ else if (width > 0 && c == '-' && radix == 10)
+ {
+ neg = TRUE;
+ NEXT(c);
+ --width;
+ }
+ scan_unsigned_number:
+ n = 0;
+ ok = FALSE;
+ while (width > 0)
+ {
+ --width;
+ if (isdigit(c))
+ d = c - '0';
+ else if (isupper(c))
+ d = c - 'A' + 10;
+ else if (islower(c))
+ d = c - 'a' + 10;
+ else
+ break;
+ if (d < 0 || d >= radix)
+ break;
+ ok = TRUE;
+ n = n * radix + d;
+ c = *buf++;
+ if (!c)
+ break;
+ else
+ ++chars;
+ }
+ if (!ok)
+ return count;
+ if (assign)
+ {
+ if (neg)
+ n = -n;
+ switch (size)
+ {
+ case 'h':
+ short_ptr = va_arg(arg_ptr, short *);
+ *short_ptr = (short) n;
+ break;
+ case 'l':
+ long_ptr = va_arg(arg_ptr, long *);
+ *long_ptr = (long) n;
+ break;
+ default:
+ int_ptr = va_arg(arg_ptr, int *);
+ *int_ptr = (int) n;
+ }
+ ++count;
+ }
+ if (!c)
+ return count;
+ else
+ UNGETC();
+ break;
+ case 'n':
+ if (assign)
+ {
+ int_ptr = va_arg(arg_ptr, int *);
+ *int_ptr = chars;
+ ++count;
+ }
+ break;
+ default:
+ if (!f) /* % at end of string */
+ return count;
+ NEXT(c);
+ if (c != f)
+ return count;
+ break;
+ }
+ ++fmt;
+ }
+ }
+ return count;
+}
+#endif /* HAVE_VSSCANF */
diff --git a/apps/lib/curses/pdcurses/pdcurses/scr_dump.c b/apps/lib/curses/pdcurses/pdcurses/scr_dump.c
new file mode 100644
index 0000000..e02046e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/scr_dump.c
@@ -0,0 +1,210 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: scr_dump.c,v 1.30 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: scr_dump
+
+ Synopsis:
+ int putwin(WINDOW *win, FILE *filep);
+ WINDOW *getwin(FILE *filep);
+ int scr_dump(const char *filename);
+ int scr_init(const char *filename);
+ int scr_restore(const char *filename);
+ int scr_set(const char *filename);
+
+ Description:
+ getwin() reads window-related data previously stored in a file
+ by putwin(). It then creates and initialises a new window using
+ that data.
+
+ putwin() writes all data associated with a window into a file,
+ using an unspecified format. This information can be retrieved
+ later using getwin().
+
+ scr_dump() writes the current contents of the virtual screen to
+ the file named by filename in an unspecified format.
+
+ scr_restore() function sets the virtual screen to the contents
+ of the file named by filename, which must have been written
+ using scr_dump(). The next refresh operation restores the screen
+ to the way it looked in the dump file.
+
+ In PDCurses, scr_init() does nothing, and scr_set() is a synonym
+ for scr_restore(). Also, scr_dump() and scr_restore() save and
+ load from curscr. This differs from some other implementations,
+ where scr_init() works with curscr, and scr_restore() works with
+ newscr; but the effect should be the same. (PDCurses has no
+ newscr.)
+
+ Return Value:
+ On successful completion, getwin() returns a pointer to the
+ window it created. Otherwise, it returns a null pointer. Other
+ functions return OK or ERR.
+
+ Portability X/Open BSD SYS V
+ putwin Y
+ getwin Y
+ scr_dump Y
+ scr_init Y
+ scr_restore Y
+ scr_set Y
+
+**man-end****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#define DUMPVER 1 /* Should be updated whenever the WINDOW struct is
+ changed */
+
+int putwin(WINDOW *win, FILE *filep)
+{
+ static const char *marker = "PDC";
+ static const unsigned char version = DUMPVER;
+
+ PDC_LOG(("putwin() - called\n"));
+
+ /* write the marker and the WINDOW struct */
+
+ if (filep && fwrite(marker, strlen(marker), 1, filep)
+ && fwrite(&version, 1, 1, filep)
+ && fwrite(win, sizeof(WINDOW), 1, filep))
+ {
+ int i;
+
+ /* write each line */
+
+ for (i = 0; i < win->_maxy && win->_y[i]; i++)
+ if (!fwrite(win->_y[i], win->_maxx * sizeof(chtype), 1, filep))
+ return ERR;
+
+ return OK;
+ }
+
+ return ERR;
+}
+
+WINDOW *getwin(FILE *filep)
+{
+ WINDOW *win;
+ char marker[4];
+ int i, nlines, ncols;
+
+ PDC_LOG(("getwin() - called\n"));
+
+ if ( !(win = malloc(sizeof(WINDOW))) )
+ return (WINDOW *)NULL;
+
+ /* check for the marker, and load the WINDOW struct */
+
+ if (!filep || !fread(marker, 4, 1, filep) || strncmp(marker, "PDC", 3)
+ || marker[3] != DUMPVER || !fread(win, sizeof(WINDOW), 1, filep))
+ {
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ nlines = win->_maxy;
+ ncols = win->_maxx;
+
+ /* allocate the line pointer array */
+
+ if ( !(win->_y = malloc(nlines * sizeof(chtype *))) )
+ {
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ /* allocate the minchng and maxchng arrays */
+
+ if ( !(win->_firstch = malloc(nlines * sizeof(int))) )
+ {
+ free(win->_y);
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ if ( !(win->_lastch = malloc(nlines * sizeof(int))) )
+ {
+ free(win->_firstch);
+ free(win->_y);
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ /* allocate the lines */
+
+ if ( !(win = PDC_makelines(win)) )
+ return (WINDOW *)NULL;
+
+ /* read them */
+
+ for (i = 0; i < nlines; i++)
+ {
+ if (!fread(win->_y[i], ncols * sizeof(chtype), 1, filep))
+ {
+ delwin(win);
+ return (WINDOW *)NULL;
+ }
+ }
+
+ touchwin(win);
+
+ return win;
+}
+
+int scr_dump(const char *filename)
+{
+ FILE *filep;
+
+ PDC_LOG(("scr_dump() - called: filename %s\n", filename));
+
+ if (filename && (filep = fopen(filename, "wb")) != NULL)
+ {
+ int result = putwin(curscr, filep);
+ fclose(filep);
+ return result;
+ }
+
+ return ERR;
+}
+
+int scr_init(const char *filename)
+{
+ PDC_LOG(("scr_init() - called: filename %s\n", filename));
+
+ return OK;
+}
+
+int scr_restore(const char *filename)
+{
+ FILE *filep;
+
+ PDC_LOG(("scr_restore() - called: filename %s\n", filename));
+
+ if (filename && (filep = fopen(filename, "rb")) != NULL)
+ {
+ WINDOW *replacement = getwin(filep);
+ fclose(filep);
+
+ if (replacement)
+ {
+ int result = overwrite(replacement, curscr);
+ delwin(replacement);
+ return result;
+ }
+ }
+
+ return ERR;
+}
+
+int scr_set(const char *filename)
+{
+ PDC_LOG(("scr_set() - called: filename %s\n", filename));
+
+ return scr_restore(filename);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/scroll.c b/apps/lib/curses/pdcurses/pdcurses/scroll.c
new file mode 100644
index 0000000..c53e295
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/scroll.c
@@ -0,0 +1,98 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: scroll.c,v 1.36 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: scroll
+
+ Synopsis:
+ int scroll(WINDOW *win);
+ int scrl(int n);
+ int wscrl(WINDOW *win, int n);
+
+ Description:
+ scroll() causes the window to scroll up one line. This involves
+ moving the lines in the window data strcture.
+
+ With a positive n, scrl() and wscrl() scroll the window up n
+ lines (line i + n becomes i); otherwise they scroll the window
+ down n lines.
+
+ For these functions to work, scrolling must be enabled via
+ scrollok(). Note also that scrolling is not allowed if the
+ supplied window is a pad.
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ scroll Y Y Y
+ scrl Y - 4.0
+ wscrl Y - 4.0
+
+**man-end****************************************************************/
+
+int wscrl(WINDOW *win, int n)
+{
+ int i, l, dir, start, end;
+ chtype blank, *temp;
+
+ /* Check if window scrolls. Valid for window AND pad */
+
+ if (!win || !win->_scroll || !n)
+ return ERR;
+
+ blank = win->_bkgd;
+
+ if (n > 0)
+ {
+ start = win->_tmarg;
+ end = win->_bmarg;
+ dir = 1;
+ }
+ else
+ {
+ start = win->_bmarg;
+ end = win->_tmarg;
+ dir = -1;
+ }
+
+ for (l = 0; l < (n * dir); l++)
+ {
+ temp = win->_y[start];
+
+ /* re-arrange line pointers */
+
+ for (i = start; i != end; i += dir)
+ win->_y[i] = win->_y[i + dir];
+
+ win->_y[end] = temp;
+
+ /* make a blank line */
+
+ for (i = 0; i < win->_maxx; i++)
+ *temp++ = blank;
+ }
+
+ touchline(win, win->_tmarg, win->_bmarg - win->_tmarg + 1);
+
+ PDC_sync(win);
+ return OK;
+}
+
+int scrl(int n)
+{
+ PDC_LOG(("scrl() - called\n"));
+
+ return wscrl(stdscr, n);
+}
+
+int scroll(WINDOW *win)
+{
+ PDC_LOG(("scroll() - called\n"));
+
+ return wscrl(win, 1);
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/slk.c b/apps/lib/curses/pdcurses/pdcurses/slk.c
new file mode 100644
index 0000000..f97f406
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/slk.c
@@ -0,0 +1,643 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: slk.c,v 1.61 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: slk
+
+ Synopsis:
+ int slk_init(int fmt);
+ int slk_set(int labnum, const char *label, int justify);
+ int slk_refresh(void);
+ int slk_noutrefresh(void);
+ char *slk_label(int labnum);
+ int slk_clear(void);
+ int slk_restore(void);
+ int slk_touch(void);
+ int slk_attron(const chtype attrs);
+ int slk_attr_on(const attr_t attrs, void *opts);
+ int slk_attrset(const chtype attrs);
+ int slk_attr_set(const attr_t attrs, short color_pair, void *opts);
+ int slk_attroff(const chtype attrs);
+ int slk_attr_off(const attr_t attrs, void *opts);
+ int slk_color(short color_pair);
+
+ int slk_wset(int labnum, const wchar_t *label, int justify);
+
+ int PDC_mouse_in_slk(int y, int x);
+ void PDC_slk_free(void);
+ void PDC_slk_initialize(void);
+
+ wchar_t *slk_wlabel(int labnum)
+
+ Description:
+ These functions manipulate a window that contain Soft Label Keys
+ (SLK). To use the SLK functions, a call to slk_init() must be
+ made BEFORE initscr() or newterm(). slk_init() removes 1 or 2
+ lines from the useable screen, depending on the format selected.
+
+ The line(s) removed from the screen are used as a separate
+ window, in which SLKs are displayed.
+
+ slk_init() requires a single parameter which describes the
+ format of the SLKs as follows:
+
+ 0 3-2-3 format
+ 1 4-4 format
+ 2 4-4-4 format (ncurses extension)
+ 3 4-4-4 format with index line (ncurses extension)
+ 2 lines used
+ 55 5-5 format (pdcurses format)
+
+ slk_refresh(), slk_noutrefresh() and slk_touch() are analogous
+ to refresh(), noutrefresh() and touch().
+
+ Return Value:
+ All functions return OK on success and ERR on error.
+
+ Portability X/Open BSD SYS V
+ slk_init Y - Y
+ slk_set Y - Y
+ slk_refresh Y - Y
+ slk_noutrefresh Y - Y
+ slk_label Y - Y
+ slk_clear Y - Y
+ slk_restore Y - Y
+ slk_touch Y - Y
+ slk_attron Y - Y
+ slk_attrset Y - Y
+ slk_attroff Y - Y
+ slk_attr_on Y
+ slk_attr_set Y
+ slk_attr_off Y
+ slk_wset Y
+ PDC_mouse_in_slk - - -
+ PDC_slk_free - - -
+ PDC_slk_initialize - - -
+ slk_wlabel - - -
+
+**man-end****************************************************************/
+
+#include <stdlib.h>
+
+enum { LABEL_NORMAL = 8, LABEL_EXTENDED = 10, LABEL_NCURSES_EXTENDED = 12 };
+
+static int label_length = 0;
+static int labels = 0;
+static int label_fmt = 0;
+static int label_line = 0;
+static bool hidden = FALSE;
+
+static struct SLK {
+ chtype label[32];
+ int len;
+ int format;
+ int start_col;
+} *slk = (struct SLK *)NULL;
+
+/* slk_init() is the slk initialization routine.
+ This must be called before initscr().
+
+ label_fmt = 0, 1 or 55.
+ 0 = 3-2-3 format
+ 1 = 4 - 4 format
+ 2 = 4-4-4 format (ncurses extension for PC 12 function keys)
+ 3 = 4-4-4 format (ncurses extension for PC 12 function keys -
+ with index line)
+ 55 = 5 - 5 format (extended for PC, 10 function keys) */
+
+int slk_init(int fmt)
+{
+ PDC_LOG(("slk_init() - called\n"));
+
+ if (SP)
+ return ERR;
+
+ switch (fmt)
+ {
+ case 0: /* 3 - 2 - 3 */
+ labels = LABEL_NORMAL;
+ break;
+
+ case 1: /* 4 - 4 */
+ labels = LABEL_NORMAL;
+ break;
+
+ case 2: /* 4 4 4 */
+ labels = LABEL_NCURSES_EXTENDED;
+ break;
+
+ case 3: /* 4 4 4 with index */
+ labels = LABEL_NCURSES_EXTENDED;
+ break;
+
+ case 55: /* 5 - 5 */
+ labels = LABEL_EXTENDED;
+ break;
+
+ default:
+ return ERR;
+ }
+
+ label_fmt = fmt;
+
+ slk = calloc(labels, sizeof(struct SLK));
+
+ if (!slk)
+ labels = 0;
+
+ return slk ? OK : ERR;
+}
+
+/* draw a single button */
+
+static void _drawone(int num)
+{
+ int i, col, slen;
+
+ if (hidden)
+ return;
+
+ slen = slk[num].len;
+
+ switch (slk[num].format)
+ {
+ case 0: /* LEFT */
+ col = 0;
+ break;
+
+ case 1: /* CENTER */
+ col = (label_length - slen) / 2;
+
+ if (col + slen > label_length)
+ --col;
+ break;
+
+ default: /* RIGHT */
+ col = label_length - slen;
+ }
+
+ wmove(SP->slk_winptr, label_line, slk[num].start_col);
+
+ for (i = 0; i < label_length; ++i)
+ waddch(SP->slk_winptr, (i >= col && i < (col + slen)) ?
+ slk[num].label[i - col] : ' ');
+}
+
+/* redraw each button */
+
+static void _redraw(void)
+{
+ int i;
+
+ for (i = 0; i < labels; ++i)
+ _drawone(i);
+}
+
+/* slk_set() Used to set a slk label to a string.
+
+ labnum = 1 - 8 (or 10) (number of the label)
+ label = string (8 or 7 bytes total), or NULL
+ justify = 0 : left, 1 : center, 2 : right */
+
+int slk_set(int labnum, const char *label, int justify)
+{
+#ifdef PDC_WIDE
+ wchar_t wlabel[32];
+
+ PDC_mbstowcs(wlabel, label, 31);
+ return slk_wset(labnum, wlabel, justify);
+#else
+ PDC_LOG(("slk_set() - called\n"));
+
+ if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
+ return ERR;
+
+ labnum--;
+
+ if (!label || !(*label))
+ {
+ /* Clear the label */
+
+ *slk[labnum].label = 0;
+ slk[labnum].format = 0;
+ slk[labnum].len = 0;
+ }
+ else
+ {
+ int i, j = 0;
+
+ /* Skip leading spaces */
+
+ while (label[j] == ' ')
+ j++;
+
+ /* Copy it */
+
+ for (i = 0; i < label_length; i++)
+ {
+ chtype ch = label[i + j];
+
+ slk[labnum].label[i] = ch;
+
+ if (!ch)
+ break;
+ }
+
+ /* Drop trailing spaces */
+
+ while ((i + j) && (label[i + j - 1] == ' '))
+ i--;
+
+ slk[labnum].label[i] = 0;
+ slk[labnum].format = justify;
+ slk[labnum].len = i;
+ }
+
+ _drawone(labnum);
+
+ return OK;
+#endif
+}
+
+int slk_refresh(void)
+{
+ PDC_LOG(("slk_refresh() - called\n"));
+
+ return (slk_noutrefresh() == ERR) ? ERR : doupdate();
+}
+
+int slk_noutrefresh(void)
+{
+ PDC_LOG(("slk_noutrefresh() - called\n"));
+
+ return wnoutrefresh(SP->slk_winptr);
+}
+
+char *slk_label(int labnum)
+{
+ static char temp[33];
+#ifdef PDC_WIDE
+ wchar_t *wtemp = slk_wlabel(labnum);
+
+ PDC_wcstombs(temp, wtemp, 32);
+#else
+ chtype *p;
+ int i;
+
+ PDC_LOG(("slk_label() - called\n"));
+
+ if (labnum < 1 || labnum > labels)
+ return (char *)0;
+
+ for (i = 0, p = slk[labnum - 1].label; *p; i++)
+ temp[i] = *p++;
+
+ temp[i] = '\0';
+#endif
+ return temp;
+}
+
+int slk_clear(void)
+{
+ PDC_LOG(("slk_clear() - called\n"));
+
+ hidden = TRUE;
+ werase(SP->slk_winptr);
+ return wrefresh(SP->slk_winptr);
+}
+
+int slk_restore(void)
+{
+ PDC_LOG(("slk_restore() - called\n"));
+
+ hidden = FALSE;
+ _redraw();
+ return wrefresh(SP->slk_winptr);
+}
+
+int slk_touch(void)
+{
+ PDC_LOG(("slk_touch() - called\n"));
+
+ return touchwin(SP->slk_winptr);
+}
+
+int slk_attron(const chtype attrs)
+{
+ int rc;
+
+ PDC_LOG(("slk_attron() - called\n"));
+
+ rc = wattron(SP->slk_winptr, attrs);
+ _redraw();
+
+ return rc;
+}
+
+int slk_attr_on(const attr_t attrs, void *opts)
+{
+ PDC_LOG(("slk_attr_on() - called\n"));
+
+ return slk_attron(attrs);
+}
+
+int slk_attroff(const chtype attrs)
+{
+ int rc;
+
+ PDC_LOG(("slk_attroff() - called\n"));
+
+ rc = wattroff(SP->slk_winptr, attrs);
+ _redraw();
+
+ return rc;
+}
+
+int slk_attr_off(const attr_t attrs, void *opts)
+{
+ PDC_LOG(("slk_attr_off() - called\n"));
+
+ return slk_attroff(attrs);
+}
+
+int slk_attrset(const chtype attrs)
+{
+ int rc;
+
+ PDC_LOG(("slk_attrset() - called\n"));
+
+ rc = wattrset(SP->slk_winptr, attrs);
+ _redraw();
+
+ return rc;
+}
+
+int slk_color(short color_pair)
+{
+ int rc;
+
+ PDC_LOG(("slk_color() - called\n"));
+
+ rc = wcolor_set(SP->slk_winptr, color_pair, NULL);
+ _redraw();
+
+ return rc;
+}
+
+int slk_attr_set(const attr_t attrs, short color_pair, void *opts)
+{
+ PDC_LOG(("slk_attr_set() - called\n"));
+
+ return slk_attrset(attrs | COLOR_PAIR(color_pair));
+}
+
+static void _slk_calc(void)
+{
+ int i, center, col = 0;
+ label_length = COLS / labels;
+
+ if (label_length > 31)
+ label_length = 31;
+
+ switch (label_fmt)
+ {
+ case 0: /* 3 - 2 - 3 F-Key layout */
+
+ --label_length;
+
+ slk[0].start_col = col;
+ slk[1].start_col = (col += label_length);
+ slk[2].start_col = (col += label_length);
+
+ center = COLS / 2;
+
+ slk[3].start_col = center - label_length + 1;
+ slk[4].start_col = center + 1;
+
+ col = COLS - (label_length * 3) + 1;
+
+ slk[5].start_col = col;
+ slk[6].start_col = (col += label_length);
+ slk[7].start_col = (col += label_length);
+ break;
+
+ case 1: /* 4 - 4 F-Key layout */
+
+ for (i = 0; i < 8; i++)
+ {
+ slk[i].start_col = col;
+ col += label_length;
+
+ if (i == 3)
+ col = COLS - (label_length * 4) + 1;
+ }
+
+ break;
+
+ case 2: /* 4 4 4 F-Key layout */
+ case 3: /* 4 4 4 F-Key layout with index */
+
+ for (i = 0; i < 4; i++)
+ {
+ slk[i].start_col = col;
+ col += label_length;
+ }
+
+ center = COLS/2;
+
+ slk[4].start_col = center - (label_length * 2) + 1;
+ slk[5].start_col = center - label_length - 1;
+ slk[6].start_col = center + 1;
+ slk[7].start_col = center + label_length + 1;
+
+ col = COLS - (label_length * 4) + 1;
+
+ for (i = 8; i < 12; i++)
+ {
+ slk[i].start_col = col;
+ col += label_length;
+ }
+
+ break;
+
+ default: /* 5 - 5 F-Key layout */
+
+ for (i = 0; i < 10; i++)
+ {
+ slk[i].start_col = col;
+ col += label_length;
+
+ if (i == 4)
+ col = COLS - (label_length * 5) + 1;
+ }
+ }
+
+ --label_length;
+
+ /* make sure labels are all in window */
+
+ _redraw();
+}
+
+void PDC_slk_initialize(void)
+{
+ if (slk)
+ {
+ if (label_fmt == 3)
+ {
+ SP->slklines = 2;
+ label_line = 1;
+ }
+ else
+ SP->slklines = 1;
+
+ if (!SP->slk_winptr)
+ {
+ if ( !(SP->slk_winptr = newwin(SP->slklines, COLS,
+ LINES - SP->slklines, 0)) )
+ return;
+
+ wattrset(SP->slk_winptr, A_REVERSE);
+ }
+
+ _slk_calc();
+
+ /* if we have an index line, display it now */
+
+ if (label_fmt == 3)
+ {
+ chtype save_attr;
+ int i;
+
+ save_attr = SP->slk_winptr->_attrs;
+ wattrset(SP->slk_winptr, A_NORMAL);
+ wmove(SP->slk_winptr, 0, 0);
+ whline(SP->slk_winptr, 0, COLS);
+
+ for (i = 0; i < labels; i++)
+ mvwprintw(SP->slk_winptr, 0, slk[i].start_col, "F%d", i + 1);
+
+ SP->slk_winptr->_attrs = save_attr;
+ }
+
+ touchwin(SP->slk_winptr);
+ }
+}
+
+void PDC_slk_free(void)
+{
+ if (slk)
+ {
+ if (SP->slk_winptr)
+ {
+ delwin(SP->slk_winptr);
+ SP->slk_winptr = (WINDOW *)NULL;
+ }
+
+ free(slk);
+ slk = (struct SLK *)NULL;
+
+ label_length = 0;
+ labels = 0;
+ label_fmt = 0;
+ label_line = 0;
+ hidden = FALSE;
+ }
+}
+
+int PDC_mouse_in_slk(int y, int x)
+{
+ int i;
+
+ PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y, x));
+
+ /* If the line on which the mouse was clicked is NOT the last line
+ of the screen, we are not interested in it. */
+
+ if (!slk || !SP->slk_winptr || (y != SP->slk_winptr->_begy + label_line))
+ return 0;
+
+ for (i = 0; i < labels; i++)
+ if (x >= slk[i].start_col && x < (slk[i].start_col + label_length))
+ return i + 1;
+
+ return 0;
+}
+
+#ifdef PDC_WIDE
+int slk_wset(int labnum, const wchar_t *label, int justify)
+{
+ PDC_LOG(("slk_wset() - called\n"));
+
+ if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
+ return ERR;
+
+ labnum--;
+
+ if (!label || !(*label))
+ {
+ /* Clear the label */
+
+ *slk[labnum].label = 0;
+ slk[labnum].format = 0;
+ slk[labnum].len = 0;
+ }
+ else
+ {
+ int i, j = 0;
+
+ /* Skip leading spaces */
+
+ while (label[j] == L' ')
+ j++;
+
+ /* Copy it */
+
+ for (i = 0; i < label_length; i++)
+ {
+ chtype ch = label[i + j];
+
+ slk[labnum].label[i] = ch;
+
+ if (!ch)
+ break;
+ }
+
+ /* Drop trailing spaces */
+
+ while ((i + j) && (label[i + j - 1] == L' '))
+ i--;
+
+ slk[labnum].label[i] = 0;
+ slk[labnum].format = justify;
+ slk[labnum].len = i;
+ }
+
+ _drawone(labnum);
+
+ return OK;
+}
+
+wchar_t *slk_wlabel(int labnum)
+{
+ static wchar_t temp[33];
+ chtype *p;
+ int i;
+
+ PDC_LOG(("slk_wlabel() - called\n"));
+
+ if (labnum < 1 || labnum > labels)
+ return (wchar_t *)0;
+
+ for (i = 0, p = slk[labnum - 1].label; *p; i++)
+ temp[i] = *p++;
+
+ temp[i] = '\0';
+
+ return temp;
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/term.h b/apps/lib/curses/pdcurses/pdcurses/term.h
new file mode 100644
index 0000000..ce6bc4f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/term.h
@@ -0,0 +1,57 @@
+/* Public Domain Curses */
+
+/* $Id: term.h,v 1.16 2008/07/13 16:08:16 wmcbrine Exp $ */
+
+/* PDCurses doesn't operate with terminfo, but we need these functions for
+ compatibility, to allow some things (notably, interface libraries for
+ other languages) to be compiled. Anyone who tries to actually _use_
+ them will be disappointed, since they only return ERR. */
+
+#ifndef __PDCURSES_TERM_H__
+#define __PDCURSES_TERM_H__ 1
+
+#include <curses.h>
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+extern "C"
+{
+#endif
+
+typedef struct
+{
+ const char *_termname;
+} TERMINAL;
+
+#ifdef PDC_DLL_BUILD
+# ifndef CURSES_LIBRARY
+__declspec(dllimport) TERMINAL *cur_term;
+# else
+__declspec(dllexport) extern TERMINAL *cur_term;
+# endif
+#else
+extern TERMINAL *cur_term;
+#endif
+
+int del_curterm(TERMINAL *);
+int putp(const char *);
+int restartterm(const char *, int, int *);
+TERMINAL *set_curterm(TERMINAL *);
+int setterm(const char *);
+int setupterm(const char *, int, int *);
+int tgetent(char *, const char *);
+int tgetflag(const char *);
+int tgetnum(const char *);
+char *tgetstr(const char *, char **);
+char *tgoto(const char *, int, int);
+int tigetflag(const char *);
+int tigetnum(const char *);
+char *tigetstr(const char *);
+char *tparm(const char *, long, long, long, long, long,
+ long, long, long, long);
+int tputs(const char *, int, int (*)(int));
+
+#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
+}
+#endif
+
+#endif /* __PDCURSES_TERM_H__ */
diff --git a/apps/lib/curses/pdcurses/pdcurses/termattr.c b/apps/lib/curses/pdcurses/pdcurses/termattr.c
new file mode 100644
index 0000000..06e9ee8
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/termattr.c
@@ -0,0 +1,176 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: termattr.c,v 1.54 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: termattr
+
+ Synopsis:
+ int baudrate(void);
+ char erasechar(void);
+ bool has_ic(void);
+ bool has_il(void);
+ char killchar(void);
+ char *longname(void);
+ chtype termattrs(void);
+ attr_t term_attrs(void);
+ char *termname(void);
+
+ int erasewchar(wchar_t *ch);
+ int killwchar(wchar_t *ch);
+
+ char wordchar(void);
+
+ Description:
+ baudrate() is supposed to return the output speed of the
+ terminal. In PDCurses, it simply returns INT_MAX.
+
+ has_ic and has_il() return TRUE. These functions have meaning in
+ some other implementations of curses.
+
+ erasechar() and killchar() return ^H and ^U, respectively -- the
+ ERASE and KILL characters. In other curses implementations,
+ these may vary by terminal type. erasewchar() and killwchar()
+ are the wide-character versions; they take a pointer to a
+ location in which to store the character, and return OK or ERR.
+
+ longname() returns a pointer to a static area containing a
+ verbose description of the current terminal. The maximum length
+ of the string is 128 characters. It is defined only after the
+ call to initscr() or newterm().
+
+ termname() returns a pointer to a static area containing a
+ short description of the current terminal (14 characters).
+
+ termattrs() returns a logical OR of all video attributes
+ supported by the terminal.
+
+ wordchar() is a PDCurses extension of the concept behind the
+ functions erasechar() and killchar(), returning the "delete
+ word" character, ^W.
+
+ Portability X/Open BSD SYS V
+ baudrate Y Y Y
+ erasechar Y Y Y
+ has_ic Y Y Y
+ has_il Y Y Y
+ killchar Y Y Y
+ longname Y Y Y
+ termattrs Y Y Y
+ termname Y Y Y
+ erasewchar Y
+ killwchar Y
+ term_attrs Y
+ wordchar - - -
+
+**man-end****************************************************************/
+
+#include <string.h>
+#include <limits.h>
+
+int baudrate(void)
+{
+ PDC_LOG(("baudrate() - called\n"));
+
+ return INT_MAX;
+}
+
+char erasechar(void)
+{
+ PDC_LOG(("erasechar() - called\n"));
+
+ return _ECHAR; /* character delete char (^H) */
+}
+
+bool has_ic(void)
+{
+ PDC_LOG(("has_ic() - called\n"));
+
+ return TRUE;
+}
+
+bool has_il(void)
+{
+ PDC_LOG(("has_il() - called\n"));
+
+ return TRUE;
+}
+
+char killchar(void)
+{
+ PDC_LOG(("killchar() - called\n"));
+
+ return _DLCHAR; /* line delete char (^U) */
+}
+
+char *longname(void)
+{
+ PDC_LOG(("longname() - called\n"));
+
+ return ttytype + 9; /* skip "pdcurses|" */
+}
+
+chtype termattrs(void)
+{
+ chtype temp = A_BLINK | A_BOLD | A_INVIS | A_REVERSE | A_UNDERLINE;
+
+ /* note: blink is bold background on some platforms */
+
+ PDC_LOG(("termattrs() - called\n"));
+
+ if (!SP->mono)
+ temp |= A_COLOR;
+
+ return temp;
+}
+
+attr_t term_attrs(void)
+{
+ PDC_LOG(("term_attrs() - called\n"));
+
+ return WA_BLINK | WA_BOLD | WA_INVIS | WA_LEFT | WA_REVERSE |
+ WA_RIGHT | WA_UNDERLINE;
+}
+
+char *termname(void)
+{
+ PDC_LOG(("termname() - called\n"));
+
+ return "pdcurses";
+}
+
+char wordchar(void)
+{
+ PDC_LOG(("wordchar() - called\n"));
+
+ return _DWCHAR; /* word delete char */
+}
+
+#ifdef PDC_WIDE
+int erasewchar(wchar_t *ch)
+{
+ PDC_LOG(("erasewchar() - called\n"));
+
+ if (!ch)
+ return ERR;
+
+ *ch = (wchar_t)_ECHAR;
+
+ return OK;
+}
+
+int killwchar(wchar_t *ch)
+{
+ PDC_LOG(("killwchar() - called\n"));
+
+ if (!ch)
+ return ERR;
+
+ *ch = (wchar_t)_DLCHAR;
+
+ return OK;
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/terminfo.c b/apps/lib/curses/pdcurses/pdcurses/terminfo.c
new file mode 100644
index 0000000..c099ada
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/terminfo.c
@@ -0,0 +1,215 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: terminfo.c,v 1.37 2008/07/21 12:29:20 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: terminfo
+
+ Synopsis:
+ int mvcur(int oldrow, int oldcol, int newrow, int newcol);
+ int vidattr(chtype attr);
+ int vid_attr(attr_t attr, short color_pair, void *opt);
+ int vidputs(chtype attr, int (*putfunc)(int));
+ int vid_puts(attr_t attr, short color_pair, void *opt,
+ int (*putfunc)(int));
+
+ int del_curterm(TERMINAL *);
+ int putp(const char *);
+ int restartterm(const char *, int, int *);
+ TERMINAL *set_curterm(TERMINAL *);
+ int setterm(const char *term);
+ int setupterm(const char *, int, int *);
+ int tgetent(char *, const char *);
+ int tgetflag(const char *);
+ int tgetnum(const char *);
+ char *tgetstr(const char *, char **);
+ char *tgoto(const char *, int, int);
+ int tigetflag(const char *);
+ int tigetnum(const char *);
+ char *tigetstr(const char *);
+ char *tparm(const char *,long, long, long, long, long, long,
+ long, long, long);
+ int tputs(const char *, int, int (*)(int));
+
+ Description:
+ mvcur() lets you move the physical cursor without updating any
+ window cursor positions. It returns OK or ERR.
+
+ The rest of these functions are currently implemented as stubs,
+ returning the appropriate errors and doing nothing else.
+
+ Portability X/Open BSD SYS V
+ mvcur Y Y Y
+
+**man-end****************************************************************/
+
+#include <term.h>
+
+TERMINAL *cur_term = NULL;
+
+int mvcur(int oldrow, int oldcol, int newrow, int newcol)
+{
+ PDC_LOG(("mvcur() - called: oldrow %d oldcol %d newrow %d newcol %d\n",
+ oldrow, oldcol, newrow, newcol));
+
+ if ((newrow >= LINES) || (newcol >= COLS) || (newrow < 0) || (newcol < 0))
+ return ERR;
+
+ PDC_gotoyx(newrow, newcol);
+ SP->cursrow = newrow;
+ SP->curscol = newcol;
+
+ return OK;
+}
+
+int vidattr(chtype attr)
+{
+ PDC_LOG(("vidattr() - called: attr %d\n", attr));
+
+ return ERR;
+}
+
+int vid_attr(attr_t attr, short color_pair, void *opt)
+{
+ PDC_LOG(("vid_attr() - called\n"));
+
+ return ERR;
+}
+
+int vidputs(chtype attr, int (*putfunc)(int))
+{
+ PDC_LOG(("vidputs() - called: attr %d\n", attr));
+
+ return ERR;
+}
+
+int vid_puts(attr_t attr, short color_pair, void *opt, int (*putfunc)(int))
+{
+ PDC_LOG(("vid_puts() - called\n"));
+
+ return ERR;
+}
+
+int del_curterm(TERMINAL *oterm)
+{
+ PDC_LOG(("del_curterm() - called\n"));
+
+ return ERR;
+}
+
+int putp(const char *str)
+{
+ PDC_LOG(("putp() - called: str %s\n", str));
+
+ return ERR;
+}
+
+int restartterm(const char *term, int filedes, int *errret)
+{
+ PDC_LOG(("restartterm() - called\n"));
+
+ if (errret)
+ *errret = -1;
+
+ return ERR;
+}
+
+TERMINAL *set_curterm(TERMINAL *nterm)
+{
+ PDC_LOG(("set_curterm() - called\n"));
+
+ return (TERMINAL *)NULL;
+}
+
+int setterm(const char *term)
+{
+ PDC_LOG(("setterm() - called\n"));
+
+ return ERR;
+}
+
+int setupterm(const char *term, int filedes, int *errret)
+{
+ PDC_LOG(("setupterm() - called\n"));
+
+ if (errret)
+ *errret = -1;
+ else
+ fprintf(stderr, "There is no terminfo database\n");
+
+ return ERR;
+}
+
+int tgetent(char *bp, const char *name)
+{
+ PDC_LOG(("tgetent() - called: name %s\n", name));
+
+ return ERR;
+}
+
+int tgetflag(const char *id)
+{
+ PDC_LOG(("tgetflag() - called: id %s\n", id));
+
+ return ERR;
+}
+
+int tgetnum(const char *id)
+{
+ PDC_LOG(("tgetnum() - called: id %s\n", id));
+
+ return ERR;
+}
+
+char *tgetstr(const char *id, char **area)
+{
+ PDC_LOG(("tgetstr() - called: id %s\n", id));
+
+ return (char *)NULL;
+}
+
+char *tgoto(const char *cap, int col, int row)
+{
+ PDC_LOG(("tgoto() - called\n"));
+
+ return (char *)NULL;
+}
+
+int tigetflag(const char *capname)
+{
+ PDC_LOG(("tigetflag() - called: capname %s\n", capname));
+
+ return -1;
+}
+
+int tigetnum(const char *capname)
+{
+ PDC_LOG(("tigetnum() - called: capname %s\n", capname));
+
+ return -2;
+}
+
+char *tigetstr(const char *capname)
+{
+ PDC_LOG(("tigetstr() - called: capname %s\n", capname));
+
+ return (char *)(-1);
+}
+
+char *tparm(const char *cap, long p1, long p2, long p3, long p4,
+ long p5, long p6, long p7, long p8, long p9)
+{
+ PDC_LOG(("tparm() - called: cap %s\n", cap));
+
+ return (char *)NULL;
+}
+
+int tputs(const char *str, int affcnt, int (*putfunc)(int))
+{
+ PDC_LOG(("tputs() - called\n"));
+
+ return ERR;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/touch.c b/apps/lib/curses/pdcurses/pdcurses/touch.c
new file mode 100644
index 0000000..9355aa1
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/touch.c
@@ -0,0 +1,160 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: touch.c,v 1.29 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: touch
+
+ Synopsis:
+ int touchwin(WINDOW *win);
+ int touchline(WINDOW *win, int start, int count);
+ int untouchwin(WINDOW *win);
+ int wtouchln(WINDOW *win, int y, int n, int changed);
+ bool is_linetouched(WINDOW *win, int line);
+ bool is_wintouched(WINDOW *win);
+
+ Description:
+ touchwin() and touchline() throw away all information about
+ which parts of the window have been touched, pretending that the
+ entire window has been drawn on. This is sometimes necessary
+ when using overlapping windows, since a change to one window
+ will affect the other window, but the records of which lines
+ have been changed in the other window will not reflect the
+ change.
+
+ untouchwin() marks all lines in the window as unchanged since
+ the last call to wrefresh().
+
+ wtouchln() makes n lines in the window, starting at line y, look
+ as if they have (changed == 1) or have not (changed == 0) been
+ changed since the last call to wrefresh().
+
+ is_linetouched() returns TRUE if the specified line in the
+ specified window has been changed since the last call to
+ wrefresh().
+
+ is_wintouched() returns TRUE if the specified window
+ has been changed since the last call to wrefresh().
+
+ Return Value:
+ All functions return OK on success and ERR on error except
+ is_wintouched() and is_linetouched().
+
+ Portability X/Open BSD SYS V
+ touchwin Y Y Y
+ touchline Y - 3.0
+ untouchwin Y - 4.0
+ wtouchln Y Y Y
+ is_linetouched Y - 4.0
+ is_wintouched Y - 4.0
+
+**man-end****************************************************************/
+
+int touchwin(WINDOW *win)
+{
+ int i;
+
+ PDC_LOG(("touchwin() - called: Win=%x\n", win));
+
+ if (!win)
+ return ERR;
+
+ for (i = 0; i < win->_maxy; i++)
+ {
+ win->_firstch[i] = 0;
+ win->_lastch[i] = win->_maxx - 1;
+ }
+
+ return OK;
+}
+
+int touchline(WINDOW *win, int start, int count)
+{
+ int i;
+
+ PDC_LOG(("touchline() - called: win=%p start %d count %d\n",
+ win, start, count));
+
+ if (!win || start > win->_maxy || start + count > win->_maxy)
+ return ERR;
+
+ for (i = start; i < start + count; i++)
+ {
+ win->_firstch[i] = 0;
+ win->_lastch[i] = win->_maxx - 1;
+ }
+
+ return OK;
+}
+
+int untouchwin(WINDOW *win)
+{
+ int i;
+
+ PDC_LOG(("untouchwin() - called: win=%p", win));
+
+ if (!win)
+ return ERR;
+
+ for (i = 0; i < win->_maxy; i++)
+ {
+ win->_firstch[i] = _NO_CHANGE;
+ win->_lastch[i] = _NO_CHANGE;
+ }
+
+ return OK;
+}
+
+int wtouchln(WINDOW *win, int y, int n, int changed)
+{
+ int i;
+
+ PDC_LOG(("wtouchln() - called: win=%p y=%d n=%d changed=%d\n",
+ win, y, n, changed));
+
+ if (!win || y > win->_maxy || y + n > win->_maxy)
+ return ERR;
+
+ for (i = y; i < y + n; i++)
+ {
+ if (changed)
+ {
+ win->_firstch[i] = 0;
+ win->_lastch[i] = win->_maxx - 1;
+ }
+ else
+ {
+ win->_firstch[i] = _NO_CHANGE;
+ win->_lastch[i] = _NO_CHANGE;
+ }
+ }
+
+ return OK;
+}
+
+bool is_linetouched(WINDOW *win, int line)
+{
+ PDC_LOG(("is_linetouched() - called: win=%p line=%d\n", win, line));
+
+ if (!win || line > win->_maxy || line < 0)
+ return FALSE;
+
+ return (win->_firstch[line] != _NO_CHANGE) ? TRUE : FALSE;
+}
+
+bool is_wintouched(WINDOW *win)
+{
+ int i;
+
+ PDC_LOG(("is_wintouched() - called: win=%p\n", win));
+
+ if (win)
+ for (i = 0; i < win->_maxy; i++)
+ if (win->_firstch[i] != _NO_CHANGE)
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/apps/lib/curses/pdcurses/pdcurses/util.c b/apps/lib/curses/pdcurses/pdcurses/util.c
new file mode 100644
index 0000000..f0673fc
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/util.c
@@ -0,0 +1,309 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: util.c,v 1.71 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: util
+
+ Synopsis:
+ char *unctrl(chtype c);
+ void filter(void);
+ void use_env(bool x);
+ int delay_output(int ms);
+
+ int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,
+ short *color_pair, void *opts);
+ int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs,
+ short color_pair, const void *opts);
+ wchar_t *wunctrl(cchar_t *wc);
+
+ int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n);
+ size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n);
+ size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n);
+
+ Description:
+ unctrl() expands the text portion of the chtype c into a
+ printable string. Control characters are changed to the "^X"
+ notation; others are passed through. wunctrl() is the wide-
+ character version of the function.
+
+ filter() and use_env() are no-ops in PDCurses.
+
+ delay_output() inserts an ms millisecond pause in output.
+
+ getcchar() works in two modes: When wch is not NULL, it reads
+ the cchar_t pointed to by wcval and stores the attributes in
+ attrs, the color pair in color_pair, and the text in the
+ wide-character string wch. When wch is NULL, getcchar() merely
+ returns the number of wide characters in wcval. In either mode,
+ the opts argument is unused.
+
+ setcchar constructs a cchar_t at wcval from the wide-character
+ text at wch, the attributes in attr and the color pair in
+ color_pair. The opts argument is unused.
+
+ Currently, the length returned by getcchar() is always 1 or 0.
+ Similarly, setcchar() will only take the first wide character
+ from wch, and ignore any others that it "should" take (i.e.,
+ combining characters). Nor will it correctly handle any
+ character outside the basic multilingual plane (UCS-2).
+
+ Return Value:
+ unctrl() and wunctrl() return NULL on failure. delay_output()
+ always returns OK.
+
+ getcchar() returns the number of wide characters wcval points to
+ when wch is NULL; when it's not, getcchar() returns OK or ERR.
+
+ setcchar() returns OK or ERR.
+
+ Portability X/Open BSD SYS V
+ unctrl Y Y Y
+ filter Y - 3.0
+ use_env Y - 4.0
+ delay_output Y Y Y
+ getcchar Y
+ setcchar Y
+ wunctrl Y
+ PDC_mbtowc - - -
+ PDC_mbstowcs - - -
+ PDC_wcstombs - - -
+
+**man-end****************************************************************/
+
+#ifdef PDC_WIDE
+# ifdef PDC_FORCE_UTF8
+# include <string.h>
+# else
+# include <stdlib.h>
+# endif
+#endif
+
+char *unctrl(chtype c)
+{
+ static char strbuf[3] = {0, 0, 0};
+
+ chtype ic;
+
+ PDC_LOG(("unctrl() - called\n"));
+
+ ic = c & A_CHARTEXT;
+
+ if (ic >= 0x20 && ic != 0x7f) /* normal characters */
+ {
+ strbuf[0] = (char)ic;
+ strbuf[1] = '\0';
+ return strbuf;
+ }
+
+ strbuf[0] = '^'; /* '^' prefix */
+
+ if (ic == 0x7f) /* 0x7f == DEL */
+ strbuf[1] = '?';
+ else /* other control */
+ strbuf[1] = (char)(ic + '@');
+
+ return strbuf;
+}
+
+void filter(void)
+{
+ PDC_LOG(("filter() - called\n"));
+}
+
+void use_env(bool x)
+{
+ PDC_LOG(("use_env() - called: x %d\n", x));
+}
+
+int delay_output(int ms)
+{
+ PDC_LOG(("delay_output() - called: ms %d\n", ms));
+
+ return napms(ms);
+}
+
+#ifdef PDC_WIDE
+int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,
+ short *color_pair, void *opts)
+{
+ if (!wcval)
+ return ERR;
+
+ if (wch)
+ {
+ if (!attrs || !color_pair)
+ return ERR;
+
+ *wch = (*wcval & A_CHARTEXT);
+ *attrs = (*wcval & (A_ATTRIBUTES & ~A_COLOR));
+ *color_pair = PAIR_NUMBER(*wcval & A_COLOR);
+
+ if (*wch)
+ *++wch = L'\0';
+
+ return OK;
+ }
+ else
+ return ((*wcval & A_CHARTEXT) != L'\0');
+}
+
+int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs,
+ short color_pair, const void *opts)
+{
+ if (!wcval || !wch)
+ return ERR;
+
+ *wcval = *wch | attrs | COLOR_PAIR(color_pair);
+
+ return OK;
+}
+
+wchar_t *wunctrl(cchar_t *wc)
+{
+ static wchar_t strbuf[3] = {0, 0, 0};
+
+ cchar_t ic;
+
+ PDC_LOG(("wunctrl() - called\n"));
+
+ ic = *wc & A_CHARTEXT;
+
+ if (ic >= 0x20 && ic != 0x7f) /* normal characters */
+ {
+ strbuf[0] = (wchar_t)ic;
+ strbuf[1] = L'\0';
+ return strbuf;
+ }
+
+ strbuf[0] = '^'; /* '^' prefix */
+
+ if (ic == 0x7f) /* 0x7f == DEL */
+ strbuf[1] = '?';
+ else /* other control */
+ strbuf[1] = (wchar_t)(ic + '@');
+
+ return strbuf;
+}
+
+int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n)
+{
+# ifdef PDC_FORCE_UTF8
+ wchar_t key;
+ int i = -1;
+ const unsigned char *string;
+
+ if (!s || (n < 1))
+ return -1;
+
+ if (!*s)
+ return 0;
+
+ string = (const unsigned char *)s;
+
+ key = string[0];
+
+ /* Simplistic UTF-8 decoder -- only does the BMP, minimal validation */
+
+ if (key & 0x80)
+ {
+ if ((key & 0xe0) == 0xc0)
+ {
+ if (1 < n)
+ {
+ key = ((key & 0x1f) << 6) | (string[1] & 0x3f);
+ i = 2;
+ }
+ }
+ else if ((key & 0xe0) == 0xe0)
+ {
+ if (2 < n)
+ {
+ key = ((key & 0x0f) << 12) | ((string[1] & 0x3f) << 6) |
+ (string[2] & 0x3f);
+ i = 3;
+ }
+ }
+ }
+ else
+ i = 1;
+
+ if (i)
+ *pwc = key;
+
+ return i;
+# else
+ return mbtowc(pwc, s, n);
+# endif
+}
+
+size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n)
+{
+# ifdef PDC_FORCE_UTF8
+ size_t i = 0, len;
+
+ if (!src || !dest)
+ return 0;
+
+ len = strlen(src);
+
+ while (*src && i < n)
+ {
+ int retval = PDC_mbtowc(dest + i, src, len);
+
+ if (retval < 1)
+ return -1;
+
+ src += retval;
+ len -= retval;
+ i++;
+ }
+# else
+ size_t i = mbstowcs(dest, src, n);
+# endif
+ dest[i] = 0;
+ return i;
+}
+
+size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n)
+{
+# ifdef PDC_FORCE_UTF8
+ size_t i = 0;
+
+ if (!src || !dest)
+ return 0;
+
+ while (*src && i < n)
+ {
+ chtype code = *src++;
+
+ if (code < 0x80)
+ {
+ dest[i] = code;
+ i++;
+ }
+ else
+ if (code < 0x800)
+ {
+ dest[i] = ((code & 0x07c0) >> 6) | 0xc0;
+ dest[i + 1] = (code & 0x003f) | 0x80;
+ i += 2;
+ }
+ else
+ {
+ dest[i] = ((code & 0xf000) >> 12) | 0xe0;
+ dest[i + 1] = ((code & 0x0fc0) >> 6) | 0x80;
+ dest[i + 2] = (code & 0x003f) | 0x80;
+ i += 3;
+ }
+ }
+# else
+ size_t i = wcstombs(dest, src, n);
+# endif
+ dest[i] = '\0';
+ return i;
+}
+#endif
diff --git a/apps/lib/curses/pdcurses/pdcurses/window.c b/apps/lib/curses/pdcurses/pdcurses/window.c
new file mode 100644
index 0000000..dbfd584
--- /dev/null
+++ b/apps/lib/curses/pdcurses/pdcurses/window.c
@@ -0,0 +1,562 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: window.c,v 1.62 2008/07/13 16:08:18 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+ Name: window
+
+ Synopsis:
+ WINDOW *newwin(int nlines, int ncols, int begy, int begx);
+ WINDOW *derwin(WINDOW* orig, int nlines, int ncols,
+ int begy, int begx);
+ WINDOW *subwin(WINDOW* orig, int nlines, int ncols,
+ int begy, int begx);
+ WINDOW *dupwin(WINDOW *win);
+ int delwin(WINDOW *win);
+ int mvwin(WINDOW *win, int y, int x);
+ int mvderwin(WINDOW *win, int pary, int parx);
+ int syncok(WINDOW *win, bool bf);
+ void wsyncup(WINDOW *win);
+ void wcursyncup(WINDOW *win);
+ void wsyncdown(WINDOW *win);
+
+ WINDOW *resize_window(WINDOW *win, int nlines, int ncols);
+ int wresize(WINDOW *win, int nlines, int ncols);
+ WINDOW *PDC_makelines(WINDOW *win);
+ WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx);
+ void PDC_sync(WINDOW *win);
+
+ Description:
+ newwin() creates a new window with the given number of lines,
+ nlines and columns, ncols. The upper left corner of the window
+ is at line begy, column begx. If nlines is zero, it defaults to
+ LINES - begy; ncols to COLS - begx. Create a new full-screen
+ window by calling newwin(0, 0, 0, 0).
+
+ delwin() deletes the named window, freeing all associated
+ memory. In the case of overlapping windows, subwindows should be
+ deleted before the main window.
+
+ mvwin() moves the window so that the upper left-hand corner is
+ at position (y,x). If the move would cause the window to be off
+ the screen, it is an error and the window is not moved. Moving
+ subwindows is allowed.
+
+ subwin() creates a new subwindow within a window. The
+ dimensions of the subwindow are nlines lines and ncols columns.
+ The subwindow is at position (begy, begx) on the screen. This
+ position is relative to the screen, and not to the window orig.
+ Changes made to either window will affect both. When using this
+ routine, you will often need to call touchwin() before calling
+ wrefresh().
+
+ derwin() is the same as subwin(), except that begy and begx are
+ relative to the origin of the window orig rather than the
+ screen. There is no difference between subwindows and derived
+ windows.
+
+ mvderwin() moves a derived window (or subwindow) inside its
+ parent window. The screen-relative parameters of the window are
+ not changed. This routine is used to display different parts of
+ the parent window at the same physical position on the screen.
+
+ dupwin() creates an exact duplicate of the window win.
+
+ wsyncup() causes a touchwin() of all of the window's parents.
+
+ If wsyncok() is called with a second argument of TRUE, this
+ causes a wsyncup() to be called every time the window is
+ changed.
+
+ wcursyncup() causes the current cursor position of all of a
+ window's ancestors to reflect the current cursor position of the
+ current window.
+
+ wsyncdown() causes a touchwin() of the current window if any of
+ its parent's windows have been touched.
+
+ resize_window() allows the user to resize an existing window. It
+ returns the pointer to the new window, or NULL on failure.
+
+ wresize() is an ncurses-compatible wrapper for resize_window().
+ Note that, unlike ncurses, it will NOT process any subwindows of
+ the window. (However, you still can call it _on_ subwindows.) It
+ returns OK or ERR.
+
+ PDC_makenew() allocates all data for a new WINDOW * except the
+ actual lines themselves. If it's unable to allocate memory for
+ the window structure, it will free all allocated memory and
+ return a NULL pointer.
+
+ PDC_makelines() allocates the memory for the lines.
+
+ PDC_sync() handles wrefresh() and wsyncup() calls when a window
+ is changed.
+
+ Return Value:
+ newwin(), subwin(), derwin() and dupwin() return a pointer
+ to the new window, or NULL on failure. delwin(), mvwin(),
+ mvderwin() and syncok() return OK or ERR. wsyncup(),
+ wcursyncup() and wsyncdown() return nothing.
+
+ Errors:
+ It is an error to call resize_window() before calling initscr().
+ Also, an error will be generated if we fail to create a newly
+ sized replacement window for curscr, or stdscr. This could
+ happen when increasing the window size. NOTE: If this happens,
+ the previously successfully allocated windows are left alone;
+ i.e., the resize is NOT cancelled for those windows.
+
+ Portability X/Open BSD SYS V
+ newwin Y Y Y
+ delwin Y Y Y
+ mvwin Y Y Y
+ subwin Y Y Y
+ derwin Y - Y
+ mvderwin Y - Y
+ dupwin Y - 4.0
+ wsyncup Y - 4.0
+ syncok Y - 4.0
+ wcursyncup Y - 4.0
+ wsyncdown Y - 4.0
+ resize_window - - -
+ wresize - - -
+ PDC_makelines - - -
+ PDC_makenew - - -
+ PDC_sync - - -
+
+**man-end****************************************************************/
+
+#include <stdlib.h>
+
+WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx)
+{
+ WINDOW *win;
+
+ PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n",
+ nlines, ncols, begy, begx));
+
+ /* allocate the window structure itself */
+
+ if ((win = calloc(1, sizeof(WINDOW))) == (WINDOW *)NULL)
+ return win;
+
+ /* allocate the line pointer array */
+
+ if ((win->_y = malloc(nlines * sizeof(chtype *))) == NULL)
+ {
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ /* allocate the minchng and maxchng arrays */
+
+ if ((win->_firstch = malloc(nlines * sizeof(int))) == NULL)
+ {
+ free(win->_y);
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ if ((win->_lastch = malloc(nlines * sizeof(int))) == NULL)
+ {
+ free(win->_firstch);
+ free(win->_y);
+ free(win);
+ return (WINDOW *)NULL;
+ }
+
+ /* initialize window variables */
+
+ win->_maxy = nlines; /* real max screen size */
+ win->_maxx = ncols; /* real max screen size */
+ win->_begy = begy;
+ win->_begx = begx;
+ win->_bkgd = ' '; /* wrs 4/10/93 -- initialize background to blank */
+ win->_clear = (bool) ((nlines == LINES) && (ncols == COLS));
+ win->_bmarg = nlines - 1;
+ win->_parx = win->_pary = -1;
+
+ /* init to say window all changed */
+
+ touchwin(win);
+
+ return win;
+}
+
+WINDOW *PDC_makelines(WINDOW *win)
+{
+ int i, j, nlines, ncols;
+
+ PDC_LOG(("PDC_makelines() - called: lines %d cols %d\n", nlines, ncols));
+
+ if (!win)
+ return (WINDOW *)NULL;
+
+ nlines = win->_maxy;
+ ncols = win->_maxx;
+
+ for (i = 0; i < nlines; i++)
+ {
+ if ((win->_y[i] = malloc(ncols * sizeof(chtype))) == NULL)
+ {
+ /* if error, free all the data */
+
+ for (j = 0; j < i; j++)
+ free(win->_y[j]);
+
+ free(win->_firstch);
+ free(win->_lastch);
+ free(win->_y);
+ free(win);
+
+ return (WINDOW *)NULL;
+ }
+ }
+
+ return win;
+}
+
+void PDC_sync(WINDOW *win)
+{
+ PDC_LOG(("PDC_sync() - called:\n"));
+
+ if (win->_immed)
+ wrefresh(win);
+ if (win->_sync)
+ wsyncup(win);
+}
+
+WINDOW *newwin(int nlines, int ncols, int begy, int begx)
+{
+ WINDOW *win;
+
+ PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n",
+ nlines, ncols, begy, begx));
+
+ if (!nlines)
+ nlines = LINES - begy;
+ if (!ncols)
+ ncols = COLS - begx;
+
+ if ( (begy + nlines > SP->lines || begx + ncols > SP->cols)
+ || !(win = PDC_makenew(nlines, ncols, begy, begx))
+ || !(win = PDC_makelines(win)) )
+ return (WINDOW *)NULL;
+
+ werase(win);
+
+ return win;
+}
+
+int delwin(WINDOW *win)
+{
+ int i;
+
+ PDC_LOG(("delwin() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ /* subwindows use parents' lines */
+
+ if (!(win->_flags & (_SUBWIN|_SUBPAD)))
+ for (i = 0; i < win->_maxy && win->_y[i]; i++)
+ if (win->_y[i])
+ free(win->_y[i]);
+
+ free(win->_firstch);
+ free(win->_lastch);
+ free(win->_y);
+ free(win);
+
+ return OK;
+}
+
+int mvwin(WINDOW *win, int y, int x)
+{
+ PDC_LOG(("mvwin() - called\n"));
+
+ if (!win || (y + win->_maxy > LINES || y < 0)
+ || (x + win->_maxx > COLS || x < 0))
+ return ERR;
+
+ win->_begy = y;
+ win->_begx = x;
+ touchwin(win);
+
+ return OK;
+}
+
+WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
+{
+ WINDOW *win;
+ int i;
+ int j = begy - orig->_begy;
+ int k = begx - orig->_begx;
+
+ PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n",
+ nlines, ncols, begy, begx));
+
+ /* make sure window fits inside the original one */
+
+ if (!orig || (begy < orig->_begy) || (begx < orig->_begx) ||
+ (begy + nlines) > (orig->_begy + orig->_maxy) ||
+ (begx + ncols) > (orig->_begx + orig->_maxx))
+ return (WINDOW *)NULL;
+
+ if (!nlines)
+ nlines = orig->_maxy - 1 - j;
+ if (!ncols)
+ ncols = orig->_maxx - 1 - k;
+
+ if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
+ return (WINDOW *)NULL;
+
+ /* initialize window variables */
+
+ win->_attrs = orig->_attrs;
+ win->_bkgd = orig->_bkgd;
+ win->_leaveit = orig->_leaveit;
+ win->_scroll = orig->_scroll;
+ win->_nodelay = orig->_nodelay;
+ win->_use_keypad = orig->_use_keypad;
+ win->_immed = orig->_immed;
+ win->_sync = orig->_sync;
+ win->_pary = j;
+ win->_parx = k;
+ win->_parent = orig;
+
+ for (i = 0; i < nlines; i++, j++)
+ win->_y[i] = orig->_y[j] + k;
+
+ win->_flags |= _SUBWIN;
+
+ return win;
+}
+
+WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx)
+{
+ return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx);
+}
+
+int mvderwin(WINDOW *win, int pary, int parx)
+{
+ int i, j;
+ WINDOW *mypar;
+
+ if (!win || !(win->_parent))
+ return ERR;
+
+ mypar = win->_parent;
+
+ if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy ||
+ (parx + win->_maxx) > mypar->_maxx)
+ return ERR;
+
+ j = pary;
+
+ for (i = 0; i < win->_maxy; i++)
+ win->_y[i] = (mypar->_y[j++]) + parx;
+
+ win->_pary = pary;
+ win->_parx = parx;
+
+ return OK;
+}
+
+WINDOW *dupwin(WINDOW *win)
+{
+ WINDOW *new;
+ chtype *ptr, *ptr1;
+ int nlines, ncols, begy, begx, i;
+
+ if (!win)
+ return (WINDOW *)NULL;
+
+ nlines = win->_maxy;
+ ncols = win->_maxx;
+ begy = win->_begy;
+ begx = win->_begx;
+
+ if ( !(new = PDC_makenew(nlines, ncols, begy, begx))
+ || !(new = PDC_makelines(new)) )
+ return (WINDOW *)NULL;
+
+ /* copy the contents of win into new */
+
+ for (i = 0; i < nlines; i++)
+ {
+ for (ptr = new->_y[i], ptr1 = win->_y[i];
+ ptr < new->_y[i] + ncols; ptr++, ptr1++)
+ *ptr = *ptr1;
+
+ new->_firstch[i] = 0;
+ new->_lastch[i] = ncols - 1;
+ }
+
+ new->_curx = win->_curx;
+ new->_cury = win->_cury;
+ new->_maxy = win->_maxy;
+ new->_maxx = win->_maxx;
+ new->_begy = win->_begy;
+ new->_begx = win->_begx;
+ new->_flags = win->_flags;
+ new->_attrs = win->_attrs;
+ new->_clear = win->_clear;
+ new->_leaveit = win->_leaveit;
+ new->_scroll = win->_scroll;
+ new->_nodelay = win->_nodelay;
+ new->_use_keypad = win->_use_keypad;
+ new->_tmarg = win->_tmarg;
+ new->_bmarg = win->_bmarg;
+ new->_parx = win->_parx;
+ new->_pary = win->_pary;
+ new->_parent = win->_parent;
+ new->_bkgd = win->_bkgd;
+ new->_flags = win->_flags;
+
+ return new;
+}
+
+WINDOW *resize_window(WINDOW *win, int nlines, int ncols)
+{
+ WINDOW *new;
+ int i, save_cury, save_curx, new_begy, new_begx;
+
+ PDC_LOG(("resize_window() - called: nlines %d ncols %d\n",
+ nlines, ncols));
+
+ if (!win)
+ return (WINDOW *)NULL;
+
+ if (win->_flags & _SUBPAD)
+ {
+ if ( !(new = subpad(win->_parent, nlines, ncols,
+ win->_begy, win->_begx)) )
+ return (WINDOW *)NULL;
+ }
+ else if (win->_flags & _SUBWIN)
+ {
+ if ( !(new = subwin(win->_parent, nlines, ncols,
+ win->_begy, win->_begx)) )
+ return (WINDOW *)NULL;
+ }
+ else
+ {
+ if (win == SP->slk_winptr)
+ {
+ new_begy = SP->lines - SP->slklines;
+ new_begx = 0;
+ }
+ else
+ {
+ new_begy = win->_begy;
+ new_begx = win->_begx;
+ }
+
+ if ( !(new = PDC_makenew(nlines, ncols, new_begy, new_begx)) )
+ return (WINDOW *)NULL;
+ }
+
+ save_curx = min(win->_curx, new->_maxx);
+ save_cury = min(win->_cury, new->_maxy);
+
+ if (!(win->_flags & (_SUBPAD|_SUBWIN)))
+ {
+ if ( !(new = PDC_makelines(new)) )
+ return (WINDOW *)NULL;
+
+ werase(new);
+
+ copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1,
+ min(win->_maxx, new->_maxx) - 1, FALSE);
+
+ for (i = 0; i < win->_maxy && win->_y[i]; i++)
+ if (win->_y[i])
+ free(win->_y[i]);
+ }
+
+ new->_flags = win->_flags;
+ new->_attrs = win->_attrs;
+ new->_clear = win->_clear;
+ new->_leaveit = win->_leaveit;
+ new->_scroll = win->_scroll;
+ new->_nodelay = win->_nodelay;
+ new->_use_keypad = win->_use_keypad;
+ new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg;
+ new->_bmarg = (win->_bmarg == win->_maxy - 1) ?
+ new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1));
+ new->_parent = win->_parent;
+ new->_immed = win->_immed;
+ new->_sync = win->_sync;
+ new->_bkgd = win->_bkgd;
+
+ new->_curx = save_curx;
+ new->_cury = save_cury;
+
+ free(win->_firstch);
+ free(win->_lastch);
+ free(win->_y);
+
+ *win = *new;
+ free(new);
+
+ return win;
+}
+
+int wresize(WINDOW *win, int nlines, int ncols)
+{
+ return (resize_window(win, nlines, ncols) ? OK : ERR);
+}
+
+void wsyncup(WINDOW *win)
+{
+ WINDOW *tmp;
+
+ PDC_LOG(("wsyncup() - called\n"));
+
+ for (tmp = win; tmp; tmp = tmp->_parent)
+ touchwin(tmp);
+}
+
+int syncok(WINDOW *win, bool bf)
+{
+ PDC_LOG(("syncok() - called\n"));
+
+ if (!win)
+ return ERR;
+
+ win->_sync = bf;
+
+ return OK;
+}
+
+void wcursyncup(WINDOW *win)
+{
+ WINDOW *tmp;
+
+ PDC_LOG(("wcursyncup() - called\n"));
+
+ for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent)
+ wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx);
+}
+
+void wsyncdown(WINDOW *win)
+{
+ WINDOW *tmp;
+
+ PDC_LOG(("wsyncdown() - called\n"));
+
+ for (tmp = win; tmp; tmp = tmp->_parent)
+ {
+ if (is_wintouched(tmp))
+ {
+ touchwin(win);
+ break;
+ }
+ }
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 14/20] app: add test curses
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (11 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 13/20] app: curses: add pdcurses Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 15/20] app: pdcurses: add libmenu Jean-Christophe PLAGNIOL-VILLARD
` (5 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 4 ++
apps/Makefile | 3 +-
apps/test_curses/Makefile | 11 +++
apps/test_curses/main.c | 172 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 188 insertions(+), 2 deletions(-)
create mode 100644 apps/test_curses/Makefile
create mode 100644 apps/test_curses/main.c
diff --git a/apps/Kconfig b/apps/Kconfig
index a025955..7c0b79e 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -41,4 +41,8 @@ endmenu
config APP_EXAMPLE
bool "example"
+config APP_TEST_CURSES
+ bool "test curses"
+ select APP_LIB_CURSES
+
endif
diff --git a/apps/Makefile b/apps/Makefile
index cce547e..3a222d3 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -6,8 +6,7 @@ APP_CPPFLAGS += $(APP_CPPFLAGS-y)
export APP_CPPFLAGS
apps-$(CONFIG_APP_EXAMPLE) += example
-
-apps-$(CONFIG_APP_EXAMPLE) += example
+apps-$(CONFIG_APP_TEST_CURSES) += test_curses
$(obj)/application: $(apps-lds) $(apps-y)
diff --git a/apps/test_curses/Makefile b/apps/test_curses/Makefile
new file mode 100644
index 0000000..94207a1
--- /dev/null
+++ b/apps/test_curses/Makefile
@@ -0,0 +1,11 @@
+targets := test_curses.map
+
+# Make sure files are removed during clean
+extra-y += test_curses.map
+
+app-y += main.o
+app-final-y = test_curses
+
+OBJCOPYFLAGS_test_curses.app = -O binary
+LDFLAGS_apps := -Map $(obj)/test_curses.map
+LDFLAGS_apps += -static --gc-sections
diff --git a/apps/test_curses/main.c b/apps/test_curses/main.c
new file mode 100644
index 0000000..54f08f2
--- /dev/null
+++ b/apps/test_curses/main.c
@@ -0,0 +1,172 @@
+/*
+ * This file is part of the bayou project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <curses.h>
+
+#define SCREEN_Y LINES
+#define SCREEN_X COLS
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static int menu_width = 0;
+static int m_entries = 4;
+static unsigned int selected = 0;
+static WINDOW *menuwin, *status;
+char *i_name[] = {"test0", "test1", "test2", "test3" };
+
+char *get_name(int i)
+{
+ return i_name[i];
+}
+
+void create_menu(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(i_name); i++) {
+ char *name = get_name(i);
+
+ if (strlen(name) > menu_width)
+ menu_width = strlen(name);
+ }
+
+ menu_width += 4;
+
+ if (menu_width < 30)
+ menu_width = 30;
+
+ menuwin = newwin(m_entries + 3, menu_width,
+ (SCREEN_Y - (m_entries + 3)) / 2,
+ (SCREEN_X - menu_width) / 2);
+
+}
+
+void draw_menu(void)
+{
+ int i;
+
+ wattrset(menuwin, COLOR_PAIR(3));
+ wbkgd(menuwin, COLOR_PAIR(3));
+ wclear(menuwin);
+ wborder(menuwin, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
+ ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER);
+
+ wattrset(menuwin, COLOR_PAIR(4) | A_BOLD);
+ mvwprintw(menuwin, 0, (menu_width - 17) / 2, " Chooser ");
+
+ wattrset(menuwin, COLOR_PAIR(3));
+
+ for (i = 0; i < m_entries; i++) {
+ char *name = get_name(i);
+ int col = (menu_width - (2 + strlen(name))) / 2;
+
+ if (i == selected)
+ wattrset(menuwin, COLOR_PAIR(5) | A_BOLD);
+ else
+ wattrset(menuwin, COLOR_PAIR(3));
+
+ mvwprintw(menuwin, 2 + i, col, name);
+ }
+
+
+ wclear(status);
+
+ mvwprintw(status, 0, (SCREEN_X - 10) / 2, "test");
+
+ wrefresh(menuwin);
+ wrefresh(status);
+}
+
+#if 0
+#define debug(fmt, arg...) debug(fmt, ##arg)
+#else
+#define debug(fmt, arg...)
+#endif
+
+void loop(void)
+{
+ int key;
+
+ while (1) {
+ key = getch();
+
+ debug("loop key = 0x%x\n", key);
+
+ if (key == ERR)
+ continue;
+
+ debug("loop key = 0x%x\n", key);
+
+ if (key == 'q') {
+ clear();
+ refresh();
+ endwin();
+ exit(0);
+ }
+ else if (key == KEY_DOWN)
+ selected = (selected + 1) % m_entries;
+ else if (key == KEY_UP)
+ selected = (selected - 1) % m_entries;
+ else if (key == KEY_ENTER) {
+ clear();
+ refresh();
+ endwin();
+ exit(0);
+ } else
+ continue;
+
+ draw_menu();
+ }
+}
+
+int main(int argc, char **argv)
+{
+ initscr();
+
+ start_color(); /* Start color */
+ clear();
+ keypad(stdscr, TRUE);
+ curs_set(0);
+
+ init_pair(1, COLOR_WHITE, COLOR_RED);
+ init_pair(2, COLOR_BLACK, COLOR_WHITE);
+ init_pair(3, COLOR_BLACK, COLOR_WHITE);
+ init_pair(4, COLOR_CYAN, COLOR_WHITE);
+ init_pair(5, COLOR_WHITE, COLOR_RED);
+
+ wattrset(stdscr, COLOR_PAIR(1));
+ wbkgd(stdscr, COLOR_PAIR(1));
+ wclear(stdscr);
+
+ status = newwin(1, SCREEN_X, SCREEN_Y - 1, 0);
+ wattrset(status, COLOR_PAIR(2));
+ wbkgd(status, COLOR_PAIR(2));
+ wclear(status);
+
+ refresh();
+
+ create_menu();
+ draw_menu();
+
+ loop();
+
+ return EXIT_SUCCESS;
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 15/20] app: pdcurses: add libmenu
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (12 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 14/20] app: add test curses Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 16/20] app: pdcurses: add libform Jean-Christophe PLAGNIOL-VILLARD
` (4 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/lib/curses/Kconfig | 4 +
apps/lib/curses/pdcurses/Makefile.include | 1 +
apps/lib/curses/pdcurses/include/nc_alloc.h | 4 +
apps/lib/curses/pdcurses/include/ncurses_cfg.h | 40 ++
| 26 ++
| 42 ++
| 54 +++
| 144 ++++++
| 112 +++++
| 556 ++++++++++++++++++++++
| 131 ++++++
| 598 ++++++++++++++++++++++++
| 151 ++++++
| 113 +++++
| 72 +++
| 275 +++++++++++
| 159 +++++++
| 107 +++++
| 76 +++
| 104 +++++
| 68 +++
| 110 +++++
| 142 ++++++
| 183 ++++++++
| 95 ++++
| 124 +++++
| 377 +++++++++++++++
| 125 +++++
| 76 +++
| 113 +++++
| 100 ++++
| 77 +++
| 76 +++
| 100 ++++
| 261 +++++++++++
| 157 +++++++
| 95 ++++
37 files changed, 5048 insertions(+)
create mode 100644 apps/lib/curses/pdcurses/include/nc_alloc.h
create mode 100644 apps/lib/curses/pdcurses/include/ncurses_cfg.h
create mode 100644 apps/lib/curses/pdcurses/menu/Makefile
create mode 100644 apps/lib/curses/pdcurses/menu/READ.ME
create mode 100644 apps/lib/curses/pdcurses/menu/eti.h
create mode 100644 apps/lib/curses/pdcurses/menu/m_attribs.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_cursor.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_driver.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_format.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_global.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_hook.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_cur.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_nam.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_new.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_opt.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_top.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_use.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_val.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_item_vis.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_items.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_new.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_opts.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_pad.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_pattern.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_post.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_req_name.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_scale.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_spacing.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_sub.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_trace.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_userptr.c
create mode 100644 apps/lib/curses/pdcurses/menu/m_win.c
create mode 100644 apps/lib/curses/pdcurses/menu/menu.h
create mode 100644 apps/lib/curses/pdcurses/menu/menu.priv.h
create mode 100644 apps/lib/curses/pdcurses/menu/mf_common.h
diff --git a/apps/lib/curses/Kconfig b/apps/lib/curses/Kconfig
index 7852afb..5950385 100644
--- a/apps/lib/curses/Kconfig
+++ b/apps/lib/curses/Kconfig
@@ -18,4 +18,8 @@ config APP_LIB_PANEL
bool "panel"
depends on APP_LIB_PDCURSES
+config APP_LIB_MENU
+ bool "menu"
+ depends on APP_LIB_PDCURSES
+
endif
diff --git a/apps/lib/curses/pdcurses/Makefile.include b/apps/lib/curses/pdcurses/Makefile.include
index 822f12f..7a0061e 100644
--- a/apps/lib/curses/pdcurses/Makefile.include
+++ b/apps/lib/curses/pdcurses/Makefile.include
@@ -1 +1,2 @@
APP_CPPFLAGS-y += -I$(srctree)/apps/lib/curses/pdcurses/include/ -D_LP64=0
+APP_CPPFLAGS-$(CONFIG_APP_LIB_MENU) += -I$(srctree)/apps/lib/curses/pdcurses/menu
diff --git a/apps/lib/curses/pdcurses/include/nc_alloc.h b/apps/lib/curses/pdcurses/include/nc_alloc.h
new file mode 100644
index 0000000..95d41f9
--- /dev/null
+++ b/apps/lib/curses/pdcurses/include/nc_alloc.h
@@ -0,0 +1,4 @@
+#define typeMalloc(type,elts) (type *)malloc((elts)*sizeof(type))
+#define typeCalloc(type,elts) (type *)calloc((elts),sizeof(type))
+#define typeRealloc(type,elts,ptr) (type *)_nc_doalloc(ptr, (elts)*sizeof(type))
+
diff --git a/apps/lib/curses/pdcurses/include/ncurses_cfg.h b/apps/lib/curses/pdcurses/include/ncurses_cfg.h
new file mode 100644
index 0000000..c6184be
--- /dev/null
+++ b/apps/lib/curses/pdcurses/include/ncurses_cfg.h
@@ -0,0 +1,40 @@
+#define USE_RCS_IDS 0
+#define USE_WIDEC_SUPPORT 0
+#define NCURSES_SP_FUNCS 0
+#define DECL_ERRNO 0
+#define NCURSES_INTEROP_FUNCS 0
+
+#define NCURSES_API
+#define NCURSES_IMPEXP
+#define NCURSES_INLINE
+#define NCURSES_SP_DCLx
+#define NCURSES_SP_NAME(x) x
+#define NCURSES_EXPORT_VAR(x) x
+#define NCURSES_EXPORT(x) x
+
+#define SP_PARM SP
+#define CURRENT_SCREEN SP
+#define StdScreen(x) stdscr
+
+#define T(x)
+#define T_CALLED(x...)
+
+#define GCC_UNUSED __attribute__((unused))
+
+#define BLANK (' '|A_NORMAL)
+#define ZEROS ('\0'|A_NORMAL)
+#define ISBLANK isblank
+
+#define ChCharOf(c) ((c) & (chtype)A_CHARTEXT)
+#define CharOf(c) ChCharOf(c)
+
+#define WINDOW_ATTRS(x) ((x)->_attrs)
+#define IsValidScreen(x) 1
+
+#define returnCode return
+#define returnWin return
+#define returnCPtr return
+#define returnVoidPtr return
+#define returnPtr return
+#define returnAttr return
+#define returnBool return
--git a/apps/lib/curses/pdcurses/menu/Makefile b/apps/lib/curses/pdcurses/menu/Makefile
new file mode 100644
index 0000000..f45f385
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/Makefile
@@ -0,0 +1,26 @@
+app-y += m_req_name.o
+app-y += m_item_nam.o
+app-y += m_pad.o
+app-y += m_cursor.o
+app-y += m_item_new.o
+app-y += m_attribs.o
+app-y += m_item_opt.o
+app-y += m_format.o
+app-y += m_post.o
+app-y += m_userptr.o
+app-y += m_item_cur.o
+app-y += m_driver.o
+app-y += m_sub.o
+app-y += m_win.o
+app-y += m_global.o
+app-y += m_item_vis.o
+app-y += m_new.o
+app-y += m_scale.o
+app-y += m_spacing.o
+app-y += m_opts.o
+app-y += m_pattern.o
+app-y += m_item_val.o
+app-y += m_hook.o
+app-y += m_item_use.o
+app-y += m_items.o
+app-y += m_item_top.o
--git a/apps/lib/curses/pdcurses/menu/READ.ME b/apps/lib/curses/pdcurses/menu/READ.ME
new file mode 100644
index 0000000..10ff5b0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/READ.ME
@@ -0,0 +1,42 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998-2003,2006 Free Software Foundation, Inc. --
+-- --
+-- 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. --
+-------------------------------------------------------------------------------
+-- $Id: READ.ME,v 1.9 2006/04/22 23:13:05 tom Exp $
+-------------------------------------------------------------------------------
+
+This is a clone of the menu library that is available with typical
+System V curses implementations (ETI).
+
+It is modelled after the documentation that comes for this library with
+a 386 based SVR4 implementation (ESIX).
+
+The development environment was and is an ELF based Linux system.
+
+For things that still need doing, see the TO-DO file in the top-level
+directory.
+
+Juergen Pfeifer
--git a/apps/lib/curses/pdcurses/menu/eti.h b/apps/lib/curses/pdcurses/menu/eti.h
new file mode 100644
index 0000000..baa6190
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/eti.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: eti.h,v 1.8 2003/10/25 15:24:29 tom Exp $ */
+
+#ifndef NCURSES_ETI_H_incl
+#define NCURSES_ETI_H_incl 1
+
+#define E_OK (0)
+#define E_SYSTEM_ERROR (-1)
+#define E_BAD_ARGUMENT (-2)
+#define E_POSTED (-3)
+#define E_CONNECTED (-4)
+#define E_BAD_STATE (-5)
+#define E_NO_ROOM (-6)
+#define E_NOT_POSTED (-7)
+#define E_UNKNOWN_COMMAND (-8)
+#define E_NO_MATCH (-9)
+#define E_NOT_SELECTABLE (-10)
+#define E_NOT_CONNECTED (-11)
+#define E_REQUEST_DENIED (-12)
+#define E_INVALID_FIELD (-13)
+#define E_CURRENT (-14)
+
+#endif
--git a/apps/lib/curses/pdcurses/menu/m_attribs.c b/apps/lib/curses/pdcurses/menu/m_attribs.c
new file mode 100644
index 0000000..1ea5c7a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_attribs.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_attribs *
+* Control menus display attributes *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_attribs.c,v 1.16 2010/01/23 21:16:54 tom Exp $")
+
+/* Macro to redraw menu if it is posted and changed */
+#define Refresh_Menu(menu) \
+ if ( (menu) && ((menu)->status & _POSTED) )\
+ {\
+ _nc_Draw_Menu( menu );\
+ _nc_Show_Menu( menu );\
+ }
+
+/* "Template" macro to generate a function to set a menus attribute */
+#define GEN_MENU_ATTR_SET_FCT( name ) \
+NCURSES_IMPEXP int NCURSES_API set_menu_ ## name (MENU* menu, chtype attr) \
+{\
+ T((T_CALLED("set_menu_" #name "(%p,%s)"), menu, _traceattr(attr))); \
+ if (!(attr==A_NORMAL || (attr & A_ATTRIBUTES)==attr))\
+ RETURN(E_BAD_ARGUMENT);\
+ if (menu && ( menu -> name != attr))\
+ {\
+ (menu -> name) = attr;\
+ Refresh_Menu(menu);\
+ }\
+ Normalize_Menu( menu ) -> name = attr;\
+ RETURN(E_OK);\
+}
+
+/* "Template" macro to generate a function to get a menu's attribute */
+#define GEN_MENU_ATTR_GET_FCT( name ) \
+NCURSES_IMPEXP chtype NCURSES_API menu_ ## name (const MENU * menu)\
+{\
+ T((T_CALLED("menu_" #name "(%p)"), (const void *) menu));\
+ returnAttr(Normalize_Menu( menu ) -> name);\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_fore(MENU *menu, chtype attr)
+|
+| Description : Set the attribute for selectable items. In single-
+| valued menus this is used to highlight the current
+| item ((i.e. where the cursor is), in multi-valued
+| menus this is used to highlight the selected items.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - an invalid value has been passed
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_SET_FCT(fore)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : chtype menu_fore(const MENU* menu)
+|
+| Description : Return the attribute used for selectable items that
+| are current (single-valued menu) or selected (multi-
+| valued menu).
+|
+| Return Values : Attribute value
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_GET_FCT(fore)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_back(MENU *menu, chtype attr)
+|
+| Description : Set the attribute for selectable but not yet selected
+| items.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - an invalid value has been passed
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_SET_FCT(back)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : chtype menu_back(const MENU *menu)
+|
+| Description : Return the attribute used for selectable but not yet
+| selected items.
+|
+| Return Values : Attribute value
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_GET_FCT(back)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_grey(MENU *menu, chtype attr)
+|
+| Description : Set the attribute for unselectable items.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - an invalid value has been passed
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_SET_FCT(grey)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : chtype menu_grey(const MENU *menu)
+|
+| Description : Return the attribute used for non-selectable items
+|
+| Return Values : Attribute value
++--------------------------------------------------------------------------*/
+GEN_MENU_ATTR_GET_FCT(grey)
+
+/* m_attribs.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_cursor.c b/apps/lib/curses/pdcurses/menu/m_cursor.c
new file mode 100644
index 0000000..9891de4
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_cursor.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_cursor *
+* Correctly position a menu's cursor *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_cursor.c,v 1.22 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : _nc_menu_cursor_pos
+|
+| Description : Return position of logical cursor to current item
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu
+| E_NOT_POSTED - Menu is not posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_menu_cursor_pos(const MENU * menu, const ITEM * item, int *pY, int *pX)
+{
+ if (!menu || !pX || !pY)
+ return (E_BAD_ARGUMENT);
+ else
+ {
+ if ((ITEM *) 0 == item)
+ item = menu->curitem;
+ assert(item != (ITEM *) 0);
+
+ if (!(menu->status & _POSTED))
+ return (E_NOT_POSTED);
+
+ *pX = item->x * (menu->spc_cols + menu->itemlen);
+ *pY = (item->y - menu->toprow) * menu->spc_rows;
+ }
+ return (E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : pos_menu_cursor
+|
+| Description : Position logical cursor to current item in menu
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu
+| E_NOT_POSTED - Menu is not posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+pos_menu_cursor(const MENU * menu)
+{
+ WINDOW *win, *sub;
+ int x = 0, y = 0;
+ int err = _nc_menu_cursor_pos(menu, (ITEM *) 0, &y, &x);
+
+ T((T_CALLED("pos_menu_cursor(%p)"), (const void *)menu));
+
+ if (E_OK == err)
+ {
+ win = Get_Menu_UserWin(menu);
+ sub = menu->usersub ? menu->usersub : win;
+ assert(win && sub);
+
+ if ((menu->opt & O_SHOWMATCH) && (menu->pindex > 0))
+ x += (menu->pindex + menu->marklen - 1);
+
+ wmove(sub, y, x);
+
+ if (win != sub)
+ {
+ wcursyncup(sub);
+ wsyncup(sub);
+ untouchwin(sub);
+ }
+ }
+ RETURN(err);
+}
+
+/* m_cursor.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_driver.c b/apps/lib/curses/pdcurses/menu/m_driver.c
new file mode 100644
index 0000000..deeff47
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_driver.c
@@ -0,0 +1,556 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_driver *
+* Central dispatching routine *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_driver.c,v 1.29 2010/01/23 21:20:10 tom Exp $")
+
+/* Macros */
+
+/* Remove the last character from the match pattern buffer */
+#define Remove_Character_From_Pattern(menu) \
+ (menu)->pattern[--((menu)->pindex)] = '\0'
+
+/* Add a new character to the match pattern buffer */
+#define Add_Character_To_Pattern(menu,ch) \
+ { (menu)->pattern[((menu)->pindex)++] = (ch);\
+ (menu)->pattern[(menu)->pindex] = '\0'; }
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : static bool Is_Sub_String(
+| bool IgnoreCaseFlag,
+| const char *part,
+| const char *string)
+|
+| Description : Checks whether or not part is a substring of string.
+|
+| Return Values : TRUE - if it is a substring
+| FALSE - if it is not a substring
++--------------------------------------------------------------------------*/
+static bool
+Is_Sub_String(
+ bool IgnoreCaseFlag,
+ const char *part,
+ const char *string
+)
+{
+ assert(part && string);
+ if (IgnoreCaseFlag)
+ {
+ while (*string && *part)
+ {
+ if (toupper(UChar(*string++)) != toupper(UChar(*part)))
+ break;
+ part++;
+ }
+ }
+ else
+ {
+ while (*string && *part)
+ if (*part != *string++)
+ break;
+ part++;
+ }
+ return ((*part) ? FALSE : TRUE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int _nc_Match_Next_Character_In_Item_Name(
+| MENU *menu,
+| int ch,
+| ITEM **item)
+|
+| Description : This internal routine is called for a menu positioned
+| at an item with three different classes of characters:
+| - a printable character; the character is added to
+| the current pattern and the next item matching
+| this pattern is searched.
+| - NUL; the pattern stays as it is and the next item
+| matching the pattern is searched
+| - BS; the pattern stays as it is and the previous
+| item matching the pattern is searched
+|
+| The item parameter contains on call a pointer to
+| the item where the search starts. On return - if
+| a match was found - it contains a pointer to the
+| matching item.
+|
+| Return Values : E_OK - an item matching the pattern was found
+| E_NO_MATCH - nothing found
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Match_Next_Character_In_Item_Name
+(MENU * menu, int ch, ITEM ** item)
+{
+ bool found = FALSE, passed = FALSE;
+ int idx, last;
+
+ T((T_CALLED("_nc_Match_Next_Character(%p,%d,%p)"),
+ (void *)menu, ch, (void *)item));
+
+ assert(menu && item && *item);
+ idx = (*item)->index;
+
+ if (ch && ch != BS)
+ {
+ /* if we become to long, we need no further checking : there can't be
+ a match ! */
+ if ((menu->pindex + 1) > menu->namelen)
+ RETURN(E_NO_MATCH);
+
+ Add_Character_To_Pattern(menu, ch);
+ /* we artificially position one item back, because in the do...while
+ loop we start with the next item. This means, that with a new
+ pattern search we always start the scan with the actual item. If
+ we do a NEXT_PATTERN oder PREV_PATTERN search, we start with the
+ one after or before the actual item. */
+ if (--idx < 0)
+ idx = menu->nitems - 1;
+ }
+
+ last = idx; /* this closes the cycle */
+
+ do
+ {
+ if (ch == BS)
+ { /* we have to go backward */
+ if (--idx < 0)
+ idx = menu->nitems - 1;
+ }
+ else
+ { /* otherwise we always go forward */
+ if (++idx >= menu->nitems)
+ idx = 0;
+ }
+ if (Is_Sub_String((bool)((menu->opt & O_IGNORECASE) != 0),
+ menu->pattern,
+ menu->items[idx]->name.str)
+ )
+ found = TRUE;
+ else
+ passed = TRUE;
+ }
+ while (!found && (idx != last));
+
+ if (found)
+ {
+ if (!((idx == (*item)->index) && passed))
+ {
+ *item = menu->items[idx];
+ RETURN(E_OK);
+ }
+ /* This point is reached, if we fully cycled through the item list
+ and the only match we found is the starting item. With a NEXT_PATTERN
+ or PREV_PATTERN scan this means, that there was no additional match.
+ If we searched with an expanded new pattern, we should never reach
+ this point, because if the expanded pattern matches also the actual
+ item we will find it in the first attempt (passed==FALSE) and we
+ will never cycle through the whole item array.
+ */
+ assert(ch == 0 || ch == BS);
+ }
+ else
+ {
+ if (ch && ch != BS && menu->pindex > 0)
+ {
+ /* if we had no match with a new pattern, we have to restore it */
+ Remove_Character_From_Pattern(menu);
+ }
+ }
+ RETURN(E_NO_MATCH);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_driver(MENU* menu, int c)
+|
+| Description : Central dispatcher for the menu. Translates the logical
+| request 'c' into a menu action.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu pointer
+| E_BAD_STATE - menu is in user hook routine
+| E_NOT_POSTED - menu is not posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_driver(MENU * menu, int c)
+{
+#define NAVIGATE(dir) \
+ if (!item->dir)\
+ result = E_REQUEST_DENIED;\
+ else\
+ item = item->dir
+
+ int result = E_OK;
+ ITEM *item;
+ int my_top_row, rdiff;
+
+ T((T_CALLED("menu_driver(%p,%d)"), (void *)menu, c));
+
+ if (!menu)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+ if (!(menu->status & _POSTED))
+ RETURN(E_NOT_POSTED);
+
+ item = menu->curitem;
+
+ my_top_row = menu->toprow;
+ assert(item);
+
+ if ((c > KEY_MAX) && (c <= MAX_MENU_COMMAND))
+ {
+ if (!((c == REQ_BACK_PATTERN)
+ || (c == REQ_NEXT_MATCH) || (c == REQ_PREV_MATCH)))
+ {
+ assert(menu->pattern);
+ Reset_Pattern(menu);
+ }
+
+ switch (c)
+ {
+ case REQ_LEFT_ITEM:
+ /*=================*/
+ NAVIGATE(left);
+ break;
+
+ case REQ_RIGHT_ITEM:
+ /*==================*/
+ NAVIGATE(right);
+ break;
+
+ case REQ_UP_ITEM:
+ /*===============*/
+ NAVIGATE(up);
+ break;
+
+ case REQ_DOWN_ITEM:
+ /*=================*/
+ NAVIGATE(down);
+ break;
+
+ case REQ_SCR_ULINE:
+ /*=================*/
+ if (my_top_row == 0 || !(item->up))
+ result = E_REQUEST_DENIED;
+ else
+ {
+ --my_top_row;
+ item = item->up;
+ }
+ break;
+
+ case REQ_SCR_DLINE:
+ /*=================*/
+ if ((my_top_row + menu->arows >= menu->rows) || !(item->down))
+ {
+ /* only if the menu has less items than rows, we can deny the
+ request. Otherwise the epilogue of this routine adjusts the
+ top row if necessary */
+ result = E_REQUEST_DENIED;
+ }
+ else
+ {
+ my_top_row++;
+ item = item->down;
+ }
+ break;
+
+ case REQ_SCR_DPAGE:
+ /*=================*/
+ rdiff = menu->rows - (menu->arows + my_top_row);
+ if (rdiff > menu->arows)
+ rdiff = menu->arows;
+ if (rdiff <= 0)
+ result = E_REQUEST_DENIED;
+ else
+ {
+ my_top_row += rdiff;
+ while (rdiff-- > 0 && item != 0 && item->down != 0)
+ item = item->down;
+ }
+ break;
+
+ case REQ_SCR_UPAGE:
+ /*=================*/
+ rdiff = (menu->arows < my_top_row) ? menu->arows : my_top_row;
+ if (rdiff <= 0)
+ result = E_REQUEST_DENIED;
+ else
+ {
+ my_top_row -= rdiff;
+ while (rdiff-- > 0 && item != 0 && item->up != 0)
+ item = item->up;
+ }
+ break;
+
+ case REQ_FIRST_ITEM:
+ /*==================*/
+ item = menu->items[0];
+ break;
+
+ case REQ_LAST_ITEM:
+ /*=================*/
+ item = menu->items[menu->nitems - 1];
+ break;
+
+ case REQ_NEXT_ITEM:
+ /*=================*/
+ if ((item->index + 1) >= menu->nitems)
+ {
+ if (menu->opt & O_NONCYCLIC)
+ result = E_REQUEST_DENIED;
+ else
+ item = menu->items[0];
+ }
+ else
+ item = menu->items[item->index + 1];
+ break;
+
+ case REQ_PREV_ITEM:
+ /*=================*/
+ if (item->index <= 0)
+ {
+ if (menu->opt & O_NONCYCLIC)
+ result = E_REQUEST_DENIED;
+ else
+ item = menu->items[menu->nitems - 1];
+ }
+ else
+ item = menu->items[item->index - 1];
+ break;
+
+ case REQ_TOGGLE_ITEM:
+ /*===================*/
+ if (menu->opt & O_ONEVALUE)
+ {
+ result = E_REQUEST_DENIED;
+ }
+ else
+ {
+ if (menu->curitem->opt & O_SELECTABLE)
+ {
+ menu->curitem->value = !menu->curitem->value;
+ Move_And_Post_Item(menu, menu->curitem);
+ _nc_Show_Menu(menu);
+ }
+ else
+ result = E_NOT_SELECTABLE;
+ }
+ break;
+
+ case REQ_CLEAR_PATTERN:
+ /*=====================*/
+ /* already cleared in prologue */
+ break;
+
+ case REQ_BACK_PATTERN:
+ /*====================*/
+ if (menu->pindex > 0)
+ {
+ assert(menu->pattern);
+ Remove_Character_From_Pattern(menu);
+ pos_menu_cursor(menu);
+ }
+ else
+ result = E_REQUEST_DENIED;
+ break;
+
+ case REQ_NEXT_MATCH:
+ /*==================*/
+ assert(menu->pattern);
+ if (menu->pattern[0])
+ result = _nc_Match_Next_Character_In_Item_Name(menu, 0, &item);
+ else
+ {
+ if ((item->index + 1) < menu->nitems)
+ item = menu->items[item->index + 1];
+ else
+ {
+ if (menu->opt & O_NONCYCLIC)
+ result = E_REQUEST_DENIED;
+ else
+ item = menu->items[0];
+ }
+ }
+ break;
+
+ case REQ_PREV_MATCH:
+ /*==================*/
+ assert(menu->pattern);
+ if (menu->pattern[0])
+ result = _nc_Match_Next_Character_In_Item_Name(menu, BS, &item);
+ else
+ {
+ if (item->index)
+ item = menu->items[item->index - 1];
+ else
+ {
+ if (menu->opt & O_NONCYCLIC)
+ result = E_REQUEST_DENIED;
+ else
+ item = menu->items[menu->nitems - 1];
+ }
+ }
+ break;
+
+ default:
+ /*======*/
+ result = E_UNKNOWN_COMMAND;
+ break;
+ }
+ }
+ else
+ { /* not a command */
+ if (!(c & ~((int)MAX_REGULAR_CHARACTER)) && isprint(UChar(c)))
+ result = _nc_Match_Next_Character_In_Item_Name(menu, c, &item);
+#ifdef NCURSES_MOUSE_VERSION
+ else if (KEY_MOUSE == c)
+ {
+ MEVENT event;
+ WINDOW *uwin = Get_Menu_UserWin(menu);
+
+ getmouse(&event);
+ if ((event.bstate & (BUTTON1_CLICKED |
+ BUTTON1_DOUBLE_CLICKED |
+ BUTTON1_TRIPLE_CLICKED))
+ && wenclose(uwin, event.y, event.x))
+ { /* we react only if the click was in the userwin, that means
+ * inside the menu display area or at the decoration window.
+ */
+ WINDOW *sub = Get_Menu_Window(menu);
+ int ry = event.y, rx = event.x; /* screen coordinates */
+
+ result = E_REQUEST_DENIED;
+ if (mouse_trafo(&ry, &rx, FALSE))
+ { /* rx, ry are now "curses" coordinates */
+ if (ry < sub->_begy)
+ { /* we clicked above the display region; this is
+ * interpreted as "scroll up" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ result = menu_driver(menu, REQ_SCR_ULINE);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ result = menu_driver(menu, REQ_SCR_UPAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ result = menu_driver(menu, REQ_FIRST_ITEM);
+ RETURN(result);
+ }
+ else if (ry > sub->_begy + sub->_maxy)
+ { /* we clicked below the display region; this is
+ * interpreted as "scroll down" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ result = menu_driver(menu, REQ_SCR_DLINE);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ result = menu_driver(menu, REQ_SCR_DPAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ result = menu_driver(menu, REQ_LAST_ITEM);
+ RETURN(result);
+ }
+ else if (wenclose(sub, event.y, event.x))
+ { /* Inside the area we try to find the hit item */
+ int i, x, y, err;
+
+ ry = event.y;
+ rx = event.x;
+ if (wmouse_trafo(sub, &ry, &rx, FALSE))
+ {
+ for (i = 0; i < menu->nitems; i++)
+ {
+ err = _nc_menu_cursor_pos(menu, menu->items[i],
+ &y, &x);
+ if (E_OK == err)
+ {
+ if ((ry == y) &&
+ (rx >= x) &&
+ (rx < x + menu->itemlen))
+ {
+ item = menu->items[i];
+ result = E_OK;
+ break;
+ }
+ }
+ }
+ if (E_OK == result)
+ { /* We found an item, now we can handle the click.
+ * A single click just positions the menu cursor
+ * to the clicked item. A double click toggles
+ * the item.
+ */
+ if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ {
+ _nc_New_TopRow_and_CurrentItem(menu,
+ my_top_row,
+ item);
+ menu_driver(menu, REQ_TOGGLE_ITEM);
+ result = E_UNKNOWN_COMMAND;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ result = E_REQUEST_DENIED;
+ }
+#endif /* NCURSES_MOUSE_VERSION */
+ else
+ result = E_UNKNOWN_COMMAND;
+ }
+
+ if (E_OK == result)
+ {
+ /* Adjust the top row if it turns out that the current item unfortunately
+ doesn't appear in the menu window */
+ if (item->y < my_top_row)
+ my_top_row = item->y;
+ else if (item->y >= (my_top_row + menu->arows))
+ my_top_row = item->y - menu->arows + 1;
+
+ _nc_New_TopRow_and_CurrentItem(menu, my_top_row, item);
+
+ }
+
+ RETURN(result);
+}
+
+/* m_driver.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_format.c b/apps/lib/curses/pdcurses/menu/m_format.c
new file mode 100644
index 0000000..8e68a03
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_format.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_format *
+* Set and get maximum numbers of rows and columns in menus *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_format.c,v 1.16 2010/01/23 21:20:10 tom Exp $")
+
+#define minimum(a,b) ((a)<(b) ? (a): (b))
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_format(MENU *menu, int rows, int cols)
+|
+| Description : Sets the maximum number of rows and columns of items
+| that may be displayed at one time on a menu. If the
+| menu contains more items than can be displayed at
+| once, the menu will be scrollable.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid values passed
+| E_NOT_CONNECTED - there are no items connected
+| E_POSTED - the menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_format(MENU * menu, int rows, int cols)
+{
+ int total_rows, total_cols;
+
+ T((T_CALLED("set_menu_format(%p,%d,%d)"), (void *)menu, rows, cols));
+
+ if (rows < 0 || cols < 0)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu)
+ {
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (!(menu->items))
+ RETURN(E_NOT_CONNECTED);
+
+ if (rows == 0)
+ rows = menu->frows;
+ if (cols == 0)
+ cols = menu->fcols;
+
+ if (menu->pattern)
+ Reset_Pattern(menu);
+
+ menu->frows = rows;
+ menu->fcols = cols;
+
+ assert(rows > 0 && cols > 0);
+ total_rows = (menu->nitems - 1) / cols + 1;
+ total_cols = (menu->opt & O_ROWMAJOR) ?
+ minimum(menu->nitems, cols) :
+ (menu->nitems - 1) / total_rows + 1;
+
+ menu->rows = total_rows;
+ menu->cols = total_cols;
+ menu->arows = minimum(total_rows, rows);
+ menu->toprow = 0;
+ menu->curitem = *(menu->items);
+ assert(menu->curitem);
+ menu->status |= _LINK_NEEDED;
+ _nc_Calculate_Item_Length_and_Width(menu);
+ }
+ else
+ {
+ if (rows > 0)
+ _nc_Default_Menu.frows = rows;
+ if (cols > 0)
+ _nc_Default_Menu.fcols = cols;
+ }
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void menu_format(const MENU *menu, int *rows, int *cols)
+|
+| Description : Returns the maximum number of rows and columns that may
+| be displayed at one time on menu.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+menu_format(const MENU * menu, int *rows, int *cols)
+{
+ if (rows)
+ *rows = Normalize_Menu(menu)->frows;
+ if (cols)
+ *cols = Normalize_Menu(menu)->fcols;
+}
+
+/* m_format.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_global.c b/apps/lib/curses/pdcurses/menu/m_global.c
new file mode 100644
index 0000000..73227f3
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_global.c
@@ -0,0 +1,598 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_global *
+* Globally used internal routines and the default menu and item structures *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_global.c,v 1.25 2010/01/23 21:20:10 tom Exp $")
+
+static char mark[] = "-";
+/* *INDENT-OFF* */
+NCURSES_EXPORT_VAR(MENU) _nc_Default_Menu = {
+ 16, /* Nr. of chars high */
+ 1, /* Nr. of chars wide */
+ 16, /* Nr. of items high */
+ 1, /* Nr. of items wide */
+ 16, /* Nr. of formatted items high */
+ 1, /* Nr. of formatted items wide */
+ 16, /* Nr. of items high (actual) */
+ 0, /* length of widest name */
+ 0, /* length of widest description */
+ 1, /* length of mark */
+ 1, /* length of one item */
+ 1, /* Spacing for descriptor */
+ 1, /* Spacing for columns */
+ 1, /* Spacing for rows */
+ (char *)0, /* buffer used to store match chars */
+ 0, /* Index into pattern buffer */
+ (WINDOW *)0, /* Window containing entire menu */
+ (WINDOW *)0, /* Portion of menu displayed */
+ (WINDOW *)0, /* User's window */
+ (WINDOW *)0, /* User's subwindow */
+ (ITEM **)0, /* List of items */
+ 0, /* Total Nr. of items in menu */
+ (ITEM *)0, /* Current item */
+ 0, /* Top row of menu */
+ (chtype)A_REVERSE, /* Attribute for selection */
+ (chtype)A_NORMAL, /* Attribute for nonselection */
+ (chtype)A_UNDERLINE, /* Attribute for inactive */
+ ' ', /* Pad character */
+ (Menu_Hook)0, /* Menu init */
+ (Menu_Hook)0, /* Menu term */
+ (Menu_Hook)0, /* Item init */
+ (Menu_Hook)0, /* Item term */
+ (void *)0, /* userptr */
+ mark, /* mark */
+ ALL_MENU_OPTS, /* options */
+ 0 /* status */
+};
+
+NCURSES_EXPORT_VAR(ITEM) _nc_Default_Item = {
+ { (char *)0, 0 }, /* name */
+ { (char *)0, 0 }, /* description */
+ (MENU *)0, /* Pointer to parent menu */
+ (char *)0, /* Userpointer */
+ ALL_ITEM_OPTS, /* options */
+ 0, /* Item Nr. */
+ 0, /* y */
+ 0, /* x */
+ FALSE, /* value */
+ (ITEM *)0, /* left */
+ (ITEM *)0, /* right */
+ (ITEM *)0, /* up */
+ (ITEM *)0 /* down */
+ };
+/* *INDENT-ON* */
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : static void ComputeMaximum_NameDesc_Lenths(MENU *menu)
+|
+| Description : Calculates the maximum name and description lengths
+| of the items connected to the menu
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static void
+ComputeMaximum_NameDesc_Lengths(MENU * menu)
+{
+ unsigned MaximumNameLength = 0;
+ unsigned MaximumDescriptionLength = 0;
+ ITEM **items;
+ unsigned check;
+
+ assert(menu && menu->items);
+ for (items = menu->items; *items; items++)
+ {
+ check = _nc_Calculate_Text_Width(&((*items)->name));
+ if (check > MaximumNameLength)
+ MaximumNameLength = check;
+
+ check = _nc_Calculate_Text_Width(&((*items)->description));
+ if (check > MaximumDescriptionLength)
+ MaximumDescriptionLength = check;
+ }
+
+ menu->namelen = MaximumNameLength;
+ menu->desclen = MaximumDescriptionLength;
+ T(("ComputeMaximum_NameDesc_Lengths %d,%d", menu->namelen, menu->desclen));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : static void ResetConnectionInfo(MENU *, ITEM **)
+|
+| Description : Reset all informations in the menu and the items in
+| the item array that indicates a connection
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static void
+ResetConnectionInfo(MENU * menu, ITEM ** items)
+{
+ ITEM **item;
+
+ assert(menu && items);
+ for (item = items; *item; item++)
+ {
+ (*item)->index = 0;
+ (*item)->imenu = (MENU *) 0;
+ }
+ if (menu->pattern)
+ free(menu->pattern);
+ menu->pattern = (char *)0;
+ menu->pindex = 0;
+ menu->items = (ITEM **) 0;
+ menu->nitems = 0;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : bool _nc_Connect_Items(MENU *menu, ITEM **items)
+|
+| Description : Connect the items in the item array to the menu.
+| Decorate all the items with a number and a backward
+| pointer to the menu.
+|
+| Return Values : TRUE - successful connection
+| FALSE - connection failed
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+_nc_Connect_Items(MENU * menu, ITEM ** items)
+{
+ ITEM **item;
+ unsigned int ItemCount = 0;
+
+ if (menu && items)
+ {
+ for (item = items; *item; item++)
+ {
+ if ((*item)->imenu)
+ {
+ /* if a item is already connected, reject connection */
+ break;
+ }
+ }
+ if (!(*item))
+ /* we reached the end, so there was no connected item */
+ {
+ for (item = items; *item; item++)
+ {
+ if (menu->opt & O_ONEVALUE)
+ {
+ (*item)->value = FALSE;
+ }
+ (*item)->index = ItemCount++;
+ (*item)->imenu = menu;
+ }
+ }
+ }
+ else
+ return (FALSE);
+
+ if (ItemCount != 0)
+ {
+ menu->items = items;
+ menu->nitems = ItemCount;
+ ComputeMaximum_NameDesc_Lengths(menu);
+ if ((menu->pattern = typeMalloc(char, (unsigned)(1 + menu->namelen))))
+ {
+ Reset_Pattern(menu);
+ set_menu_format(menu, menu->frows, menu->fcols);
+ menu->curitem = *items;
+ menu->toprow = 0;
+ return (TRUE);
+ }
+ }
+
+ /* If we fall through to this point, we have to reset all items connection
+ and inform about a reject connection */
+ ResetConnectionInfo(menu, items);
+ return (FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Disconnect_Items(MENU *menu)
+|
+| Description : Disconnect the menus item array from the menu
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Disconnect_Items(MENU * menu)
+{
+ if (menu && menu->items)
+ ResetConnectionInfo(menu, menu->items);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int _nc_Calculate_Text_Width(const TEXT * item)
+|
+| Description : Calculate the number of columns for a TEXT.
+|
+| Return Values : the width
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Calculate_Text_Width(const TEXT * item /*FIXME: limit length */ )
+{
+#if USE_WIDEC_SUPPORT
+ int result = item->length;
+
+ T((T_CALLED("_nc_menu_text_width(%p)"), (const void *)item));
+ if (result != 0 && item->str != 0)
+ {
+ int count = mbstowcs(0, item->str, 0);
+ wchar_t *temp = 0;
+
+ if (count > 0
+ && (temp = typeMalloc(wchar_t, 2 + count)) != 0)
+ {
+ int n;
+
+ result = 0;
+ mbstowcs(temp, item->str, (unsigned)count);
+ for (n = 0; n < count; ++n)
+ {
+ int test = wcwidth(temp[n]);
+
+ if (test <= 0)
+ test = 1;
+ result += test;
+ }
+ free(temp);
+ }
+ }
+ returnCode(result);
+#else
+ return item->length;
+#endif
+}
+
+/*
+ * Calculate the actual width of a menu entry for wide-characters.
+ */
+#if USE_WIDEC_SUPPORT
+static int
+calculate_actual_width(MENU * menu, bool name)
+{
+ int width = 0;
+ int check = 0;
+ ITEM **items;
+
+ assert(menu && menu->items);
+
+ if (menu->items != 0)
+ {
+ for (items = menu->items; *items; items++)
+ {
+ if (name)
+ {
+ check = _nc_Calculate_Text_Width(&((*items)->name));
+ }
+ else
+ {
+ check = _nc_Calculate_Text_Width(&((*items)->description));
+ }
+ if (check > width)
+ width = check;
+ }
+ }
+ else
+ {
+ width = (name ? menu->namelen : menu->desclen);
+ }
+
+ T(("calculate_actual_width %s = %d/%d",
+ name ? "name" : "desc",
+ width,
+ name ? menu->namelen : menu->desclen));
+ return width;
+}
+#else
+#define calculate_actual_width(menu, name) (name ? menu->namelen : menu->desclen)
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Calculate_Item_Length_and_Width(MENU *menu)
+|
+| Description : Calculate the length of an item and the width of the
+| whole menu.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Calculate_Item_Length_and_Width(MENU * menu)
+{
+ int l;
+
+ assert(menu);
+
+ menu->height = 1 + menu->spc_rows * (menu->arows - 1);
+
+ l = calculate_actual_width(menu, TRUE);
+ l += menu->marklen;
+
+ if ((menu->opt & O_SHOWDESC) && (menu->desclen > 0))
+ {
+ l += calculate_actual_width(menu, FALSE);
+ l += menu->spc_desc;
+ }
+
+ menu->itemlen = l;
+ l *= menu->cols;
+ l += (menu->cols - 1) * menu->spc_cols; /* for the padding between the columns */
+ menu->width = l;
+
+ T(("_nc_CalculateItem_Length_and_Width columns %d, item %d, width %d",
+ menu->cols,
+ menu->itemlen,
+ menu->width));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Link_Item(MENU *menu)
+|
+| Description : Statically calculate for every item its four neighbors.
+| This depends on the orientation of the menu. This
+| static approach simplifies navigation in the menu a lot.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Link_Items(MENU * menu)
+{
+ if (menu && menu->items && *(menu->items))
+ {
+ int i, j;
+ ITEM *item;
+ int Number_Of_Items = menu->nitems;
+ int col = 0, row = 0;
+ int Last_in_Row;
+ int Last_in_Column;
+ bool cycle = (menu->opt & O_NONCYCLIC) ? FALSE : TRUE;
+
+ menu->status &= ~_LINK_NEEDED;
+
+ if (menu->opt & O_ROWMAJOR)
+ {
+ int Number_Of_Columns = menu->cols;
+
+ for (i = 0; i < Number_Of_Items; i++)
+ {
+ item = menu->items[i];
+
+ Last_in_Row = row * Number_Of_Columns + (Number_Of_Columns - 1);
+
+ item->left = (col) ?
+ /* if we are not in the leftmost column, we can use the
+ predecessor in the items array */
+ menu->items[i - 1] :
+ (cycle ? menu->items[(Last_in_Row >= Number_Of_Items) ?
+ Number_Of_Items - 1 :
+ Last_in_Row] :
+ (ITEM *) 0);
+
+ item->right = ((col < (Number_Of_Columns - 1)) &&
+ ((i + 1) < Number_Of_Items)
+ )?
+ menu->items[i + 1] :
+ (cycle ? menu->items[row * Number_Of_Columns] :
+ (ITEM *) 0
+ );
+
+ Last_in_Column = (menu->rows - 1) * Number_Of_Columns + col;
+
+ item->up = (row) ? menu->items[i - Number_Of_Columns] :
+ (cycle ? menu->items[(Last_in_Column >= Number_Of_Items) ?
+ Number_Of_Items - 1 :
+ Last_in_Column] :
+ (ITEM *) 0);
+
+ item->down = ((i + Number_Of_Columns) < Number_Of_Items)
+ ?
+ menu->items[i + Number_Of_Columns] :
+ (cycle ? menu->items[(row + 1) < menu->rows ?
+ Number_Of_Items - 1 : col] :
+ (ITEM *) 0);
+ item->x = col;
+ item->y = row;
+ if (++col == Number_Of_Columns)
+ {
+ row++;
+ col = 0;
+ }
+ }
+ }
+ else
+ {
+ int Number_Of_Rows = menu->rows;
+
+ for (j = 0; j < Number_Of_Items; j++)
+ {
+ item = menu->items[i = (col * Number_Of_Rows + row)];
+
+ Last_in_Column = (menu->cols - 1) * Number_Of_Rows + row;
+
+ item->left = (col) ?
+ menu->items[i - Number_Of_Rows] :
+ (cycle ? (Last_in_Column >= Number_Of_Items) ?
+ menu->items[Last_in_Column - Number_Of_Rows] :
+ menu->items[Last_in_Column] :
+ (ITEM *) 0);
+
+ item->right = ((i + Number_Of_Rows) < Number_Of_Items)
+ ?
+ menu->items[i + Number_Of_Rows] :
+ (cycle ? menu->items[row] : (ITEM *) 0);
+
+ Last_in_Row = col * Number_Of_Rows + (Number_Of_Rows - 1);
+
+ item->up = (row) ?
+ menu->items[i - 1] :
+ (cycle ?
+ menu->items[(Last_in_Row >= Number_Of_Items) ?
+ Number_Of_Items - 1 :
+ Last_in_Row] :
+ (ITEM *) 0);
+
+ item->down = (row < (Number_Of_Rows - 1))
+ ?
+ (menu->items[((i + 1) < Number_Of_Items) ?
+ i + 1 :
+ (col - 1) * Number_Of_Rows + row + 1]) :
+ (cycle ?
+ menu->items[col * Number_Of_Rows] :
+ (ITEM *) 0
+ );
+
+ item->x = col;
+ item->y = row;
+ if ((++row) == Number_Of_Rows)
+ {
+ col++;
+ row = 0;
+ }
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Show_Menu(const MENU* menu)
+|
+| Description : Update the window that is associated with the menu
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Show_Menu(const MENU * menu)
+{
+ WINDOW *win;
+ int maxy, maxx;
+
+ assert(menu);
+ if ((menu->status & _POSTED) && !(menu->status & _IN_DRIVER))
+ {
+ /* adjust the internal subwindow to start on the current top */
+ assert(menu->sub);
+ mvderwin(menu->sub, menu->spc_rows * menu->toprow, 0);
+ win = Get_Menu_Window(menu);
+
+ maxy = getmaxy(win);
+ maxx = getmaxx(win);
+
+ if (menu->height < maxy)
+ maxy = menu->height;
+ if (menu->width < maxx)
+ maxx = menu->width;
+
+ copywin(menu->sub, win, 0, 0, 0, 0, maxy - 1, maxx - 1, 0);
+ pos_menu_cursor(menu);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_New_TopRow_and_CurrentItem(
+| MENU *menu,
+| int new_toprow,
+| ITEM *new_current_item)
+|
+| Description : Redisplay the menu so that the given row becomes the
+| top row and the given item becomes the new current
+| item.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_New_TopRow_and_CurrentItem(
+ MENU * menu,
+ int new_toprow,
+ ITEM * new_current_item)
+{
+ ITEM *cur_item;
+ bool mterm_called = FALSE;
+ bool iterm_called = FALSE;
+
+ assert(menu);
+ if (menu->status & _POSTED)
+ {
+ if (new_current_item != menu->curitem)
+ {
+ Call_Hook(menu, itemterm);
+ iterm_called = TRUE;
+ }
+ if (new_toprow != menu->toprow)
+ {
+ Call_Hook(menu, menuterm);
+ mterm_called = TRUE;
+ }
+
+ cur_item = menu->curitem;
+ assert(cur_item);
+ menu->toprow = new_toprow;
+ menu->curitem = new_current_item;
+
+ if (mterm_called)
+ {
+ Call_Hook(menu, menuinit);
+ }
+ if (iterm_called)
+ {
+ /* this means, move from the old current_item to the new one... */
+ Move_To_Current_Item(menu, cur_item);
+ Call_Hook(menu, iteminit);
+ }
+ if (mterm_called || iterm_called)
+ {
+ _nc_Show_Menu(menu);
+ }
+ else
+ pos_menu_cursor(menu);
+ }
+ else
+ { /* if we are not posted, this is quite simple */
+ menu->toprow = new_toprow;
+ menu->curitem = new_current_item;
+ }
+}
+
+/* m_global.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_hook.c b/apps/lib/curses/pdcurses/menu/m_hook.c
new file mode 100644
index 0000000..df78d0a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_hook.c
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_hook *
+* Assign application specific routines for automatic invocation by menus *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_hook.c,v 1.15 2010/01/23 21:16:54 tom Exp $")
+
+/* "Template" macro to generate function to set application specific hook */
+#define GEN_HOOK_SET_FUNCTION( typ, name ) \
+NCURSES_IMPEXP int NCURSES_API set_ ## typ ## _ ## name (MENU *menu, Menu_Hook func )\
+{\
+ T((T_CALLED("set_" #typ "_" #name "(%p,%p)"), menu, func));\
+ (Normalize_Menu(menu) -> typ ## name = func );\
+ RETURN(E_OK);\
+}
+
+/* "Template" macro to generate function to get application specific hook */
+#define GEN_HOOK_GET_FUNCTION( typ, name ) \
+NCURSES_IMPEXP Menu_Hook NCURSES_API typ ## _ ## name ( const MENU *menu )\
+{\
+ T((T_CALLED(#typ "_" #name "(%p)"), (const void *) menu));\
+ returnMenuHook(Normalize_Menu(menu) -> typ ## name);\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_init(MENU *menu, void (*f)(MENU *))
+|
+| Description : Set user-exit which is called when menu is posted
+| or just after the top row changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(menu, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void (*)(MENU *) menu_init(const MENU *menu)
+|
+| Description : Return address of user-exit function which is called
+| when a menu is posted or just after the top row
+| changes.
+|
+| Return Values : Menu init function address or NULL
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(menu, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_term (MENU *menu, void (*f)(MENU *))
+|
+| Description : Set user-exit which is called when menu is unposted
+| or just before the top row changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(menu, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void (*)(MENU *) menu_term(const MENU *menu)
+|
+| Description : Return address of user-exit function which is called
+| when a menu is unposted or just before the top row
+| changes.
+|
+| Return Values : Menu finalization function address or NULL
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(menu, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_item_init (MENU *menu, void (*f)(MENU *))
+|
+| Description : Set user-exit which is called when menu is posted
+| or just after the current item changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(item, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void (*)(MENU *) item_init (const MENU *menu)
+|
+| Description : Return address of user-exit function which is called
+| when a menu is posted or just after the current item
+| changes.
+|
+| Return Values : Item init function address or NULL
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(item, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_item_term (MENU *menu, void (*f)(MENU *))
+|
+| Description : Set user-exit which is called when menu is unposted
+| or just before the current item changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(item, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void (*)(MENU *) item_init (const MENU *menu)
+|
+| Description : Return address of user-exit function which is called
+| when a menu is unposted or just before the current item
+| changes.
+|
+| Return Values : Item finalization function address or NULL
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(item, term)
+
+/* m_hook.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_cur.c b/apps/lib/curses/pdcurses/menu/m_item_cur.c
new file mode 100644
index 0000000..189e61b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_cur.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_cur *
+* Set and get current menus item *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_cur.c,v 1.18 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_current_item(MENU *menu, const ITEM *item)
+|
+| Description : Make the item the current item
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_current_item(MENU * menu, ITEM * item)
+{
+ T((T_CALLED("set_current_item(%p,%p)"), (void *)menu, (void *)item));
+
+ if (menu && item && (item->imenu == menu))
+ {
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ assert(menu->curitem);
+ if (item != menu->curitem)
+ {
+ if (menu->status & _LINK_NEEDED)
+ {
+ /*
+ * Items are available, but they are not linked together.
+ * So we have to link here.
+ */
+ _nc_Link_Items(menu);
+ }
+ assert(menu->pattern);
+ Reset_Pattern(menu);
+ /* adjust the window to make item visible and update the menu */
+ Adjust_Current_Item(menu, menu->toprow, item);
+ }
+ }
+ else
+ RETURN(E_BAD_ARGUMENT);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : ITEM *current_item(const MENU *menu)
+|
+| Description : Return the menus current item
+|
+| Return Values : Item pointer or NULL if failure
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(ITEM *)
+current_item(const MENU * menu)
+{
+ T((T_CALLED("current_item(%p)"), (const void *)menu));
+ returnItem((menu && menu->items) ? menu->curitem : (ITEM *) 0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int item_index(const ITEM *)
+|
+| Description : Return the logical index of this item.
+|
+| Return Values : The index or ERR if this is an invalid item pointer
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+item_index(const ITEM * item)
+{
+ T((T_CALLED("item_index(%p)"), (const void *)item));
+ returnCode((item && item->imenu) ? item->index : ERR);
+}
+
+/* m_item_cur.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_nam.c b/apps/lib/curses/pdcurses/menu/m_item_nam.c
new file mode 100644
index 0000000..eb6f58a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_nam.c
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_nam *
+* Get menus item name and description *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_nam.c,v 1.15 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : char *item_name(const ITEM *item)
+|
+| Description : Return name of menu item
+|
+| Return Values : See above; returns NULL if item is invalid
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(const char *)
+item_name(const ITEM * item)
+{
+ T((T_CALLED("item_name(%p)"), (const void *)item));
+ returnCPtr((item) ? item->name.str : (char *)0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : char *item_description(const ITEM *item)
+|
+| Description : Returns description of item
+|
+| Return Values : See above; Returns NULL if item is invalid
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(const char *)
+item_description(const ITEM * item)
+{
+ T((T_CALLED("item_description(%p)"), (const void *)item));
+ returnCPtr((item) ? item->description.str : (char *)0);
+}
+
+/* m_item_nam.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_new.c b/apps/lib/curses/pdcurses/menu/m_item_new.c
new file mode 100644
index 0000000..a10ec4b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_new.c
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_new *
+* Create and destroy menu items *
+* Set and get marker string for menu *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+#if USE_WIDEC_SUPPORT
+#if HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
+#endif
+
+MODULE_ID("$Id: m_item_new.c,v 1.30 2010/01/23 21:20:11 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : bool Is_Printable_String(const char *s)
+|
+| Description : Checks whether or not the string contains only printable
+| characters.
+|
+| Return Values : TRUE - if string is printable
+| FALSE - if string contains non-printable characters
++--------------------------------------------------------------------------*/
+static bool
+Is_Printable_String(const char *s)
+{
+ int result = TRUE;
+
+#if USE_WIDEC_SUPPORT
+ int count = mbstowcs(0, s, 0);
+ wchar_t *temp = 0;
+
+ assert(s);
+
+ if (count > 0
+ && (temp = typeCalloc(wchar_t, (2 + (unsigned)count))) != 0)
+ {
+ int n;
+
+ mbstowcs(temp, s, (unsigned)count);
+ for (n = 0; n < count; ++n)
+ if (!iswprint((wint_t) temp[n]))
+ {
+ result = FALSE;
+ break;
+ }
+ free(temp);
+ }
+#else
+ assert(s);
+ while (*s)
+ {
+ if (!isprint(UChar(*s)))
+ {
+ result = FALSE;
+ break;
+ }
+ s++;
+ }
+#endif
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : ITEM *new_item(char *name, char *description)
+|
+| Description : Create a new item with name and description. Return
+| a pointer to this new item.
+| N.B.: an item must(!) have a name.
+|
+| Return Values : The item pointer or NULL if creation failed.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(ITEM *)
+new_item(const char *name, const char *description)
+{
+ ITEM *item;
+
+ T((T_CALLED("new_item(\"%s\", \"%s\")"),
+ name ? name : "",
+ description ? description : ""));
+
+ if (!name || (*name == '\0') || !Is_Printable_String(name))
+ {
+ item = (ITEM *) 0;
+ SET_ERROR(E_BAD_ARGUMENT);
+ }
+ else
+ {
+ item = typeCalloc(ITEM, 1);
+ if (item)
+ {
+ *item = _nc_Default_Item; /* hope we have struct assignment */
+
+ item->name.length = strlen(name);
+ item->name.str = name;
+
+ if (description && (*description != '\0') &&
+ Is_Printable_String(description))
+ {
+ item->description.length = strlen(description);
+ item->description.str = description;
+ }
+ else
+ {
+ item->description.length = 0;
+ item->description.str = (char *)0;
+ }
+ }
+ else
+ SET_ERROR(E_SYSTEM_ERROR);
+ }
+ returnItem(item);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int free_item(ITEM *item)
+|
+| Description : Free the allocated storage for this item.
+| N.B.: a connected item can't be freed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid value has been passed
+| E_CONNECTED - item is still connected to a menu
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+free_item(ITEM * item)
+{
+ T((T_CALLED("free_item(%p)"), (void *)item));
+
+ if (!item)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (item->imenu)
+ RETURN(E_CONNECTED);
+
+ free(item);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_mark( MENU *menu, const char *mark )
+|
+| Description : Set the mark string used to indicate the current
+| item (single-valued menu) or the selected items
+| (multi-valued menu).
+| The mark argument may be NULL, in which case no
+| marker is used.
+| This might be a little bit tricky, because this may
+| affect the geometry of the menu, which we don't allow
+| if it is already posted.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - an invalid value has been passed
+| E_SYSTEM_ERROR - no memory to store mark
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_mark(MENU * menu, const char *mark)
+{
+ unsigned l;
+
+ T((T_CALLED("set_menu_mark(%p,%s)"), (void *)menu, _nc_visbuf(mark)));
+
+ if (mark && (*mark != '\0') && Is_Printable_String(mark))
+ l = strlen(mark);
+ else
+ l = 0;
+
+ if (menu)
+ {
+ char *old_mark = menu->mark;
+ unsigned short old_status = menu->status;
+
+ if (menu->status & _POSTED)
+ {
+ /* If the menu is already posted, the geometry is fixed. Then
+ we can only accept a mark with exactly the same length */
+ if (menu->marklen != (int)l)
+ RETURN(E_BAD_ARGUMENT);
+ }
+ menu->marklen = l;
+ if (l)
+ {
+ menu->mark = strdup(mark);
+ if (menu->mark)
+ {
+ strcpy(menu->mark, mark);
+ if (menu != &_nc_Default_Menu)
+ menu->status |= _MARK_ALLOCATED;
+ }
+ else
+ {
+ menu->mark = old_mark;
+ menu->marklen = (old_mark != 0) ? strlen(old_mark) : 0;
+ RETURN(E_SYSTEM_ERROR);
+ }
+ }
+ else
+ menu->mark = (char *)0;
+
+ if ((old_status & _MARK_ALLOCATED) && old_mark)
+ free(old_mark);
+
+ if (menu->status & _POSTED)
+ {
+ _nc_Draw_Menu(menu);
+ _nc_Show_Menu(menu);
+ }
+ else
+ {
+ /* Recalculate the geometry */
+ _nc_Calculate_Item_Length_and_Width(menu);
+ }
+ }
+ else
+ {
+ returnCode(set_menu_mark(&_nc_Default_Menu, mark));
+ }
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : char *menu_mark(const MENU *menu)
+|
+| Description : Return a pointer to the marker string
+|
+| Return Values : The marker string pointer or NULL if no marker defined
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(const char *)
+menu_mark(const MENU * menu)
+{
+ T((T_CALLED("menu_mark(%p)"), (const void *)menu));
+ returnPtr(Normalize_Menu(menu)->mark);
+}
+
+/* m_item_new.c */
--git a/apps/lib/curses/pdcurses/menu/m_item_opt.c b/apps/lib/curses/pdcurses/menu/m_item_opt.c
new file mode 100644
index 0000000..de5eb8d
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_opt.c
@@ -0,0 +1,159 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_opt *
+* Menus item option routines *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_opt.c,v 1.18 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_item_opts(ITEM *item, Item_Options opts)
+|
+| Description : Set the options of the item. If there are relevant
+| changes, the item is connected and the menu is posted,
+| the menu will be redisplayed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid item options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_item_opts(ITEM * item, Item_Options opts)
+{
+ T((T_CALLED("set_menu_opts(%p,%d)"), (void *)item, opts));
+
+ opts &= ALL_ITEM_OPTS;
+
+ if (opts & ~ALL_ITEM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (item)
+ {
+ if (item->opt != opts)
+ {
+ MENU *menu = item->imenu;
+
+ item->opt = opts;
+
+ if ((!(opts & O_SELECTABLE)) && item->value)
+ item->value = FALSE;
+
+ if (menu && (menu->status & _POSTED))
+ {
+ Move_And_Post_Item(menu, item);
+ _nc_Show_Menu(menu);
+ }
+ }
+ }
+ else
+ _nc_Default_Item.opt = opts;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int item_opts_off(ITEM *item, Item_Options opts)
+|
+| Description : Switch of the options for this item.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+item_opts_off(ITEM * item, Item_Options opts)
+{
+ ITEM *citem = item; /* use a copy because set_item_opts must detect
+
+ NULL item itself to adjust its behavior */
+
+ T((T_CALLED("item_opts_off(%p,%d)"), (void *)item, opts));
+
+ if (opts & ~ALL_ITEM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Item(citem);
+ opts = citem->opt & ~(opts & ALL_ITEM_OPTS);
+ returnCode(set_item_opts(item, opts));
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int item_opts_on(ITEM *item, Item_Options opts)
+|
+| Description : Switch on the options for this item.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+item_opts_on(ITEM * item, Item_Options opts)
+{
+ ITEM *citem = item; /* use a copy because set_item_opts must detect
+
+ NULL item itself to adjust its behavior */
+
+ T((T_CALLED("item_opts_on(%p,%d)"), (void *)item, opts));
+
+ opts &= ALL_ITEM_OPTS;
+ if (opts & ~ALL_ITEM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Item(citem);
+ opts = citem->opt | opts;
+ returnCode(set_item_opts(item, opts));
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : Item_Options item_opts(const ITEM *item)
+|
+| Description : Switch of the options for this item.
+|
+| Return Values : Items options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(Item_Options)
+item_opts(const ITEM * item)
+{
+ T((T_CALLED("item_opts(%p)"), (const void *)item));
+ returnItemOpts(ALL_ITEM_OPTS & Normalize_Item(item)->opt);
+}
+
+/* m_item_opt.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_top.c b/apps/lib/curses/pdcurses/menu/m_item_top.c
new file mode 100644
index 0000000..89f8316
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_top.c
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_top *
+* Set and get top menus item *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_top.c,v 1.11 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_top_row(MENU *menu, int row)
+|
+| Description : Makes the specified row the top row in the menu
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - not a menu pointer or invalid row
+| E_NOT_CONNECTED - there are no items for the menu
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_top_row(MENU * menu, int row)
+{
+ ITEM *item;
+
+ T((T_CALLED("set_top_row(%p,%d)"), (void *)menu, row));
+
+ if (menu)
+ {
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+ if (menu->items == (ITEM **) 0)
+ RETURN(E_NOT_CONNECTED);
+
+ if ((row < 0) || (row > (menu->rows - menu->arows)))
+ RETURN(E_BAD_ARGUMENT);
+ }
+ else
+ RETURN(E_BAD_ARGUMENT);
+
+ if (row != menu->toprow)
+ {
+ if (menu->status & _LINK_NEEDED)
+ _nc_Link_Items(menu);
+
+ item = menu->items[(menu->opt & O_ROWMAJOR) ? (row * menu->cols) : row];
+ assert(menu->pattern);
+ Reset_Pattern(menu);
+ _nc_New_TopRow_and_CurrentItem(menu, row, item);
+ }
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int top_row(const MENU *)
+|
+| Description : Return the top row of the menu
+|
+| Return Values : The row number or ERR if there is no row
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+top_row(const MENU * menu)
+{
+ T((T_CALLED("top_row(%p)"), (const void *)menu));
+ if (menu && menu->items && *(menu->items))
+ {
+ assert((menu->toprow >= 0) && (menu->toprow < menu->rows));
+ returnCode(menu->toprow);
+ }
+ else
+ returnCode(ERR);
+}
+
+/* m_item_top.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_use.c b/apps/lib/curses/pdcurses/menu/m_item_use.c
new file mode 100644
index 0000000..4a25a85
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_use.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_use *
+* Associate application data with menu items *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_use.c,v 1.17 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_item_userptr(ITEM *item, void *userptr)
+|
+| Description : Set the pointer that is reserved in any item to store
+| application relevant informations.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_item_userptr(ITEM * item, void *userptr)
+{
+ T((T_CALLED("set_item_userptr(%p,%p)"), (void *)item, (void *)userptr));
+ Normalize_Item(item)->userptr = userptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void *item_userptr(const ITEM *item)
+|
+| Description : Return the pointer that is reserved in any item to store
+| application relevant informations.
+|
+| Return Values : Value of the pointer. If no such pointer has been set,
+| NULL is returned.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void *)
+item_userptr(const ITEM * item)
+{
+ T((T_CALLED("item_userptr(%p)"), (const void *)item));
+ returnVoidPtr(Normalize_Item(item)->userptr);
+}
+
+/* m_item_use.c */
--git a/apps/lib/curses/pdcurses/menu/m_item_val.c b/apps/lib/curses/pdcurses/menu/m_item_val.c
new file mode 100644
index 0000000..c628338
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_val.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_val *
+* Set and get menus item values *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_val.c,v 1.15 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_item_value(ITEM *item, int value)
+|
+| Description : Programmatically set the item's selection value. This is
+| only allowed if the item is selectable at all and if
+| it is not connected to a single-valued menu.
+| If the item is connected to a posted menu, the menu
+| will be redisplayed.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - not selectable or single valued menu
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_item_value(ITEM * item, bool value)
+{
+ MENU *menu;
+
+ T((T_CALLED("set_item_value(%p,%d)"), (void *)item, value));
+ if (item)
+ {
+ menu = item->imenu;
+
+ if ((!(item->opt & O_SELECTABLE)) ||
+ (menu && (menu->opt & O_ONEVALUE)))
+ RETURN(E_REQUEST_DENIED);
+
+ if (item->value ^ value)
+ {
+ item->value = value ? TRUE : FALSE;
+ if (menu)
+ {
+ if (menu->status & _POSTED)
+ {
+ Move_And_Post_Item(menu, item);
+ _nc_Show_Menu(menu);
+ }
+ }
+ }
+ }
+ else
+ _nc_Default_Item.value = value;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : bool item_value(const ITEM *item)
+|
+| Description : Return the selection value of the item
+|
+| Return Values : TRUE - if item is selected
+| FALSE - if item is not selected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+item_value(const ITEM * item)
+{
+ T((T_CALLED("item_value(%p)"), (const void *)item));
+ returnBool((Normalize_Item(item)->value) ? TRUE : FALSE);
+}
+
+/* m_item_val.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_item_vis.c b/apps/lib/curses/pdcurses/menu/m_item_vis.c
new file mode 100644
index 0000000..312f0a0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_item_vis.c
@@ -0,0 +1,68 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_item_vis *
+* Tell if menu item is visible *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_item_vis.c,v 1.16 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : bool item_visible(const ITEM *item)
+|
+| Description : A item is visible if it currently appears in the
+| subwindow of a posted menu.
+|
+| Return Values : TRUE if visible
+| FALSE if invisible
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+item_visible(const ITEM * item)
+{
+ MENU *menu;
+
+ T((T_CALLED("item_visible(%p)"), (const void *)item));
+ if (item &&
+ (menu = item->imenu) &&
+ (menu->status & _POSTED) &&
+ ((menu->toprow + menu->arows) > (item->y)) &&
+ (item->y >= menu->toprow))
+ returnBool(TRUE);
+ else
+ returnBool(FALSE);
+}
+
+/* m_item_vis.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_items.c b/apps/lib/curses/pdcurses/menu/m_items.c
new file mode 100644
index 0000000..e1755f1
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_items.c
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_items *
+* Connect and disconnect items to and from menus *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_items.c,v 1.17 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_items(MENU *menu, ITEM **items)
+|
+| Description : Sets the item pointer array connected to menu.
+|
+| Return Values : E_OK - success
+| E_POSTED - menu is already posted
+| E_CONNECTED - one or more items are already connected
+| to another menu.
+| E_BAD_ARGUMENT - An incorrect menu or item array was
+| passed to the function
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_items(MENU * menu, ITEM ** items)
+{
+ T((T_CALLED("set_menu_items(%p,%p)"), (void *)menu, (void *)items));
+
+ if (!menu || (items && !(*items)))
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (menu->items)
+ _nc_Disconnect_Items(menu);
+
+ if (items)
+ {
+ if (!_nc_Connect_Items(menu, items))
+ RETURN(E_CONNECTED);
+ }
+
+ menu->items = items;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : ITEM **menu_items(const MENU *menu)
+|
+| Description : Returns a pointer to the item pointer array of the menu
+|
+| Return Values : NULL on error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(ITEM **)
+menu_items(const MENU * menu)
+{
+ T((T_CALLED("menu_items(%p)"), (const void *)menu));
+ returnItemPtr(menu ? menu->items : (ITEM **) 0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int item_count(const MENU *menu)
+|
+| Description : Get the number of items connected to the menu. If the
+| menu pointer is NULL we return -1.
+|
+| Return Values : Number of items or -1 to indicate error.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+item_count(const MENU * menu)
+{
+ T((T_CALLED("item_count(%p)"), (const void *)menu));
+ returnCode(menu ? menu->nitems : -1);
+}
+
+/* m_items.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_new.c b/apps/lib/curses/pdcurses/menu/m_new.c
new file mode 100644
index 0000000..2f9fe55
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_new.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_new *
+* Creation and destruction of new menus *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_new.c,v 1.21 2010/01/23 21:20:11 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : MENU* _nc_new_menu(SCREEN*, ITEM **items)
+|
+| Description : Creates a new menu connected to the item pointer
+| array items and returns a pointer to the new menu.
+| The new menu is initialized with the values from the
+| default menu.
+|
+| Return Values : NULL on error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(MENU *)
+NCURSES_SP_NAME(new_menu) (NCURSES_SP_DCLx ITEM ** items)
+{
+ int err = E_SYSTEM_ERROR;
+ MENU *menu = typeCalloc(MENU, 1);
+
+ T((T_CALLED("new_menu(%p,%p)"), (void *)SP_PARM, (void *)items));
+ if (menu)
+ {
+ *menu = _nc_Default_Menu;
+ menu->status = 0;
+ menu->rows = menu->frows;
+ menu->cols = menu->fcols;
+#if NCURSES_SP_FUNCS
+ /* This ensures userwin and usersub are always non-null,
+ so we can derive always the SCREEN that this menu is
+ running on. */
+ menu->userwin = SP_PARM->_stdscr;
+ menu->usersub = SP_PARM->_stdscr;
+#endif
+ if (items && *items)
+ {
+ if (!_nc_Connect_Items(menu, items))
+ {
+ err = E_NOT_CONNECTED;
+ free(menu);
+ menu = (MENU *) 0;
+ }
+ else
+ err = E_OK;
+ }
+ }
+
+ if (!menu)
+ SET_ERROR(err);
+
+ returnMenu(menu);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : MENU *new_menu(ITEM **items)
+|
+| Description : Creates a new menu connected to the item pointer
+| array items and returns a pointer to the new menu.
+| The new menu is initialized with the values from the
+| default menu.
+|
+| Return Values : NULL on error
++--------------------------------------------------------------------------*/
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(MENU *)
+new_menu(ITEM ** items)
+{
+ return NCURSES_SP_NAME(new_menu) (CURRENT_SCREEN, items);
+}
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int free_menu(MENU *menu)
+|
+| Description : Disconnects menu from its associated item pointer
+| array and frees the storage allocated for the menu.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - Invalid menu pointer passed
+| E_POSTED - Menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+free_menu(MENU * menu)
+{
+ T((T_CALLED("free_menu(%p)"), (void *)menu));
+ if (!menu)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (menu->items)
+ _nc_Disconnect_Items(menu);
+
+ if ((menu->status & _MARK_ALLOCATED) && menu->mark)
+ free(menu->mark);
+
+ free(menu);
+ RETURN(E_OK);
+}
+
+/* m_new.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_opts.c b/apps/lib/curses/pdcurses/menu/m_opts.c
new file mode 100644
index 0000000..bc6924b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_opts.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_opts *
+* Menus option routines *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_opts.c,v 1.20 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_opts(MENU *menu, Menu_Options opts)
+|
+| Description : Set the options for this menu. If the new settings
+| end up in a change of the geometry of the menu, it
+| will be recalculated. This operation is forbidden if
+| the menu is already posted.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu options
+| E_POSTED - menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_opts(MENU * menu, Menu_Options opts)
+{
+ T((T_CALLED("set_menu_opts(%p,%d)"), (void *)menu, opts));
+
+ opts &= ALL_MENU_OPTS;
+
+ if (opts & ~ALL_MENU_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu)
+ {
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if ((opts & O_ROWMAJOR) != (menu->opt & O_ROWMAJOR))
+ {
+ /* we need this only if the layout really changed ... */
+ if (menu->items && menu->items[0])
+ {
+ menu->toprow = 0;
+ menu->curitem = menu->items[0];
+ assert(menu->curitem);
+ set_menu_format(menu, menu->frows, menu->fcols);
+ }
+ }
+
+ menu->opt = opts;
+
+ if (opts & O_ONEVALUE)
+ {
+ ITEM **item;
+
+ if (((item = menu->items) != (ITEM **) 0))
+ for (; *item; item++)
+ (*item)->value = FALSE;
+ }
+
+ if (opts & O_SHOWDESC) /* this also changes the geometry */
+ _nc_Calculate_Item_Length_and_Width(menu);
+ }
+ else
+ _nc_Default_Menu.opt = opts;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_opts_off(MENU *menu, Menu_Options opts)
+|
+| Description : Switch off the options for this menu. If the new settings
+| end up in a change of the geometry of the menu, it
+| will be recalculated. This operation is forbidden if
+| the menu is already posted.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
+| E_POSTED - menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_opts_off(MENU * menu, Menu_Options opts)
+{
+ MENU *cmenu = menu; /* use a copy because set_menu_opts must detect
+
+ NULL menu itself to adjust its behavior */
+
+ T((T_CALLED("menu_opts_off(%p,%d)"), (void *)menu, opts));
+
+ opts &= ALL_MENU_OPTS;
+ if (opts & ~ALL_MENU_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Menu(cmenu);
+ opts = cmenu->opt & ~opts;
+ returnCode(set_menu_opts(menu, opts));
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_opts_on(MENU *menu, Menu_Options opts)
+|
+| Description : Switch on the options for this menu. If the new settings
+| end up in a change of the geometry of the menu, it
+| will be recalculated. This operation is forbidden if
+| the menu is already posted.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu options
+| E_POSTED - menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_opts_on(MENU * menu, Menu_Options opts)
+{
+ MENU *cmenu = menu; /* use a copy because set_menu_opts must detect
+
+ NULL menu itself to adjust its behavior */
+
+ T((T_CALLED("menu_opts_on(%p,%d)"), (void *)menu, opts));
+
+ opts &= ALL_MENU_OPTS;
+ if (opts & ~ALL_MENU_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Menu(cmenu);
+ opts = cmenu->opt | opts;
+ returnCode(set_menu_opts(menu, opts));
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : Menu_Options menu_opts(const MENU *menu)
+|
+| Description : Return the options for this menu.
+|
+| Return Values : Menu options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(Menu_Options)
+menu_opts(const MENU * menu)
+{
+ T((T_CALLED("menu_opts(%p)"), (const void *)menu));
+ returnMenuOpts(ALL_MENU_OPTS & Normalize_Menu(menu)->opt);
+}
+
+/* m_opts.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_pad.c b/apps/lib/curses/pdcurses/menu/m_pad.c
new file mode 100644
index 0000000..379ce7c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_pad.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_pad *
+* Control menus padding character *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_pad.c,v 1.12 2010/01/23 21:20:10 tom Exp $")
+
+/* Macro to redraw menu if it is posted and changed */
+#define Refresh_Menu(menu) \
+ if ( (menu) && ((menu)->status & _POSTED) )\
+ {\
+ _nc_Draw_Menu( menu );\
+ _nc_Show_Menu( menu ); \
+ }
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_pad(MENU* menu, int pad)
+|
+| Description : Set the character to be used to separate the item name
+| from its description. This must be a printable
+| character.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - an invalid value has been passed
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_pad(MENU * menu, int pad)
+{
+ bool do_refresh = (menu != (MENU *) 0);
+
+ T((T_CALLED("set_menu_pad(%p,%d)"), (void *)menu, pad));
+
+ if (!isprint(UChar(pad)))
+ RETURN(E_BAD_ARGUMENT);
+
+ Normalize_Menu(menu);
+ menu->pad = pad;
+
+ if (do_refresh)
+ Refresh_Menu(menu);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_pad(const MENU *menu)
+|
+| Description : Return the value of the padding character
+|
+| Return Values : The pad character
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_pad(const MENU * menu)
+{
+ T((T_CALLED("menu_pad(%p)"), (const void *)menu));
+ returnCode(Normalize_Menu(menu)->pad);
+}
+
+/* m_pad.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_pattern.c b/apps/lib/curses/pdcurses/menu/m_pattern.c
new file mode 100644
index 0000000..ebede0a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_pattern.c
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_pattern *
+* Pattern matching handling *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_pattern.c,v 1.16 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : char *menu_pattern(const MENU *menu)
+|
+| Description : Return the value of the pattern buffer.
+|
+| Return Values : NULL - if there is no pattern buffer allocated
+| EmptyString - if there is a pattern buffer but no
+| pattern is stored
+| PatternString - as expected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(char *)
+menu_pattern(const MENU * menu)
+{
+ static char empty[] = "";
+
+ T((T_CALLED("menu_pattern(%p)"), (const void *)menu));
+ returnPtr(menu ? (menu->pattern ? menu->pattern : empty) : 0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_pattern(MENU *menu, const char *p)
+|
+| Description : Set the match pattern for a menu and position to the
+| first item that matches.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu or pattern pointer
+| E_BAD_STATE - menu in user hook routine
+| E_NOT_CONNECTED - no items connected to menu
+| E_NO_MATCH - no item matches pattern
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_pattern(MENU * menu, const char *p)
+{
+ ITEM *matchitem;
+ int matchpos;
+
+ T((T_CALLED("set_menu_pattern(%p,%s)"), (void *)menu, _nc_visbuf(p)));
+
+ if (!menu || !p)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(menu->items))
+ RETURN(E_NOT_CONNECTED);
+
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ Reset_Pattern(menu);
+
+ if (!(*p))
+ {
+ pos_menu_cursor(menu);
+ RETURN(E_OK);
+ }
+
+ if (menu->status & _LINK_NEEDED)
+ _nc_Link_Items(menu);
+
+ matchpos = menu->toprow;
+ matchitem = menu->curitem;
+ assert(matchitem);
+
+ while (*p)
+ {
+ if (!isprint(UChar(*p)) ||
+ (_nc_Match_Next_Character_In_Item_Name(menu, *p, &matchitem) != E_OK))
+ {
+ Reset_Pattern(menu);
+ pos_menu_cursor(menu);
+ RETURN(E_NO_MATCH);
+ }
+ p++;
+ }
+
+ /* This is reached if there was a match. So we position to the new item */
+ Adjust_Current_Item(menu, matchpos, matchitem);
+ RETURN(E_OK);
+}
+
+/* m_pattern.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_post.c b/apps/lib/curses/pdcurses/menu/m_post.c
new file mode 100644
index 0000000..007476b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_post.c
@@ -0,0 +1,377 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_post *
+* Write or erase menus from associated subwindows *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_post.c,v 1.29 2010/05/01 19:18:27 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Post_Item(MENU *menu, ITEM *item)
+|
+| Description : Draw the item in the menus window at the current
+| window position
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Post_Item(const MENU * menu, const ITEM * item)
+{
+ int i;
+ chtype ch;
+ int item_x, item_y;
+ int count = 0;
+ bool isfore = FALSE, isback = FALSE, isgrey = FALSE;
+ int name_len;
+ int desc_len;
+
+ assert(menu->win);
+
+ getyx(menu->win, item_y, item_x);
+
+ /* We need a marker iff
+ - it is a onevalued menu and it is the current item
+ - or it has a selection value
+ */
+ wattron(menu->win, menu->back);
+ if (item->value || (item == menu->curitem))
+ {
+ if (menu->marklen)
+ {
+ /* In a multi selection menu we use the fore attribute
+ for a selected marker that is not the current one.
+ This improves visualization of the menu, because now
+ always the 'normal' marker denotes the current
+ item. */
+ if (!(menu->opt & O_ONEVALUE) && item->value && item != menu->curitem)
+ {
+ wattron(menu->win, menu->fore);
+ isfore = TRUE;
+ }
+ waddstr(menu->win, menu->mark);
+ if (isfore)
+ {
+ wattron(menu->win, menu->fore);
+ isfore = FALSE;
+ }
+ }
+ }
+ else /* otherwise we have to wipe out the marker area */
+ for (ch = ' ', i = menu->marklen; i > 0; i--)
+ waddch(menu->win, ch);
+ wattroff(menu->win, menu->back);
+ count += menu->marklen;
+
+ /* First we have to calculate the attribute depending on selectability
+ and selection status
+ */
+ if (!(item->opt & O_SELECTABLE))
+ {
+ wattron(menu->win, menu->grey);
+ isgrey = TRUE;
+ }
+ else
+ {
+ if (item->value || item == menu->curitem)
+ {
+ wattron(menu->win, menu->fore);
+ isfore = TRUE;
+ }
+ else
+ {
+ wattron(menu->win, menu->back);
+ isback = TRUE;
+ }
+ }
+
+ waddnstr(menu->win, item->name.str, item->name.length);
+ name_len = _nc_Calculate_Text_Width(&(item->name));
+ for (ch = ' ', i = menu->namelen - name_len; i > 0; i--)
+ {
+ waddch(menu->win, ch);
+ }
+ count += menu->namelen;
+
+ /* Show description if required and available */
+ if ((menu->opt & O_SHOWDESC) && menu->desclen > 0)
+ {
+ int m = menu->spc_desc / 2;
+ int cy = -1, cx = -1;
+
+ for (ch = ' ', i = 0; i < menu->spc_desc; i++)
+ {
+ if (i == m)
+ {
+ waddch(menu->win, menu->pad);
+ getyx(menu->win, cy, cx);
+ }
+ else
+ waddch(menu->win, ch);
+ }
+ if (item->description.length)
+ waddnstr(menu->win, item->description.str, item->description.length);
+ desc_len = _nc_Calculate_Text_Width(&(item->description));
+ for (ch = ' ', i = menu->desclen - desc_len; i > 0; i--)
+ {
+ waddch(menu->win, ch);
+ }
+ count += menu->desclen + menu->spc_desc;
+
+ if (menu->spc_rows > 1)
+ {
+ int j, k, ncy, ncx;
+
+ assert(cx >= 0 && cy >= 0);
+ getyx(menu->win, ncy, ncx);
+ if (isgrey)
+ wattroff(menu->win, menu->grey);
+ else if (isfore)
+ wattroff(menu->win, menu->fore);
+ wattron(menu->win, menu->back);
+ for (j = 1; j < menu->spc_rows; j++)
+ {
+ if ((item_y + j) < getmaxy(menu->win))
+ {
+ wmove(menu->win, item_y + j, item_x);
+ for (k = 0; k < count; k++)
+ waddch(menu->win, ' ');
+ }
+ if ((cy + j) < getmaxy(menu->win))
+ (void)mvwaddch(menu->win, cy + j, cx - 1, menu->pad);
+ }
+ wmove(menu->win, ncy, ncx);
+ if (!isback)
+ wattroff(menu->win, menu->back);
+ }
+ }
+
+ /* Remove attributes */
+ if (isfore)
+ wattroff(menu->win, menu->fore);
+ if (isback)
+ wattroff(menu->win, menu->back);
+ if (isgrey)
+ wattroff(menu->win, menu->grey);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void _nc_Draw_Menu(const MENU *)
+|
+| Description : Display the menu in its windows
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Draw_Menu(const MENU * menu)
+{
+ ITEM *item = menu->items[0];
+ ITEM *lasthor, *lastvert;
+ ITEM *hitem;
+ int y = 0;
+ chtype s_bkgd;
+
+ assert(item && menu->win);
+
+ s_bkgd = getbkgd(menu->win);
+ wbkgdset(menu->win, menu->back);
+ werase(menu->win);
+ wbkgdset(menu->win, s_bkgd);
+
+ lastvert = (menu->opt & O_NONCYCLIC) ? (ITEM *) 0 : item;
+
+ do
+ {
+ wmove(menu->win, y, 0);
+
+ hitem = item;
+ lasthor = (menu->opt & O_NONCYCLIC) ? (ITEM *) 0 : hitem;
+
+ do
+ {
+ _nc_Post_Item(menu, hitem);
+
+ wattron(menu->win, menu->back);
+ if (((hitem = hitem->right) != lasthor) && hitem)
+ {
+ int i, j, cy, cx;
+ chtype ch = ' ';
+
+ getyx(menu->win, cy, cx);
+ for (j = 0; j < menu->spc_rows; j++)
+ {
+ wmove(menu->win, cy + j, cx);
+ for (i = 0; i < menu->spc_cols; i++)
+ {
+ waddch(menu->win, ch);
+ }
+ }
+ wmove(menu->win, cy, cx + menu->spc_cols);
+ }
+ }
+ while (hitem && (hitem != lasthor));
+ wattroff(menu->win, menu->back);
+
+ item = item->down;
+ y += menu->spc_rows;
+
+ }
+ while (item && (item != lastvert));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int post_menu(MENU* menu)
+|
+| Description : Post a menu to the screen. This makes it visible.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - not a valid menu pointer
+| E_SYSTEM_ERROR - error in lower layers
+| E_NOT_CONNECTED - No items connected to menu
+| E_BAD_STATE - Menu in userexit routine
+| E_POSTED - Menu already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+post_menu(MENU * menu)
+{
+ T((T_CALLED("post_menu(%p)"), (void *)menu));
+
+ if (!menu)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (menu->items && *(menu->items))
+ {
+ int y;
+ int h = 1 + menu->spc_rows * (menu->rows - 1);
+
+ WINDOW *win = Get_Menu_Window(menu);
+ int maxy = getmaxy(win);
+
+ if ((menu->win = newpad(h+2, menu->width+2)))
+ {
+ y = (maxy >= h) ? h : maxy;
+ if (y >= menu->height)
+ y = menu->height;
+ if (!(menu->sub = subpad(menu->win, y, menu->width, 0, 0)))
+ RETURN(E_SYSTEM_ERROR);
+ }
+ else
+ RETURN(E_SYSTEM_ERROR);
+
+ if (menu->status & _LINK_NEEDED)
+ _nc_Link_Items(menu);
+ }
+ else
+ RETURN(E_NOT_CONNECTED);
+
+ menu->status |= _POSTED;
+
+ if (!(menu->opt & O_ONEVALUE))
+ {
+ ITEM **items;
+
+ for (items = menu->items; *items; items++)
+ {
+ (*items)->value = FALSE;
+ }
+ }
+
+ _nc_Draw_Menu(menu);
+
+ Call_Hook(menu, menuinit);
+ Call_Hook(menu, iteminit);
+
+ _nc_Show_Menu(menu);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int unpost_menu(MENU*)
+|
+| Description : Detach menu from screen
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - not a valid menu pointer
+| E_BAD_STATE - menu in userexit routine
+| E_NOT_POSTED - menu is not posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+unpost_menu(MENU * menu)
+{
+ WINDOW *win;
+
+ T((T_CALLED("unpost_menu(%p)"), (void *)menu));
+
+ if (!menu)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ if (!(menu->status & _POSTED))
+ RETURN(E_NOT_POSTED);
+
+ Call_Hook(menu, itemterm);
+ Call_Hook(menu, menuterm);
+
+ win = Get_Menu_Window(menu);
+ werase(win);
+ wsyncup(win);
+
+ assert(menu->sub);
+ delwin(menu->sub);
+ menu->sub = (WINDOW *)0;
+
+ assert(menu->win);
+ delwin(menu->win);
+ menu->win = (WINDOW *)0;
+
+ menu->status &= ~_POSTED;
+
+ RETURN(E_OK);
+}
+
+/* m_post.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_req_name.c b/apps/lib/curses/pdcurses/menu/m_req_name.c
new file mode 100644
index 0000000..50c0c68
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_req_name.c
@@ -0,0 +1,125 @@
+/****************************************************************************
+ * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_request_name *
+* Routines to handle external names of menu requests *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_req_name.c,v 1.21 2009/10/10 16:17:23 tom Exp $")
+
+static const char *request_names[MAX_MENU_COMMAND - MIN_MENU_COMMAND + 1] =
+{
+ "LEFT_ITEM",
+ "RIGHT_ITEM",
+ "UP_ITEM",
+ "DOWN_ITEM",
+ "SCR_ULINE",
+ "SCR_DLINE",
+ "SCR_DPAGE",
+ "SCR_UPAGE",
+ "FIRST_ITEM",
+ "LAST_ITEM",
+ "NEXT_ITEM",
+ "PREV_ITEM",
+ "TOGGLE_ITEM",
+ "CLEAR_PATTERN",
+ "BACK_PATTERN",
+ "NEXT_MATCH",
+ "PREV_MATCH"
+};
+
+#define A_SIZE (sizeof(request_names)/sizeof(request_names[0]))
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : const char * menu_request_name (int request);
+|
+| Description : Get the external name of a menu request.
+|
+| Return Values : Pointer to name - on success
+| NULL - on invalid request code
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(const char *)
+menu_request_name(int request)
+{
+ T((T_CALLED("menu_request_name(%d)"), request));
+ if ((request < MIN_MENU_COMMAND) || (request > MAX_MENU_COMMAND))
+ {
+ SET_ERROR(E_BAD_ARGUMENT);
+ returnCPtr((const char *)0);
+ }
+ else
+ returnCPtr(request_names[request - MIN_MENU_COMMAND]);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_request_by_name (const char *str);
+|
+| Description : Search for a request with this name.
+|
+| Return Values : Request Id - on success
+| E_NO_MATCH - request not found
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_request_by_name(const char *str)
+{
+ /* because the table is so small, it doesn't really hurt
+ to run sequentially through it.
+ */
+ unsigned int i = 0;
+ char buf[16];
+
+ T((T_CALLED("menu_request_by_name(%s)"), _nc_visbuf(str)));
+
+ if (str)
+ {
+ strncpy(buf, str, sizeof(buf));
+ while ((i < sizeof(buf)) && (buf[i] != '\0'))
+ {
+ buf[i] = (char)toupper(UChar(buf[i]));
+ i++;
+ }
+
+ for (i = 0; i < A_SIZE; i++)
+ {
+ if (strncmp(request_names[i], buf, sizeof(buf)) == 0)
+ returnCode(MIN_MENU_COMMAND + (int)i);
+ }
+ }
+ RETURN(E_NO_MATCH);
+}
+
+/* m_req_name.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_scale.c b/apps/lib/curses/pdcurses/menu/m_scale.c
new file mode 100644
index 0000000..26a560e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_scale.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_scale *
+* Menu scaling routine *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_scale.c,v 1.10 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int scale_menu(const MENU *menu)
+|
+| Description : Returns the minimum window size necessary for the
+| subwindow of menu.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid menu pointer
+| E_NOT_CONNECTED - no items are connected to menu
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+scale_menu(const MENU * menu, int *rows, int *cols)
+{
+ T((T_CALLED("scale_menu(%p,%p,%p)"),
+ (const void *)menu,
+ (void *)rows,
+ (void *)cols));
+
+ if (!menu)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (menu->items && *(menu->items))
+ {
+ if (rows)
+ *rows = menu->height;
+ if (cols)
+ *cols = menu->width;
+ RETURN(E_OK);
+ }
+ else
+ RETURN(E_NOT_CONNECTED);
+}
+
+/* m_scale.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_spacing.c b/apps/lib/curses/pdcurses/menu/m_spacing.c
new file mode 100644
index 0000000..1cfa2e1
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_spacing.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_spacing *
+* Routines to handle spacing between entries *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_spacing.c,v 1.18 2010/01/23 21:20:10 tom Exp $")
+
+#define MAX_SPC_DESC ((TABSIZE) ? (TABSIZE) : 8)
+#define MAX_SPC_COLS ((TABSIZE) ? (TABSIZE) : 8)
+#define MAX_SPC_ROWS (3)
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_spacing(MENU *menu,int desc, int r, int c);
+|
+| Description : Set the spacing between entries
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_spacing(MENU * menu, int s_desc, int s_row, int s_col)
+{
+ MENU *m; /* split for ATAC workaround */
+
+ T((T_CALLED("set_menu_spacing(%p,%d,%d,%d)"),
+ (void *)menu, s_desc, s_row, s_col));
+
+ m = Normalize_Menu(menu);
+
+ assert(m);
+ if (m->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (((s_desc < 0) || (s_desc > MAX_SPC_DESC)) ||
+ ((s_row < 0) || (s_row > MAX_SPC_ROWS)) ||
+ ((s_col < 0) || (s_col > MAX_SPC_COLS)))
+ RETURN(E_BAD_ARGUMENT);
+
+ m->spc_desc = s_desc ? s_desc : 1;
+ m->spc_rows = s_row ? s_row : 1;
+ m->spc_cols = s_col ? s_col : 1;
+ _nc_Calculate_Item_Length_and_Width(m);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int menu_spacing (const MENU *,int *,int *,int *);
+|
+| Description : Retrieve info about spacing between the entries
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+menu_spacing(const MENU * menu, int *s_desc, int *s_row, int *s_col)
+{
+ const MENU *m; /* split for ATAC workaround */
+
+ T((T_CALLED("menu_spacing(%p,%p,%p,%p)"),
+ (const void *)menu,
+ (void *)s_desc,
+ (void *)s_row,
+ (void *)s_col));
+
+ m = Normalize_Menu(menu);
+
+ assert(m);
+ if (s_desc)
+ *s_desc = m->spc_desc;
+ if (s_row)
+ *s_row = m->spc_rows;
+ if (s_col)
+ *s_col = m->spc_cols;
+
+ RETURN(E_OK);
+}
+
+/* m_spacing.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_sub.c b/apps/lib/curses/pdcurses/menu/m_sub.c
new file mode 100644
index 0000000..4bb373f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_sub.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_sub *
+* Menus subwindow association routines *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_sub.c,v 1.12 2010/01/23 21:20:11 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_sub(MENU *menu, WINDOW *win)
+|
+| Description : Sets the subwindow of the menu.
+|
+| Return Values : E_OK - success
+| E_POSTED - menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_sub(MENU * menu, WINDOW *win)
+{
+ T((T_CALLED("set_menu_sub(%p,%p)"), (void *)menu, (void *)win));
+
+ if (menu)
+ {
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+ else
+#if NCURSES_SP_FUNCS
+ {
+ /* We ensure that usersub is never null. So even if a null
+ WINDOW parameter is passed, we store the SCREENS stdscr.
+ The only MENU that can have a null usersub is the static
+ _nc_default_Menu.
+ */
+ SCREEN *sp = _nc_screen_of(menu->usersub);
+
+ menu->usersub = win ? win : stdscr;
+ _nc_Calculate_Item_Length_and_Width(menu);
+ }
+#else
+ menu->usersub = win;
+#endif
+ }
+ else
+ _nc_Default_Menu.usersub = win;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : WINDOW* menu_sub(const MENU *menu)
+|
+| Description : Returns a pointer to the subwindow of the menu
+|
+| Return Values : NULL on error, otherwise a pointer to the window
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(WINDOW *)
+menu_sub(const MENU * menu)
+{
+ const MENU *m = Normalize_Menu(menu);
+
+ T((T_CALLED("menu_sub(%p)"), (const void *)menu));
+ returnWin(Get_Menu_Window(m));
+}
+
+/* m_sub.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_trace.c b/apps/lib/curses/pdcurses/menu/m_trace.c
new file mode 100644
index 0000000..094ff86
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_trace.c
@@ -0,0 +1,77 @@
+/****************************************************************************
+ * Copyright (c) 2004-2005,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey *
+ ****************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_trace.c,v 1.4 2010/01/23 21:20:10 tom Exp $")
+
+NCURSES_EXPORT(ITEM *)
+_nc_retrace_item(ITEM * code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(ITEM **)
+_nc_retrace_item_ptr(ITEM ** code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(Item_Options)
+_nc_retrace_item_opts(Item_Options code)
+{
+ T((T_RETURN("%d"), code));
+ return code;
+}
+
+NCURSES_EXPORT(MENU *)
+_nc_retrace_menu(MENU * code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(Menu_Hook)
+_nc_retrace_menu_hook(Menu_Hook code)
+{
+ T((T_RETURN("%p"), code));
+ return code;
+}
+
+NCURSES_EXPORT(Menu_Options)
+_nc_retrace_menu_opts(Menu_Options code)
+{
+ T((T_RETURN("%d"), code));
+ return code;
+}
--git a/apps/lib/curses/pdcurses/menu/m_userptr.c b/apps/lib/curses/pdcurses/menu/m_userptr.c
new file mode 100644
index 0000000..67d6ecd
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_userptr.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_userptr *
+* Associate application data with menus *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_userptr.c,v 1.17 2010/01/23 21:20:10 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_userptr(MENU *menu, void *userptr)
+|
+| Description : Set the pointer that is reserved in any menu to store
+| application relevant informations.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_userptr(MENU * menu, void *userptr)
+{
+ T((T_CALLED("set_menu_userptr(%p,%p)"), (void *)menu, (void *)userptr));
+ Normalize_Menu(menu)->userptr = userptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : void *menu_userptr(const MENU *menu)
+|
+| Description : Return the pointer that is reserved in any menu to
+| store application relevant informations.
+|
+| Return Values : Value of the pointer. If no such pointer has been set,
+| NULL is returned
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void *)
+menu_userptr(const MENU * menu)
+{
+ T((T_CALLED("menu_userptr(%p)"), (const void *)menu));
+ returnVoidPtr(Normalize_Menu(menu)->userptr);
+}
+
+/* m_userptr.c ends here */
--git a/apps/lib/curses/pdcurses/menu/m_win.c b/apps/lib/curses/pdcurses/menu/m_win.c
new file mode 100644
index 0000000..d025c1b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/m_win.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module m_win *
+* Menus window association routines *
+***************************************************************************/
+
+#include "menu.priv.h"
+
+MODULE_ID("$Id: m_win.c,v 1.17 2010/01/23 21:20:11 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : int set_menu_win(MENU *menu, WINDOW *win)
+|
+| Description : Sets the window of the menu.
+|
+| Return Values : E_OK - success
+| E_POSTED - menu is already posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_menu_win(MENU * menu, WINDOW *win)
+{
+ T((T_CALLED("set_menu_win(%p,%p)"), (void *)menu, (void *)win));
+
+ if (menu)
+ {
+ if (menu->status & _POSTED)
+ RETURN(E_POSTED);
+ else
+#if NCURSES_SP_FUNCS
+ {
+ /* We ensure that userwin is never null. So even if a null
+ WINDOW parameter is passed, we store the SCREENS stdscr.
+ The only MENU that can have a null userwin is the static
+ _nc_default_Menu.
+ */
+ SCREEN *sp = _nc_screen_of(menu->userwin);
+
+ menu->userwin = win ? win : stdscr;
+ _nc_Calculate_Item_Length_and_Width(menu);
+ }
+#else
+ menu->userwin = win;
+#endif
+ }
+ else
+ _nc_Default_Menu.userwin = win;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnmenu
+| Function : WINDOW* menu_win(const MENU*)
+|
+| Description : Returns pointer to the window of the menu
+|
+| Return Values : NULL on error, otherwise pointer to window
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(WINDOW *)
+menu_win(const MENU * menu)
+{
+ const MENU *m = Normalize_Menu(menu);
+
+ T((T_CALLED("menu_win(%p)"), (const void *)menu));
+ returnWin(Get_Menu_UserWin(m));
+}
+
+/* m_win.c ends here */
--git a/apps/lib/curses/pdcurses/menu/menu.h b/apps/lib/curses/pdcurses/menu/menu.h
new file mode 100644
index 0000000..1fdd9e7
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/menu.h
@@ -0,0 +1,261 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: menu.h,v 1.20 2009/04/05 00:28:07 tom Exp $ */
+
+#ifndef ETI_MENU
+#define ETI_MENU
+
+#ifdef AMIGA
+#define TEXT TEXT_ncurses
+#endif
+
+#include <curses.h>
+#include <eti.h>
+#include <ncurses_cfg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int Menu_Options;
+typedef int Item_Options;
+
+/* Menu options: */
+#define O_ONEVALUE (0x01)
+#define O_SHOWDESC (0x02)
+#define O_ROWMAJOR (0x04)
+#define O_IGNORECASE (0x08)
+#define O_SHOWMATCH (0x10)
+#define O_NONCYCLIC (0x20)
+
+/* Item options: */
+#define O_SELECTABLE (0x01)
+
+typedef struct
+{
+ const char* str;
+ unsigned short length;
+} TEXT;
+
+typedef struct tagITEM
+{
+ TEXT name; /* name of menu item */
+ TEXT description; /* description of item, optional in display */
+ struct tagMENU *imenu; /* Pointer to parent menu */
+ void *userptr; /* Pointer to user defined per item data */
+ Item_Options opt; /* Item options */
+ short index; /* Item number if connected to a menu */
+ short y; /* y and x location of item in menu */
+ short x;
+ bool value; /* Selection value */
+
+ struct tagITEM *left; /* neighbor items */
+ struct tagITEM *right;
+ struct tagITEM *up;
+ struct tagITEM *down;
+
+} ITEM;
+
+typedef void (*Menu_Hook)(struct tagMENU *);
+
+typedef struct tagMENU
+{
+ short height; /* Nr. of chars high */
+ short width; /* Nr. of chars wide */
+ short rows; /* Nr. of items high */
+ short cols; /* Nr. of items wide */
+ short frows; /* Nr. of formatted items high */
+ short fcols; /* Nr. of formatted items wide */
+ short arows; /* Nr. of items high (actual) */
+ short namelen; /* Max. name length */
+ short desclen; /* Max. description length */
+ short marklen; /* Length of mark, if any */
+ short itemlen; /* Length of one item */
+ short spc_desc; /* Spacing for descriptor */
+ short spc_cols; /* Spacing for columns */
+ short spc_rows; /* Spacing for rows */
+ char *pattern; /* Buffer to store match chars */
+ short pindex; /* Index into pattern buffer */
+ WINDOW *win; /* Window containing menu */
+ WINDOW *sub; /* Subwindow for menu display */
+ WINDOW *userwin; /* User's window */
+ WINDOW *usersub; /* User's subwindow */
+ ITEM **items; /* array of items */
+ short nitems; /* Nr. of items in menu */
+ ITEM *curitem; /* Current item */
+ short toprow; /* Top row of menu */
+ chtype fore; /* Selection attribute */
+ chtype back; /* Nonselection attribute */
+ chtype grey; /* Inactive attribute */
+ unsigned char pad; /* Pad character */
+
+ Menu_Hook menuinit; /* User hooks */
+ Menu_Hook menuterm;
+ Menu_Hook iteminit;
+ Menu_Hook itemterm;
+
+ void *userptr; /* Pointer to menus user data */
+ char *mark; /* Pointer to marker string */
+
+ Menu_Options opt; /* Menu options */
+ unsigned short status; /* Internal state of menu */
+
+} MENU;
+
+
+/* Define keys */
+
+#define REQ_LEFT_ITEM (KEY_MAX + 1)
+#define REQ_RIGHT_ITEM (KEY_MAX + 2)
+#define REQ_UP_ITEM (KEY_MAX + 3)
+#define REQ_DOWN_ITEM (KEY_MAX + 4)
+#define REQ_SCR_ULINE (KEY_MAX + 5)
+#define REQ_SCR_DLINE (KEY_MAX + 6)
+#define REQ_SCR_DPAGE (KEY_MAX + 7)
+#define REQ_SCR_UPAGE (KEY_MAX + 8)
+#define REQ_FIRST_ITEM (KEY_MAX + 9)
+#define REQ_LAST_ITEM (KEY_MAX + 10)
+#define REQ_NEXT_ITEM (KEY_MAX + 11)
+#define REQ_PREV_ITEM (KEY_MAX + 12)
+#define REQ_TOGGLE_ITEM (KEY_MAX + 13)
+#define REQ_CLEAR_PATTERN (KEY_MAX + 14)
+#define REQ_BACK_PATTERN (KEY_MAX + 15)
+#define REQ_NEXT_MATCH (KEY_MAX + 16)
+#define REQ_PREV_MATCH (KEY_MAX + 17)
+
+#define MIN_MENU_COMMAND (KEY_MAX + 1)
+#define MAX_MENU_COMMAND (KEY_MAX + 17)
+
+/*
+ * Some AT&T code expects MAX_COMMAND to be out-of-band not
+ * just for menu commands but for forms ones as well.
+ */
+#if defined(MAX_COMMAND)
+# if (MAX_MENU_COMMAND > MAX_COMMAND)
+# error Something is wrong -- MAX_MENU_COMMAND is greater than MAX_COMMAND
+# elif (MAX_COMMAND != (KEY_MAX + 128))
+# error Something is wrong -- MAX_COMMAND is already inconsistently defined.
+# endif
+#else
+# define MAX_COMMAND (KEY_MAX + 128)
+#endif
+
+
+/* --------- prototypes for libmenu functions ----------------------------- */
+
+extern NCURSES_EXPORT(ITEM **) menu_items (const MENU *);
+extern NCURSES_EXPORT(ITEM *) current_item (const MENU *);
+extern NCURSES_EXPORT(ITEM *) new_item (const char *,const char *);
+
+extern NCURSES_EXPORT(MENU *) new_menu (ITEM **);
+
+extern NCURSES_EXPORT(Item_Options) item_opts (const ITEM *);
+extern NCURSES_EXPORT(Menu_Options) menu_opts (const MENU *);
+
+extern NCURSES_EXPORT(Menu_Hook) item_init (const MENU *);
+extern NCURSES_EXPORT(Menu_Hook) item_term (const MENU *);
+extern NCURSES_EXPORT(Menu_Hook) menu_init (const MENU *);
+extern NCURSES_EXPORT(Menu_Hook) menu_term (const MENU *);
+
+extern NCURSES_EXPORT(WINDOW *) menu_sub (const MENU *);
+extern NCURSES_EXPORT(WINDOW *) menu_win (const MENU *);
+
+extern NCURSES_EXPORT(const char *) item_description (const ITEM *);
+extern NCURSES_EXPORT(const char *) item_name (const ITEM *);
+extern NCURSES_EXPORT(const char *) menu_mark (const MENU *);
+extern NCURSES_EXPORT(const char *) menu_request_name (int);
+
+extern NCURSES_EXPORT(char *) menu_pattern (const MENU *);
+
+extern NCURSES_EXPORT(void *) menu_userptr (const MENU *);
+extern NCURSES_EXPORT(void *) item_userptr (const ITEM *);
+
+extern NCURSES_EXPORT(chtype) menu_back (const MENU *);
+extern NCURSES_EXPORT(chtype) menu_fore (const MENU *);
+extern NCURSES_EXPORT(chtype) menu_grey (const MENU *);
+
+extern NCURSES_EXPORT(int) free_item (ITEM *);
+extern NCURSES_EXPORT(int) free_menu (MENU *);
+extern NCURSES_EXPORT(int) item_count (const MENU *);
+extern NCURSES_EXPORT(int) item_index (const ITEM *);
+extern NCURSES_EXPORT(int) item_opts_off (ITEM *,Item_Options);
+extern NCURSES_EXPORT(int) item_opts_on (ITEM *,Item_Options);
+extern NCURSES_EXPORT(int) menu_driver (MENU *,int);
+extern NCURSES_EXPORT(int) menu_opts_off (MENU *,Menu_Options);
+extern NCURSES_EXPORT(int) menu_opts_on (MENU *,Menu_Options);
+extern NCURSES_EXPORT(int) menu_pad (const MENU *);
+extern NCURSES_EXPORT(int) pos_menu_cursor (const MENU *);
+extern NCURSES_EXPORT(int) post_menu (MENU *);
+extern NCURSES_EXPORT(int) scale_menu (const MENU *,int *,int *);
+extern NCURSES_EXPORT(int) set_current_item (MENU *menu,ITEM *item);
+extern NCURSES_EXPORT(int) set_item_init (MENU *, Menu_Hook);
+extern NCURSES_EXPORT(int) set_item_opts (ITEM *,Item_Options);
+extern NCURSES_EXPORT(int) set_item_term (MENU *, Menu_Hook);
+extern NCURSES_EXPORT(int) set_item_userptr (ITEM *, void *);
+extern NCURSES_EXPORT(int) set_item_value (ITEM *,bool);
+extern NCURSES_EXPORT(int) set_menu_back (MENU *,chtype);
+extern NCURSES_EXPORT(int) set_menu_fore (MENU *,chtype);
+extern NCURSES_EXPORT(int) set_menu_format (MENU *,int,int);
+extern NCURSES_EXPORT(int) set_menu_grey (MENU *,chtype);
+extern NCURSES_EXPORT(int) set_menu_init (MENU *, Menu_Hook);
+extern NCURSES_EXPORT(int) set_menu_items (MENU *,ITEM **);
+extern NCURSES_EXPORT(int) set_menu_mark (MENU *, const char *);
+extern NCURSES_EXPORT(int) set_menu_opts (MENU *,Menu_Options);
+extern NCURSES_EXPORT(int) set_menu_pad (MENU *,int);
+extern NCURSES_EXPORT(int) set_menu_pattern (MENU *,const char *);
+extern NCURSES_EXPORT(int) set_menu_sub (MENU *,WINDOW *);
+extern NCURSES_EXPORT(int) set_menu_term (MENU *, Menu_Hook);
+extern NCURSES_EXPORT(int) set_menu_userptr (MENU *,void *);
+extern NCURSES_EXPORT(int) set_menu_win (MENU *,WINDOW *);
+extern NCURSES_EXPORT(int) set_top_row (MENU *,int);
+extern NCURSES_EXPORT(int) top_row (const MENU *);
+extern NCURSES_EXPORT(int) unpost_menu (MENU *);
+extern NCURSES_EXPORT(int) menu_request_by_name (const char *);
+extern NCURSES_EXPORT(int) set_menu_spacing (MENU *,int,int,int);
+extern NCURSES_EXPORT(int) menu_spacing (const MENU *,int *,int *,int *);
+
+
+extern NCURSES_EXPORT(bool) item_value (const ITEM *);
+extern NCURSES_EXPORT(bool) item_visible (const ITEM *);
+
+extern NCURSES_EXPORT(void) menu_format (const MENU *,int *,int *);
+
+#if NCURSES_SP_FUNCS
+extern NCURSES_EXPORT(MENU *) NCURSES_SP_NAME(new_menu) (SCREEN*, ITEM **);
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* ETI_MENU */
--git a/apps/lib/curses/pdcurses/menu/menu.priv.h b/apps/lib/curses/pdcurses/menu/menu.priv.h
new file mode 100644
index 0000000..f6edc1a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/menu.priv.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: menu.priv.h,v 1.23 2009/02/28 21:02:57 juergen Exp $ */
+
+/***************************************************************************
+* Module menu.priv.h *
+* Top level private header file for all libnmenu modules *
+***************************************************************************/
+
+#ifndef MENU_PRIV_H_incl
+#define MENU_PRIV_H_incl 1
+
+#include "../pdcurses/curspriv.h"
+#include <errno.h>
+#include "mf_common.h"
+#include "menu.h"
+
+/* Backspace code */
+#define BS (8)
+
+extern NCURSES_EXPORT_VAR(ITEM) _nc_Default_Item;
+extern NCURSES_EXPORT_VAR(MENU) _nc_Default_Menu;
+
+/* Normalize item to default if none was given */
+#define Normalize_Item( item ) ((item)=(item)?(item):&_nc_Default_Item)
+
+/* Normalize menu to default if none was given */
+#define Normalize_Menu( menu ) ((menu)=(menu)?(menu):&_nc_Default_Menu)
+
+#define Get_Menu_Screen( menu ) (menu->userwin ? \
+ _nc_screen_of(menu->userwin) : CURRENT_SCREEN)
+
+/* Get the user defined (framing) window of the menu */
+#define Get_Menu_UserWin(menu) ((menu)->userwin ? \
+ (menu)->userwin : stdscr)
+
+/* Normalize menu window */
+#define Get_Menu_Window( menu ) \
+ ((menu)->usersub ? (menu)->usersub : Get_Menu_UserWin(menu))
+
+/* menu specific status flags */
+#define _LINK_NEEDED (0x04)
+#define _MARK_ALLOCATED (0x08)
+
+#define ALL_MENU_OPTS ( \
+ O_ONEVALUE | \
+ O_SHOWDESC | \
+ O_ROWMAJOR | \
+ O_IGNORECASE | \
+ O_SHOWMATCH | \
+ O_NONCYCLIC )
+
+#define ALL_ITEM_OPTS (O_SELECTABLE)
+
+/* Move to the window position of an item and draw it */
+#define Move_And_Post_Item(menu,item) \
+ {wmove((menu)->win,(menu)->spc_rows*(item)->y,((menu)->itemlen+(menu)->spc_cols)*(item)->x);\
+ _nc_Post_Item((menu),(item));}
+
+#define Move_To_Current_Item(menu,item) \
+ if ( (item) != (menu)->curitem)\
+ {\
+ Move_And_Post_Item(menu,item);\
+ Move_And_Post_Item(menu,(menu)->curitem);\
+ }
+
+/* This macro ensures, that the item becomes visible, if possible with the
+ specified row as the top row of the window. If this is not possible,
+ the top row will be adjusted and the value is stored in the row argument.
+*/
+#define Adjust_Current_Item(menu,row,item) \
+ { if ((item)->y < row) \
+ row = (item)->y;\
+ if ( (item)->y >= (row + (menu)->arows) )\
+ row = ( (item)->y < ((menu)->rows - row) ) ? \
+ (item)->y : (menu)->rows - (menu)->arows;\
+ _nc_New_TopRow_and_CurrentItem(menu,row,item); }
+
+/* Reset the match pattern buffer */
+#define Reset_Pattern(menu) \
+ { (menu)->pindex = 0; \
+ (menu)->pattern[0] = '\0'; }
+
+#define UChar(c) ((unsigned char)(c))
+
+/* Internal functions. */
+extern NCURSES_EXPORT(void) _nc_Draw_Menu (const MENU *);
+extern NCURSES_EXPORT(void) _nc_Show_Menu (const MENU *);
+extern NCURSES_EXPORT(void) _nc_Calculate_Item_Length_and_Width (MENU *);
+extern NCURSES_EXPORT(int) _nc_Calculate_Text_Width(const TEXT *);
+extern NCURSES_EXPORT(void) _nc_Post_Item (const MENU *, const ITEM *);
+extern NCURSES_EXPORT(bool) _nc_Connect_Items (MENU *, ITEM **);
+extern NCURSES_EXPORT(void) _nc_Disconnect_Items (MENU *);
+extern NCURSES_EXPORT(void) _nc_New_TopRow_and_CurrentItem (MENU *,int, ITEM *);
+extern NCURSES_EXPORT(void) _nc_Link_Items (MENU *);
+extern NCURSES_EXPORT(int) _nc_Match_Next_Character_In_Item_Name (MENU*,int,ITEM**);
+extern NCURSES_EXPORT(int) _nc_menu_cursor_pos (const MENU* menu, const ITEM* item,
+ int* pY, int* pX);
+
+#ifdef TRACE
+
+#define returnItem(code) TRACE_RETURN(code,item)
+#define returnItemPtr(code) TRACE_RETURN(code,item_ptr)
+#define returnItemOpts(code) TRACE_RETURN(code,item_opts)
+#define returnMenu(code) TRACE_RETURN(code,menu)
+#define returnMenuHook(code) TRACE_RETURN(code,menu_hook)
+#define returnMenuOpts(code) TRACE_RETURN(code,menu_opts)
+
+extern NCURSES_EXPORT(ITEM *) _nc_retrace_item (ITEM *);
+extern NCURSES_EXPORT(ITEM **) _nc_retrace_item_ptr (ITEM **);
+extern NCURSES_EXPORT(Item_Options) _nc_retrace_item_opts (Item_Options);
+extern NCURSES_EXPORT(MENU *) _nc_retrace_menu (MENU *);
+extern NCURSES_EXPORT(Menu_Hook) _nc_retrace_menu_hook (Menu_Hook);
+extern NCURSES_EXPORT(Menu_Options) _nc_retrace_menu_opts (Menu_Options);
+
+#else /* !TRACE */
+
+#define returnItem(code) return code
+#define returnItemPtr(code) return code
+#define returnItemOpts(code) return code
+#define returnMenu(code) return code
+#define returnMenuHook(code) return code
+#define returnMenuOpts(code) return code
+
+#endif /* TRACE/!TRACE */
+
+#endif /* MENU_PRIV_H_incl */
--git a/apps/lib/curses/pdcurses/menu/mf_common.h b/apps/lib/curses/pdcurses/menu/mf_common.h
new file mode 100644
index 0000000..681672d
--- /dev/null
+++ b/apps/lib/curses/pdcurses/menu/mf_common.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * Copyright (c) 1998-2003,2004 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: mf_common.h,v 0.22 2005/11/26 15:26:52 tom Exp $ */
+
+/* Common internal header for menu and form library */
+
+#ifndef MF_COMMON_H_incl
+#define MF_COMMON_H_incl 1
+
+#include <ncurses_cfg.h>
+#include <curses.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#if DECL_ERRNO
+extern int errno;
+#endif
+
+/* in case of debug version we ignore the suppression of assertions */
+#ifdef TRACE
+# ifdef NDEBUG
+# undef NDEBUG
+# endif
+#endif
+
+#include <nc_alloc.h>
+
+#if USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+
+/* Maximum regular 8-bit character code */
+#define MAX_REGULAR_CHARACTER (0xff)
+
+#define SET_ERROR(code) (errno=(code))
+#define GET_ERROR() (errno)
+
+#ifdef TRACE
+#define RETURN(code) returnCode( SET_ERROR(code) )
+#else
+#define RETURN(code) return( SET_ERROR(code) )
+#endif
+
+/* The few common values in the status fields for menus and forms */
+#define _POSTED (0x01U) /* menu or form is posted */
+#define _IN_DRIVER (0x02U) /* menu or form is processing hook routine */
+
+/* Call object hook */
+#define Call_Hook( object, handler ) \
+ if ( (object) != 0 && ((object)->handler) != (void *) 0 )\
+ {\
+ (object)->status |= _IN_DRIVER;\
+ (object)->handler(object);\
+ (object)->status &= ~_IN_DRIVER;\
+ }
+
+#endif /* MF_COMMON_H_incl */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 16/20] app: pdcurses: add libform
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (13 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 15/20] app: pdcurses: add libmenu Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 17/20] app: curses: add menu example Jean-Christophe PLAGNIOL-VILLARD
` (3 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/lib/curses/Kconfig | 4 +
apps/lib/curses/pdcurses/Makefile | 114 +-
apps/lib/curses/pdcurses/Makefile.include | 1 +
apps/lib/curses/pdcurses/form/Makefile | 42 +
apps/lib/curses/pdcurses/form/READ.ME | 42 +
apps/lib/curses/pdcurses/form/f_trace.c | 70 +
apps/lib/curses/pdcurses/form/fld_arg.c | 98 +
apps/lib/curses/pdcurses/form/fld_attr.c | 119 +
apps/lib/curses/pdcurses/form/fld_current.c | 137 +
apps/lib/curses/pdcurses/form/fld_def.c | 399 +++
apps/lib/curses/pdcurses/form/fld_dup.c | 101 +
apps/lib/curses/pdcurses/form/fld_ftchoice.c | 70 +
apps/lib/curses/pdcurses/form/fld_ftlink.c | 87 +
apps/lib/curses/pdcurses/form/fld_info.c | 113 +
apps/lib/curses/pdcurses/form/fld_just.c | 86 +
apps/lib/curses/pdcurses/form/fld_link.c | 96 +
apps/lib/curses/pdcurses/form/fld_max.c | 77 +
apps/lib/curses/pdcurses/form/fld_move.c | 64 +
apps/lib/curses/pdcurses/form/fld_newftyp.c | 143 +
apps/lib/curses/pdcurses/form/fld_opts.c | 138 +
apps/lib/curses/pdcurses/form/fld_pad.c | 85 +
apps/lib/curses/pdcurses/form/fld_page.c | 82 +
apps/lib/curses/pdcurses/form/fld_stat.c | 79 +
apps/lib/curses/pdcurses/form/fld_type.c | 97 +
apps/lib/curses/pdcurses/form/fld_user.c | 72 +
apps/lib/curses/pdcurses/form/form.h | 423 +++
apps/lib/curses/pdcurses/form/form.priv.h | 299 ++
apps/lib/curses/pdcurses/form/frm_cursor.c | 70 +
apps/lib/curses/pdcurses/form/frm_data.c | 193 ++
apps/lib/curses/pdcurses/form/frm_def.c | 448 +++
apps/lib/curses/pdcurses/form/frm_driver.c | 4646 ++++++++++++++++++++++++++
apps/lib/curses/pdcurses/form/frm_hook.c | 142 +
apps/lib/curses/pdcurses/form/frm_opts.c | 127 +
apps/lib/curses/pdcurses/form/frm_page.c | 106 +
apps/lib/curses/pdcurses/form/frm_post.c | 124 +
apps/lib/curses/pdcurses/form/frm_req_name.c | 170 +
apps/lib/curses/pdcurses/form/frm_scale.c | 69 +
apps/lib/curses/pdcurses/form/frm_sub.c | 86 +
apps/lib/curses/pdcurses/form/frm_user.c | 72 +
apps/lib/curses/pdcurses/form/frm_win.c | 92 +
apps/lib/curses/pdcurses/form/fty_alnum.c | 202 ++
apps/lib/curses/pdcurses/form/fty_alpha.c | 202 ++
apps/lib/curses/pdcurses/form/fty_enum.c | 442 +++
apps/lib/curses/pdcurses/form/fty_generic.c | 297 ++
apps/lib/curses/pdcurses/form/fty_int.c | 293 ++
apps/lib/curses/pdcurses/form/fty_ipv4.c | 120 +
apps/lib/curses/pdcurses/form/fty_num.c | 339 ++
apps/lib/curses/pdcurses/form/fty_regex.c | 350 ++
48 files changed, 11639 insertions(+), 89 deletions(-)
rewrite apps/lib/curses/pdcurses/Makefile (78%)
create mode 100644 apps/lib/curses/pdcurses/form/Makefile
create mode 100644 apps/lib/curses/pdcurses/form/READ.ME
create mode 100644 apps/lib/curses/pdcurses/form/f_trace.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_arg.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_attr.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_current.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_def.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_dup.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_ftchoice.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_ftlink.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_info.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_just.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_link.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_max.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_move.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_newftyp.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_opts.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_pad.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_page.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_stat.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_type.c
create mode 100644 apps/lib/curses/pdcurses/form/fld_user.c
create mode 100644 apps/lib/curses/pdcurses/form/form.h
create mode 100644 apps/lib/curses/pdcurses/form/form.priv.h
create mode 100644 apps/lib/curses/pdcurses/form/frm_cursor.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_data.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_def.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_driver.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_hook.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_opts.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_page.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_post.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_req_name.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_scale.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_sub.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_user.c
create mode 100644 apps/lib/curses/pdcurses/form/frm_win.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_alnum.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_alpha.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_enum.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_generic.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_int.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_ipv4.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_num.c
create mode 100644 apps/lib/curses/pdcurses/form/fty_regex.c
diff --git a/apps/lib/curses/Kconfig b/apps/lib/curses/Kconfig
index 5950385..8c0fa1b 100644
--- a/apps/lib/curses/Kconfig
+++ b/apps/lib/curses/Kconfig
@@ -22,4 +22,8 @@ config APP_LIB_MENU
bool "menu"
depends on APP_LIB_PDCURSES
+config APP_LIB_FORM
+ bool "form"
+ depends on APP_LIB_MENU
+
endif
diff --git a/apps/lib/curses/pdcurses/Makefile b/apps/lib/curses/pdcurses/Makefile
dissimilarity index 78%
index 3707947..37c7b8e 100644
--- a/apps/lib/curses/pdcurses/Makefile
+++ b/apps/lib/curses/pdcurses/Makefile
@@ -1,89 +1,25 @@
-#ifeq (y,y)
-#INCLUDES += -D_LP64=0 -Icurses/PDCurses-3.4 -Icurses/pdcurses-backend -Icurses/menu -Icurses/form
-#endif
-
-
-obj-y += pdcurses/
-obj-y += backend/
-
-includes-y += pdcurses-backend/nc_alloc.h
-includes-y += pdcurses-backend/ncurses_cfg.h
-includes-y += PDCurses-3.4/curses.h
-includes-y += PDCurses-3.4/term.h
-includes-y += PDCurses-3.4/panel.h
-includes-y += menu/eti.h
-includes-y += menu/menu.h
-includes-y += menu/mf_common.h
-includes-y += form/form.h
-
-libpanel-y += PDCurses-3.4/pdcurses/panel.o
-
-libmenu-y += menu/m_req_name.o
-libmenu-y += menu/m_item_nam.o
-libmenu-y += menu/m_pad.o
-libmenu-y += menu/m_cursor.o
-libmenu-y += menu/m_item_new.o
-libmenu-y += menu/m_attribs.o
-libmenu-y += menu/m_item_opt.o
-libmenu-y += menu/m_format.o
-libmenu-y += menu/m_post.o
-libmenu-y += menu/m_userptr.o
-libmenu-y += menu/m_item_cur.o
-libmenu-y += menu/m_driver.o
-libmenu-y += menu/m_sub.o
-libmenu-y += menu/m_win.o
-libmenu-y += menu/m_global.o
-libmenu-y += menu/m_item_vis.o
-libmenu-y += menu/m_new.o
-libmenu-y += menu/m_scale.o
-libmenu-y += menu/m_spacing.o
-libmenu-y += menu/m_opts.o
-libmenu-y += menu/m_pattern.o
-libmenu-y += menu/m_item_val.o
-libmenu-y += menu/m_hook.o
-libmenu-y += menu/m_item_use.o
-libmenu-y += menu/m_items.o
-libmenu-y += menu/m_item_top.o
-libform-y += form/frm_page.o
-libform-y += form/frm_opts.o
-libform-y += form/frm_def.o
-libform-y += form/frm_req_name.o
-libform-y += form/fty_alpha.o
-libform-y += form/frm_driver.o
-libform-y += form/fld_user.o
-libform-y += form/frm_win.o
-libform-y += form/fld_newftyp.o
-#libform-y += form/fty_regex.o
-libform-y += form/fld_stat.o
-libform-y += form/fld_pad.o
-libform-y += form/fld_current.o
-libform-y += form/frm_post.o
-#libform-y += form/f_trace.o
-libform-y += form/fty_generic.o
-libform-y += form/fld_page.o
-libform-y += form/frm_hook.o
-libform-y += form/frm_scale.o
-libform-y += form/fty_int.o
-libform-y += form/fty_alnum.o
-libform-y += form/frm_cursor.o
-#libform-y += form/fty_ipv4.o
-libform-y += form/fld_link.o
-libform-y += form/fld_arg.o
-libform-y += form/fld_move.o
-libform-y += form/fld_def.o
-libform-y += form/fld_type.o
-libform-y += form/fld_max.o
-libform-y += form/fld_ftlink.o
-libform-y += form/fld_ftchoice.o
-libform-y += form/fld_info.o
-libform-y += form/frm_user.o
-#libform-y += form/fty_num.o
-libform-y += form/frm_sub.o
-libform-y += form/fty_enum.o
-libform-y += form/frm_data.o
-libform-y += form/fld_opts.o
-libform-y += form/fld_attr.o
-libform-y += form/fld_dup.o
-libform-y += form/fld_just.o
-
-app-y += $(curses-y)
+#ifeq (y,y)
+#INCLUDES += -D_LP64=0 -Icurses/PDCurses-3.4 -Icurses/pdcurses-backend -Icurses/menu -Icurses/form
+#endif
+
+
+obj-y += pdcurses/
+obj-y += backend/
+obj-$(CONFIG_APP_LIB_MENU) += menu/
+obj-$(CONFIG_APP_LIB_FORM) += form/
+
+includes-y += pdcurses-backend/nc_alloc.h
+includes-y += pdcurses-backend/ncurses_cfg.h
+includes-y += PDCurses-3.4/curses.h
+includes-y += PDCurses-3.4/term.h
+includes-y += PDCurses-3.4/panel.h
+includes-y += menu/eti.h
+includes-y += menu/menu.h
+includes-y += menu/mf_common.h
+includes-y += form/form.h
+
+libpanel-y += PDCurses-3.4/pdcurses/panel.o
+
+
+
+app-y += $(curses-y)
diff --git a/apps/lib/curses/pdcurses/Makefile.include b/apps/lib/curses/pdcurses/Makefile.include
index 7a0061e..710e782 100644
--- a/apps/lib/curses/pdcurses/Makefile.include
+++ b/apps/lib/curses/pdcurses/Makefile.include
@@ -1,2 +1,3 @@
APP_CPPFLAGS-y += -I$(srctree)/apps/lib/curses/pdcurses/include/ -D_LP64=0
APP_CPPFLAGS-$(CONFIG_APP_LIB_MENU) += -I$(srctree)/apps/lib/curses/pdcurses/menu
+APP_CPPFLAGS-$(CONFIG_APP_LIB_FORM) += -I$(srctree)/apps/lib/curses/pdcurses/form
diff --git a/apps/lib/curses/pdcurses/form/Makefile b/apps/lib/curses/pdcurses/form/Makefile
new file mode 100644
index 0000000..42f641c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/Makefile
@@ -0,0 +1,42 @@
+app-y += frm_page.o
+app-y += frm_opts.o
+app-y += frm_def.o
+app-y += frm_req_name.o
+app-y += fty_alpha.o
+app-y += frm_driver.o
+app-y += fld_user.o
+app-y += frm_win.o
+app-y += fld_newftyp.o
+#app-y += fty_regex.o
+app-y += fld_stat.o
+app-y += fld_pad.o
+app-y += fld_current.o
+app-y += frm_post.o
+#app-y += f_trace.o
+app-y += fty_generic.o
+app-y += fld_page.o
+app-y += frm_hook.o
+app-y += frm_scale.o
+app-y += fty_int.o
+app-y += fty_alnum.o
+app-y += frm_cursor.o
+#app-y += fty_ipv4.o
+app-y += fld_link.o
+app-y += fld_arg.o
+app-y += fld_move.o
+app-y += fld_def.o
+app-y += fld_type.o
+app-y += fld_max.o
+app-y += fld_ftlink.o
+app-y += fld_ftchoice.o
+app-y += fld_info.o
+app-y += frm_user.o
+#app-y += fty_num.o
+app-y += frm_sub.o
+app-y += fty_enum.o
+app-y += frm_data.o
+app-y += fld_opts.o
+app-y += fld_attr.o
+app-y += fld_dup.o
+app-y += fld_just.o
+
diff --git a/apps/lib/curses/pdcurses/form/READ.ME b/apps/lib/curses/pdcurses/form/READ.ME
new file mode 100644
index 0000000..da86bf6
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/READ.ME
@@ -0,0 +1,42 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998-2003,2006 Free Software Foundation, Inc. --
+-- --
+-- 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. --
+-------------------------------------------------------------------------------
+-- $Id: READ.ME,v 0.7 2006/04/22 23:13:05 tom Exp $
+-------------------------------------------------------------------------------
+
+This is a clone of the form library that is available with typical
+System V curses implementations (ETI).
+
+It is modelled after the documentation that comes for this library with
+a 386 based SVR4 implementation (ESIX).
+
+The development environment was and is an ELF based Linux system.
+
+For things that still need doing, see the TO-DO file in the top-level
+directory.
+
+Juergen Pfeifer
diff --git a/apps/lib/curses/pdcurses/form/f_trace.c b/apps/lib/curses/pdcurses/form/f_trace.c
new file mode 100644
index 0000000..6044e03
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/f_trace.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Copyright (c) 2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: f_trace.c,v 1.2 2010/01/23 21:14:36 tom Exp $")
+
+NCURSES_EXPORT(FIELD **)
+_nc_retrace_field_ptr(FIELD **code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(FIELD *)
+_nc_retrace_field(FIELD *code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_retrace_field_type(FIELDTYPE *code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(FORM *)
+_nc_retrace_form(FORM *code)
+{
+ T((T_RETURN("%p"), (void *)code));
+ return code;
+}
+
+NCURSES_EXPORT(Form_Hook)
+_nc_retrace_form_hook(Form_Hook code)
+{
+ T((T_RETURN("%p"), code));
+ return code;
+}
diff --git a/apps/lib/curses/pdcurses/form/fld_arg.c b/apps/lib/curses/pdcurses/form/fld_arg.c
new file mode 100644
index 0000000..a07bdb1
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_arg.c
@@ -0,0 +1,98 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_arg.c,v 1.12 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_fieldtype_arg(
+| FIELDTYPE *typ,
+| void * (* const make_arg)(va_list *),
+| void * (* const copy_arg)(const void *),
+| void (* const free_arg)(void *) )
+|
+| Description : Connects to the type additional arguments necessary
+| for a set_field_type call. The various function pointer
+| arguments are:
+| make_arg : allocates a structure for the field
+| specific parameters.
+| copy_arg : duplicate the structure created by
+| make_arg
+| free_arg : Release the memory allocated by make_arg
+| or copy_arg
+|
+| At least make_arg must be non-NULL.
+| You may pass NULL for copy_arg and free_arg if your
+| make_arg function doesn't allocate memory and your
+| arg fits into the storage for a (void*).
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_fieldtype_arg(FIELDTYPE *typ,
+ void *(*const make_arg)(va_list *),
+ void *(*const copy_arg)(const void *),
+ void (*const free_arg) (void *))
+{
+ T((T_CALLED("set_fieldtype_arg(%p,%p,%p,%p)"),
+ (void *)typ, make_arg, copy_arg, free_arg));
+
+ if (typ != 0 && make_arg != (void *)0)
+ {
+ typ->status |= _HAS_ARGS;
+ typ->makearg = make_arg;
+ typ->copyarg = copy_arg;
+ typ->freearg = free_arg;
+ RETURN(E_OK);
+ }
+ RETURN(E_BAD_ARGUMENT);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *field_arg(const FIELD *field)
+|
+| Description : Retrieve pointer to the fields argument structure.
+|
+| Return Values : Pointer to structure or NULL if none is defined.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void *)
+field_arg(const FIELD *field)
+{
+ T((T_CALLED("field_arg(%p)"), (const void *)field));
+ returnVoidPtr(Normalize_Field(field)->arg);
+}
+
+/* fld_arg.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_attr.c b/apps/lib/curses/pdcurses/form/fld_attr.c
new file mode 100644
index 0000000..0112f00
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_attr.c
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_attr.c,v 1.11 2010/01/23 21:12:08 tom Exp $")
+
+/*----------------------------------------------------------------------------
+ Field-Attribute manipulation routines
+ --------------------------------------------------------------------------*/
+/* "Template" macro to generate a function to set a fields attribute */
+#define GEN_FIELD_ATTR_SET_FCT( name ) \
+NCURSES_IMPEXP int NCURSES_API set_field_ ## name (FIELD * field, chtype attr)\
+{\
+ int res = E_BAD_ARGUMENT;\
+ T((T_CALLED("set_field_" #name "(%p,%s)"), field, _traceattr(attr)));\
+ if ( attr==A_NORMAL || ((attr & A_ATTRIBUTES)==attr) )\
+ {\
+ Normalize_Field( field );\
+ if (field != 0) \
+ { \
+ if ((field -> name) != attr)\
+ {\
+ field -> name = attr;\
+ res = _nc_Synchronize_Attributes( field );\
+ }\
+ else\
+ {\
+ res = E_OK;\
+ }\
+ }\
+ }\
+ RETURN(res);\
+}
+
+/* "Template" macro to generate a function to get a fields attribute */
+#define GEN_FIELD_ATTR_GET_FCT( name ) \
+NCURSES_IMPEXP chtype NCURSES_API field_ ## name (const FIELD * field)\
+{\
+ T((T_CALLED("field_" #name "(%p)"), (const void *) field));\
+ returnAttr( A_ATTRIBUTES & (Normalize_Field( field ) -> name) );\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_fore(FIELD *field, chtype attr)
+|
+| Description : Sets the foreground of the field used to display the
+| field contents.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid attributes
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_SET_FCT(fore)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : chtype field_fore(const FIELD *)
+|
+| Description : Retrieve fields foreground attribute
+|
+| Return Values : The foreground attribute
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_GET_FCT(fore)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_back(FIELD *field, chtype attr)
+|
+| Description : Sets the background of the field used to display the
+| fields extend.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid attributes
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_SET_FCT(back)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : chtype field_back(const
+|
+| Description : Retrieve fields background attribute
+|
+| Return Values : The background attribute
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_GET_FCT(back)
+
+/* fld_attr.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_current.c b/apps/lib/curses/pdcurses/form/fld_current.c
new file mode 100644
index 0000000..ef9ec00
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_current.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_current.c,v 1.12 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_current_field(FORM * form,FIELD * field)
+|
+| Description : Set the current field of the form to the specified one.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form or field pointer
+| E_REQUEST_DENIED - field not selectable
+| E_BAD_STATE - called from a hook routine
+| E_INVALID_FIELD - current field can't be left
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_current_field(FORM *form, FIELD *field)
+{
+ int err = E_OK;
+
+ T((T_CALLED("set_current_field(%p,%p)"), (void *)form, (void *)field));
+ if (form == 0 || field == 0)
+ {
+ RETURN(E_BAD_ARGUMENT);
+ }
+ else if ((form != field->form) || Field_Is_Not_Selectable(field))
+ {
+ RETURN(E_REQUEST_DENIED);
+ }
+ else if ((form->status & _POSTED) == 0)
+ {
+ form->current = field;
+ form->curpage = field->page;
+ }
+ else
+ {
+ if ((form->status & _IN_DRIVER) != 0)
+ {
+ err = E_BAD_STATE;
+ }
+ else
+ {
+ if (form->current != field)
+ {
+ if (!_nc_Internal_Validation(form))
+ {
+ err = E_INVALID_FIELD;
+ }
+ else
+ {
+ Call_Hook(form, fieldterm);
+ if (field->page != form->curpage)
+ {
+ Call_Hook(form, formterm);
+ err = _nc_Set_Form_Page(form, (int)field->page, field);
+ Call_Hook(form, forminit);
+ }
+ else
+ {
+ err = _nc_Set_Current_Field(form, field);
+ }
+ Call_Hook(form, fieldinit);
+ (void)_nc_Refresh_Current_Field(form);
+ }
+ }
+ }
+ }
+ RETURN(err);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *current_field(const FORM * form)
+|
+| Description : Return the current field.
+|
+| Return Values : Pointer to the current field.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD *)
+current_field(const FORM *form)
+{
+ T((T_CALLED("current_field(%p)"), (const void *)form));
+ returnField(Normalize_Form(form)->current);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_index(const FIELD * field)
+|
+| Description : Return the index of the field in the field-array of
+| the form.
+|
+| Return Values : >= 0 : field index
+| -1 : fieldpointer invalid or field not connected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_index(const FIELD *field)
+{
+ T((T_CALLED("field_index(%p)"), (const void *)field));
+ returnCode((field != 0 && field->form != 0) ? (int)field->index : -1);
+}
+
+/* fld_current.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_def.c b/apps/lib/curses/pdcurses/form/fld_def.c
new file mode 100644
index 0000000..6d7bd34
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_def.c
@@ -0,0 +1,399 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_def.c,v 1.38 2010/01/23 21:14:35 tom Exp $")
+
+/* this can't be readonly */
+static FIELD default_field =
+{
+ 0, /* status */
+ 0, /* rows */
+ 0, /* cols */
+ 0, /* frow */
+ 0, /* fcol */
+ 0, /* drows */
+ 0, /* dcols */
+ 0, /* maxgrow */
+ 0, /* nrow */
+ 0, /* nbuf */
+ NO_JUSTIFICATION, /* just */
+ 0, /* page */
+ 0, /* index */
+ (int)' ', /* pad */
+ A_NORMAL, /* fore */
+ A_NORMAL, /* back */
+ ALL_FIELD_OPTS, /* opts */
+ (FIELD *)0, /* snext */
+ (FIELD *)0, /* sprev */
+ (FIELD *)0, /* link */
+ (FORM *)0, /* form */
+ (FIELDTYPE *)0, /* type */
+ (char *)0, /* arg */
+ (FIELD_CELL *)0, /* buf */
+ (char *)0 /* usrptr */
+ NCURSES_FIELD_EXTENSION
+};
+
+NCURSES_EXPORT_VAR(FIELD *)
+_nc_Default_Field = &default_field;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : TypeArgument *_nc_Make_Argument(
+| const FIELDTYPE *typ,
+| va_list *ap,
+| int *err )
+|
+| Description : Create an argument structure for the specified type.
+| Use the type-dependent argument list to construct
+| it.
+|
+| Return Values : Pointer to argument structure. Maybe NULL.
+| In case of an error in *err an error counter is increased.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(TypeArgument *)
+_nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)
+{
+ TypeArgument *res = (TypeArgument *)0;
+ TypeArgument *p;
+
+ if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
+ {
+ assert(err != 0 && ap != (va_list *)0);
+ if ((typ->status & _LINKED_TYPE) != 0)
+ {
+ p = typeMalloc(TypeArgument, 1);
+
+ if (p != 0)
+ {
+ p->left = _nc_Make_Argument(typ->left, ap, err);
+ p->right = _nc_Make_Argument(typ->right, ap, err);
+ return p;
+ }
+ else
+ {
+ *err += 1;
+ }
+ }
+ else
+ {
+ assert(typ->makearg != (void *)0);
+ if (!(res = (TypeArgument *)typ->makearg(ap)))
+ {
+ *err += 1;
+ }
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,
+| const TypeArgument *argp,
+| int *err )
+|
+| Description : Create a copy of an argument structure for the specified
+| type.
+|
+| Return Values : Pointer to argument structure. Maybe NULL.
+| In case of an error in *err an error counter is increased.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(TypeArgument *)
+_nc_Copy_Argument(const FIELDTYPE *typ, const TypeArgument *argp, int *err)
+{
+ TypeArgument *res = (TypeArgument *)0;
+ TypeArgument *p;
+
+ if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
+ {
+ assert(err != 0 && argp != 0);
+ if ((typ->status & _LINKED_TYPE) != 0)
+ {
+ p = typeMalloc(TypeArgument, 1);
+
+ if (p != 0)
+ {
+ p->left = _nc_Copy_Argument(typ, argp->left, err);
+ p->right = _nc_Copy_Argument(typ, argp->right, err);
+ return p;
+ }
+ *err += 1;
+ }
+ else
+ {
+ if (typ->copyarg != (void *)0)
+ {
+ if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
+ {
+ *err += 1;
+ }
+ }
+ else
+ {
+ res = (TypeArgument *)argp;
+ }
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void _nc_Free_Argument(const FIELDTYPE *typ,
+| TypeArgument * argp )
+|
+| Description : Release memory associated with the argument structure
+| for the given fieldtype.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Free_Argument(const FIELDTYPE *typ, TypeArgument *argp)
+{
+ if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
+ {
+ if ((typ->status & _LINKED_TYPE) != 0)
+ {
+ assert(argp != 0);
+ _nc_Free_Argument(typ->left, argp->left);
+ _nc_Free_Argument(typ->right, argp->right);
+ free(argp);
+ }
+ else
+ {
+ if (typ->freearg != (void *)0)
+ {
+ typ->freearg((void *)argp);
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool _nc_Copy_Type( FIELD *dst, FIELD const *src )
+|
+| Description : Copy argument structure of field src to field dst
+|
+| Return Values : TRUE - copy worked
+| FALSE - error occurred
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+_nc_Copy_Type(FIELD *dst, FIELD const *src)
+{
+ int err = 0;
+
+ assert(dst != 0 && src != 0);
+
+ dst->type = src->type;
+ dst->arg = (void *)_nc_Copy_Argument(src->type, (TypeArgument *)(src->arg), &err);
+
+ if (err != 0)
+ {
+ _nc_Free_Argument(dst->type, (TypeArgument *)(dst->arg));
+ dst->type = (FIELDTYPE *)0;
+ dst->arg = (void *)0;
+ return FALSE;
+ }
+ else
+ {
+ if (dst->type != 0)
+ {
+ dst->type->ref++;
+ }
+ return TRUE;
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void _nc_Free_Type( FIELD *field )
+|
+| Description : Release Argument structure for this field
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_Free_Type(FIELD *field)
+{
+ assert(field != 0);
+ if (field->type != 0)
+ {
+ field->type->ref--;
+ _nc_Free_Argument(field->type, (TypeArgument *)(field->arg));
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *new_field( int rows, int cols,
+| int frow, int fcol,
+| int nrow, int nbuf )
+|
+| Description : Create a new field with this many 'rows' and 'cols',
+| starting at 'frow/fcol' in the subwindow of the form.
+| Allocate 'nrow' off-screen rows and 'nbuf' additional
+| buffers. If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD *)
+new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
+{
+ static const FIELD_CELL blank = BLANK;
+ static const FIELD_CELL zeros = ZEROS;
+
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ T((T_CALLED("new_field(%d,%d,%d,%d,%d,%d)"), rows, cols, frow, fcol, nrow, nbuf));
+ if (rows > 0 &&
+ cols > 0 &&
+ frow >= 0 &&
+ fcol >= 0 &&
+ nrow >= 0 &&
+ nbuf >= 0 &&
+ ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
+ (New_Field = typeMalloc(FIELD, 1)) != 0)
+ {
+ T((T_CREATE("field %p"), (void *)New_Field));
+ *New_Field = default_field;
+ New_Field->rows = rows;
+ New_Field->cols = cols;
+ New_Field->drows = rows + nrow;
+ New_Field->dcols = cols;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+ New_Field->nrow = nrow;
+ New_Field->nbuf = nbuf;
+ New_Field->link = New_Field;
+
+#if USE_WIDEC_SUPPORT
+ New_Field->working = newpad(1, Buffer_Length(New_Field) + 1);
+ New_Field->expanded = typeCalloc(char *, 1 + (unsigned)nbuf);
+#endif
+
+ if (_nc_Copy_Type(New_Field, &default_field))
+ {
+ size_t len;
+
+ len = Total_Buffer_Size(New_Field);
+ if ((New_Field->buf = (FIELD_CELL *)malloc(len)))
+ {
+ /* Prefill buffers with blanks and insert terminating zeroes
+ between buffers */
+ int i, j;
+ int cells = Buffer_Length(New_Field);
+
+ for (i = 0; i <= New_Field->nbuf; i++)
+ {
+ FIELD_CELL *buffer = &(New_Field->buf[(cells + 1) * i]);
+
+ for (j = 0; j < cells; ++j)
+ {
+ buffer[j] = blank;
+ }
+ buffer[j] = zeros;
+ }
+ returnField(New_Field);
+ }
+ }
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR(err);
+ returnField((FIELD *)0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_field( FIELD *field )
+|
+| Description : Frees the storage allocated for the field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+free_field(FIELD *field)
+{
+ T((T_CALLED("free_field(%p)"), (void *)field));
+ if (!field)
+ {
+ RETURN(E_BAD_ARGUMENT);
+ }
+ else if (field->form != 0)
+ {
+ RETURN(E_CONNECTED);
+ }
+ else if (field == field->link)
+ {
+ if (field->buf != 0)
+ free(field->buf);
+ }
+ else
+ {
+ FIELD *f;
+
+ for (f = field; f->link != field; f = f->link)
+ {
+ }
+ f->link = field->link;
+ }
+ _nc_Free_Type(field);
+#if USE_WIDEC_SUPPORT
+ if (field->expanded != 0)
+ {
+ int n;
+
+ for (n = 0; n <= field->nbuf; ++n)
+ {
+ FreeIfNeeded(field->expanded[n]);
+ }
+ free(field->expanded);
+ (void)delwin(field->working);
+ }
+#endif
+ free(field);
+ RETURN(E_OK);
+}
+
+/* fld_def.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_dup.c b/apps/lib/curses/pdcurses/form/fld_dup.c
new file mode 100644
index 0000000..b8e501b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_dup.c
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_dup.c,v 1.13 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *dup_field(FIELD *field, int frow, int fcol)
+|
+| Description : Duplicates the field at the specified position. All
+| field attributes and the buffers are copied.
+| If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD *)
+dup_field(FIELD *field, int frow, int fcol)
+{
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ T((T_CALLED("dup_field(%p,%d,%d)"), (void *)field, frow, fcol));
+ if (field && (frow >= 0) && (fcol >= 0) &&
+ ((err = E_SYSTEM_ERROR) != 0) && /* trick : this resets the default error */
+ (New_Field = typeMalloc(FIELD, 1)))
+ {
+ T((T_CREATE("field %p"), (void *)New_Field));
+ *New_Field = *_nc_Default_Field;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+ New_Field->link = New_Field;
+ New_Field->rows = field->rows;
+ New_Field->cols = field->cols;
+ New_Field->nrow = field->nrow;
+ New_Field->drows = field->drows;
+ New_Field->dcols = field->dcols;
+ New_Field->maxgrow = field->maxgrow;
+ New_Field->nbuf = field->nbuf;
+ New_Field->just = field->just;
+ New_Field->fore = field->fore;
+ New_Field->back = field->back;
+ New_Field->pad = field->pad;
+ New_Field->opts = field->opts;
+ New_Field->usrptr = field->usrptr;
+
+ if (_nc_Copy_Type(New_Field, field))
+ {
+ size_t i, len;
+
+ len = Total_Buffer_Size(New_Field);
+ if ((New_Field->buf = (FIELD_CELL *)malloc(len)))
+ {
+ for (i = 0; i < len; ++i)
+ New_Field->buf[i] = field->buf[i];
+ returnField(New_Field);
+ }
+ }
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR(err);
+ returnField((FIELD *)0);
+}
+
+/* fld_dup.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_ftchoice.c b/apps/lib/curses/pdcurses/form/fld_ftchoice.c
new file mode 100644
index 0000000..e628171
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_ftchoice.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_ftchoice.c,v 1.12 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_fieldtype_choice(
+| FIELDTYPE *typ,
+| bool (* const next_choice)(FIELD *,const void *),
+| bool (* const prev_choice)(FIELD *,const void *))
+|
+| Description : Define implementation of enumeration requests.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid arguments
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_fieldtype_choice(FIELDTYPE *typ,
+ bool (*const next_choice) (FIELD *, const void *),
+ bool (*const prev_choice) (FIELD *, const void *))
+{
+ T((T_CALLED("set_fieldtype_choice(%p,%p,%p)"), (void *)typ, next_choice, prev_choice));
+
+ if (!typ || !next_choice || !prev_choice)
+ RETURN(E_BAD_ARGUMENT);
+
+ typ->status |= _HAS_CHOICE;
+#if NCURSES_INTEROP_FUNCS
+ typ->enum_next.onext = next_choice;
+ typ->enum_prev.oprev = prev_choice;
+#else
+ typ->next = next_choice;
+ typ->prev = prev_choice;
+#endif
+ RETURN(E_OK);
+}
+
+/* fld_ftchoice.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_ftlink.c b/apps/lib/curses/pdcurses/form/fld_ftlink.c
new file mode 100644
index 0000000..aa5862f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_ftlink.c
@@ -0,0 +1,87 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_ftlink.c,v 1.14 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *link_fieldtype(
+| FIELDTYPE *type1,
+| FIELDTYPE *type2)
+|
+| Description : Create a new fieldtype built from the two given types.
+| They are connected by an logical 'OR'.
+| If an error occurs, errno is set to
+| E_BAD_ARGUMENT - invalid arguments
+| E_SYSTEM_ERROR - system error (no memory)
+|
+| Return Values : Fieldtype pointer or NULL if error occurred.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELDTYPE *)
+link_fieldtype(FIELDTYPE *type1, FIELDTYPE *type2)
+{
+ FIELDTYPE *nftyp = (FIELDTYPE *)0;
+
+ T((T_CALLED("link_fieldtype(%p,%p)"), (void *)type1, (void *)type2));
+ if (type1 && type2)
+ {
+ nftyp = typeMalloc(FIELDTYPE, 1);
+
+ if (nftyp)
+ {
+ T((T_CREATE("fieldtype %p"), (void *)nftyp));
+ *nftyp = *_nc_Default_FieldType;
+ nftyp->status |= _LINKED_TYPE;
+ if ((type1->status & _HAS_ARGS) || (type2->status & _HAS_ARGS))
+ nftyp->status |= _HAS_ARGS;
+ if ((type1->status & _HAS_CHOICE) || (type2->status & _HAS_CHOICE))
+ nftyp->status |= _HAS_CHOICE;
+ nftyp->left = type1;
+ nftyp->right = type2;
+ type1->ref++;
+ type2->ref++;
+ }
+ else
+ {
+ SET_ERROR(E_SYSTEM_ERROR);
+ }
+ }
+ else
+ {
+ SET_ERROR(E_BAD_ARGUMENT);
+ }
+ returnFieldType(nftyp);
+}
+
+/* fld_ftlink.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_info.c b/apps/lib/curses/pdcurses/form/fld_info.c
new file mode 100644
index 0000000..da95e65
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_info.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_info.c,v 1.11 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_info(const FIELD *field,
+| int *rows, int *cols,
+| int *frow, int *fcol,
+| int *nrow, int *nbuf)
+|
+| Description : Retrieve infos about the fields creation parameters.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_info(const FIELD *field,
+ int *rows, int *cols,
+ int *frow, int *fcol,
+ int *nrow, int *nbuf)
+{
+ T((T_CALLED("field_info(%p,%p,%p,%p,%p,%p,%p)"),
+ (const void *)field,
+ (void *)rows, (void *)cols,
+ (void *)frow, (void *)fcol,
+ (void *)nrow, (void *)nbuf));
+
+ if (!field)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (rows)
+ *rows = field->rows;
+ if (cols)
+ *cols = field->cols;
+ if (frow)
+ *frow = field->frow;
+ if (fcol)
+ *fcol = field->fcol;
+ if (nrow)
+ *nrow = field->nrow;
+ if (nbuf)
+ *nbuf = field->nbuf;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int dynamic_field_info(const FIELD *field,
+| int *drows, int *dcols,
+| int *maxgrow)
+|
+| Description : Retrieve informations about a dynamic fields current
+| dynamic parameters.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+dynamic_field_info(const FIELD *field, int *drows, int *dcols, int *maxgrow)
+{
+ T((T_CALLED("dynamic_field_info(%p,%p,%p,%p)"),
+ (const void *)field,
+ (void *)drows,
+ (void *)dcols,
+ (void *)maxgrow));
+
+ if (!field)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (drows)
+ *drows = field->drows;
+ if (dcols)
+ *dcols = field->dcols;
+ if (maxgrow)
+ *maxgrow = field->maxgrow;
+
+ RETURN(E_OK);
+}
+
+/* fld_info.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_just.c b/apps/lib/curses/pdcurses/form/fld_just.c
new file mode 100644
index 0000000..a87ea70
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_just.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_just.c,v 1.12 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_just(FIELD *field, int just)
+|
+| Description : Set the fields type of justification.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - one of the arguments was incorrect
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_just(FIELD *field, int just)
+{
+ int res = E_BAD_ARGUMENT;
+
+ T((T_CALLED("set_field_just(%p,%d)"), (void *)field, just));
+
+ if ((just == NO_JUSTIFICATION) ||
+ (just == JUSTIFY_LEFT) ||
+ (just == JUSTIFY_CENTER) ||
+ (just == JUSTIFY_RIGHT))
+ {
+ Normalize_Field(field);
+ if (field->just != just)
+ {
+ field->just = just;
+ res = _nc_Synchronize_Attributes(field);
+ }
+ else
+ res = E_OK;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_just( const FIELD *field )
+|
+| Description : Retrieve the fields type of justification
+|
+| Return Values : The justification type.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_just(const FIELD *field)
+{
+ T((T_CALLED("field_just(%p)"), (const void *)field));
+ returnCode(Normalize_Field(field)->just);
+}
+
+/* fld_just.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_link.c b/apps/lib/curses/pdcurses/form/fld_link.c
new file mode 100644
index 0000000..31b9da0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_link.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_link.c,v 1.12 2010/01/23 21:14:35 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *link_field(FIELD *field, int frow, int fcol)
+|
+| Description : Duplicates the field at the specified position. The
+| new field shares its buffers with the original one,
+| the attributes are independent.
+| If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD *)
+link_field(FIELD *field, int frow, int fcol)
+{
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ T((T_CALLED("link_field(%p,%d,%d)"), (void *)field, frow, fcol));
+ if (field && (frow >= 0) && (fcol >= 0) &&
+ ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
+ (New_Field = typeMalloc(FIELD, 1)))
+ {
+ T((T_CREATE("field %p"), (void *)New_Field));
+ *New_Field = *_nc_Default_Field;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+
+ New_Field->link = field->link;
+ field->link = New_Field;
+
+ New_Field->buf = field->buf;
+ New_Field->rows = field->rows;
+ New_Field->cols = field->cols;
+ New_Field->nrow = field->nrow;
+ New_Field->nbuf = field->nbuf;
+ New_Field->drows = field->drows;
+ New_Field->dcols = field->dcols;
+ New_Field->maxgrow = field->maxgrow;
+ New_Field->just = field->just;
+ New_Field->fore = field->fore;
+ New_Field->back = field->back;
+ New_Field->pad = field->pad;
+ New_Field->opts = field->opts;
+ New_Field->usrptr = field->usrptr;
+
+ if (_nc_Copy_Type(New_Field, field))
+ returnField(New_Field);
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR(err);
+ returnField((FIELD *)0);
+}
+
+/* fld_link.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_max.c b/apps/lib/curses/pdcurses/form/fld_max.c
new file mode 100644
index 0000000..91d9819
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_max.c
@@ -0,0 +1,77 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_max.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_max_field(FIELD *field, int maxgrow)
+|
+| Description : Set the maximum growth for a dynamic field. If maxgrow=0
+| the field may grow to any possible size.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_max_field(FIELD *field, int maxgrow)
+{
+ T((T_CALLED("set_max_field(%p,%d)"), (void *)field, maxgrow));
+
+ if (!field || (maxgrow < 0))
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ bool single_line_field = Single_Line_Field(field);
+
+ if (maxgrow > 0)
+ {
+ if ((single_line_field && (maxgrow < field->dcols)) ||
+ (!single_line_field && (maxgrow < field->drows)))
+ RETURN(E_BAD_ARGUMENT);
+ }
+ field->maxgrow = maxgrow;
+ field->status &= ~_MAY_GROW;
+ if (!(field->opts & O_STATIC))
+ {
+ if ((maxgrow == 0) ||
+ (single_line_field && (field->dcols < maxgrow)) ||
+ (!single_line_field && (field->drows < maxgrow)))
+ field->status |= _MAY_GROW;
+ }
+ }
+ RETURN(E_OK);
+}
+
+/* fld_max.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_move.c b/apps/lib/curses/pdcurses/form/fld_move.c
new file mode 100644
index 0000000..24652ea
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_move.c
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_move.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int move_field(FIELD *field,int frow, int fcol)
+|
+| Description : Moves the disconnected field to the new location in
+| the forms subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument passed
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+move_field(FIELD *field, int frow, int fcol)
+{
+ T((T_CALLED("move_field(%p,%d,%d)"), (void *)field, frow, fcol));
+
+ if (!field || (frow < 0) || (fcol < 0))
+ RETURN(E_BAD_ARGUMENT);
+
+ if (field->form)
+ RETURN(E_CONNECTED);
+
+ field->frow = frow;
+ field->fcol = fcol;
+ RETURN(E_OK);
+}
+
+/* fld_move.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_newftyp.c b/apps/lib/curses/pdcurses/form/fld_newftyp.c
new file mode 100644
index 0000000..4351aed
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_newftyp.c
@@ -0,0 +1,143 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_newftyp.c,v 1.19 2010/01/23 21:14:36 tom Exp $")
+
+static FIELDTYPE default_fieldtype =
+{
+ 0, /* status */
+ 0L, /* reference count */
+ (FIELDTYPE *)0, /* pointer to left operand */
+ (FIELDTYPE *)0, /* pointer to right operand */
+ NULL, /* makearg function */
+ NULL, /* copyarg function */
+ NULL, /* freearg function */
+ INIT_FT_FUNC(NULL), /* field validation function */
+ INIT_FT_FUNC(NULL), /* Character check function */
+ INIT_FT_FUNC(NULL), /* enumerate next function */
+ INIT_FT_FUNC(NULL), /* enumerate previous function */
+#if NCURSES_INTEROP_FUNCS
+ NULL /* generic callback alternative to makearg */
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE *)
+_nc_Default_FieldType = &default_fieldtype;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *new_fieldtype(
+| bool (* const field_check)(FIELD *,const void *),
+| bool (* const char_check) (int, const void *) )
+|
+| Description : Create a new fieldtype. The application programmer must
+| write a field_check and a char_check function and give
+| them as input to this call.
+| If an error occurs, errno is set to
+| E_BAD_ARGUMENT - invalid arguments
+| E_SYSTEM_ERROR - system error (no memory)
+|
+| Return Values : Fieldtype pointer or NULL if error occurred
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELDTYPE *)
+new_fieldtype(bool (*const field_check) (FIELD *, const void *),
+ bool (*const char_check) (int, const void *))
+{
+ FIELDTYPE *nftyp = (FIELDTYPE *)0;
+
+ T((T_CALLED("new_fieldtype(%p,%p)"), field_check, char_check));
+ if ((field_check) || (char_check))
+ {
+ nftyp = typeMalloc(FIELDTYPE, 1);
+
+ if (nftyp)
+ {
+ T((T_CREATE("fieldtype %p"), (void *)nftyp));
+ *nftyp = default_fieldtype;
+#if NCURSES_INTEROP_FUNCS
+ nftyp->fieldcheck.ofcheck = field_check;
+ nftyp->charcheck.occheck = char_check;
+#else
+ nftyp->fcheck = field_check;
+ nftyp->ccheck = char_check;
+#endif
+ }
+ else
+ {
+ SET_ERROR(E_SYSTEM_ERROR);
+ }
+ }
+ else
+ {
+ SET_ERROR(E_BAD_ARGUMENT);
+ }
+ returnFieldType(nftyp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_fieldtype(FIELDTYPE *typ)
+|
+| Description : Release the memory associated with this fieldtype.
+|
+| Return Values : E_OK - success
+| E_CONNECTED - there are fields referencing the type
+| E_BAD_ARGUMENT - invalid fieldtype pointer
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+free_fieldtype(FIELDTYPE *typ)
+{
+ T((T_CALLED("free_fieldtype(%p)"), (void *)typ));
+
+ if (!typ)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (typ->ref != 0)
+ RETURN(E_CONNECTED);
+
+ if (typ->status & _RESIDENT)
+ RETURN(E_CONNECTED);
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ if (typ->left)
+ typ->left->ref--;
+ if (typ->right)
+ typ->right->ref--;
+ }
+ free(typ);
+ RETURN(E_OK);
+}
+
+/* fld_newftyp.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_opts.c b/apps/lib/curses/pdcurses/form/fld_opts.c
new file mode 100644
index 0000000..4e92bd9
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_opts.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_opts.c,v 1.12 2010/01/23 21:14:36 tom Exp $")
+
+/*----------------------------------------------------------------------------
+ Field-Options manipulation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_opts(FIELD *field, Field_Options opts)
+|
+| Description : Turns on the named options for this field and turns
+| off all the remaining options.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_opts(FIELD *field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+
+ T((T_CALLED("set_field_opts(%p,%d)"), (void *)field, opts));
+
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ res = _nc_Synchronize_Options(Normalize_Field(field), opts);
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Field_Options field_opts(const FIELD *field)
+|
+| Description : Retrieve the fields options.
+|
+| Return Values : The options.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(Field_Options)
+field_opts(const FIELD *field)
+{
+ T((T_CALLED("field_opts(%p)"), (const void *)field));
+
+ returnCode(ALL_FIELD_OPTS & Normalize_Field(field)->opts);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_opts_on(FIELD *field, Field_Options opts)
+|
+| Description : Turns on the named options for this field and all the
+| remaining options are unchanged.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_opts_on(FIELD *field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+
+ T((T_CALLED("field_opts_on(%p,%d)"), (void *)field, opts));
+
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ {
+ Normalize_Field(field);
+ res = _nc_Synchronize_Options(field, field->opts | opts);
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_opts_off(FIELD *field, Field_Options opts)
+|
+| Description : Turns off the named options for this field and all the
+| remaining options are unchanged.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_opts_off(FIELD *field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+
+ T((T_CALLED("field_opts_off(%p,%d)"), (void *)field, opts));
+
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ {
+ Normalize_Field(field);
+ res = _nc_Synchronize_Options(field, field->opts & ~opts);
+ }
+ RETURN(res);
+}
+
+/* fld_opts.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_pad.c b/apps/lib/curses/pdcurses/form/fld_pad.c
new file mode 100644
index 0000000..37df703
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_pad.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_pad.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_pad(FIELD *field, int ch)
+|
+| Description : Set the pad character used to fill the field. This must
+| be a printable character.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer or pad character
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_pad(FIELD *field, int ch)
+{
+ int res = E_BAD_ARGUMENT;
+
+ T((T_CALLED("set_field_pad(%p,%d)"), (void *)field, ch));
+
+ Normalize_Field(field);
+ if (isprint(UChar(ch)))
+ {
+ if (field->pad != ch)
+ {
+ field->pad = ch;
+ res = _nc_Synchronize_Attributes(field);
+ }
+ else
+ res = E_OK;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_pad(const FIELD *field)
+|
+| Description : Retrieve the fields pad character.
+|
+| Return Values : The pad character.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_pad(const FIELD *field)
+{
+ T((T_CALLED("field_pad(%p)"), (const void *)field));
+
+ returnCode(Normalize_Field(field)->pad);
+}
+
+/* fld_pad.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_page.c b/apps/lib/curses/pdcurses/form/fld_page.c
new file mode 100644
index 0000000..67f48a1
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_page.c
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_page.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_new_page(FIELD *field, bool new_page_flag)
+|
+| Description : Marks the field as the beginning of a new page of
+| the form.
+|
+| Return Values : E_OK - success
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_new_page(FIELD *field, bool new_page_flag)
+{
+ T((T_CALLED("set_new_page(%p,%d)"), (void *)field, new_page_flag));
+
+ Normalize_Field(field);
+ if (field->form)
+ RETURN(E_CONNECTED);
+
+ if (new_page_flag)
+ field->status |= _NEWPAGE;
+ else
+ field->status &= ~_NEWPAGE;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool new_page(const FIELD *field)
+|
+| Description : Retrieve the info whether or not the field starts a
+| new page on the form.
+|
+| Return Values : TRUE - field starts a new page
+| FALSE - field doesn't start a new page
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+new_page(const FIELD *field)
+{
+ T((T_CALLED("new_page(%p)"), (const void *)field));
+
+ returnBool((Normalize_Field(field)->status & _NEWPAGE) ? TRUE : FALSE);
+}
+
+/* fld_page.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_stat.c b/apps/lib/curses/pdcurses/form/fld_stat.c
new file mode 100644
index 0000000..bc5ba50
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_stat.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_stat.c,v 1.12 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_status(FIELD *field, bool status)
+|
+| Description : Set or clear the 'changed' indication flag for that
+| fields primary buffer.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_status(FIELD *field, bool status)
+{
+ T((T_CALLED("set_field_status(%p,%d)"), (void *)field, status));
+
+ Normalize_Field(field);
+
+ if (status)
+ field->status |= _CHANGED;
+ else
+ field->status &= ~_CHANGED;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool field_status(const FIELD *field)
+|
+| Description : Retrieve the value of the 'changed' indication flag
+| for that fields primary buffer.
+|
+| Return Values : TRUE - buffer has been changed
+| FALSE - buffer has not been changed
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+field_status(const FIELD *field)
+{
+ T((T_CALLED("field_status(%p)"), (const void *)field));
+
+ returnBool((Normalize_Field(field)->status & _CHANGED) ? TRUE : FALSE);
+}
+
+/* fld_stat.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_type.c b/apps/lib/curses/pdcurses/form/fld_type.c
new file mode 100644
index 0000000..1117a56
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_type.c
@@ -0,0 +1,97 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_type.c,v 1.16 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_type(FIELD *field, FIELDTYPE *type,...)
+|
+| Description : Associate the specified fieldtype with the field.
+| Certain field types take additional arguments. Look
+| at the spec of the field types !
+|
+| Return Values : E_OK - success
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_type(FIELD *field, FIELDTYPE *type,...)
+{
+ va_list ap;
+ int res = E_SYSTEM_ERROR;
+ int err = 0;
+
+ T((T_CALLED("set_field_type(%p,%p)"), (void *)field, (void *)type));
+
+ va_start(ap, type);
+
+ Normalize_Field(field);
+ _nc_Free_Type(field);
+
+ field->type = type;
+ field->arg = (void *)_nc_Make_Argument(field->type, &ap, &err);
+
+ if (err)
+ {
+ _nc_Free_Argument(field->type, (TypeArgument *)(field->arg));
+ field->type = (FIELDTYPE *)0;
+ field->arg = (void *)0;
+ }
+ else
+ {
+ res = E_OK;
+ if (field->type)
+ field->type->ref++;
+ }
+
+ va_end(ap);
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *field_type(const FIELD *field)
+|
+| Description : Retrieve the associated fieldtype for this field.
+|
+| Return Values : Pointer to fieldtype of NULL if none is defined.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELDTYPE *)
+field_type(const FIELD *field)
+{
+ T((T_CALLED("field_type(%p)"), (const void *)field));
+ returnFieldType(Normalize_Field(field)->type);
+}
+
+/* fld_type.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fld_user.c b/apps/lib/curses/pdcurses/form/fld_user.c
new file mode 100644
index 0000000..075580b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fld_user.c
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fld_user.c,v 1.16 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_userptr(FIELD *field, void *usrptr)
+|
+| Description : Set the pointer that is reserved in any field to store
+| application relevant informations
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_userptr(FIELD *field, void *usrptr)
+{
+ T((T_CALLED("set_field_userptr(%p,%p)"), (void *)field, (void *)usrptr));
+
+ Normalize_Field(field)->usrptr = usrptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *field_userptr(const FIELD *field)
+|
+| Description : Return the pointer that is reserved in any field to
+| store application relevant informations.
+|
+| Return Values : Value of pointer. If no such pointer has been set,
+| NULL is returned
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void *)
+field_userptr(const FIELD *field)
+{
+ T((T_CALLED("field_userptr(%p)"), (const void *)field));
+ returnVoidPtr(Normalize_Field(field)->usrptr);
+}
+
+/* fld_user.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/form.h b/apps/lib/curses/pdcurses/form/form.h
new file mode 100644
index 0000000..d7bb85a
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/form.h
@@ -0,0 +1,423 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: form.h,v 0.21 2009/11/07 19:31:11 tom Exp $ */
+
+#ifndef FORM_H
+#define FORM_H
+
+#include <curses.h>
+#include <eti.h>
+#include <ncurses_cfg.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef FORM_PRIV_H
+typedef void *FIELD_CELL;
+#endif
+
+#ifndef NCURSES_FIELD_INTERNALS
+#define NCURSES_FIELD_INTERNALS /* nothing */
+#endif
+
+typedef int Form_Options;
+typedef int Field_Options;
+
+ /**********
+ * _PAGE *
+ **********/
+
+typedef struct {
+ short pmin; /* index of first field on page */
+ short pmax; /* index of last field on page */
+ short smin; /* index of top leftmost field on page */
+ short smax; /* index of bottom rightmost field on page */
+} _PAGE;
+
+ /**********
+ * FIELD *
+ **********/
+
+typedef struct fieldnode {
+ unsigned short status; /* flags */
+ short rows; /* size in rows */
+ short cols; /* size in cols */
+ short frow; /* first row */
+ short fcol; /* first col */
+ int drows; /* dynamic rows */
+ int dcols; /* dynamic cols */
+ int maxgrow; /* maximum field growth */
+ int nrow; /* off-screen rows */
+ short nbuf; /* additional buffers */
+ short just; /* justification */
+ short page; /* page on form */
+ short index; /* into form -> field */
+ int pad; /* pad character */
+ chtype fore; /* foreground attribute */
+ chtype back; /* background attribute */
+ Field_Options opts; /* options */
+ struct fieldnode * snext; /* sorted order pointer */
+ struct fieldnode * sprev; /* sorted order pointer */
+ struct fieldnode * link; /* linked field chain */
+ struct formnode * form; /* containing form */
+ struct typenode * type; /* field type */
+ void * arg; /* argument for type */
+ FIELD_CELL * buf; /* field buffers */
+ void * usrptr; /* user pointer */
+ /*
+ * The wide-character configuration requires extra information. Because
+ * there are existing applications that manipulate the members of FIELD
+ * directly, we cannot make the struct opaque. Offsets of members up to
+ * this point are the same in the narrow- and wide-character configuration.
+ * But note that the type of buf depends on the configuration, and is made
+ * opaque for that reason.
+ */
+ NCURSES_FIELD_INTERNALS
+} FIELD;
+
+
+ /*********
+ * FORM *
+ *********/
+
+typedef struct formnode {
+ unsigned short status; /* flags */
+ short rows; /* size in rows */
+ short cols; /* size in cols */
+ int currow; /* current row in field window */
+ int curcol; /* current col in field window */
+ int toprow; /* in scrollable field window */
+ int begincol; /* in horiz. scrollable field */
+ short maxfield; /* number of fields */
+ short maxpage; /* number of pages */
+ short curpage; /* index into page */
+ Form_Options opts; /* options */
+ WINDOW * win; /* window */
+ WINDOW * sub; /* subwindow */
+ WINDOW * w; /* window for current field */
+ FIELD ** field; /* field [maxfield] */
+ FIELD * current; /* current field */
+ _PAGE * page; /* page [maxpage] */
+ void * usrptr; /* user pointer */
+
+ void (*forminit)(struct formnode *);
+ void (*formterm)(struct formnode *);
+ void (*fieldinit)(struct formnode *);
+ void (*fieldterm)(struct formnode *);
+
+} FORM;
+
+
+ /**************
+ * FIELDTYPE *
+ **************/
+
+typedef struct typenode {
+ unsigned short status; /* flags */
+ long ref; /* reference count */
+ struct typenode * left; /* ptr to operand for | */
+ struct typenode * right; /* ptr to operand for | */
+
+ void* (*makearg)(va_list *); /* make fieldtype arg */
+ void* (*copyarg)(const void *); /* copy fieldtype arg */
+ void (*freearg)(void *); /* free fieldtype arg */
+
+#if NCURSES_INTEROP_FUNCS
+ union {
+ bool (*ofcheck)(FIELD *,const void *); /* field validation */
+ bool (*gfcheck)(FORM*,FIELD *,const void*); /* generic field validation */
+ } fieldcheck;
+ union {
+ bool (*occheck)(int,const void *); /* character validation */
+ bool (*gccheck)(int,FORM*,
+ FIELD*,const void*); /* generic char validation */
+ } charcheck;
+ union {
+ bool (*onext)(FIELD *,const void *); /* enumerate next value */
+ bool (*gnext)(FORM*,FIELD*,const void*); /* generic enumerate next */
+ } enum_next;
+ union {
+ bool (*oprev)(FIELD *,const void *); /* enumerate prev value */
+ bool (*gprev)(FORM*,FIELD*,const void*); /* generic enumerate prev */
+ } enum_prev;
+ void* (*genericarg)(void*); /* Alternate Arg method */
+#else
+ bool (*fcheck)(FIELD *,const void *); /* field validation */
+ bool (*ccheck)(int,const void *); /* character validation */
+
+ bool (*next)(FIELD *,const void *); /* enumerate next value */
+ bool (*prev)(FIELD *,const void *); /* enumerate prev value */
+#endif
+} FIELDTYPE;
+
+typedef void (*Form_Hook)(FORM *);
+
+ /***************************
+ * miscellaneous #defines *
+ ***************************/
+
+/* field justification */
+#define NO_JUSTIFICATION (0)
+#define JUSTIFY_LEFT (1)
+#define JUSTIFY_CENTER (2)
+#define JUSTIFY_RIGHT (3)
+
+/* field options */
+#define O_VISIBLE (0x0001U)
+#define O_ACTIVE (0x0002U)
+#define O_PUBLIC (0x0004U)
+#define O_EDIT (0x0008U)
+#define O_WRAP (0x0010U)
+#define O_BLANK (0x0020U)
+#define O_AUTOSKIP (0x0040U)
+#define O_NULLOK (0x0080U)
+#define O_PASSOK (0x0100U)
+#define O_STATIC (0x0200U)
+
+/* form options */
+#define O_NL_OVERLOAD (0x0001U)
+#define O_BS_OVERLOAD (0x0002U)
+
+/* form driver commands */
+#define REQ_NEXT_PAGE (KEY_MAX + 1) /* move to next page */
+#define REQ_PREV_PAGE (KEY_MAX + 2) /* move to previous page */
+#define REQ_FIRST_PAGE (KEY_MAX + 3) /* move to first page */
+#define REQ_LAST_PAGE (KEY_MAX + 4) /* move to last page */
+
+#define REQ_NEXT_FIELD (KEY_MAX + 5) /* move to next field */
+#define REQ_PREV_FIELD (KEY_MAX + 6) /* move to previous field */
+#define REQ_FIRST_FIELD (KEY_MAX + 7) /* move to first field */
+#define REQ_LAST_FIELD (KEY_MAX + 8) /* move to last field */
+#define REQ_SNEXT_FIELD (KEY_MAX + 9) /* move to sorted next field */
+#define REQ_SPREV_FIELD (KEY_MAX + 10) /* move to sorted prev field */
+#define REQ_SFIRST_FIELD (KEY_MAX + 11) /* move to sorted first field */
+#define REQ_SLAST_FIELD (KEY_MAX + 12) /* move to sorted last field */
+#define REQ_LEFT_FIELD (KEY_MAX + 13) /* move to left to field */
+#define REQ_RIGHT_FIELD (KEY_MAX + 14) /* move to right to field */
+#define REQ_UP_FIELD (KEY_MAX + 15) /* move to up to field */
+#define REQ_DOWN_FIELD (KEY_MAX + 16) /* move to down to field */
+
+#define REQ_NEXT_CHAR (KEY_MAX + 17) /* move to next char in field */
+#define REQ_PREV_CHAR (KEY_MAX + 18) /* move to prev char in field */
+#define REQ_NEXT_LINE (KEY_MAX + 19) /* move to next line in field */
+#define REQ_PREV_LINE (KEY_MAX + 20) /* move to prev line in field */
+#define REQ_NEXT_WORD (KEY_MAX + 21) /* move to next word in field */
+#define REQ_PREV_WORD (KEY_MAX + 22) /* move to prev word in field */
+#define REQ_BEG_FIELD (KEY_MAX + 23) /* move to first char in field */
+#define REQ_END_FIELD (KEY_MAX + 24) /* move after last char in fld */
+#define REQ_BEG_LINE (KEY_MAX + 25) /* move to beginning of line */
+#define REQ_END_LINE (KEY_MAX + 26) /* move after last char in line */
+#define REQ_LEFT_CHAR (KEY_MAX + 27) /* move left in field */
+#define REQ_RIGHT_CHAR (KEY_MAX + 28) /* move right in field */
+#define REQ_UP_CHAR (KEY_MAX + 29) /* move up in field */
+#define REQ_DOWN_CHAR (KEY_MAX + 30) /* move down in field */
+
+#define REQ_NEW_LINE (KEY_MAX + 31) /* insert/overlay new line */
+#define REQ_INS_CHAR (KEY_MAX + 32) /* insert blank char at cursor */
+#define REQ_INS_LINE (KEY_MAX + 33) /* insert blank line at cursor */
+#define REQ_DEL_CHAR (KEY_MAX + 34) /* delete char at cursor */
+#define REQ_DEL_PREV (KEY_MAX + 35) /* delete char before cursor */
+#define REQ_DEL_LINE (KEY_MAX + 36) /* delete line at cursor */
+#define REQ_DEL_WORD (KEY_MAX + 37) /* delete word at cursor */
+#define REQ_CLR_EOL (KEY_MAX + 38) /* clear to end of line */
+#define REQ_CLR_EOF (KEY_MAX + 39) /* clear to end of field */
+#define REQ_CLR_FIELD (KEY_MAX + 40) /* clear entire field */
+#define REQ_OVL_MODE (KEY_MAX + 41) /* begin overlay mode */
+#define REQ_INS_MODE (KEY_MAX + 42) /* begin insert mode */
+#define REQ_SCR_FLINE (KEY_MAX + 43) /* scroll field forward a line */
+#define REQ_SCR_BLINE (KEY_MAX + 44) /* scroll field backward a line */
+#define REQ_SCR_FPAGE (KEY_MAX + 45) /* scroll field forward a page */
+#define REQ_SCR_BPAGE (KEY_MAX + 46) /* scroll field backward a page */
+#define REQ_SCR_FHPAGE (KEY_MAX + 47) /* scroll field forward half page */
+#define REQ_SCR_BHPAGE (KEY_MAX + 48) /* scroll field backward half page */
+#define REQ_SCR_FCHAR (KEY_MAX + 49) /* horizontal scroll char */
+#define REQ_SCR_BCHAR (KEY_MAX + 50) /* horizontal scroll char */
+#define REQ_SCR_HFLINE (KEY_MAX + 51) /* horizontal scroll line */
+#define REQ_SCR_HBLINE (KEY_MAX + 52) /* horizontal scroll line */
+#define REQ_SCR_HFHALF (KEY_MAX + 53) /* horizontal scroll half line */
+#define REQ_SCR_HBHALF (KEY_MAX + 54) /* horizontal scroll half line */
+
+#define REQ_VALIDATION (KEY_MAX + 55) /* validate field */
+#define REQ_NEXT_CHOICE (KEY_MAX + 56) /* display next field choice */
+#define REQ_PREV_CHOICE (KEY_MAX + 57) /* display prev field choice */
+
+#define MIN_FORM_COMMAND (KEY_MAX + 1) /* used by form_driver */
+#define MAX_FORM_COMMAND (KEY_MAX + 57) /* used by form_driver */
+
+#if defined(MAX_COMMAND)
+# if (MAX_FORM_COMMAND > MAX_COMMAND)
+# error Something is wrong -- MAX_FORM_COMMAND is greater than MAX_COMMAND
+# elif (MAX_COMMAND != (KEY_MAX + 128))
+# error Something is wrong -- MAX_COMMAND is already inconsistently defined.
+# endif
+#else
+# define MAX_COMMAND (KEY_MAX + 128)
+#endif
+
+ /*************************
+ * standard field types *
+ *************************/
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ALPHA;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ALNUM;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ENUM;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_INTEGER;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_NUMERIC;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_REGEXP;
+
+ /************************************
+ * built-in additional field types *
+ * They are not defined in SVr4 *
+ ************************************/
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_IPV4; /* Internet IP Version 4 address */
+
+ /***********************
+ * FIELDTYPE routines *
+ ***********************/
+extern NCURSES_EXPORT(FIELDTYPE *) new_fieldtype (
+ bool (* const field_check)(FIELD *,const void *),
+ bool (* const char_check)(int,const void *));
+extern NCURSES_EXPORT(FIELDTYPE *) link_fieldtype(
+ FIELDTYPE *, FIELDTYPE *);
+
+extern NCURSES_EXPORT(int) free_fieldtype (FIELDTYPE *);
+extern NCURSES_EXPORT(int) set_fieldtype_arg (FIELDTYPE *,
+ void * (* const make_arg)(va_list *),
+ void * (* const copy_arg)(const void *),
+ void (* const free_arg)(void *));
+extern NCURSES_EXPORT(int) set_fieldtype_choice (FIELDTYPE *,
+ bool (* const next_choice)(FIELD *,const void *),
+ bool (* const prev_choice)(FIELD *,const void *));
+
+ /*******************
+ * FIELD routines *
+ *******************/
+extern NCURSES_EXPORT(FIELD *) new_field (int,int,int,int,int,int);
+extern NCURSES_EXPORT(FIELD *) dup_field (FIELD *,int,int);
+extern NCURSES_EXPORT(FIELD *) link_field (FIELD *,int,int);
+
+extern NCURSES_EXPORT(int) free_field (FIELD *);
+extern NCURSES_EXPORT(int) field_info (const FIELD *,int *,int *,int *,int *,int *,int *);
+extern NCURSES_EXPORT(int) dynamic_field_info (const FIELD *,int *,int *,int *);
+extern NCURSES_EXPORT(int) set_max_field ( FIELD *,int);
+extern NCURSES_EXPORT(int) move_field (FIELD *,int,int);
+extern NCURSES_EXPORT(int) set_field_type (FIELD *,FIELDTYPE *,...);
+extern NCURSES_EXPORT(int) set_new_page (FIELD *,bool);
+extern NCURSES_EXPORT(int) set_field_just (FIELD *,int);
+extern NCURSES_EXPORT(int) field_just (const FIELD *);
+extern NCURSES_EXPORT(int) set_field_fore (FIELD *,chtype);
+extern NCURSES_EXPORT(int) set_field_back (FIELD *,chtype);
+extern NCURSES_EXPORT(int) set_field_pad (FIELD *,int);
+extern NCURSES_EXPORT(int) field_pad (const FIELD *);
+extern NCURSES_EXPORT(int) set_field_buffer (FIELD *,int,const char *);
+extern NCURSES_EXPORT(int) set_field_status (FIELD *,bool);
+extern NCURSES_EXPORT(int) set_field_userptr (FIELD *, void *);
+extern NCURSES_EXPORT(int) set_field_opts (FIELD *,Field_Options);
+extern NCURSES_EXPORT(int) field_opts_on (FIELD *,Field_Options);
+extern NCURSES_EXPORT(int) field_opts_off (FIELD *,Field_Options);
+
+extern NCURSES_EXPORT(chtype) field_fore (const FIELD *);
+extern NCURSES_EXPORT(chtype) field_back (const FIELD *);
+
+extern NCURSES_EXPORT(bool) new_page (const FIELD *);
+extern NCURSES_EXPORT(bool) field_status (const FIELD *);
+
+extern NCURSES_EXPORT(void *) field_arg (const FIELD *);
+
+extern NCURSES_EXPORT(void *) field_userptr (const FIELD *);
+
+extern NCURSES_EXPORT(FIELDTYPE *) field_type (const FIELD *);
+
+extern NCURSES_EXPORT(char *) field_buffer (const FIELD *,int);
+
+extern NCURSES_EXPORT(Field_Options) field_opts (const FIELD *);
+
+ /******************
+ * FORM routines *
+ ******************/
+
+extern NCURSES_EXPORT(FORM *) new_form (FIELD **);
+
+extern NCURSES_EXPORT(FIELD **) form_fields (const FORM *);
+extern NCURSES_EXPORT(FIELD *) current_field (const FORM *);
+
+extern NCURSES_EXPORT(WINDOW *) form_win (const FORM *);
+extern NCURSES_EXPORT(WINDOW *) form_sub (const FORM *);
+
+extern NCURSES_EXPORT(Form_Hook) form_init (const FORM *);
+extern NCURSES_EXPORT(Form_Hook) form_term (const FORM *);
+extern NCURSES_EXPORT(Form_Hook) field_init (const FORM *);
+extern NCURSES_EXPORT(Form_Hook) field_term (const FORM *);
+
+extern NCURSES_EXPORT(int) free_form (FORM *);
+extern NCURSES_EXPORT(int) set_form_fields (FORM *,FIELD **);
+extern NCURSES_EXPORT(int) field_count (const FORM *);
+extern NCURSES_EXPORT(int) set_form_win (FORM *,WINDOW *);
+extern NCURSES_EXPORT(int) set_form_sub (FORM *,WINDOW *);
+extern NCURSES_EXPORT(int) set_current_field (FORM *,FIELD *);
+extern NCURSES_EXPORT(int) field_index (const FIELD *);
+extern NCURSES_EXPORT(int) set_form_page (FORM *,int);
+extern NCURSES_EXPORT(int) form_page (const FORM *);
+extern NCURSES_EXPORT(int) scale_form (const FORM *,int *,int *);
+extern NCURSES_EXPORT(int) set_form_init (FORM *,Form_Hook);
+extern NCURSES_EXPORT(int) set_form_term (FORM *,Form_Hook);
+extern NCURSES_EXPORT(int) set_field_init (FORM *,Form_Hook);
+extern NCURSES_EXPORT(int) set_field_term (FORM *,Form_Hook);
+extern NCURSES_EXPORT(int) post_form (FORM *);
+extern NCURSES_EXPORT(int) unpost_form (FORM *);
+extern NCURSES_EXPORT(int) pos_form_cursor (FORM *);
+extern NCURSES_EXPORT(int) form_driver (FORM *,int);
+extern NCURSES_EXPORT(int) set_form_userptr (FORM *,void *);
+extern NCURSES_EXPORT(int) set_form_opts (FORM *,Form_Options);
+extern NCURSES_EXPORT(int) form_opts_on (FORM *,Form_Options);
+extern NCURSES_EXPORT(int) form_opts_off (FORM *,Form_Options);
+extern NCURSES_EXPORT(int) form_request_by_name (const char *);
+
+extern NCURSES_EXPORT(const char *) form_request_name (int);
+
+extern NCURSES_EXPORT(void *) form_userptr (const FORM *);
+
+extern NCURSES_EXPORT(Form_Options) form_opts (const FORM *);
+
+extern NCURSES_EXPORT(bool) data_ahead (const FORM *);
+extern NCURSES_EXPORT(bool) data_behind (const FORM *);
+
+#if NCURSES_SP_FUNCS
+extern NCURSES_EXPORT(FORM *) NCURSES_SP_NAME(new_form) (SCREEN*, FIELD **);
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FORM_H */
diff --git a/apps/lib/curses/pdcurses/form/form.priv.h b/apps/lib/curses/pdcurses/form/form.priv.h
new file mode 100644
index 0000000..a118b29
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/form.priv.h
@@ -0,0 +1,299 @@
+/****************************************************************************
+ * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/* $Id: form.priv.h,v 0.32 2009/11/07 21:26:43 tom Exp $ */
+
+#ifndef FORM_PRIV_H
+#define FORM_PRIV_H 1
+
+#include "../pdcurses/curspriv.h"
+#include "../menu/mf_common.h"
+
+#define UChar(c) ((unsigned char)(c))
+
+#if USE_WIDEC_SUPPORT
+#if HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 8 /* should be >= MB_CUR_MAX, but that may be a function */
+#endif
+
+#define FIELD_CELL NCURSES_CH_T
+
+#define NCURSES_FIELD_INTERNALS char** expanded; WINDOW *working;
+#define NCURSES_FIELD_EXTENSION , (char **)0, (WINDOW *)0
+
+#else
+
+#define FIELD_CELL char
+
+#define NCURSES_FIELD_EXTENSION /* nothing */
+
+#endif
+
+#include "form.h"
+
+ /***********************
+ * Default objects *
+ ***********************/
+extern NCURSES_EXPORT_VAR(FORM *) _nc_Default_Form;
+extern NCURSES_EXPORT_VAR(FIELD *) _nc_Default_Field;
+extern NCURSES_EXPORT_VAR(FIELDTYPE *) _nc_Default_FieldType;
+
+/* form status values */
+#define _OVLMODE (0x04U) /* Form is in overlay mode */
+#define _WINDOW_MODIFIED (0x10U) /* Current field window has been modified */
+#define _FCHECK_REQUIRED (0x20U) /* Current field needs validation */
+
+/* field status values */
+#define _CHANGED (0x01U) /* Field has been changed */
+#define _NEWTOP (0x02U) /* Vertical scrolling occurred */
+#define _NEWPAGE (0x04U) /* field begins new page of form */
+#define _MAY_GROW (0x08U) /* dynamic field may still grow */
+
+/* fieldtype status values */
+#define _LINKED_TYPE (0x01U) /* Type is a linked type */
+#define _HAS_ARGS (0x02U) /* Type has arguments */
+#define _HAS_CHOICE (0x04U) /* Type has choice methods */
+#define _RESIDENT (0x08U) /* Type is built-in */
+#define _GENERIC (0x10U) /* A generic field type */
+
+/* This are the field options required to be a selectable field in field
+ navigation requests */
+#define O_SELECTABLE (O_ACTIVE | O_VISIBLE)
+
+/* If form is NULL replace form argument by default-form */
+#define Normalize_Form(form) \
+ ((form) = (form != 0) ? (form) : _nc_Default_Form)
+
+/* If field is NULL replace field argument by default-field */
+#define Normalize_Field(field) \
+ ((field) = (field != 0) ? (field) : _nc_Default_Field)
+
+#if NCURSES_SP_FUNCS
+#define Get_Form_Screen(form) \
+ ((form)->win ? _nc_screen_of((form->win)):CURRENT_SCREEN)
+#else
+#define Get_Form_Screen(form) CURRENT_SCREEN
+#endif
+
+/* Retrieve forms window */
+#define Get_Form_Window(form) \
+ ((form)->sub != NULL \
+ ? (form)->sub \
+ : ((form)->win != NULL \
+ ? (form)->win \
+ : StdScreen(Get_Form_Screen(form))))
+
+/* Calculate the size for a single buffer for this field */
+#define Buffer_Length(field) ((field)->drows * (field)->dcols)
+
+/* Calculate the total size of all buffers for this field */
+#define Total_Buffer_Size(field) \
+ ( (Buffer_Length(field) + 1) * (1+(field)->nbuf) * sizeof(FIELD_CELL) )
+
+/* Logic to determine whether or not a field is single lined */
+#define Single_Line_Field(field) \
+ (((field)->rows + (field)->nrow) == 1)
+
+/* Logic to determine whether or not a field is selectable */
+#define Field_Is_Selectable(f) (((unsigned)((f)->opts) & O_SELECTABLE)==O_SELECTABLE)
+#define Field_Is_Not_Selectable(f) (((unsigned)((f)->opts) & O_SELECTABLE)!=O_SELECTABLE)
+
+typedef struct typearg
+ {
+ struct typearg *left;
+ struct typearg *right;
+ }
+TypeArgument;
+
+/* This is a dummy request code (normally invalid) to be used internally
+ with the form_driver() routine to position to the first active field
+ on the form
+*/
+#define FIRST_ACTIVE_MAGIC (-291056)
+
+#define ALL_FORM_OPTS ( \
+ O_NL_OVERLOAD |\
+ O_BS_OVERLOAD )
+
+#define ALL_FIELD_OPTS (Field_Options)( \
+ O_VISIBLE |\
+ O_ACTIVE |\
+ O_PUBLIC |\
+ O_EDIT |\
+ O_WRAP |\
+ O_BLANK |\
+ O_AUTOSKIP|\
+ O_NULLOK |\
+ O_PASSOK |\
+ O_STATIC )
+
+#define C_BLANK ' '
+#define is_blank(c) ((c)==C_BLANK)
+
+#define C_ZEROS '\0'
+
+extern NCURSES_EXPORT(TypeArgument *) _nc_Make_Argument (const FIELDTYPE*, va_list*, int*);
+extern NCURSES_EXPORT(TypeArgument *) _nc_Copy_Argument (const FIELDTYPE*, const TypeArgument*, int*);
+extern NCURSES_EXPORT(void) _nc_Free_Argument (const FIELDTYPE*, TypeArgument*);
+extern NCURSES_EXPORT(bool) _nc_Copy_Type (FIELD*, FIELD const *);
+extern NCURSES_EXPORT(void) _nc_Free_Type (FIELD *);
+
+extern NCURSES_EXPORT(int) _nc_Synchronize_Attributes (FIELD*);
+extern NCURSES_EXPORT(int) _nc_Synchronize_Options (FIELD*, Field_Options);
+extern NCURSES_EXPORT(int) _nc_Set_Form_Page (FORM*, int, FIELD*);
+extern NCURSES_EXPORT(int) _nc_Refresh_Current_Field (FORM*);
+extern NCURSES_EXPORT(FIELD *) _nc_First_Active_Field (FORM*);
+extern NCURSES_EXPORT(bool) _nc_Internal_Validation (FORM*);
+extern NCURSES_EXPORT(int) _nc_Set_Current_Field (FORM*, FIELD*);
+extern NCURSES_EXPORT(int) _nc_Position_Form_Cursor (FORM*);
+
+#if NCURSES_INTEROP_FUNCS
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_INTEGER(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_ALNUM(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_ALPHA(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_ENUM(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_NUMERIC(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_REGEXP(void);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_TYPE_IPV4(void);
+
+extern NCURSES_EXPORT(FIELDTYPE *)
+_nc_generic_fieldtype(bool (*const field_check) (FORM*,
+ FIELD *,
+ const void *),
+ bool (*const char_check) (int,
+ FORM*,
+ FIELD*,
+ const void *),
+ bool (*const next)(FORM*,FIELD*,const void*),
+ bool (*const prev)(FORM*,FIELD*,const void*),
+ void (*freecallback)(void*));
+extern NCURSES_EXPORT(int) _nc_set_generic_fieldtype(FIELD*, FIELDTYPE*, int (*)(void**));
+extern NCURSES_EXPORT(WINDOW*) _nc_form_cursor(const FORM* , int* , int* );
+
+#define INIT_FT_FUNC(func) {func}
+#else
+#define INIT_FT_FUNC(func) func
+#endif
+
+extern NCURSES_EXPORT(void) _nc_get_fieldbuffer(FORM*, FIELD*, FIELD_CELL*);
+
+#if USE_WIDEC_SUPPORT
+extern NCURSES_EXPORT(wchar_t *) _nc_Widen_String(char *, int *);
+#endif
+
+#ifdef TRACE
+
+#define returnField(code) TRACE_RETURN(code,field)
+#define returnFieldPtr(code) TRACE_RETURN(code,field_ptr)
+#define returnForm(code) TRACE_RETURN(code,form)
+#define returnFieldType(code) TRACE_RETURN(code,field_type)
+#define returnFormHook(code) TRACE_RETURN(code,form_hook)
+
+extern NCURSES_EXPORT(FIELD **) _nc_retrace_field_ptr (FIELD **);
+extern NCURSES_EXPORT(FIELD *) _nc_retrace_field (FIELD *);
+extern NCURSES_EXPORT(FIELDTYPE *) _nc_retrace_field_type (FIELDTYPE *);
+extern NCURSES_EXPORT(FORM *) _nc_retrace_form (FORM *);
+extern NCURSES_EXPORT(Form_Hook) _nc_retrace_form_hook (Form_Hook);
+
+#else /* !TRACE */
+
+#define returnFieldPtr(code) return code
+#define returnFieldType(code) return code
+#define returnField(code) return code
+#define returnForm(code) return code
+#define returnFormHook(code) return code
+
+#endif /* TRACE/!TRACE */
+
+/*
+ * Use Check_CTYPE_Field() to simplify FIELDTYPE's that use only the ccheck()
+ * function.
+ */
+#if USE_WIDEC_SUPPORT
+#define Check_CTYPE_Field(result, buffer, width, ccheck) \
+ while (*buffer && *buffer == ' ') \
+ buffer++; \
+ if (*buffer) \
+ { \
+ bool blank = FALSE; \
+ int len; \
+ int n; \
+ wchar_t *list = _nc_Widen_String((char *)buffer, &len); \
+ if (list != 0) \
+ { \
+ result = TRUE; \
+ for (n = 0; n < len; ++n) \
+ { \
+ if (blank) \
+ { \
+ if (list[n] != ' ') \
+ { \
+ result = FALSE; \
+ break; \
+ } \
+ } \
+ else if (list[n] == ' ') \
+ { \
+ blank = TRUE; \
+ result = (n + 1 >= width); \
+ } \
+ else if (!ccheck(list[n], NULL)) \
+ { \
+ result = FALSE; \
+ break; \
+ } \
+ } \
+ free(list); \
+ } \
+ }
+#else
+#define Check_CTYPE_Field(result, buffer, width, ccheck) \
+ while (*buffer && *buffer == ' ') \
+ buffer++; \
+ if (*buffer) \
+ { \
+ unsigned char *s = buffer; \
+ int l = -1; \
+ while (*buffer && ccheck(*buffer, NULL)) \
+ buffer++; \
+ l = (int)(buffer - s); \
+ while (*buffer && *buffer == ' ') \
+ buffer++; \
+ result = ((*buffer || (l < width)) ? FALSE : TRUE); \
+ }
+#endif
+
+#endif /* FORM_PRIV_H */
diff --git a/apps/lib/curses/pdcurses/form/frm_cursor.c b/apps/lib/curses/pdcurses/form/frm_cursor.c
new file mode 100644
index 0000000..091b0fd
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_cursor.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_cursor.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int pos_form_cursor(FORM * form)
+|
+| Description : Moves the form window cursor to the location required
+| by the form driver to resume form processing. This may
+| be needed after the application calls a curses library
+| I/O routine that modifies the cursor position.
+|
+| Return Values : E_OK - Success
+| E_SYSTEM_ERROR - System error.
+| E_BAD_ARGUMENT - Invalid form pointer
+| E_NOT_POSTED - Form is not posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+pos_form_cursor(FORM *form)
+{
+ int res;
+
+ T((T_CALLED("pos_form_cursor(%p)"), (void *)form));
+
+ if (!form)
+ res = E_BAD_ARGUMENT;
+ else
+ {
+ if (!(form->status & _POSTED))
+ res = E_NOT_POSTED;
+ else
+ res = _nc_Position_Form_Cursor(form);
+ }
+ RETURN(res);
+}
+
+/* frm_cursor.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_data.c b/apps/lib/curses/pdcurses/form/frm_data.c
new file mode 100644
index 0000000..85914eb
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_data.c
@@ -0,0 +1,193 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_data.c,v 1.15 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool data_behind(const FORM *form)
+|
+| Description : Check for off-screen data behind. This is nearly trivial
+| because the beginning of a field is fixed.
+|
+| Return Values : TRUE - there are off-screen data behind
+| FALSE - there are no off-screen data behind
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+data_behind(const FORM *form)
+{
+ bool result = FALSE;
+
+ T((T_CALLED("data_behind(%p)"), (const void *)form));
+
+ if (form && (form->status & _POSTED) && form->current)
+ {
+ FIELD *field;
+
+ field = form->current;
+ if (!Single_Line_Field(field))
+ {
+ result = (form->toprow == 0) ? FALSE : TRUE;
+ }
+ else
+ {
+ result = (form->begincol == 0) ? FALSE : TRUE;
+ }
+ }
+ returnBool(result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char * Only_Padding(
+| WINDOW *w,
+| int len,
+| int pad)
+|
+| Description : Test if 'length' cells starting at the current position
+| contain a padding character.
+|
+| Return Values : true if only padding cells are found
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static bool
+Only_Padding(WINDOW *w, int len, int pad)
+{
+ bool result = TRUE;
+ int y, x, j;
+ FIELD_CELL cell;
+
+ getyx(w, y, x);
+ for (j = 0; j < len; ++j)
+ {
+ if (wmove(w, y, x + j) != ERR)
+ {
+#if USE_WIDEC_SUPPORT
+ if (win_wch(w, &cell) != ERR)
+ {
+ if ((chtype)CharOf(cell) != ChCharOf(pad)
+ || cell.chars[1] != 0)
+ {
+ result = FALSE;
+ break;
+ }
+ }
+#else
+ cell = winch(w);
+ if (ChCharOf(cell) != ChCharOf(pad))
+ {
+ result = FALSE;
+ break;
+ }
+#endif
+ }
+ else
+ {
+ /* if an error, return true: no non-padding text found */
+ break;
+ }
+ }
+ /* no need to reset the cursor position; caller does this */
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool data_ahead(const FORM *form)
+|
+| Description : Check for off-screen data ahead. This is more difficult
+| because a dynamic field has a variable end.
+|
+| Return Values : TRUE - there are off-screen data ahead
+| FALSE - there are no off-screen data ahead
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+data_ahead(const FORM *form)
+{
+ bool result = FALSE;
+
+ T((T_CALLED("data_ahead(%p)"), (const void *)form));
+
+ if (form && (form->status & _POSTED) && form->current)
+ {
+ FIELD *field;
+ bool cursor_moved = FALSE;
+ int pos;
+
+ field = form->current;
+ assert(form->w);
+
+ if (Single_Line_Field(field))
+ {
+ int check_len;
+
+ pos = form->begincol + field->cols;
+ while (pos < field->dcols)
+ {
+ check_len = field->dcols - pos;
+ if (check_len >= field->cols)
+ check_len = field->cols;
+ cursor_moved = TRUE;
+ wmove(form->w, 0, pos);
+ if (Only_Padding(form->w, check_len, field->pad))
+ pos += field->cols;
+ else
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pos = form->toprow + field->rows;
+ while (pos < field->drows)
+ {
+ cursor_moved = TRUE;
+ wmove(form->w, pos, 0);
+ pos++;
+ if (!Only_Padding(form->w, field->cols, field->pad))
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (cursor_moved)
+ wmove(form->w, form->currow, form->curcol);
+ }
+ returnBool(result);
+}
+
+/* frm_data.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_def.c b/apps/lib/curses/pdcurses/form/frm_def.c
new file mode 100644
index 0000000..54f743b
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_def.c
@@ -0,0 +1,448 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_def.c,v 1.25 2010/01/23 21:14:36 tom Exp $")
+
+/* this can't be readonly */
+static FORM default_form =
+{
+ 0, /* status */
+ 0, /* rows */
+ 0, /* cols */
+ 0, /* currow */
+ 0, /* curcol */
+ 0, /* toprow */
+ 0, /* begincol */
+ -1, /* maxfield */
+ -1, /* maxpage */
+ -1, /* curpage */
+ ALL_FORM_OPTS, /* opts */
+ (WINDOW *)0, /* win */
+ (WINDOW *)0, /* sub */
+ (WINDOW *)0, /* w */
+ (FIELD **)0, /* field */
+ (FIELD *)0, /* current */
+ (_PAGE *) 0, /* page */
+ (char *)0, /* usrptr */
+ NULL, /* forminit */
+ NULL, /* formterm */
+ NULL, /* fieldinit */
+ NULL /* fieldterm */
+};
+
+NCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form;
+\f
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Insert_Field_By_Position(
+| FIELD *new_field,
+| FIELD *head )
+|
+| Description : Insert new_field into sorted fieldlist with head "head"
+| and return new head of sorted fieldlist. Sorting
+| criteria is (row,column). This is a circular list.
+|
+| Return Values : New head of sorted fieldlist
++--------------------------------------------------------------------------*/
+static FIELD *
+Insert_Field_By_Position(FIELD *newfield, FIELD *head)
+{
+ FIELD *current, *newhead;
+
+ assert(newfield);
+
+ if (!head)
+ { /* empty list is trivial */
+ newhead = newfield->snext = newfield->sprev = newfield;
+ }
+ else
+ {
+ newhead = current = head;
+ while ((current->frow < newfield->frow) ||
+ ((current->frow == newfield->frow) &&
+ (current->fcol < newfield->fcol)))
+ {
+ current = current->snext;
+ if (current == head)
+ { /* We cycled through. Reset head to indicate that */
+ head = (FIELD *)0;
+ break;
+ }
+ }
+ /* we leave the loop with current pointing to the field after newfield */
+ newfield->snext = current;
+ newfield->sprev = current->sprev;
+ newfield->snext->sprev = newfield;
+ newfield->sprev->snext = newfield;
+ if (current == head)
+ newhead = newfield;
+ }
+ return (newhead);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Disconnect_Fields(FORM *form)
+|
+| Description : Break association between form and array of fields.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Disconnect_Fields(FORM *form)
+{
+ if (form->field)
+ {
+ FIELD **fields;
+
+ for (fields = form->field; *fields; fields++)
+ {
+ if (form == (*fields)->form)
+ (*fields)->form = (FORM *)0;
+ }
+
+ form->rows = form->cols = 0;
+ form->maxfield = form->maxpage = -1;
+ form->field = (FIELD **)0;
+ if (form->page)
+ free(form->page);
+ form->page = (_PAGE *) 0;
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Connect_Fields(FORM *form, FIELD **fields)
+|
+| Description : Set association between form and array of fields.
+|
+| Return Values : E_OK - no error
+| E_CONNECTED - a field is already connected
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+static int
+Connect_Fields(FORM *form, FIELD **fields)
+{
+ int field_cnt, j;
+ int page_nr;
+ int maximum_row_in_field, maximum_col_in_field;
+ _PAGE *pg;
+
+ T((T_CALLED("Connect_Fields(%p,%p)"), (void *)form, (void *)fields));
+
+ assert(form);
+
+ form->field = fields;
+ form->maxfield = 0;
+ form->maxpage = 0;
+
+ if (!fields)
+ RETURN(E_OK);
+
+ page_nr = 0;
+ /* store formpointer in fields and count pages */
+ for (field_cnt = 0; fields[field_cnt]; field_cnt++)
+ {
+ if (fields[field_cnt]->form)
+ RETURN(E_CONNECTED);
+ if (field_cnt == 0 ||
+ (fields[field_cnt]->status & _NEWPAGE))
+ page_nr++;
+ fields[field_cnt]->form = form;
+ }
+ if (field_cnt == 0 || (short)field_cnt < 0)
+ RETURN(E_BAD_ARGUMENT);
+
+ /* allocate page structures */
+ if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0)
+ {
+ T((T_CREATE("_PAGE %p"), (void *)pg));
+ form->page = pg;
+ }
+ else
+ RETURN(E_SYSTEM_ERROR);
+
+ /* Cycle through fields and calculate page boundaries as well as
+ size of the form */
+ for (j = 0; j < field_cnt; j++)
+ {
+ if (j == 0)
+ pg->pmin = j;
+ else
+ {
+ if (fields[j]->status & _NEWPAGE)
+ {
+ pg->pmax = j - 1;
+ pg++;
+ pg->pmin = j;
+ }
+ }
+
+ maximum_row_in_field = fields[j]->frow + fields[j]->rows;
+ maximum_col_in_field = fields[j]->fcol + fields[j]->cols;
+
+ if (form->rows < maximum_row_in_field)
+ form->rows = maximum_row_in_field;
+ if (form->cols < maximum_col_in_field)
+ form->cols = maximum_col_in_field;
+ }
+
+ pg->pmax = field_cnt - 1;
+ form->maxfield = field_cnt;
+ form->maxpage = page_nr;
+
+ /* Sort fields on form pages */
+ for (page_nr = 0; page_nr < form->maxpage; page_nr++)
+ {
+ FIELD *fld = (FIELD *)0;
+
+ for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++)
+ {
+ fields[j]->index = j;
+ fields[j]->page = page_nr;
+ fld = Insert_Field_By_Position(fields[j], fld);
+ }
+ if (fld)
+ {
+ form->page[page_nr].smin = fld->index;
+ form->page[page_nr].smax = fld->sprev->index;
+ }
+ else
+ {
+ form->page[page_nr].smin = 0;
+ form->page[page_nr].smax = 0;
+ }
+ }
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Associate_Fields(FORM *form, FIELD **fields)
+|
+| Description : Set association between form and array of fields.
+| If there are fields, position to first active field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_CONNECTED - a field is already connected
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static int
+Associate_Fields(FORM *form, FIELD **fields)
+{
+ int res = Connect_Fields(form, fields);
+
+ if (res == E_OK)
+ {
+ if (form->maxpage > 0)
+ {
+ form->curpage = 0;
+ form_driver(form, FIRST_ACTIVE_MAGIC);
+ }
+ else
+ {
+ form->curpage = -1;
+ form->current = (FIELD *)0;
+ }
+ }
+ return (res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FORM *new_form_sp(SCREEN* sp, FIELD** fields )
+|
+| Description : Create new form with given array of fields.
+|
+| Return Values : Pointer to form. NULL if error occurred.
+! Set errno:
+| E_OK - success
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_CONNECTED - a field is already connected
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FORM *)
+NCURSES_SP_NAME(new_form) (NCURSES_SP_DCLx FIELD **fields)
+{
+ int err = E_SYSTEM_ERROR;
+ FORM *form = (FORM *)0;
+
+ T((T_CALLED("new_form(%p,%p)"), (void *)SP_PARM, (void *)fields));
+
+ if (IsValidScreen(SP_PARM))
+ {
+ form = typeMalloc(FORM, 1);
+
+ if (form)
+ {
+ T((T_CREATE("form %p"), (void *)form));
+ *form = *_nc_Default_Form;
+ /* This ensures win and sub are always non-null,
+ so we can derive always the SCREEN that this form is
+ running on. */
+ form->win = StdScreen(SP_PARM);
+ form->sub = StdScreen(SP_PARM);
+ if ((err = Associate_Fields(form, fields)) != E_OK)
+ {
+ free_form(form);
+ form = (FORM *)0;
+ }
+ }
+ }
+
+ if (!form)
+ SET_ERROR(err);
+
+ returnForm(form);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FORM* new_form(FIELD** fields )
+|
+| Description : Create new form with given array of fields.
+|
+| Return Values : Pointer to form. NULL if error occurred.
+! Set errno:
+| E_OK - success
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_CONNECTED - a field is already connected
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(FORM *)
+new_form(FIELD **fields)
+{
+ return NCURSES_SP_NAME(new_form) (CURRENT_SCREEN, fields);
+}
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_form( FORM *form )
+|
+| Description : Release internal memory associated with form.
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - invalid form pointer
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+free_form(FORM *form)
+{
+ T((T_CALLED("free_form(%p)"), (void *)form));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (form->status & _POSTED)
+ RETURN(E_POSTED);
+
+ Disconnect_Fields(form);
+ if (form->page)
+ free(form->page);
+ free(form);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_fields( FORM *form, FIELD **fields )
+|
+| Description : Set a new association of an array of fields to a form
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_CONNECTED - a field is already connected
+| E_POSTED - form is posted
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_fields(FORM *form, FIELD **fields)
+{
+ FIELD **old;
+ int res;
+
+ T((T_CALLED("set_form_fields(%p,%p)"), (void *)form, (void *)fields));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (form->status & _POSTED)
+ RETURN(E_POSTED);
+
+ old = form->field;
+ Disconnect_Fields(form);
+
+ if ((res = Associate_Fields(form, fields)) != E_OK)
+ Connect_Fields(form, old);
+
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD **form_fields( const FORM *form )
+|
+| Description : Retrieve array of fields
+|
+| Return Values : Pointer to field array
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD **)
+form_fields(const FORM *form)
+{
+ T((T_CALLED("form_field(%p)"), (const void *)form));
+ returnFieldPtr(Normalize_Form(form)->field);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_count( const FORM *form )
+|
+| Description : Retrieve number of fields
+|
+| Return Values : Number of fields, -1 if none are defined
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+field_count(const FORM *form)
+{
+ T((T_CALLED("field_count(%p)"), (const void *)form));
+
+ returnCode(Normalize_Form(form)->maxfield);
+}
+
+/* frm_def.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_driver.c b/apps/lib/curses/pdcurses/form/frm_driver.c
new file mode 100644
index 0000000..e0892bf
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_driver.c
@@ -0,0 +1,4646 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_driver.c,v 1.98 2010/05/01 21:11:43 tom Exp $")
+
+/*----------------------------------------------------------------------------
+ This is the core module of the form library. It contains the majority
+ of the driver routines as well as the form_driver function.
+
+ Essentially this module is nearly the whole library. This is because
+ all the functions in this module depends on some others in the module,
+ so it makes no sense to split them into separate files because they
+ will always be linked together. The only acceptable concern is turnaround
+ time for this module, but now we have all Pentiums or RISCs, so what!
+
+ The driver routines are grouped into nine generic categories:
+
+ a) Page Navigation ( all functions prefixed by PN_ )
+ The current page of the form is left and some new page is
+ entered.
+ b) Inter-Field Navigation ( all functions prefixed by FN_ )
+ The current field of the form is left and some new field is
+ entered.
+ c) Intra-Field Navigation ( all functions prefixed by IFN_ )
+ The current position in the current field is changed.
+ d) Vertical Scrolling ( all functions prefixed by VSC_ )
+ Essentially this is a specialization of Intra-Field navigation.
+ It has to check for a multi-line field.
+ e) Horizontal Scrolling ( all functions prefixed by HSC_ )
+ Essentially this is a specialization of Intra-Field navigation.
+ It has to check for a single-line field.
+ f) Field Editing ( all functions prefixed by FE_ )
+ The content of the current field is changed
+ g) Edit Mode requests ( all functions prefixed by EM_ )
+ Switching between insert and overlay mode
+ h) Field-Validation requests ( all functions prefixed by FV_ )
+ Perform verifications of the field.
+ i) Choice requests ( all functions prefixed by CR_ )
+ Requests to enumerate possible field values
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Some remarks on the placements of assert() macros :
+ I use them only on "strategic" places, i.e. top level entries where
+ I want to make sure that things are set correctly. Throughout subordinate
+ routines I omit them mostly.
+ --------------------------------------------------------------------------*/
+
+/*
+Some options that may effect compatibility in behavior to SVr4 forms,
+but they are here to allow a more intuitive and user friendly behavior of
+our form implementation. This doesn't affect the API, so we feel it is
+uncritical.
+
+The initial implementation tries to stay very close with the behavior
+of the original SVr4 implementation, although in some areas it is quite
+clear that this isn't the most appropriate way. As far as possible this
+sources will allow you to build a forms lib that behaves quite similar
+to SVr4, but now and in the future we will give you better options.
+Perhaps at some time we will make this configurable at runtime.
+*/
+
+/* Implement a more user-friendly previous/next word behavior */
+#define FRIENDLY_PREV_NEXT_WORD (1)
+/* Fix the wrong behavior for forms with all fields inactive */
+#define FIX_FORM_INACTIVE_BUG (1)
+/* Allow dynamic field growth also when navigating past the end */
+#define GROW_IF_NAVIGATE (1)
+
+#if USE_WIDEC_SUPPORT
+#define myADDNSTR(w, s, n) wadd_wchnstr(w, s, n)
+#define myINSNSTR(w, s, n) wins_wchnstr(w, s, n)
+#define myINNSTR(w, s, n) fix_wchnstr(w, s, n)
+#define myWCWIDTH(w, y, x) cell_width(w, y, x)
+#else
+#define myADDNSTR(w, s, n) waddnstr(w, s, n)
+#define myINSNSTR(w, s, n) winsnstr(w, s, n)
+#define myINNSTR(w, s, n) winnstr(w, s, n)
+#define myWCWIDTH(w, y, x) 1
+#endif
+
+/*----------------------------------------------------------------------------
+ Forward references to some internally used static functions
+ --------------------------------------------------------------------------*/
+static int Inter_Field_Navigation(int (*const fct) (FORM *), FORM *form);
+static int FN_Next_Field(FORM *form);
+static int FN_Previous_Field(FORM *form);
+static int FE_New_Line(FORM *);
+static int FE_Delete_Previous(FORM *);
+
+/*----------------------------------------------------------------------------
+ Macro Definitions.
+
+ Some Remarks on that: I use the convention to use UPPERCASE for constants
+ defined by Macros. If I provide a macro as a kind of inline routine to
+ provide some logic, I use my Upper_Lower case style.
+ --------------------------------------------------------------------------*/
+
+/* Calculate the position of a single row in a field buffer */
+#define Position_Of_Row_In_Buffer(field,row) ((row)*(field)->dcols)
+
+/* Calculate start address for the fields buffer# N */
+#define Address_Of_Nth_Buffer(field,N) \
+ ((field)->buf + (N)*(1+Buffer_Length(field)))
+
+/* Calculate the start address of the row in the fields specified buffer# N */
+#define Address_Of_Row_In_Nth_Buffer(field,N,row) \
+ (Address_Of_Nth_Buffer(field,N) + Position_Of_Row_In_Buffer(field,row))
+
+/* Calculate the start address of the row in the fields primary buffer */
+#define Address_Of_Row_In_Buffer(field,row) \
+ Address_Of_Row_In_Nth_Buffer(field,0,row)
+
+/* Calculate the start address of the row in the forms current field
+ buffer# N */
+#define Address_Of_Current_Row_In_Nth_Buffer(form,N) \
+ Address_Of_Row_In_Nth_Buffer((form)->current,N,(form)->currow)
+
+/* Calculate the start address of the row in the forms current field
+ primary buffer */
+#define Address_Of_Current_Row_In_Buffer(form) \
+ Address_Of_Current_Row_In_Nth_Buffer(form,0)
+
+/* Calculate the address of the cursor in the forms current field
+ primary buffer */
+#define Address_Of_Current_Position_In_Nth_Buffer(form,N) \
+ (Address_Of_Current_Row_In_Nth_Buffer(form,N) + (form)->curcol)
+
+/* Calculate the address of the cursor in the forms current field
+ buffer# N */
+#define Address_Of_Current_Position_In_Buffer(form) \
+ Address_Of_Current_Position_In_Nth_Buffer(form,0)
+
+/* Logic to decide whether or not a field is actually a field with
+ vertical or horizontal scrolling */
+#define Is_Scroll_Field(field) \
+ (((field)->drows > (field)->rows) || \
+ ((field)->dcols > (field)->cols))
+
+/* Logic to decide whether or not a field needs to have an individual window
+ instead of a derived window because it contains invisible parts.
+ This is true for non-public fields and for scrollable fields. */
+#define Has_Invisible_Parts(field) \
+ (!((field)->opts & O_PUBLIC) || \
+ Is_Scroll_Field(field))
+
+/* Logic to decide whether or not a field needs justification */
+#define Justification_Allowed(field) \
+ (((field)->just != NO_JUSTIFICATION) && \
+ (Single_Line_Field(field)) && \
+ (((field)->dcols == (field)->cols) && \
+ ((field)->opts & O_STATIC)) )
+
+/* Logic to determine whether or not a dynamic field may still grow */
+#define Growable(field) ((field)->status & _MAY_GROW)
+
+/* Macro to set the attributes for a fields window */
+#define Set_Field_Window_Attributes(field,win) \
+( wbkgdset((win),(chtype)((field)->pad | (field)->back)), \
+ (void) wattrset((win),(field)->fore) )
+
+/* Logic to decide whether or not a field really appears on the form */
+#define Field_Really_Appears(field) \
+ ((field->form) &&\
+ (field->form->status & _POSTED) &&\
+ (field->opts & O_VISIBLE) &&\
+ (field->page == field->form->curpage))
+
+/* Logic to determine whether or not we are on the first position in the
+ current field */
+#define First_Position_In_Current_Field(form) \
+ (((form)->currow==0) && ((form)->curcol==0))
+
+#define Minimum(a,b) (((a)<=(b)) ? (a) : (b))
+#define Maximum(a,b) (((a)>=(b)) ? (a) : (b))
+
+/*----------------------------------------------------------------------------
+ Useful constants
+ --------------------------------------------------------------------------*/
+static FIELD_CELL myBLANK = BLANK;
+static FIELD_CELL myZEROS;
+
+#ifdef TRACE
+static void
+check_pos(FORM *form, int lineno)
+{
+ int y, x;
+
+ if (form && form->w)
+ {
+ getyx(form->w, y, x);
+ if (y != form->currow || x != form->curcol)
+ {
+ T(("CHECKPOS %s@%d have position %d,%d vs want %d,%d",
+ __FILE__, lineno,
+ y, x,
+ form->currow, form->curcol));
+ }
+ }
+}
+#define CHECKPOS(form) check_pos(form, __LINE__)
+#else
+#define CHECKPOS(form) /* nothing */
+#endif
+
+/*----------------------------------------------------------------------------
+ Wide-character special functions
+ --------------------------------------------------------------------------*/
+#if USE_WIDEC_SUPPORT
+/* like winsnstr */
+static int
+wins_wchnstr(WINDOW *w, cchar_t *s, int n)
+{
+ int code = ERR;
+ int y, x;
+
+ while (n-- > 0)
+ {
+ getyx(w, y, x);
+ if ((code = wins_wch(w, s++)) != OK)
+ break;
+ if ((code = wmove(w, y, x + 1)) != OK)
+ break;
+ }
+ return code;
+}
+
+/* win_wchnstr is inconsistent with winnstr, since it returns OK rather than
+ * the number of items transferred.
+ */
+static int
+fix_wchnstr(WINDOW *w, cchar_t *s, int n)
+{
+ int x;
+
+ win_wchnstr(w, s, n);
+ /*
+ * This function is used to extract the text only from the window.
+ * Strip attributes and color from the string so they will not be added
+ * back when copying the string to the window.
+ */
+ for (x = 0; x < n; ++x)
+ {
+ RemAttr(s[x], A_ATTRIBUTES);
+ SetPair(s[x], 0);
+ }
+ return n;
+}
+
+/*
+ * Returns the column of the base of the given cell.
+ */
+static int
+cell_base(WINDOW *win, int y, int x)
+{
+ int result = x;
+
+ while (LEGALYX(win, y, x))
+ {
+ cchar_t *data = &(win->_line[y].text[x]);
+
+ if (isWidecBase(CHDEREF(data)) || !isWidecExt(CHDEREF(data)))
+ {
+ result = x;
+ break;
+ }
+ --x;
+ }
+ return result;
+}
+
+/*
+ * Returns the number of columns needed for the given cell in a window.
+ */
+static int
+cell_width(WINDOW *win, int y, int x)
+{
+ int result = 1;
+
+ if (LEGALYX(win, y, x))
+ {
+ cchar_t *data = &(win->_line[y].text[x]);
+
+ if (isWidecExt(CHDEREF(data)))
+ {
+ /* recur, providing the number of columns to the next character */
+ result = cell_width(win, y, x - 1);
+ }
+ else
+ {
+ result = wcwidth(CharOf(CHDEREF(data)));
+ }
+ }
+ return result;
+}
+
+/*
+ * There is no wide-character function such as wdel_wch(), so we must find
+ * all of the cells that comprise a multi-column character and delete them
+ * one-by-one.
+ */
+static void
+delete_char(FORM *form)
+{
+ int cells = cell_width(form->w, form->currow, form->curcol);
+
+ form->curcol = cell_base(form->w, form->currow, form->curcol);
+ wmove(form->w, form->currow, form->curcol);
+ while (cells-- > 0)
+ {
+ wdelch(form->w);
+ }
+}
+#define DeleteChar(form) delete_char(form)
+#else
+#define DeleteChar(form) \
+ wmove((form)->w, (form)->currow, (form)->curcol), \
+ wdelch((form)->w)
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *Get_Start_Of_Data(char * buf, int blen)
+|
+| Description : Return pointer to first non-blank position in buffer.
+| If buffer is empty return pointer to buffer itself.
+|
+| Return Values : Pointer to first non-blank position in buffer
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD_CELL *
+Get_Start_Of_Data(FIELD_CELL *buf, int blen)
+{
+ FIELD_CELL *p = buf;
+ FIELD_CELL *end = &buf[blen];
+
+ assert(buf && blen >= 0);
+ while ((p < end) && ISBLANK(*p))
+ p++;
+ return ((p == end) ? buf : p);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *After_End_Of_Data(char * buf, int blen)
+|
+| Description : Return pointer after last non-blank position in buffer.
+| If buffer is empty, return pointer to buffer itself.
+|
+| Return Values : Pointer to position after last non-blank position in
+| buffer.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD_CELL *
+After_End_Of_Data(FIELD_CELL *buf, int blen)
+{
+ FIELD_CELL *p = &buf[blen];
+
+ assert(buf && blen >= 0);
+ while ((p > buf) && ISBLANK(p[-1]))
+ p--;
+ return (p);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *Get_First_Whitespace_Character(
+| char * buf, int blen)
+|
+| Description : Position to the first whitespace character.
+|
+| Return Values : Pointer to first whitespace character in buffer.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD_CELL *
+Get_First_Whitespace_Character(FIELD_CELL *buf, int blen)
+{
+ FIELD_CELL *p = buf;
+ FIELD_CELL *end = &p[blen];
+
+ assert(buf && blen >= 0);
+ while ((p < end) && !ISBLANK(*p))
+ p++;
+ return ((p == end) ? buf : p);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *After_Last_Whitespace_Character(
+| char * buf, int blen)
+|
+| Description : Get the position after the last whitespace character.
+|
+| Return Values : Pointer to position after last whitespace character in
+| buffer.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD_CELL *
+After_Last_Whitespace_Character(FIELD_CELL *buf, int blen)
+{
+ FIELD_CELL *p = &buf[blen];
+
+ assert(buf && blen >= 0);
+ while ((p > buf) && !ISBLANK(p[-1]))
+ p--;
+ return (p);
+}
+
+/* Set this to 1 to use the div_t version. This is a good idea if your
+ compiler has an intrinsic div() support. Unfortunately GNU-C has it
+ not yet.
+ N.B.: This only works if form->curcol follows immediately form->currow
+ and both are of type int.
+*/
+#define USE_DIV_T (0)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Adjust_Cursor_Position(
+| FORM * form, const char * pos)
+|
+| Description : Set current row and column of the form to values
+| corresponding to the buffer position.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static void
+Adjust_Cursor_Position(FORM *form, const FIELD_CELL *pos)
+{
+ FIELD *field;
+ int idx;
+
+ field = form->current;
+ assert(pos >= field->buf && field->dcols > 0);
+ idx = (int)(pos - field->buf);
+#if USE_DIV_T
+ *((div_t *) & (form->currow)) = div(idx, field->dcols);
+#else
+ form->currow = idx / field->dcols;
+ form->curcol = idx - field->cols * form->currow;
+#endif
+ if (field->drows < form->currow)
+ form->currow = 0;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Buffer_To_Window(
+| const FIELD * field,
+| WINDOW * win)
+|
+| Description : Copy the buffer to the window. If it is a multi-line
+| field, the buffer is split to the lines of the
+| window without any editing.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Buffer_To_Window(const FIELD *field, WINDOW *win)
+{
+ int width, height;
+ int y, x;
+ int len;
+ int row;
+ FIELD_CELL *pBuffer;
+
+ assert(win && field);
+
+ getyx(win, y, x);
+ width = getmaxx(win);
+ height = getmaxy(win);
+
+ for (row = 0, pBuffer = field->buf;
+ row < height;
+ row++, pBuffer += width)
+ {
+ if ((len = (int)(After_End_Of_Data(pBuffer, width) - pBuffer)) > 0)
+ {
+ wmove(win, row, 0);
+ myADDNSTR(win, pBuffer, len);
+ }
+ }
+ wmove(win, y, x);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void _nc_get_fieldbuffer(
+| WINDOW * win,
+| FIELD * field,
+| FIELD_CELL * buf)
+|
+| Description : Copy the content of the window into the buffer.
+| The multiple lines of a window are simply
+| concatenated into the buffer. Pad characters in
+| the window will be replaced by blanks in the buffer.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void)
+_nc_get_fieldbuffer(FORM *form, FIELD *field, FIELD_CELL *buf)
+{
+ int pad;
+ int len = 0;
+ FIELD_CELL *p;
+ int row, height;
+ WINDOW *win;
+
+ assert(form && field && buf);
+
+ win = form->w;
+ assert(win);
+
+ pad = field->pad;
+ p = buf;
+ height = getmaxy(win);
+
+ for (row = 0; (row < height) && (row < field->drows); row++)
+ {
+ wmove(win, row, 0);
+ len += myINNSTR(win, p + len, field->dcols);
+ }
+ p[len] = myZEROS;
+
+ /* replace visual padding character by blanks in buffer */
+ if (pad != C_BLANK)
+ {
+ int i;
+
+ for (i = 0; i < len; i++, p++)
+ {
+ if ((unsigned long)CharOf(*p) == ChCharOf(pad)
+#if USE_WIDEC_SUPPORT
+ && p->chars[1] == 0
+#endif
+ )
+ *p = myBLANK;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Window_To_Buffer(
+| FORM * form,
+| FIELD * field)
+|
+| Description : Copy the content of the window into the buffer.
+| The multiple lines of a window are simply
+| concatenated into the buffer. Pad characters in
+| the window will be replaced by blanks in the buffer.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Window_To_Buffer(FORM *form, FIELD *field)
+{
+ _nc_get_fieldbuffer(form, field, field->buf);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Synchronize_Buffer(FORM * form)
+|
+| Description : If there was a change, copy the content of the
+| window into the buffer, so the buffer is synchronized
+| with the windows content. We have to indicate that the
+| buffer needs validation due to the change.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static void
+Synchronize_Buffer(FORM *form)
+{
+ if (form->status & _WINDOW_MODIFIED)
+ {
+ form->status &= ~_WINDOW_MODIFIED;
+ form->status |= _FCHECK_REQUIRED;
+ Window_To_Buffer(form, form->current);
+ wmove(form->w, form->currow, form->curcol);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Field_Grown( FIELD *field, int amount)
+|
+| Description : This function is called for growable dynamic fields
+| only. It has to increase the buffers and to allocate
+| a new window for this field.
+| This function has the side effect to set a new
+| field-buffer pointer, the dcols and drows values
+| as well as a new current Window for the field.
+|
+| Return Values : TRUE - field successfully increased
+| FALSE - there was some error
++--------------------------------------------------------------------------*/
+static bool
+Field_Grown(FIELD *field, int amount)
+{
+ bool result = FALSE;
+
+ if (field && Growable(field))
+ {
+ bool single_line_field = Single_Line_Field(field);
+ int old_buflen = Buffer_Length(field);
+ int new_buflen;
+ int old_dcols = field->dcols;
+ int old_drows = field->drows;
+ FIELD_CELL *oldbuf = field->buf;
+ FIELD_CELL *newbuf;
+
+ int growth;
+ FORM *form = field->form;
+ bool need_visual_update = ((form != (FORM *)0) &&
+ (form->status & _POSTED) &&
+ (form->current == field));
+
+ if (need_visual_update)
+ Synchronize_Buffer(form);
+
+ if (single_line_field)
+ {
+ growth = field->cols * amount;
+ if (field->maxgrow)
+ growth = Minimum(field->maxgrow - field->dcols, growth);
+ field->dcols += growth;
+ if (field->dcols == field->maxgrow)
+ field->status &= ~_MAY_GROW;
+ }
+ else
+ {
+ growth = (field->rows + field->nrow) * amount;
+ if (field->maxgrow)
+ growth = Minimum(field->maxgrow - field->drows, growth);
+ field->drows += growth;
+ if (field->drows == field->maxgrow)
+ field->status &= ~_MAY_GROW;
+ }
+ /* drows, dcols changed, so we get really the new buffer length */
+ new_buflen = Buffer_Length(field);
+ newbuf = (FIELD_CELL *)malloc(Total_Buffer_Size(field));
+ if (!newbuf)
+ {
+ /* restore to previous state */
+ field->dcols = old_dcols;
+ field->drows = old_drows;
+ if ((single_line_field && (field->dcols != field->maxgrow)) ||
+ (!single_line_field && (field->drows != field->maxgrow)))
+ field->status |= _MAY_GROW;
+ }
+ else
+ {
+ /* Copy all the buffers. This is the reason why we can't just use
+ * realloc().
+ */
+ int i, j;
+ FIELD_CELL *old_bp;
+ FIELD_CELL *new_bp;
+
+ result = TRUE; /* allow sharing of recovery on failure */
+
+ T((T_CREATE("fieldcell %p"), (void *)newbuf));
+ field->buf = newbuf;
+ for (i = 0; i <= field->nbuf; i++)
+ {
+ new_bp = Address_Of_Nth_Buffer(field, i);
+ old_bp = oldbuf + i * (1 + old_buflen);
+ for (j = 0; j < old_buflen; ++j)
+ new_bp[j] = old_bp[j];
+ while (j < new_buflen)
+ new_bp[j++] = myBLANK;
+ new_bp[new_buflen] = myZEROS;
+ }
+
+#if USE_WIDEC_SUPPORT && NCURSES_EXT_FUNCS
+ if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR)
+ result = FALSE;
+#endif
+
+ if (need_visual_update && result)
+ {
+ WINDOW *new_window = newpad(field->drows, field->dcols);
+
+ if (new_window != 0)
+ {
+ assert(form != (FORM *)0);
+ if (form->w)
+ delwin(form->w);
+ form->w = new_window;
+ Set_Field_Window_Attributes(field, form->w);
+ werase(form->w);
+ Buffer_To_Window(field, form->w);
+ untouchwin(form->w);
+ wmove(form->w, form->currow, form->curcol);
+ }
+ else
+ result = FALSE;
+ }
+
+ if (result)
+ {
+ free(oldbuf);
+ /* reflect changes in linked fields */
+ if (field != field->link)
+ {
+ FIELD *linked_field;
+
+ for (linked_field = field->link;
+ linked_field != field;
+ linked_field = linked_field->link)
+ {
+ linked_field->buf = field->buf;
+ linked_field->drows = field->drows;
+ linked_field->dcols = field->dcols;
+ }
+ }
+ }
+ else
+ {
+ /* restore old state */
+ field->dcols = old_dcols;
+ field->drows = old_drows;
+ field->buf = oldbuf;
+ if ((single_line_field &&
+ (field->dcols != field->maxgrow)) ||
+ (!single_line_field &&
+ (field->drows != field->maxgrow)))
+ field->status |= _MAY_GROW;
+ free(newbuf);
+ }
+ }
+ }
+ return (result);
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int Field_encloses(FIELD *field, int ry, int rx)
+|
+| Description : Check if the given coordinates lie within the given field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - form has no current field or
+| field-window
++--------------------------------------------------------------------------*/
+static int
+Field_encloses(FIELD *field, int ry, int rx)
+{
+ T((T_CALLED("Field_encloses(%p)"), (void *)field));
+ if (field != 0
+ && field->frow <= ry
+ && (field->frow + field->rows) > ry
+ && field->fcol <= rx
+ && (field->fcol + field->cols) > rx)
+ {
+ RETURN(E_OK);
+ }
+ RETURN(E_INVALID_FIELD);
+}
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Position_Form_Cursor(FORM * form)
+|
+| Description : Position the cursor in the window for the current
+| field to be in sync. with the currow and curcol
+| values.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - form has no current field or
+| field-window
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Position_Form_Cursor(FORM *form)
+{
+ FIELD *field;
+ WINDOW *formwin;
+
+ if (!form)
+ return (E_BAD_ARGUMENT);
+
+ if (!form->w || !form->current)
+ return (E_SYSTEM_ERROR);
+
+ field = form->current;
+ formwin = Get_Form_Window(form);
+
+ wmove(form->w, form->currow, form->curcol);
+ if (Has_Invisible_Parts(field))
+ {
+ /* in this case fieldwin isn't derived from formwin, so we have
+ to move the cursor in formwin by hand... */
+ wmove(formwin,
+ field->frow + form->currow - form->toprow,
+ field->fcol + form->curcol - form->begincol);
+ wcursyncup(formwin);
+ }
+ else
+ wcursyncup(form->w);
+ return (E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Refresh_Current_Field(FORM * form)
+|
+| Description : Propagate the changes in the fields window to the
+| window of the form.
+|
+| Return Values : E_OK - on success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - general error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Refresh_Current_Field(FORM *form)
+{
+ WINDOW *formwin;
+ FIELD *field;
+
+ T((T_CALLED("_nc_Refresh_Current_Field(%p)"), (void *)form));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!form->w || !form->current)
+ RETURN(E_SYSTEM_ERROR);
+
+ field = form->current;
+ formwin = Get_Form_Window(form);
+
+ if (field->opts & O_PUBLIC)
+ {
+ if (Is_Scroll_Field(field))
+ {
+ /* Again, in this case the fieldwin isn't derived from formwin,
+ so we have to perform a copy operation. */
+ if (Single_Line_Field(field))
+ {
+ /* horizontal scrolling */
+ if (form->curcol < form->begincol)
+ form->begincol = form->curcol;
+ else
+ {
+ if (form->curcol >= (form->begincol + field->cols))
+ form->begincol = form->curcol - field->cols + 1;
+ }
+ copywin(form->w,
+ formwin,
+ 0,
+ form->begincol,
+ field->frow,
+ field->fcol,
+ field->frow,
+ field->cols + field->fcol - 1,
+ 0);
+ }
+ else
+ {
+ /* A multi-line, i.e. vertical scrolling field */
+ int row_after_bottom, first_modified_row, first_unmodified_row;
+
+ if (field->drows > field->rows)
+ {
+ row_after_bottom = form->toprow + field->rows;
+ if (form->currow < form->toprow)
+ {
+ form->toprow = form->currow;
+ field->status |= _NEWTOP;
+ }
+ if (form->currow >= row_after_bottom)
+ {
+ form->toprow = form->currow - field->rows + 1;
+ field->status |= _NEWTOP;
+ }
+ if (field->status & _NEWTOP)
+ {
+ /* means we have to copy whole range */
+ first_modified_row = form->toprow;
+ first_unmodified_row = first_modified_row + field->rows;
+ field->status &= ~_NEWTOP;
+ }
+ else
+ {
+ /* we try to optimize : finding the range of touched
+ lines */
+ first_modified_row = form->toprow;
+ while (first_modified_row < row_after_bottom)
+ {
+ if (is_linetouched(form->w, first_modified_row))
+ break;
+ first_modified_row++;
+ }
+ first_unmodified_row = first_modified_row;
+ while (first_unmodified_row < row_after_bottom)
+ {
+ if (!is_linetouched(form->w, first_unmodified_row))
+ break;
+ first_unmodified_row++;
+ }
+ }
+ }
+ else
+ {
+ first_modified_row = form->toprow;
+ first_unmodified_row = first_modified_row + field->rows;
+ }
+ if (first_unmodified_row != first_modified_row)
+ copywin(form->w,
+ formwin,
+ first_modified_row,
+ 0,
+ field->frow + first_modified_row - form->toprow,
+ field->fcol,
+ field->frow + first_unmodified_row - form->toprow - 1,
+ field->cols + field->fcol - 1,
+ 0);
+ }
+ wsyncup(formwin);
+ }
+ else
+ {
+ /* if the field-window is simply a derived window, i.e. contains no
+ * invisible parts, the whole thing is trivial
+ */
+ wsyncup(form->w);
+ }
+ }
+ untouchwin(form->w);
+ returnCode(_nc_Position_Form_Cursor(form));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Perform_Justification(
+| FIELD * field,
+| WINDOW * win)
+|
+| Description : Output field with requested justification
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Perform_Justification(FIELD *field, WINDOW *win)
+{
+ FIELD_CELL *bp;
+ int len;
+ int col = 0;
+
+ bp = Get_Start_Of_Data(field->buf, Buffer_Length(field));
+ len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp);
+
+ if (len > 0)
+ {
+ assert(win && (field->drows == 1) && (field->dcols == field->cols));
+
+ switch (field->just)
+ {
+ case JUSTIFY_LEFT:
+ break;
+ case JUSTIFY_CENTER:
+ col = (field->cols - len) / 2;
+ break;
+ case JUSTIFY_RIGHT:
+ col = field->cols - len;
+ break;
+ default:
+ break;
+ }
+
+ wmove(win, 0, col);
+ myADDNSTR(win, bp, len);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Undo_Justification(
+| FIELD * field,
+| WINDOW * win)
+|
+| Description : Display field without any justification, i.e.
+| left justified
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Undo_Justification(FIELD *field, WINDOW *win)
+{
+ FIELD_CELL *bp;
+ int len;
+
+ bp = Get_Start_Of_Data(field->buf, Buffer_Length(field));
+ len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp);
+
+ if (len > 0)
+ {
+ assert(win);
+ wmove(win, 0, 0);
+ myADDNSTR(win, bp, len);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Char(FORM *form,
+| FIELD *field,
+| FIELDTYPE * typ,
+| int ch,
+| TypeArgument *argp)
+|
+| Description : Perform a single character check for character ch
+| according to the fieldtype instance.
+|
+| Return Values : TRUE - Character is valid
+| FALSE - Character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_Char(FORM *form,
+ FIELD *field,
+ FIELDTYPE *typ,
+ int ch,
+ TypeArgument *argp)
+{
+ if (typ)
+ {
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp);
+ return (
+ Check_Char(form, field, typ->left, ch, argp->left) ||
+ Check_Char(form, field, typ->right, ch, argp->right));
+ }
+ else
+ {
+#if NCURSES_INTEROP_FUNCS
+ if (typ->charcheck.occheck)
+ {
+ if (typ->status & _GENERIC)
+ return typ->charcheck.gccheck(ch, form, field, (void *)argp);
+ else
+ return typ->charcheck.occheck(ch, (void *)argp);
+ }
+#else
+ if (typ->ccheck)
+ return typ->ccheck(ch, (void *)argp);
+#endif
+ }
+ }
+ return (!iscntrl(UChar(ch)) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Display_Or_Erase_Field(
+| FIELD * field,
+| bool bEraseFlag)
+|
+| Description : Create a subwindow for the field and display the
+| buffer contents (apply justification if required)
+| or simply erase the field.
+|
+| Return Values : E_OK - on success
+| E_SYSTEM_ERROR - some error (typical no memory)
++--------------------------------------------------------------------------*/
+static int
+Display_Or_Erase_Field(FIELD *field, bool bEraseFlag)
+{
+ WINDOW *win;
+ WINDOW *fwin;
+
+ if (!field)
+ return E_SYSTEM_ERROR;
+
+ fwin = Get_Form_Window(field->form);
+ win = derwin(fwin,
+ field->rows, field->cols, field->frow, field->fcol);
+
+ if (!win)
+ return E_SYSTEM_ERROR;
+ else
+ {
+ if (field->opts & O_VISIBLE)
+ {
+ Set_Field_Window_Attributes(field, win);
+ }
+ else
+ {
+ (void)wattrset(win, WINDOW_ATTRS(fwin));
+ }
+ werase(win);
+ }
+
+ if (!bEraseFlag)
+ {
+ if (field->opts & O_PUBLIC)
+ {
+ if (Justification_Allowed(field))
+ Perform_Justification(field, win);
+ else
+ Buffer_To_Window(field, win);
+ }
+ field->status &= ~_NEWTOP;
+ }
+ wsyncup(win);
+ delwin(win);
+ return E_OK;
+}
+
+/* Macros to preset the bEraseFlag */
+#define Display_Field(field) Display_Or_Erase_Field(field,FALSE)
+#define Erase_Field(field) Display_Or_Erase_Field(field,TRUE)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Synchronize_Field(FIELD * field)
+|
+| Description : Synchronize the windows content with the value in
+| the buffer.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+static int
+Synchronize_Field(FIELD *field)
+{
+ FORM *form;
+ int res = E_OK;
+
+ if (!field)
+ return (E_BAD_ARGUMENT);
+
+ if (((form = field->form) != (FORM *)0)
+ && Field_Really_Appears(field))
+ {
+ if (field == form->current)
+ {
+ form->currow = form->curcol = form->toprow = form->begincol = 0;
+ werase(form->w);
+
+ if ((field->opts & O_PUBLIC) && Justification_Allowed(field))
+ Undo_Justification(field, form->w);
+ else
+ Buffer_To_Window(field, form->w);
+
+ field->status |= _NEWTOP;
+ res = _nc_Refresh_Current_Field(form);
+ }
+ else
+ res = Display_Field(field);
+ }
+ field->status |= _CHANGED;
+ return (res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Synchronize_Linked_Fields(FIELD * field)
+|
+| Description : Propagate the Synchronize_Field function to all linked
+| fields. The first error that occurs in the sequence
+| of updates is the return value.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+static int
+Synchronize_Linked_Fields(FIELD *field)
+{
+ FIELD *linked_field;
+ int res = E_OK;
+ int syncres;
+
+ if (!field)
+ return (E_BAD_ARGUMENT);
+
+ if (!field->link)
+ return (E_SYSTEM_ERROR);
+
+ for (linked_field = field->link;
+ linked_field != field;
+ linked_field = linked_field->link)
+ {
+ if (((syncres = Synchronize_Field(linked_field)) != E_OK) &&
+ (res == E_OK))
+ res = syncres;
+ }
+ return (res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Synchronize_Attributes(FIELD * field)
+|
+| Description : If a fields visual attributes have changed, this
+| routine is called to propagate those changes to the
+| screen.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Synchronize_Attributes(FIELD *field)
+{
+ FORM *form;
+ int res = E_OK;
+ WINDOW *formwin;
+
+ T((T_CALLED("_nc_Synchronize_Attributes(%p)"), (void *)field));
+
+ if (!field)
+ returnCode(E_BAD_ARGUMENT);
+
+ CHECKPOS(field->form);
+ if (((form = field->form) != (FORM *)0)
+ && Field_Really_Appears(field))
+ {
+ if (form->current == field)
+ {
+ Synchronize_Buffer(form);
+ Set_Field_Window_Attributes(field, form->w);
+ werase(form->w);
+ wmove(form->w, form->currow, form->curcol);
+
+ if (field->opts & O_PUBLIC)
+ {
+ if (Justification_Allowed(field))
+ Undo_Justification(field, form->w);
+ else
+ Buffer_To_Window(field, form->w);
+ }
+ else
+ {
+ formwin = Get_Form_Window(form);
+ copywin(form->w, formwin,
+ 0, 0,
+ field->frow, field->fcol,
+ field->rows - 1, field->cols - 1, 0);
+ wsyncup(formwin);
+ Buffer_To_Window(field, form->w);
+ field->status |= _NEWTOP; /* fake refresh to paint all */
+ _nc_Refresh_Current_Field(form);
+ }
+ }
+ else
+ {
+ res = Display_Field(field);
+ }
+ }
+ CHECKPOS(form);
+ returnCode(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Synchronize_Options(FIELD * field,
+| Field_Options newopts)
+|
+| Description : If a fields options have changed, this routine is
+| called to propagate these changes to the screen and
+| to really change the behavior of the field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_CURRENT - field is the current one
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Synchronize_Options(FIELD *field, Field_Options newopts)
+{
+ Field_Options oldopts;
+ Field_Options changed_opts;
+ FORM *form;
+ int res = E_OK;
+
+ T((T_CALLED("_nc_Synchronize_Options(%p,%#x)"), (void *)field, newopts));
+
+ if (!field)
+ returnCode(E_BAD_ARGUMENT);
+
+ oldopts = field->opts;
+ changed_opts = oldopts ^ newopts;
+ field->opts = newopts;
+ form = field->form;
+
+ if (form)
+ {
+ if (form->status & _POSTED)
+ {
+ if (form->current == field)
+ {
+ field->opts = oldopts;
+ returnCode(E_CURRENT);
+ }
+ if ((form->curpage == field->page))
+ {
+ if (changed_opts & O_VISIBLE)
+ {
+ if (newopts & O_VISIBLE)
+ res = Display_Field(field);
+ else
+ res = Erase_Field(field);
+ }
+ else
+ {
+ if ((changed_opts & O_PUBLIC) &&
+ (newopts & O_VISIBLE))
+ res = Display_Field(field);
+ }
+ }
+ }
+ }
+
+ if (changed_opts & O_STATIC)
+ {
+ bool single_line_field = Single_Line_Field(field);
+ int res2 = E_OK;
+
+ if (newopts & O_STATIC)
+ {
+ /* the field becomes now static */
+ field->status &= ~_MAY_GROW;
+ /* if actually we have no hidden columns, justification may
+ occur again */
+ if (single_line_field &&
+ (field->cols == field->dcols) &&
+ (field->just != NO_JUSTIFICATION) &&
+ Field_Really_Appears(field))
+ {
+ res2 = Display_Field(field);
+ }
+ }
+ else
+ {
+ /* field is no longer static */
+ if ((field->maxgrow == 0) ||
+ (single_line_field && (field->dcols < field->maxgrow)) ||
+ (!single_line_field && (field->drows < field->maxgrow)))
+ {
+ field->status |= _MAY_GROW;
+ /* a field with justification now changes its behavior,
+ so we must redisplay it */
+ if (single_line_field &&
+ (field->just != NO_JUSTIFICATION) &&
+ Field_Really_Appears(field))
+ {
+ res2 = Display_Field(field);
+ }
+ }
+ }
+ if (res2 != E_OK)
+ res = res2;
+ }
+
+ returnCode(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Set_Current_Field(FORM * form,
+| FIELD * newfield)
+|
+| Description : Make the newfield the new current field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form or field pointer
+| E_SYSTEM_ERROR - some severe basic error
+| E_NOT_CONNECTED - no fields are connected to the form
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Set_Current_Field(FORM *form, FIELD *newfield)
+{
+ FIELD *field;
+ WINDOW *new_window;
+
+ T((T_CALLED("_nc_Set_Current_Field(%p,%p)"), (void *)form, (void *)newfield));
+
+ if (!form || !newfield || !form->current || (newfield->form != form))
+ returnCode(E_BAD_ARGUMENT);
+
+ if ((form->status & _IN_DRIVER))
+ returnCode(E_BAD_STATE);
+
+ if (!(form->field))
+ returnCode(E_NOT_CONNECTED);
+
+ field = form->current;
+
+ if ((field != newfield) ||
+ !(form->status & _POSTED))
+ {
+ if ((form->w) &&
+ (field->opts & O_VISIBLE) &&
+ (field->form->curpage == field->page))
+ {
+ _nc_Refresh_Current_Field(form);
+ if (field->opts & O_PUBLIC)
+ {
+ if (field->drows > field->rows)
+ {
+ if (form->toprow == 0)
+ field->status &= ~_NEWTOP;
+ else
+ field->status |= _NEWTOP;
+ }
+ else
+ {
+ if (Justification_Allowed(field))
+ {
+ Window_To_Buffer(form, field);
+ werase(form->w);
+ Perform_Justification(field, form->w);
+ wsyncup(form->w);
+ }
+ }
+ }
+ delwin(form->w);
+ form->w = (WINDOW *)0;
+ }
+
+ field = newfield;
+
+ if (Has_Invisible_Parts(field))
+ new_window = newpad(field->drows, field->dcols);
+ else
+ new_window = derwin(Get_Form_Window(form),
+ field->rows, field->cols, field->frow, field->fcol);
+
+ if (!new_window)
+ returnCode(E_SYSTEM_ERROR);
+
+ form->current = field;
+
+ if (form->w)
+ delwin(form->w);
+ form->w = new_window;
+
+ form->status &= ~_WINDOW_MODIFIED;
+ Set_Field_Window_Attributes(field, form->w);
+
+ if (Has_Invisible_Parts(field))
+ {
+ werase(form->w);
+ Buffer_To_Window(field, form->w);
+ }
+ else
+ {
+ if (Justification_Allowed(field))
+ {
+ werase(form->w);
+ Undo_Justification(field, form->w);
+ wsyncup(form->w);
+ }
+ }
+
+ untouchwin(form->w);
+ }
+
+ form->currow = form->curcol = form->toprow = form->begincol = 0;
+ returnCode(E_OK);
+}
+
+/*----------------------------------------------------------------------------
+ Intra-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Character(FORM * form)
+|
+| Description : Move to the next character in the field. In a multi-line
+| field this wraps at the end of the line.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the rightmost position
++--------------------------------------------------------------------------*/
+static int
+IFN_Next_Character(FORM *form)
+{
+ FIELD *field = form->current;
+ int step = myWCWIDTH(form->w, form->currow, form->curcol);
+
+ T((T_CALLED("IFN_Next_Character(%p)"), (void *)form));
+ if ((form->curcol += step) == field->dcols)
+ {
+ if ((++(form->currow)) == field->drows)
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field, 1))
+ {
+ form->curcol = 0;
+ returnCode(E_OK);
+ }
+#endif
+ form->currow--;
+#if GROW_IF_NAVIGATE
+ if (Single_Line_Field(field) && Field_Grown(field, 1))
+ returnCode(E_OK);
+#endif
+ form->curcol -= step;
+ returnCode(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Character(FORM * form)
+|
+| Description : Move to the previous character in the field. In a
+| multi-line field this wraps and the beginning of the
+| line.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the leftmost position
++--------------------------------------------------------------------------*/
+static int
+IFN_Previous_Character(FORM *form)
+{
+ int amount = myWCWIDTH(form->w, form->currow, form->curcol - 1);
+ int oldcol = form->curcol;
+
+ T((T_CALLED("IFN_Previous_Character(%p)"), (void *)form));
+ if ((form->curcol -= amount) < 0)
+ {
+ if ((--(form->currow)) < 0)
+ {
+ form->currow++;
+ form->curcol = oldcol;
+ returnCode(E_REQUEST_DENIED);
+ }
+ form->curcol = form->current->dcols - 1;
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Line(FORM * form)
+|
+| Description : Move to the beginning of the next line in the field
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the last line
++--------------------------------------------------------------------------*/
+static int
+IFN_Next_Line(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("IFN_Next_Line(%p)"), (void *)form));
+ if ((++(form->currow)) == field->drows)
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field, 1))
+ returnCode(E_OK);
+#endif
+ form->currow--;
+ returnCode(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Line(FORM * form)
+|
+| Description : Move to the beginning of the previous line in the field
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the first line
++--------------------------------------------------------------------------*/
+static int
+IFN_Previous_Line(FORM *form)
+{
+ T((T_CALLED("IFN_Previous_Line(%p)"), (void *)form));
+ if ((--(form->currow)) < 0)
+ {
+ form->currow++;
+ returnCode(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Word(FORM * form)
+|
+| Description : Move to the beginning of the next word in the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - there is no next word
++--------------------------------------------------------------------------*/
+static int
+IFN_Next_Word(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *bp = Address_Of_Current_Position_In_Buffer(form);
+ FIELD_CELL *s;
+ FIELD_CELL *t;
+
+ T((T_CALLED("IFN_Next_Word(%p)"), (void *)form));
+
+ /* We really need access to the data, so we have to synchronize */
+ Synchronize_Buffer(form);
+
+ /* Go to the first whitespace after the current position (including
+ current position). This is then the starting point to look for the
+ next non-blank data */
+ s = Get_First_Whitespace_Character(bp, Buffer_Length(field) -
+ (int)(bp - field->buf));
+
+ /* Find the start of the next word */
+ t = Get_Start_Of_Data(s, Buffer_Length(field) -
+ (int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s == t)
+ returnCode(E_REQUEST_DENIED);
+ else
+#endif
+ {
+ Adjust_Cursor_Position(form, t);
+ returnCode(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Word(FORM * form)
+|
+| Description : Move to the beginning of the previous word in the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - there is no previous word
++--------------------------------------------------------------------------*/
+static int
+IFN_Previous_Word(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *bp = Address_Of_Current_Position_In_Buffer(form);
+ FIELD_CELL *s;
+ FIELD_CELL *t;
+ bool again = FALSE;
+
+ T((T_CALLED("IFN_Previous_Word(%p)"), (void *)form));
+
+ /* We really need access to the data, so we have to synchronize */
+ Synchronize_Buffer(form);
+
+ s = After_End_Of_Data(field->buf, (int)(bp - field->buf));
+ /* s points now right after the last non-blank in the buffer before bp.
+ If bp was in a word, s equals bp. In this case we must find the last
+ whitespace in the buffer before bp and repeat the game to really find
+ the previous word! */
+ if (s == bp)
+ again = TRUE;
+
+ /* And next call now goes backward to look for the last whitespace
+ before that, pointing right after this, so it points to the begin
+ of the previous word.
+ */
+ t = After_Last_Whitespace_Character(field->buf, (int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s == t)
+ returnCode(E_REQUEST_DENIED);
+#endif
+ if (again)
+ {
+ /* and do it again, replacing bp by t */
+ s = After_End_Of_Data(field->buf, (int)(t - field->buf));
+ t = After_Last_Whitespace_Character(field->buf, (int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s == t)
+ returnCode(E_REQUEST_DENIED);
+#endif
+ }
+ Adjust_Cursor_Position(form, t);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Beginning_Of_Field(FORM * form)
+|
+| Description : Place the cursor at the first non-pad character in
+| the field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+IFN_Beginning_Of_Field(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("IFN_Beginning_Of_Field(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ Adjust_Cursor_Position(form,
+ Get_Start_Of_Data(field->buf, Buffer_Length(field)));
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_End_Of_Field(FORM * form)
+|
+| Description : Place the cursor after the last non-pad character in
+| the field. If the field occupies the last position in
+| the buffer, the cursor is positioned on the last
+| character.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+IFN_End_Of_Field(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *pos;
+
+ T((T_CALLED("IFN_End_Of_Field(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ pos = After_End_Of_Data(field->buf, Buffer_Length(field));
+ if (pos == (field->buf + Buffer_Length(field)))
+ pos--;
+ Adjust_Cursor_Position(form, pos);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Beginning_Of_Line(FORM * form)
+|
+| Description : Place the cursor on the first non-pad character in
+| the current line of the field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+IFN_Beginning_Of_Line(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("IFN_Beginning_Of_Line(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ Adjust_Cursor_Position(form,
+ Get_Start_Of_Data(Address_Of_Current_Row_In_Buffer(form),
+ field->dcols));
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_End_Of_Line(FORM * form)
+|
+| Description : Place the cursor after the last non-pad character in the
+| current line of the field. If the field occupies the
+| last column in the line, the cursor is positioned on the
+| last character of the line.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+IFN_End_Of_Line(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *pos;
+ FIELD_CELL *bp;
+
+ T((T_CALLED("IFN_End_Of_Line(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ bp = Address_Of_Current_Row_In_Buffer(form);
+ pos = After_End_Of_Data(bp, field->dcols);
+ if (pos == (bp + field->dcols))
+ pos--;
+ Adjust_Cursor_Position(form, pos);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Left_Character(FORM * form)
+|
+| Description : Move one character to the left in the current line.
+| This doesn't cycle.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in first column
++--------------------------------------------------------------------------*/
+static int
+IFN_Left_Character(FORM *form)
+{
+ int amount = myWCWIDTH(form->w, form->currow, form->curcol - 1);
+ int oldcol = form->curcol;
+
+ T((T_CALLED("IFN_Left_Character(%p)"), (void *)form));
+ if ((form->curcol -= amount) < 0)
+ {
+ form->curcol = oldcol;
+ returnCode(E_REQUEST_DENIED);
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Right_Character(FORM * form)
+|
+| Description : Move one character to the right in the current line.
+| This doesn't cycle.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int
+IFN_Right_Character(FORM *form)
+{
+ int amount = myWCWIDTH(form->w, form->currow, form->curcol);
+ int oldcol = form->curcol;
+
+ T((T_CALLED("IFN_Right_Character(%p)"), (void *)form));
+ if ((form->curcol += amount) >= form->current->dcols)
+ {
+#if GROW_IF_NAVIGATE
+ FIELD *field = form->current;
+
+ if (Single_Line_Field(field) && Field_Grown(field, 1))
+ returnCode(E_OK);
+#endif
+ form->curcol = oldcol;
+ returnCode(E_REQUEST_DENIED);
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Up_Character(FORM * form)
+|
+| Description : Move one line up. This doesn't cycle through the lines
+| of the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int
+IFN_Up_Character(FORM *form)
+{
+ T((T_CALLED("IFN_Up_Character(%p)"), (void *)form));
+ if ((--(form->currow)) < 0)
+ {
+ form->currow++;
+ returnCode(E_REQUEST_DENIED);
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Down_Character(FORM * form)
+|
+| Description : Move one line down. This doesn't cycle through the
+| lines of the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int
+IFN_Down_Character(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("IFN_Down_Character(%p)"), (void *)form));
+ if ((++(form->currow)) == field->drows)
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field, 1))
+ returnCode(E_OK);
+#endif
+ --(form->currow);
+ returnCode(E_REQUEST_DENIED);
+ }
+ returnCode(E_OK);
+}
+/*----------------------------------------------------------------------------
+ END of Intra-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Vertical scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Generic(FORM *form, int nlines)
+|
+| Description : Scroll multi-line field forward (nlines>0) or
+| backward (nlines<0) this many lines.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - can't scroll
++--------------------------------------------------------------------------*/
+static int
+VSC_Generic(FORM *form, int nlines)
+{
+ FIELD *field = form->current;
+ int res = E_REQUEST_DENIED;
+ int rows_to_go = (nlines > 0 ? nlines : -nlines);
+
+ if (nlines > 0)
+ {
+ if ((rows_to_go + form->toprow) > (field->drows - field->rows))
+ rows_to_go = (field->drows - field->rows - form->toprow);
+
+ if (rows_to_go > 0)
+ {
+ form->currow += rows_to_go;
+ form->toprow += rows_to_go;
+ res = E_OK;
+ }
+ }
+ else
+ {
+ if (rows_to_go > form->toprow)
+ rows_to_go = form->toprow;
+
+ if (rows_to_go > 0)
+ {
+ form->currow -= rows_to_go;
+ form->toprow -= rows_to_go;
+ res = E_OK;
+ }
+ }
+ return (res);
+}
+/*----------------------------------------------------------------------------
+ End of Vertical scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Vertical scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Vertical_Scrolling(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Performs the generic vertical scrolling routines.
+| This has to check for a multi-line field and to set
+| the _NEWTOP flag if scrolling really occurred.
+|
+| Return Values : Propagated error code from low-level driver calls
++--------------------------------------------------------------------------*/
+static int
+Vertical_Scrolling(int (*const fct) (FORM *), FORM *form)
+{
+ int res = E_REQUEST_DENIED;
+
+ if (!Single_Line_Field(form->current))
+ {
+ res = fct(form);
+ if (res == E_OK)
+ form->current->status |= _NEWTOP;
+ }
+ return (res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Line_Forward(FORM * form)
+|
+| Description : Scroll multi-line field forward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Line_Forward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Line_Forward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, 1));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Line_Backward(FORM * form)
+|
+| Description : Scroll multi-line field backward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Line_Backward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Line_Backward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, -1));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Page_Forward(FORM * form)
+|
+| Description : Scroll a multi-line field forward a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Page_Forward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Page_Forward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, form->current->rows));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Half_Page_Forward(FORM * form)
+|
+| Description : Scroll a multi-line field forward half a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Half_Page_Forward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Half_Page_Forward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, (form->current->rows + 1) / 2));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Page_Backward(FORM * form)
+|
+| Description : Scroll a multi-line field backward a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Page_Backward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Page_Backward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, -(form->current->rows)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Half_Page_Backward(FORM * form)
+|
+| Description : Scroll a multi-line field backward half a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+VSC_Scroll_Half_Page_Backward(FORM *form)
+{
+ T((T_CALLED("VSC_Scroll_Half_Page_Backward(%p)"), (void *)form));
+ returnCode(VSC_Generic(form, -((form->current->rows + 1) / 2)));
+}
+/*----------------------------------------------------------------------------
+ End of Vertical scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Horizontal scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Generic(FORM *form, int ncolumns)
+|
+| Description : Scroll single-line field forward (ncolumns>0) or
+| backward (ncolumns<0) this many columns.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - can't scroll
++--------------------------------------------------------------------------*/
+static int
+HSC_Generic(FORM *form, int ncolumns)
+{
+ FIELD *field = form->current;
+ int res = E_REQUEST_DENIED;
+ int cols_to_go = (ncolumns > 0 ? ncolumns : -ncolumns);
+
+ if (ncolumns > 0)
+ {
+ if ((cols_to_go + form->begincol) > (field->dcols - field->cols))
+ cols_to_go = field->dcols - field->cols - form->begincol;
+
+ if (cols_to_go > 0)
+ {
+ form->curcol += cols_to_go;
+ form->begincol += cols_to_go;
+ res = E_OK;
+ }
+ }
+ else
+ {
+ if (cols_to_go > form->begincol)
+ cols_to_go = form->begincol;
+
+ if (cols_to_go > 0)
+ {
+ form->curcol -= cols_to_go;
+ form->begincol -= cols_to_go;
+ res = E_OK;
+ }
+ }
+ return (res);
+}
+/*----------------------------------------------------------------------------
+ End of Horizontal scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Horizontal scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Horizontal_Scrolling(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Performs the generic horizontal scrolling routines.
+| This has to check for a single-line field.
+|
+| Return Values : Propagated error code from low-level driver calls
++--------------------------------------------------------------------------*/
+static int
+Horizontal_Scrolling(int (*const fct) (FORM *), FORM *form)
+{
+ if (Single_Line_Field(form->current))
+ return fct(form);
+ else
+ return (E_REQUEST_DENIED);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Scroll_Char_Forward(FORM * form)
+|
+| Description : Scroll single-line field forward a character
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+HSC_Scroll_Char_Forward(FORM *form)
+{
+ T((T_CALLED("HSC_Scroll_Char_Forward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, 1));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Scroll_Char_Backward(FORM * form)
+|
+| Description : Scroll single-line field backward a character
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+HSC_Scroll_Char_Backward(FORM *form)
+{
+ T((T_CALLED("HSC_Scroll_Char_Backward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, -1));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Line_Forward(FORM* form)
+|
+| Description : Scroll single-line field forward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+HSC_Horizontal_Line_Forward(FORM *form)
+{
+ T((T_CALLED("HSC_Horizontal_Line_Forward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, form->current->cols));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Half_Line_Forward(FORM* form)
+|
+| Description : Scroll single-line field forward half a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int
+HSC_Horizontal_Half_Line_Forward(FORM *form)
+{
+ T((T_CALLED("HSC_Horizontal_Half_Line_Forward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, (form->current->cols + 1) / 2));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Line_Backward(FORM* form)
+|
+| Description : Scroll single-line field backward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+HSC_Horizontal_Line_Backward(FORM *form)
+{
+ T((T_CALLED("HSC_Horizontal_Line_Backward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, -(form->current->cols)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Half_Line_Backward(FORM* form)
+|
+| Description : Scroll single-line field backward half a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int
+HSC_Horizontal_Half_Line_Backward(FORM *form)
+{
+ T((T_CALLED("HSC_Horizontal_Half_Line_Backward(%p)"), (void *)form));
+ returnCode(HSC_Generic(form, -((form->current->cols + 1) / 2)));
+}
+
+/*----------------------------------------------------------------------------
+ End of Horizontal scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Field Editing
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Is_There_Room_For_A_Line(FORM * form)
+|
+| Description : Check whether or not there is enough room in the
+| buffer to enter a whole line.
+|
+| Return Values : TRUE - there is enough space
+| FALSE - there is not enough space
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static bool
+Is_There_Room_For_A_Line(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *begin_of_last_line, *s;
+
+ Synchronize_Buffer(form);
+ begin_of_last_line = Address_Of_Row_In_Buffer(field, (field->drows - 1));
+ s = After_End_Of_Data(begin_of_last_line, field->dcols);
+ return ((s == begin_of_last_line) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Is_There_Room_For_A_Char_In_Line(FORM * form)
+|
+| Description : Checks whether or not there is room for a new character
+| in the current line.
+|
+| Return Values : TRUE - there is room
+| FALSE - there is not enough room (line full)
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static bool
+Is_There_Room_For_A_Char_In_Line(FORM *form)
+{
+ int last_char_in_line;
+
+ wmove(form->w, form->currow, form->current->dcols - 1);
+ last_char_in_line = (int)(winch(form->w) & A_CHARTEXT);
+ wmove(form->w, form->currow, form->curcol);
+ return (((last_char_in_line == form->current->pad) ||
+ is_blank(last_char_in_line)) ? TRUE : FALSE);
+}
+
+#define There_Is_No_Room_For_A_Char_In_Line(f) \
+ !Is_There_Room_For_A_Char_In_Line(f)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Insert_String(
+| FORM * form,
+| int row,
+| char *txt,
+| int len )
+|
+| Description : Insert the 'len' characters beginning at pointer 'txt'
+| into the 'row' of the 'form'. The insertion occurs
+| on the beginning of the row, all other characters are
+| moved to the right. After the text a pad character will
+| be inserted to separate the text from the rest. If
+| necessary the insertion moves characters on the next
+| line to make place for the requested insertion string.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED -
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+static int
+Insert_String(FORM *form, int row, FIELD_CELL *txt, int len)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *bp = Address_Of_Row_In_Buffer(field, row);
+ int datalen = (int)(After_End_Of_Data(bp, field->dcols) - bp);
+ int freelen = field->dcols - datalen;
+ int requiredlen = len + 1;
+ FIELD_CELL *split;
+ int result = E_REQUEST_DENIED;
+
+ if (freelen >= requiredlen)
+ {
+ wmove(form->w, row, 0);
+ myINSNSTR(form->w, txt, len);
+ wmove(form->w, row, len);
+ myINSNSTR(form->w, &myBLANK, 1);
+ return E_OK;
+ }
+ else
+ {
+ /* we have to move characters on the next line. If we are on the
+ last line this may work, if the field is growable */
+ if ((row == (field->drows - 1)) && Growable(field))
+ {
+ if (!Field_Grown(field, 1))
+ return (E_SYSTEM_ERROR);
+ /* !!!Side-Effect : might be changed due to growth!!! */
+ bp = Address_Of_Row_In_Buffer(field, row);
+ }
+
+ if (row < (field->drows - 1))
+ {
+ split =
+ After_Last_Whitespace_Character(bp,
+ (int)(Get_Start_Of_Data(bp
+ + field->dcols
+ - requiredlen,
+ requiredlen)
+ - bp));
+ /* split points now to the first character of the portion of the
+ line that must be moved to the next line */
+ datalen = (int)(split - bp); /* + freelen has to stay on this line */
+ freelen = field->dcols - (datalen + freelen); /* for the next line */
+
+ if ((result = Insert_String(form, row + 1, split, freelen)) == E_OK)
+ {
+ wmove(form->w, row, datalen);
+ wclrtoeol(form->w);
+ wmove(form->w, row, 0);
+ myINSNSTR(form->w, txt, len);
+ wmove(form->w, row, len);
+ myINSNSTR(form->w, &myBLANK, 1);
+ return E_OK;
+ }
+ }
+ return (result);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Wrapping_Not_Necessary_Or_Wrapping_Ok(
+| FORM * form)
+|
+| Description : If a character has been entered into a field, it may
+| be that wrapping has to occur. This routine checks
+| whether or not wrapping is required and if so, performs
+| the wrapping.
+|
+| Return Values : E_OK - no wrapping required or wrapping
+| was successful
+| E_REQUEST_DENIED -
+| E_SYSTEM_ERROR - some system error
++--------------------------------------------------------------------------*/
+static int
+Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM *form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+ bool Last_Row = ((field->drows - 1) == form->currow);
+
+ if ((field->opts & O_WRAP) && /* wrapping wanted */
+ (!Single_Line_Field(field)) && /* must be multi-line */
+ (There_Is_No_Room_For_A_Char_In_Line(form)) && /* line is full */
+ (!Last_Row || Growable(field))) /* there are more lines */
+ {
+ FIELD_CELL *bp;
+ FIELD_CELL *split;
+ int chars_to_be_wrapped;
+ int chars_to_remain_on_line;
+
+ if (Last_Row)
+ {
+ /* the above logic already ensures, that in this case the field
+ is growable */
+ if (!Field_Grown(field, 1))
+ return E_SYSTEM_ERROR;
+ }
+ bp = Address_Of_Current_Row_In_Buffer(form);
+ Window_To_Buffer(form, field);
+ split = After_Last_Whitespace_Character(bp, field->dcols);
+ /* split points to the first character of the sequence to be brought
+ on the next line */
+ chars_to_remain_on_line = (int)(split - bp);
+ chars_to_be_wrapped = field->dcols - chars_to_remain_on_line;
+ if (chars_to_remain_on_line > 0)
+ {
+ if ((result = Insert_String(form, form->currow + 1, split,
+ chars_to_be_wrapped)) == E_OK)
+ {
+ wmove(form->w, form->currow, chars_to_remain_on_line);
+ wclrtoeol(form->w);
+ if (form->curcol >= chars_to_remain_on_line)
+ {
+ form->currow++;
+ form->curcol -= chars_to_remain_on_line;
+ }
+ return E_OK;
+ }
+ }
+ else
+ return E_OK;
+ if (result != E_OK)
+ {
+ DeleteChar(form);
+ Window_To_Buffer(form, field);
+ result = E_REQUEST_DENIED;
+ }
+ }
+ else
+ result = E_OK; /* wrapping was not necessary */
+ return (result);
+}
+
+/*----------------------------------------------------------------------------
+ Field Editing routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Field_Editing(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic routine for field editing requests. The driver
+| routines are only called for editable fields, the
+| _WINDOW_MODIFIED flag is set if editing occurred.
+| This is somewhat special due to the overload semantics
+| of the NEW_LINE and DEL_PREV requests.
+|
+| Return Values : Error code from low level drivers.
++--------------------------------------------------------------------------*/
+static int
+Field_Editing(int (*const fct) (FORM *), FORM *form)
+{
+ int res = E_REQUEST_DENIED;
+
+ /* We have to deal here with the specific case of the overloaded
+ behavior of New_Line and Delete_Previous requests.
+ They may end up in navigational requests if we are on the first
+ character in a field. But navigation is also allowed on non-
+ editable fields.
+ */
+ if ((fct == FE_Delete_Previous) &&
+ (form->opts & O_BS_OVERLOAD) &&
+ First_Position_In_Current_Field(form))
+ {
+ res = Inter_Field_Navigation(FN_Previous_Field, form);
+ }
+ else
+ {
+ if (fct == FE_New_Line)
+ {
+ if ((form->opts & O_NL_OVERLOAD) &&
+ First_Position_In_Current_Field(form))
+ {
+ res = Inter_Field_Navigation(FN_Next_Field, form);
+ }
+ else
+ /* FE_New_Line deals itself with the _WINDOW_MODIFIED flag */
+ res = fct(form);
+ }
+ else
+ {
+ /* From now on, everything must be editable */
+ if (form->current->opts & O_EDIT)
+ {
+ res = fct(form);
+ if (res == E_OK)
+ form->status |= _WINDOW_MODIFIED;
+ }
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_New_Line(FORM * form)
+|
+| Description : Perform a new line request. This is rather complex
+| compared to other routines in this code due to the
+| rather difficult to understand description in the
+| manuals.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - new line not allowed
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+static int
+FE_New_Line(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *bp, *t;
+ bool Last_Row = ((field->drows - 1) == form->currow);
+
+ T((T_CALLED("FE_New_Line(%p)"), (void *)form));
+ if (form->status & _OVLMODE)
+ {
+ if (Last_Row &&
+ (!(Growable(field) && !Single_Line_Field(field))))
+ {
+ if (!(form->opts & O_NL_OVERLOAD))
+ returnCode(E_REQUEST_DENIED);
+ wmove(form->w, form->currow, form->curcol);
+ wclrtoeol(form->w);
+ /* we have to set this here, although it is also
+ handled in the generic routine. The reason is,
+ that FN_Next_Field may fail, but the form is
+ definitively changed */
+ form->status |= _WINDOW_MODIFIED;
+ returnCode(Inter_Field_Navigation(FN_Next_Field, form));
+ }
+ else
+ {
+ if (Last_Row && !Field_Grown(field, 1))
+ {
+ /* N.B.: due to the logic in the 'if', LastRow==TRUE
+ means here that the field is growable and not
+ a single-line field */
+ returnCode(E_SYSTEM_ERROR);
+ }
+ wmove(form->w, form->currow, form->curcol);
+ wclrtoeol(form->w);
+ form->currow++;
+ form->curcol = 0;
+ form->status |= _WINDOW_MODIFIED;
+ returnCode(E_OK);
+ }
+ }
+ else
+ {
+ /* Insert Mode */
+ if (Last_Row &&
+ !(Growable(field) && !Single_Line_Field(field)))
+ {
+ if (!(form->opts & O_NL_OVERLOAD))
+ returnCode(E_REQUEST_DENIED);
+ returnCode(Inter_Field_Navigation(FN_Next_Field, form));
+ }
+ else
+ {
+ bool May_Do_It = !Last_Row && Is_There_Room_For_A_Line(form);
+
+ if (!(May_Do_It || Growable(field)))
+ returnCode(E_REQUEST_DENIED);
+ if (!May_Do_It && !Field_Grown(field, 1))
+ returnCode(E_SYSTEM_ERROR);
+
+ bp = Address_Of_Current_Position_In_Buffer(form);
+ t = After_End_Of_Data(bp, field->dcols - form->curcol);
+ wmove(form->w, form->currow, form->curcol);
+ wclrtoeol(form->w);
+ form->currow++;
+ form->curcol = 0;
+ wmove(form->w, form->currow, form->curcol);
+ winsertln(form->w);
+ myADDNSTR(form->w, bp, (int)(t - bp));
+ form->status |= _WINDOW_MODIFIED;
+ returnCode(E_OK);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Insert_Character(FORM * form)
+|
+| Description : Insert blank character at the cursor position
+|
+| Return Values : E_OK
+| E_REQUEST_DENIED
++--------------------------------------------------------------------------*/
+static int
+FE_Insert_Character(FORM *form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ T((T_CALLED("FE_Insert_Character(%p)"), (void *)form));
+ if (Check_Char(form, field, field->type, (int)C_BLANK,
+ (TypeArgument *)(field->arg)))
+ {
+ bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
+
+ if (There_Is_Room ||
+ ((Single_Line_Field(field) && Growable(field))))
+ {
+ if (!There_Is_Room && !Field_Grown(field, 1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+ winsch(form->w, (chtype)C_BLANK);
+ result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form);
+ }
+ }
+ }
+ returnCode(result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Insert_Line(FORM * form)
+|
+| Description : Insert a blank line at the cursor position
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - line can not be inserted
++--------------------------------------------------------------------------*/
+static int
+FE_Insert_Line(FORM *form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ T((T_CALLED("FE_Insert_Line(%p)"), (void *)form));
+ if (Check_Char(form, field,
+ field->type, (int)C_BLANK, (TypeArgument *)(field->arg)))
+ {
+ bool Maybe_Done = (form->currow != (field->drows - 1)) &&
+ Is_There_Room_For_A_Line(form);
+
+ if (!Single_Line_Field(field) &&
+ (Maybe_Done || Growable(field)))
+ {
+ if (!Maybe_Done && !Field_Grown(field, 1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+ form->curcol = 0;
+ winsertln(form->w);
+ result = E_OK;
+ }
+ }
+ }
+ returnCode(result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Character(FORM * form)
+|
+| Description : Delete character at the cursor position
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+FE_Delete_Character(FORM *form)
+{
+ T((T_CALLED("FE_Delete_Character(%p)"), (void *)form));
+ DeleteChar(form);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Previous(FORM * form)
+|
+| Description : Delete character before cursor. Again this is a rather
+| difficult piece compared to others due to the overloading
+| semantics of backspace.
+| N.B.: The case of overloaded BS on first field position
+| is already handled in the generic routine.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - Character can't be deleted
++--------------------------------------------------------------------------*/
+static int
+FE_Delete_Previous(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("FE_Delete_Previous(%p)"), (void *)form));
+ if (First_Position_In_Current_Field(form))
+ returnCode(E_REQUEST_DENIED);
+
+ if ((--(form->curcol)) < 0)
+ {
+ FIELD_CELL *this_line, *prev_line, *prev_end, *this_end;
+ int this_row = form->currow;
+
+ form->curcol++;
+ if (form->status & _OVLMODE)
+ returnCode(E_REQUEST_DENIED);
+
+ prev_line = Address_Of_Row_In_Buffer(field, (form->currow - 1));
+ this_line = Address_Of_Row_In_Buffer(field, (form->currow));
+ Synchronize_Buffer(form);
+ prev_end = After_End_Of_Data(prev_line, field->dcols);
+ this_end = After_End_Of_Data(this_line, field->dcols);
+ if ((int)(this_end - this_line) >
+ (field->cols - (int)(prev_end - prev_line)))
+ returnCode(E_REQUEST_DENIED);
+ wmove(form->w, form->currow, form->curcol);
+ wdeleteln(form->w);
+ Adjust_Cursor_Position(form, prev_end);
+ /*
+ * If we did not really move to the previous line, help the user a
+ * little. It is however a little inconsistent. Normally, when
+ * backspacing around the point where text wraps to a new line in a
+ * multi-line form, we absorb one keystroke for the wrapping point. That
+ * is consistent with SVr4 forms. However, SVr4 does not allow typing
+ * into the last column of the field, and requires the user to enter a
+ * newline to move to the next line. Therefore it can consistently eat
+ * that keystroke. Since ncurses allows the last column, it wraps
+ * automatically (given the proper options). But we cannot eat the
+ * keystroke to back over the wrapping point, since that would put the
+ * cursor past the end of the form field. In this case, just delete the
+ * character at the end of the field.
+ */
+ if (form->currow == this_row && this_row > 0)
+ {
+ form->currow -= 1;
+ form->curcol = field->dcols - 1;
+ DeleteChar(form);
+ }
+ else
+ {
+ wmove(form->w, form->currow, form->curcol);
+ myADDNSTR(form->w, this_line, (int)(this_end - this_line));
+ }
+ }
+ else
+ {
+ DeleteChar(form);
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Line(FORM * form)
+|
+| Description : Delete line at cursor position.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+FE_Delete_Line(FORM *form)
+{
+ T((T_CALLED("FE_Delete_Line(%p)"), (void *)form));
+ form->curcol = 0;
+ wdeleteln(form->w);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Word(FORM * form)
+|
+| Description : Delete word at cursor position
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - failure
++--------------------------------------------------------------------------*/
+static int
+FE_Delete_Word(FORM *form)
+{
+ FIELD *field = form->current;
+ FIELD_CELL *bp = Address_Of_Current_Row_In_Buffer(form);
+ FIELD_CELL *ep = bp + field->dcols;
+ FIELD_CELL *cp = bp + form->curcol;
+ FIELD_CELL *s;
+
+ T((T_CALLED("FE_Delete_Word(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ if (ISBLANK(*cp))
+ returnCode(E_REQUEST_DENIED); /* not in word */
+
+ /* move cursor to begin of word and erase to end of screen-line */
+ Adjust_Cursor_Position(form,
+ After_Last_Whitespace_Character(bp, form->curcol));
+ wmove(form->w, form->currow, form->curcol);
+ wclrtoeol(form->w);
+
+ /* skip over word in buffer */
+ s = Get_First_Whitespace_Character(cp, (int)(ep - cp));
+ /* to begin of next word */
+ s = Get_Start_Of_Data(s, (int)(ep - s));
+ if ((s != cp) && !ISBLANK(*s))
+ {
+ /* copy remaining line to window */
+ myADDNSTR(form->w, s, (int)(s - After_End_Of_Data(s, (int)(ep - s))));
+ }
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_To_End_Of_Line(FORM * form)
+|
+| Description : Clear to end of current line.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+FE_Clear_To_End_Of_Line(FORM *form)
+{
+ T((T_CALLED("FE_Clear_To_End_Of_Line(%p)"), (void *)form));
+ wmove(form->w, form->currow, form->curcol);
+ wclrtoeol(form->w);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_To_End_Of_Field(FORM * form)
+|
+| Description : Clear to end of field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+FE_Clear_To_End_Of_Field(FORM *form)
+{
+ T((T_CALLED("FE_Clear_To_End_Of_Field(%p)"), (void *)form));
+ wmove(form->w, form->currow, form->curcol);
+ wclrtobot(form->w);
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_Field(FORM * form)
+|
+| Description : Clear entire field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+FE_Clear_Field(FORM *form)
+{
+ T((T_CALLED("FE_Clear_Field(%p)"), (void *)form));
+ form->currow = form->curcol = 0;
+ werase(form->w);
+ returnCode(E_OK);
+}
+/*----------------------------------------------------------------------------
+ END of Field Editing routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Edit Mode routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int EM_Overlay_Mode(FORM * form)
+|
+| Description : Switch to overlay mode.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+EM_Overlay_Mode(FORM *form)
+{
+ T((T_CALLED("EM_Overlay_Mode(%p)"), (void *)form));
+ form->status |= _OVLMODE;
+ returnCode(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int EM_Insert_Mode(FORM * form)
+|
+| Description : Switch to insert mode
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int
+EM_Insert_Mode(FORM *form)
+{
+ T((T_CALLED("EM_Insert_Mode(%p)"), (void *)form));
+ form->status &= ~_OVLMODE;
+ returnCode(E_OK);
+}
+
+/*----------------------------------------------------------------------------
+ END of Edit Mode routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Next_Choice(FORM * form,
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument *argp)
+|
+| Description : Get the next field choice. For linked types this is
+| done recursively.
+|
+| Return Values : TRUE - next choice successfully retrieved
+| FALSE - couldn't retrieve next choice
++--------------------------------------------------------------------------*/
+static bool
+Next_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
+{
+ if (!typ || !(typ->status & _HAS_CHOICE))
+ return FALSE;
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp);
+ return (
+ Next_Choice(form, typ->left, field, argp->left) ||
+ Next_Choice(form, typ->right, field, argp->right));
+ }
+ else
+ {
+#if NCURSES_INTEROP_FUNCS
+ assert(typ->enum_next.onext);
+ if (typ->status & _GENERIC)
+ return typ->enum_next.gnext(form, field, (void *)argp);
+ else
+ return typ->enum_next.onext(field, (void *)argp);
+#else
+ assert(typ->next);
+ return typ->next(field, (void *)argp);
+#endif
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Previous_Choice(FORM * form,
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument *argp)
+|
+| Description : Get the previous field choice. For linked types this
+| is done recursively.
+|
+| Return Values : TRUE - previous choice successfully retrieved
+| FALSE - couldn't retrieve previous choice
++--------------------------------------------------------------------------*/
+static bool
+Previous_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
+{
+ if (!typ || !(typ->status & _HAS_CHOICE))
+ return FALSE;
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp);
+ return (
+ Previous_Choice(form, typ->left, field, argp->left) ||
+ Previous_Choice(form, typ->right, field, argp->right));
+ }
+ else
+ {
+#if NCURSES_INTEROP_FUNCS
+ assert(typ->enum_prev.oprev);
+ if (typ->status & _GENERIC)
+ return typ->enum_prev.gprev(form, field, (void *)argp);
+ else
+ return typ->enum_prev.oprev(field, (void *)argp);
+#else
+ assert(typ->prev);
+ return typ->prev(field, (void *)argp);
+#endif
+ }
+}
+/*----------------------------------------------------------------------------
+ End of Helper routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int CR_Next_Choice(FORM * form)
+|
+| Description : Get the next field choice.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - next choice couldn't be retrieved
++--------------------------------------------------------------------------*/
+static int
+CR_Next_Choice(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("CR_Next_Choice(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ returnCode((Next_Choice(form, field->type, field, (TypeArgument *)(field->arg)))
+ ? E_OK
+ : E_REQUEST_DENIED);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int CR_Previous_Choice(FORM * form)
+|
+| Description : Get the previous field choice.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - prev. choice couldn't be retrieved
++--------------------------------------------------------------------------*/
+static int
+CR_Previous_Choice(FORM *form)
+{
+ FIELD *field = form->current;
+
+ T((T_CALLED("CR_Previous_Choice(%p)"), (void *)form));
+ Synchronize_Buffer(form);
+ returnCode((Previous_Choice(form, field->type, field, (TypeArgument *)(field->arg)))
+ ? E_OK
+ : E_REQUEST_DENIED);
+}
+/*----------------------------------------------------------------------------
+ End of Routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Field Validations.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Field(FORM* form,
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument * argp)
+|
+| Description : Check the field according to its fieldtype and its
+| actual arguments. For linked fieldtypes this is done
+| recursively.
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid.
++--------------------------------------------------------------------------*/
+static bool
+Check_Field(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
+{
+ if (typ)
+ {
+ if (field->opts & O_NULLOK)
+ {
+ FIELD_CELL *bp = field->buf;
+
+ assert(bp);
+ while (ISBLANK(*bp))
+ {
+ bp++;
+ }
+ if (CharOf(*bp) == 0)
+ return TRUE;
+ }
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp);
+ return (
+ Check_Field(form, typ->left, field, argp->left) ||
+ Check_Field(form, typ->right, field, argp->right));
+ }
+ else
+ {
+#if NCURSES_INTEROP_FUNCS
+ if (typ->fieldcheck.ofcheck)
+ {
+ if (typ->status & _GENERIC)
+ return typ->fieldcheck.gfcheck(form, field, (void *)argp);
+ else
+ return typ->fieldcheck.ofcheck(field, (void *)argp);
+ }
+#else
+ if (typ->fcheck)
+ return typ->fcheck(field, (void *)argp);
+#endif
+ }
+ }
+ return TRUE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool _nc_Internal_Validation(FORM * form )
+|
+| Description : Validate the current field of the form.
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(bool)
+_nc_Internal_Validation(FORM *form)
+{
+ FIELD *field;
+
+ field = form->current;
+
+ Synchronize_Buffer(form);
+ if ((form->status & _FCHECK_REQUIRED) ||
+ (!(field->opts & O_PASSOK)))
+ {
+ if (!Check_Field(form, field->type, field, (TypeArgument *)(field->arg)))
+ return FALSE;
+ form->status &= ~_FCHECK_REQUIRED;
+ field->status |= _CHANGED;
+ Synchronize_Linked_Fields(field);
+ }
+ return TRUE;
+}
+/*----------------------------------------------------------------------------
+ End of Helper routines for Field Validations.
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Routines for Field Validation.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FV_Validation(FORM * form)
+|
+| Description : Validate the current field of the form.
+|
+| Return Values : E_OK - field valid
+| E_INVALID_FIELD - field not valid
++--------------------------------------------------------------------------*/
+static int
+FV_Validation(FORM *form)
+{
+ T((T_CALLED("FV_Validation(%p)"), (void *)form));
+ if (_nc_Internal_Validation(form))
+ returnCode(E_OK);
+ else
+ returnCode(E_INVALID_FIELD);
+}
+/*----------------------------------------------------------------------------
+ End of routines for Field Validation.
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Inter-Field Navigation
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Next_Field_On_Page(FIELD * field)
+|
+| Description : Get the next field after the given field on the current
+| page. The order of fields is the one defined by the
+| fields array. Only visible and active fields are
+| counted.
+|
+| Return Values : Pointer to the next field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Next_Field_On_Page(FIELD *field)
+{
+ FORM *form = field->form;
+ FIELD **field_on_page = &form->field[field->index];
+ FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+
+ do
+ {
+ field_on_page =
+ (field_on_page == last_on_page) ? first_on_page : field_on_page + 1;
+ if (Field_Is_Selectable(*field_on_page))
+ break;
+ }
+ while (field != (*field_on_page));
+ return (*field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD* _nc_First_Active_Field(FORM * form)
+|
+| Description : Get the first active field on the current page,
+| if there are such. If there are none, get the first
+| visible field on the page. If there are also none,
+| we return the first field on page and hope the best.
+|
+| Return Values : Pointer to calculated field.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELD *)
+_nc_First_Active_Field(FORM *form)
+{
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+ FIELD *proposed = Next_Field_On_Page(*last_on_page);
+
+ if (proposed == *last_on_page)
+ {
+ /* there might be the special situation, where there is no
+ active and visible field on the current page. We then select
+ the first visible field on this readonly page
+ */
+ if (Field_Is_Not_Selectable(proposed))
+ {
+ FIELD **field = &form->field[proposed->index];
+ FIELD **first = &form->field[form->page[form->curpage].pmin];
+
+ do
+ {
+ field = (field == last_on_page) ? first : field + 1;
+ if (((*field)->opts & O_VISIBLE))
+ break;
+ }
+ while (proposed != (*field));
+
+ proposed = *field;
+
+ if ((proposed == *last_on_page) && !(proposed->opts & O_VISIBLE))
+ {
+ /* This means, there is also no visible field on the page.
+ So we propose the first one and hope the very best...
+ Some very clever user has designed a readonly and invisible
+ page on this form.
+ */
+ proposed = *first;
+ }
+ }
+ }
+ return (proposed);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Previous_Field_On_Page(FIELD * field)
+|
+| Description : Get the previous field before the given field on the
+| current page. The order of fields is the one defined by
+| the fields array. Only visible and active fields are
+| counted.
+|
+| Return Values : Pointer to the previous field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Previous_Field_On_Page(FIELD *field)
+{
+ FORM *form = field->form;
+ FIELD **field_on_page = &form->field[field->index];
+ FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+
+ do
+ {
+ field_on_page =
+ (field_on_page == first_on_page) ? last_on_page : field_on_page - 1;
+ if (Field_Is_Selectable(*field_on_page))
+ break;
+ }
+ while (field != (*field_on_page));
+
+ return (*field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Sorted_Next_Field(FIELD * field)
+|
+| Description : Get the next field after the given field on the current
+| page. The order of fields is the one defined by the
+| (row,column) geometry, rows are major.
+|
+| Return Values : Pointer to the next field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Sorted_Next_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+
+ do
+ {
+ field_on_page = field_on_page->snext;
+ if (Field_Is_Selectable(field_on_page))
+ break;
+ }
+ while (field_on_page != field);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Sorted_Previous_Field(FIELD * field)
+|
+| Description : Get the previous field before the given field on the
+| current page. The order of fields is the one defined
+| by the (row,column) geometry, rows are major.
+|
+| Return Values : Pointer to the previous field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Sorted_Previous_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+
+ do
+ {
+ field_on_page = field_on_page->sprev;
+ if (Field_Is_Selectable(field_on_page))
+ break;
+ }
+ while (field_on_page != field);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Left_Neighbor_Field(FIELD * field)
+|
+| Description : Get the left neighbor of the field on the same line
+| and the same page. Cycles through the line.
+|
+| Return Values : Pointer to left neighbor field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Left_Neighbor_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+
+ /* For a field that has really a left neighbor, the while clause
+ immediately fails and the loop is left, positioned at the right
+ neighbor. Otherwise we cycle backwards through the sorted field list
+ until we enter the same line (from the right end).
+ */
+ do
+ {
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ }
+ while (field_on_page->frow != field->frow);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Right_Neighbor_Field(FIELD * field)
+|
+| Description : Get the right neighbor of the field on the same line
+| and the same page.
+|
+| Return Values : Pointer to right neighbor field.
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static FIELD *
+Right_Neighbor_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+
+ /* See the comments on Left_Neighbor_Field to understand how it works */
+ do
+ {
+ field_on_page = Sorted_Next_Field(field_on_page);
+ }
+ while (field_on_page->frow != field->frow);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Upper_Neighbor_Field(FIELD * field)
+|
+| Description : Because of the row-major nature of sorting the fields,
+| it is more difficult to define whats the upper neighbor
+| field really means. We define that it must be on a
+| 'previous' line (cyclic order!) and is the rightmost
+| field laying on the left side of the given field. If
+| this set is empty, we take the first field on the line.
+|
+| Return Values : Pointer to the upper neighbor field.
++--------------------------------------------------------------------------*/
+static FIELD *
+Upper_Neighbor_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+ int frow = field->frow;
+ int fcol = field->fcol;
+
+ /* Walk back to the 'previous' line. The second term in the while clause
+ just guarantees that we stop if we cycled through the line because
+ there might be no 'previous' line if the page has just one line.
+ */
+ do
+ {
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ }
+ while (field_on_page->frow == frow && field_on_page->fcol != fcol);
+
+ if (field_on_page->frow != frow)
+ {
+ /* We really found a 'previous' line. We are positioned at the
+ rightmost field on this line */
+ frow = field_on_page->frow;
+
+ /* We walk to the left as long as we are really right of the
+ field. */
+ while (field_on_page->frow == frow && field_on_page->fcol > fcol)
+ field_on_page = Sorted_Previous_Field(field_on_page);
+
+ /* If we wrapped, just go to the right which is the first field on
+ the row */
+ if (field_on_page->frow != frow)
+ field_on_page = Sorted_Next_Field(field_on_page);
+ }
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Down_Neighbor_Field(FIELD * field)
+|
+| Description : Because of the row-major nature of sorting the fields,
+| its more difficult to define whats the down neighbor
+| field really means. We define that it must be on a
+| 'next' line (cyclic order!) and is the leftmost
+| field laying on the right side of the given field. If
+| this set is empty, we take the last field on the line.
+|
+| Return Values : Pointer to the upper neighbor field.
++--------------------------------------------------------------------------*/
+static FIELD *
+Down_Neighbor_Field(FIELD *field)
+{
+ FIELD *field_on_page = field;
+ int frow = field->frow;
+ int fcol = field->fcol;
+
+ /* Walk forward to the 'next' line. The second term in the while clause
+ just guarantees that we stop if we cycled through the line because
+ there might be no 'next' line if the page has just one line.
+ */
+ do
+ {
+ field_on_page = Sorted_Next_Field(field_on_page);
+ }
+ while (field_on_page->frow == frow && field_on_page->fcol != fcol);
+
+ if (field_on_page->frow != frow)
+ {
+ /* We really found a 'next' line. We are positioned at the rightmost
+ field on this line */
+ frow = field_on_page->frow;
+
+ /* We walk to the right as long as we are really left of the
+ field. */
+ while (field_on_page->frow == frow && field_on_page->fcol < fcol)
+ field_on_page = Sorted_Next_Field(field_on_page);
+
+ /* If we wrapped, just go to the left which is the last field on
+ the row */
+ if (field_on_page->frow != frow)
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ }
+
+ return (field_on_page);
+}
+
+/*----------------------------------------------------------------------------
+ Inter-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Inter_Field_Navigation(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic behavior for changing the current field, the
+| field is left and a new field is entered. So the field
+| must be validated and the field init/term hooks must
+| be called.
+|
+| Return Values : E_OK - success
+| E_INVALID_FIELD - field is invalid
+| some other - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+Inter_Field_Navigation(int (*const fct) (FORM *), FORM *form)
+{
+ int res;
+
+ if (!_nc_Internal_Validation(form))
+ res = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form, fieldterm);
+ res = fct(form);
+ Call_Hook(form, fieldinit);
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Next_Field(FORM * form)
+|
+| Description : Move to the next field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Next_Field(FORM *form)
+{
+ T((T_CALLED("FN_Next_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Next_Field_On_Page(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Previous_Field(FORM * form)
+|
+| Description : Move to the previous field on the current page of the
+| form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Previous_Field(FORM *form)
+{
+ T((T_CALLED("FN_Previous_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Previous_Field_On_Page(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_First_Field(FORM * form)
+|
+| Description : Move to the first field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_First_Field(FORM *form)
+{
+ T((T_CALLED("FN_First_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Next_Field_On_Page(form->field[form->page[form->curpage].pmax])));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Last_Field(FORM * form)
+|
+| Description : Move to the last field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Last_Field(FORM *form)
+{
+ T((T_CALLED("FN_Last_Field(%p)"), (void *)form));
+ returnCode(
+ _nc_Set_Current_Field(form,
+ Previous_Field_On_Page(form->field[form->page[form->curpage].pmin])));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Next_Field(FORM * form)
+|
+| Description : Move to the sorted next field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Sorted_Next_Field(FORM *form)
+{
+ T((T_CALLED("FN_Sorted_Next_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Sorted_Next_Field(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Previous_Field(FORM * form)
+|
+| Description : Move to the sorted previous field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Sorted_Previous_Field(FORM *form)
+{
+ T((T_CALLED("FN_Sorted_Previous_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Sorted_Previous_Field(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_First_Field(FORM * form)
+|
+| Description : Move to the sorted first field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Sorted_First_Field(FORM *form)
+{
+ T((T_CALLED("FN_Sorted_First_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Sorted_Next_Field(form->field[form->page[form->curpage].smax])));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Last_Field(FORM * form)
+|
+| Description : Move to the sorted last field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Sorted_Last_Field(FORM *form)
+{
+ T((T_CALLED("FN_Sorted_Last_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Sorted_Previous_Field(form->field[form->page[form->curpage].smin])));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Left_Field(FORM * form)
+|
+| Description : Get the field on the left of the current field on the
+| same line and the same page. Cycles through the line.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Left_Field(FORM *form)
+{
+ T((T_CALLED("FN_Left_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Left_Neighbor_Field(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Right_Field(FORM * form)
+|
+| Description : Get the field on the right of the current field on the
+| same line and the same page. Cycles through the line.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Right_Field(FORM *form)
+{
+ T((T_CALLED("FN_Right_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Right_Neighbor_Field(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Up_Field(FORM * form)
+|
+| Description : Get the upper neighbor of the current field. This
+| cycles through the page. See the comments of the
+| Upper_Neighbor_Field function to understand how
+| 'upper' is defined.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Up_Field(FORM *form)
+{
+ T((T_CALLED("FN_Up_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Upper_Neighbor_Field(form->current)));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Down_Field(FORM * form)
+|
+| Description : Get the down neighbor of the current field. This
+| cycles through the page. See the comments of the
+| Down_Neighbor_Field function to understand how
+| 'down' is defined.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+FN_Down_Field(FORM *form)
+{
+ T((T_CALLED("FN_Down_Field(%p)"), (void *)form));
+ returnCode(_nc_Set_Current_Field(form,
+ Down_Neighbor_Field(form->current)));
+}
+/*----------------------------------------------------------------------------
+ END of Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Page Navigation
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Set_Form_Page(FORM * form,
+| int page,
+| FIELD * field)
+|
+| Description : Make the given page number the current page and make
+| the given field the current field on the page. If
+| for the field NULL is given, make the first field on
+| the page the current field. The routine acts only
+| if the requested page is not the current page.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_Set_Form_Page(FORM *form, int page, FIELD *field)
+{
+ int res = E_OK;
+
+ if ((form->curpage != page))
+ {
+ FIELD *last_field, *field_on_page;
+
+ werase(Get_Form_Window(form));
+ form->curpage = page;
+ last_field = field_on_page = form->field[form->page[page].smin];
+ do
+ {
+ if (field_on_page->opts & O_VISIBLE)
+ if ((res = Display_Field(field_on_page)) != E_OK)
+ return (res);
+ field_on_page = field_on_page->snext;
+ }
+ while (field_on_page != last_field);
+
+ if (field)
+ res = _nc_Set_Current_Field(form, field);
+ else
+ /* N.B.: we don't encapsulate this by Inter_Field_Navigation(),
+ because this is already executed in a page navigation
+ context that contains field navigation
+ */
+ res = FN_First_Field(form);
+ }
+ return (res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Next_Page_Number(const FORM * form)
+|
+| Description : Calculate the page number following the current page
+| number. This cycles if the highest page number is
+| reached.
+|
+| Return Values : The next page number
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static int
+Next_Page_Number(const FORM *form)
+{
+ return (form->curpage + 1) % form->maxpage;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Previous_Page_Number(const FORM * form)
+|
+| Description : Calculate the page number before the current page
+| number. This cycles if the first page number is
+| reached.
+|
+| Return Values : The previous page number
++--------------------------------------------------------------------------*/
+NCURSES_INLINE static int
+Previous_Page_Number(const FORM *form)
+{
+ return (form->curpage != 0 ? form->curpage - 1 : form->maxpage - 1);
+}
+
+/*----------------------------------------------------------------------------
+ Page Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Page_Navigation(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic behavior for changing a page. This means
+| that the field is left and a new field is entered.
+| So the field must be validated and the field init/term
+| hooks must be called. Because also the page is changed,
+| the forms init/term hooks must be called also.
+|
+| Return Values : E_OK - success
+| E_INVALID_FIELD - field is invalid
+| some other - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+Page_Navigation(int (*const fct) (FORM *), FORM *form)
+{
+ int res;
+
+ if (!_nc_Internal_Validation(form))
+ res = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form, fieldterm);
+ Call_Hook(form, formterm);
+ res = fct(form);
+ Call_Hook(form, forminit);
+ Call_Hook(form, fieldinit);
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Next_Page(FORM * form)
+|
+| Description : Move to the next page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+PN_Next_Page(FORM *form)
+{
+ T((T_CALLED("PN_Next_Page(%p)"), (void *)form));
+ returnCode(_nc_Set_Form_Page(form, Next_Page_Number(form), (FIELD *)0));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Previous_Page(FORM * form)
+|
+| Description : Move to the previous page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+PN_Previous_Page(FORM *form)
+{
+ T((T_CALLED("PN_Previous_Page(%p)"), (void *)form));
+ returnCode(_nc_Set_Form_Page(form, Previous_Page_Number(form), (FIELD *)0));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_First_Page(FORM * form)
+|
+| Description : Move to the first page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+PN_First_Page(FORM *form)
+{
+ T((T_CALLED("PN_First_Page(%p)"), (void *)form));
+ returnCode(_nc_Set_Form_Page(form, 0, (FIELD *)0));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Last_Page(FORM * form)
+|
+| Description : Move to the last page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int
+PN_Last_Page(FORM *form)
+{
+ T((T_CALLED("PN_Last_Page(%p)"), (void *)form));
+ returnCode(_nc_Set_Form_Page(form, form->maxpage - 1, (FIELD *)0));
+}
+
+/*----------------------------------------------------------------------------
+ END of Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for the core form driver.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Data_Entry(FORM * form,int c)
+|
+| Description : Enter character c into at the current position of the
+| current field of the form.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - driver could not process the request
+| E_SYSTEM_ERROR -
++--------------------------------------------------------------------------*/
+static int
+Data_Entry(FORM *form, int c)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ T((T_CALLED("Data_Entry(%p,%s)"), (void *)form, _tracechtype((chtype)c)));
+ if ((field->opts & O_EDIT)
+#if FIX_FORM_INACTIVE_BUG
+ && (field->opts & O_ACTIVE)
+#endif
+ )
+ {
+ if ((field->opts & O_BLANK) &&
+ First_Position_In_Current_Field(form) &&
+ !(form->status & _FCHECK_REQUIRED) &&
+ !(form->status & _WINDOW_MODIFIED))
+ werase(form->w);
+
+ if (form->status & _OVLMODE)
+ {
+ waddch(form->w, (chtype)c);
+ }
+ else
+ /* no _OVLMODE */
+ {
+ bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
+
+ if (!(There_Is_Room ||
+ ((Single_Line_Field(field) && Growable(field)))))
+ RETURN(E_REQUEST_DENIED);
+
+ if (!There_Is_Room && !Field_Grown(field, 1))
+ RETURN(E_SYSTEM_ERROR);
+
+ winsch(form->w, (chtype)c);
+ }
+
+ if ((result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form)) == E_OK)
+ {
+ bool End_Of_Field = (((field->drows - 1) == form->currow) &&
+ ((field->dcols - 1) == form->curcol));
+
+ form->status |= _WINDOW_MODIFIED;
+ if (End_Of_Field && !Growable(field) && (field->opts & O_AUTOSKIP))
+ result = Inter_Field_Navigation(FN_Next_Field, form);
+ else
+ {
+ if (End_Of_Field && Growable(field) && !Field_Grown(field, 1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+#if USE_WIDEC_SUPPORT
+ /*
+ * We have just added a byte to the form field. It may have
+ * been part of a multibyte character. If it was, the
+ * addch_used field is nonzero and we should not try to move
+ * to a new column.
+ */
+ if (WINDOW_EXT(form->w, addch_used) == 0)
+ IFN_Next_Character(form);
+#else
+ IFN_Next_Character(form);
+#endif
+ result = E_OK;
+ }
+ }
+ }
+ }
+ RETURN(result);
+}
+
+/* Structure to describe the binding of a request code to a function.
+ The member keycode codes the request value as well as the generic
+ routine to use for the request. The code for the generic routine
+ is coded in the upper 16 Bits while the request code is coded in
+ the lower 16 bits.
+
+ In terms of C++ you might think of a request as a class with a
+ virtual method "perform". The different types of request are
+ derived from this base class and overload (or not) the base class
+ implementation of perform.
+*/
+typedef struct
+{
+ int keycode; /* must be at least 32 bit: hi:mode, lo: key */
+ int (*cmd) (FORM *); /* low level driver routine for this key */
+}
+Binding_Info;
+
+/* You may see this is the class-id of the request type class */
+#define ID_PN (0x00000000) /* Page navigation */
+#define ID_FN (0x00010000) /* Inter-Field navigation */
+#define ID_IFN (0x00020000) /* Intra-Field navigation */
+#define ID_VSC (0x00030000) /* Vertical Scrolling */
+#define ID_HSC (0x00040000) /* Horizontal Scrolling */
+#define ID_FE (0x00050000) /* Field Editing */
+#define ID_EM (0x00060000) /* Edit Mode */
+#define ID_FV (0x00070000) /* Field Validation */
+#define ID_CH (0x00080000) /* Choice */
+#define ID_Mask (0xffff0000)
+#define Key_Mask (0x0000ffff)
+#define ID_Shft (16)
+
+/* This array holds all the Binding Infos */
+/* *INDENT-OFF* */
+static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
+{
+ { REQ_NEXT_PAGE |ID_PN ,PN_Next_Page},
+ { REQ_PREV_PAGE |ID_PN ,PN_Previous_Page},
+ { REQ_FIRST_PAGE |ID_PN ,PN_First_Page},
+ { REQ_LAST_PAGE |ID_PN ,PN_Last_Page},
+
+ { REQ_NEXT_FIELD |ID_FN ,FN_Next_Field},
+ { REQ_PREV_FIELD |ID_FN ,FN_Previous_Field},
+ { REQ_FIRST_FIELD |ID_FN ,FN_First_Field},
+ { REQ_LAST_FIELD |ID_FN ,FN_Last_Field},
+ { REQ_SNEXT_FIELD |ID_FN ,FN_Sorted_Next_Field},
+ { REQ_SPREV_FIELD |ID_FN ,FN_Sorted_Previous_Field},
+ { REQ_SFIRST_FIELD |ID_FN ,FN_Sorted_First_Field},
+ { REQ_SLAST_FIELD |ID_FN ,FN_Sorted_Last_Field},
+ { REQ_LEFT_FIELD |ID_FN ,FN_Left_Field},
+ { REQ_RIGHT_FIELD |ID_FN ,FN_Right_Field},
+ { REQ_UP_FIELD |ID_FN ,FN_Up_Field},
+ { REQ_DOWN_FIELD |ID_FN ,FN_Down_Field},
+
+ { REQ_NEXT_CHAR |ID_IFN ,IFN_Next_Character},
+ { REQ_PREV_CHAR |ID_IFN ,IFN_Previous_Character},
+ { REQ_NEXT_LINE |ID_IFN ,IFN_Next_Line},
+ { REQ_PREV_LINE |ID_IFN ,IFN_Previous_Line},
+ { REQ_NEXT_WORD |ID_IFN ,IFN_Next_Word},
+ { REQ_PREV_WORD |ID_IFN ,IFN_Previous_Word},
+ { REQ_BEG_FIELD |ID_IFN ,IFN_Beginning_Of_Field},
+ { REQ_END_FIELD |ID_IFN ,IFN_End_Of_Field},
+ { REQ_BEG_LINE |ID_IFN ,IFN_Beginning_Of_Line},
+ { REQ_END_LINE |ID_IFN ,IFN_End_Of_Line},
+ { REQ_LEFT_CHAR |ID_IFN ,IFN_Left_Character},
+ { REQ_RIGHT_CHAR |ID_IFN ,IFN_Right_Character},
+ { REQ_UP_CHAR |ID_IFN ,IFN_Up_Character},
+ { REQ_DOWN_CHAR |ID_IFN ,IFN_Down_Character},
+
+ { REQ_NEW_LINE |ID_FE ,FE_New_Line},
+ { REQ_INS_CHAR |ID_FE ,FE_Insert_Character},
+ { REQ_INS_LINE |ID_FE ,FE_Insert_Line},
+ { REQ_DEL_CHAR |ID_FE ,FE_Delete_Character},
+ { REQ_DEL_PREV |ID_FE ,FE_Delete_Previous},
+ { REQ_DEL_LINE |ID_FE ,FE_Delete_Line},
+ { REQ_DEL_WORD |ID_FE ,FE_Delete_Word},
+ { REQ_CLR_EOL |ID_FE ,FE_Clear_To_End_Of_Line},
+ { REQ_CLR_EOF |ID_FE ,FE_Clear_To_End_Of_Field},
+ { REQ_CLR_FIELD |ID_FE ,FE_Clear_Field},
+
+ { REQ_OVL_MODE |ID_EM ,EM_Overlay_Mode},
+ { REQ_INS_MODE |ID_EM ,EM_Insert_Mode},
+
+ { REQ_SCR_FLINE |ID_VSC ,VSC_Scroll_Line_Forward},
+ { REQ_SCR_BLINE |ID_VSC ,VSC_Scroll_Line_Backward},
+ { REQ_SCR_FPAGE |ID_VSC ,VSC_Scroll_Page_Forward},
+ { REQ_SCR_BPAGE |ID_VSC ,VSC_Scroll_Page_Backward},
+ { REQ_SCR_FHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Forward},
+ { REQ_SCR_BHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Backward},
+
+ { REQ_SCR_FCHAR |ID_HSC ,HSC_Scroll_Char_Forward},
+ { REQ_SCR_BCHAR |ID_HSC ,HSC_Scroll_Char_Backward},
+ { REQ_SCR_HFLINE |ID_HSC ,HSC_Horizontal_Line_Forward},
+ { REQ_SCR_HBLINE |ID_HSC ,HSC_Horizontal_Line_Backward},
+ { REQ_SCR_HFHALF |ID_HSC ,HSC_Horizontal_Half_Line_Forward},
+ { REQ_SCR_HBHALF |ID_HSC ,HSC_Horizontal_Half_Line_Backward},
+
+ { REQ_VALIDATION |ID_FV ,FV_Validation},
+
+ { REQ_NEXT_CHOICE |ID_CH ,CR_Next_Choice},
+ { REQ_PREV_CHOICE |ID_CH ,CR_Previous_Choice}
+};
+/* *INDENT-ON* */
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_driver(FORM * form,int c)
+|
+| Description : This is the workhorse of the forms system. It checks
+| to determine whether the character c is a request or
+| data. If it is a request, the form driver executes
+| the request and returns the result. If it is data
+| (printable character), it enters the data into the
+| current position in the current field. If it is not
+| recognized, the form driver assumes it is an application
+| defined command and returns E_UNKNOWN_COMMAND.
+| Application defined command should be defined relative
+| to MAX_FORM_COMMAND, the maximum value of a request.
+|
+| Return Values : E_OK - success
+| E_SYSTEM_ERROR - system error
+| E_BAD_ARGUMENT - an argument is incorrect
+| E_NOT_POSTED - form is not posted
+| E_INVALID_FIELD - field contents are invalid
+| E_BAD_STATE - called from inside a hook routine
+| E_REQUEST_DENIED - request failed
+| E_NOT_CONNECTED - no fields are connected to the form
+| E_UNKNOWN_COMMAND - command not known
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+form_driver(FORM *form, int c)
+{
+ const Binding_Info *BI = (Binding_Info *) 0;
+ int res = E_UNKNOWN_COMMAND;
+
+ T((T_CALLED("form_driver(%p,%d)"), (void *)form, c));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->field))
+ RETURN(E_NOT_CONNECTED);
+
+ assert(form->page);
+
+ if (c == FIRST_ACTIVE_MAGIC)
+ {
+ form->current = _nc_First_Active_Field(form);
+ RETURN(E_OK);
+ }
+
+ assert(form->current &&
+ form->current->buf &&
+ (form->current->form == form)
+ );
+
+ if (form->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ if (!(form->status & _POSTED))
+ RETURN(E_NOT_POSTED);
+
+ if ((c >= MIN_FORM_COMMAND && c <= MAX_FORM_COMMAND) &&
+ ((bindings[c - MIN_FORM_COMMAND].keycode & Key_Mask) == c))
+ BI = &(bindings[c - MIN_FORM_COMMAND]);
+
+ if (BI)
+ {
+ typedef int (*Generic_Method) (int (*const) (FORM *), FORM *);
+ static const Generic_Method Generic_Methods[] =
+ {
+ Page_Navigation, /* overloaded to call field&form hooks */
+ Inter_Field_Navigation, /* overloaded to call field hooks */
+ NULL, /* Intra-Field is generic */
+ Vertical_Scrolling, /* Overloaded to check multi-line */
+ Horizontal_Scrolling, /* Overloaded to check single-line */
+ Field_Editing, /* Overloaded to mark modification */
+ NULL, /* Edit Mode is generic */
+ NULL, /* Field Validation is generic */
+ NULL /* Choice Request is generic */
+ };
+ size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
+ size_t method = (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */
+
+ if ((method >= nMethods) || !(BI->cmd))
+ res = E_SYSTEM_ERROR;
+ else
+ {
+ Generic_Method fct = Generic_Methods[method];
+
+ if (fct)
+ res = fct(BI->cmd, form);
+ else
+ res = (BI->cmd) (form);
+ }
+ }
+#ifdef NCURSES_MOUSE_VERSION
+ else if (KEY_MOUSE == c)
+ {
+ MEVENT event;
+ WINDOW *win = form->win ? form->win : StdScreen(Get_Form_Screen(form));
+ WINDOW *sub = form->sub ? form->sub : win;
+
+ getmouse(&event);
+ if ((event.bstate & (BUTTON1_CLICKED |
+ BUTTON1_DOUBLE_CLICKED |
+ BUTTON1_TRIPLE_CLICKED))
+ && wenclose(win, event.y, event.x))
+ { /* we react only if the click was in the userwin, that means
+ * inside the form display area or at the decoration window.
+ */
+ int ry = event.y, rx = event.x; /* screen coordinates */
+
+ res = E_REQUEST_DENIED;
+ if (mouse_trafo(&ry, &rx, FALSE))
+ { /* rx, ry are now "curses" coordinates */
+ if (ry < sub->_begy)
+ { /* we clicked above the display region; this is
+ * interpreted as "scroll up" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ res = form_driver(form, REQ_PREV_FIELD);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ res = form_driver(form, REQ_PREV_PAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ res = form_driver(form, REQ_FIRST_FIELD);
+ }
+ else if (ry > sub->_begy + sub->_maxy)
+ { /* we clicked below the display region; this is
+ * interpreted as "scroll down" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ res = form_driver(form, REQ_NEXT_FIELD);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ res = form_driver(form, REQ_NEXT_PAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ res = form_driver(form, REQ_LAST_FIELD);
+ }
+ else if (wenclose(sub, event.y, event.x))
+ { /* Inside the area we try to find the hit item */
+ int i;
+
+ ry = event.y;
+ rx = event.x;
+ if (wmouse_trafo(sub, &ry, &rx, FALSE))
+ {
+ int min_field = form->page[form->curpage].pmin;
+ int max_field = form->page[form->curpage].pmax;
+
+ for (i = min_field; i <= max_field; ++i)
+ {
+ FIELD *field = form->field[i];
+
+ if (Field_Is_Selectable(field)
+ && Field_encloses(field, ry, rx) == E_OK)
+ {
+ res = _nc_Set_Current_Field(form, field);
+ if (res == E_OK)
+ res = _nc_Position_Form_Cursor(form);
+ if (res == E_OK
+ && (event.bstate & BUTTON1_DOUBLE_CLICKED))
+ res = E_UNKNOWN_COMMAND;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ res = E_REQUEST_DENIED;
+ }
+#endif /* NCURSES_MOUSE_VERSION */
+ else if (!(c & (~(int)MAX_REGULAR_CHARACTER)))
+ {
+ /*
+ * If we're using 8-bit characters, iscntrl+isprint cover the whole set.
+ * But with multibyte characters, there is a third possibility, i.e.,
+ * parts of characters that build up into printable characters which are
+ * not considered printable.
+ *
+ * FIXME: the wide-character branch should also use Check_Char().
+ */
+#if USE_WIDEC_SUPPORT
+ if (!iscntrl(UChar(c)))
+#else
+ if (isprint(UChar(c)) &&
+ Check_Char(form, form->current, form->current->type, c,
+ (TypeArgument *)(form->current->arg)))
+#endif
+ res = Data_Entry(form, c);
+ }
+ _nc_Refresh_Current_Field(form);
+ RETURN(res);
+}
+
+/*----------------------------------------------------------------------------
+ Field-Buffer manipulation routines.
+ The effects of setting a buffer are tightly coupled to the core of the form
+ driver logic. This is especially true in the case of growable fields.
+ So I don't separate this into a separate module.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_buffer(FIELD *field,
+| int buffer, char *value)
+|
+| Description : Set the given buffer of the field to the given value.
+| Buffer 0 stores the displayed content of the field.
+| For dynamic fields this may grow the fieldbuffers if
+| the length of the value exceeds the current buffer
+| length. For buffer 0 only printable values are allowed.
+| For static fields, the value needs not to be zero ter-
+| minated. It is copied up to the length of the buffer.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_field_buffer(FIELD *field, int buffer, const char *value)
+{
+ FIELD_CELL *p;
+ int res = E_OK;
+ unsigned int i;
+ unsigned int len;
+
+#if USE_WIDEC_SUPPORT
+ FIELD_CELL *widevalue = 0;
+#endif
+
+ T((T_CALLED("set_field_buffer(%p,%d,%s)"), (void *)field, buffer, _nc_visbuf(value)));
+
+ if (!field || !value || ((buffer < 0) || (buffer > field->nbuf)))
+ RETURN(E_BAD_ARGUMENT);
+
+ len = Buffer_Length(field);
+
+ if (Growable(field))
+ {
+ /* for a growable field we must assume zero terminated strings, because
+ somehow we have to detect the length of what should be copied.
+ */
+ unsigned int vlen = strlen(value);
+
+ if (vlen > len)
+ {
+ if (!Field_Grown(field,
+ (int)(1 + (vlen - len) / ((field->rows + field->nrow)
+ * field->cols))))
+ RETURN(E_SYSTEM_ERROR);
+
+#if !USE_WIDEC_SUPPORT
+ len = vlen;
+#endif
+ }
+ }
+
+ p = Address_Of_Nth_Buffer(field, buffer);
+
+#if USE_WIDEC_SUPPORT
+ /*
+ * Use addstr's logic for converting a string to an array of cchar_t's.
+ * There should be a better way, but this handles nonspacing characters
+ * and other special cases that we really do not want to handle here.
+ */
+#if NCURSES_EXT_FUNCS
+ if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR)
+#endif
+ {
+ delwin(field->working);
+ field->working = newpad(1, Buffer_Length(field) + 1);
+ }
+ len = Buffer_Length(field);
+ wclear(field->working);
+ (void)mvwaddstr(field->working, 0, 0, value);
+
+ if ((widevalue = typeCalloc(FIELD_CELL, len + 1)) == 0)
+ {
+ RETURN(E_SYSTEM_ERROR);
+ }
+ else
+ {
+ for (i = 0; i < (unsigned)field->drows; ++i)
+ {
+ (void)mvwin_wchnstr(field->working, 0, i * field->dcols,
+ widevalue + (i * field->dcols),
+ field->dcols);
+ }
+ for (i = 0; i < len; ++i)
+ {
+ if (CharEq(myZEROS, widevalue[i]))
+ {
+ while (i < len)
+ p[i++] = myBLANK;
+ break;
+ }
+ p[i] = widevalue[i];
+ }
+ free(widevalue);
+ }
+#else
+ for (i = 0; i < len; ++i)
+ {
+ if (value[i] == '\0')
+ {
+ while (i < len)
+ p[i++] = myBLANK;
+ break;
+ }
+ p[i] = value[i];
+ }
+#endif
+
+ if (buffer == 0)
+ {
+ int syncres;
+
+ if (((syncres = Synchronize_Field(field)) != E_OK) &&
+ (res == E_OK))
+ res = syncres;
+ if (((syncres = Synchronize_Linked_Fields(field)) != E_OK) &&
+ (res == E_OK))
+ res = syncres;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : char *field_buffer(const FIELD *field,int buffer)
+|
+| Description : Return the address of the buffer for the field.
+|
+| Return Values : Pointer to buffer or NULL if arguments were invalid.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(char *)
+field_buffer(const FIELD *field, int buffer)
+{
+ char *result = 0;
+
+ T((T_CALLED("field_buffer(%p,%d)"), (const void *)field, buffer));
+
+ if (field && (buffer >= 0) && (buffer <= field->nbuf))
+ {
+#if USE_WIDEC_SUPPORT
+ FIELD_CELL *data = Address_Of_Nth_Buffer(field, buffer);
+ unsigned need = 0;
+ int size = Buffer_Length(field);
+ int n;
+
+ /* determine the number of bytes needed to store the expanded string */
+ for (n = 0; n < size; ++n)
+ {
+ if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0')
+ {
+ mbstate_t state;
+ size_t next;
+
+ init_mb(state);
+ next = _nc_wcrtomb(0, data[n].chars[0], &state);
+ if (!isEILSEQ(next))
+ need += next;
+ }
+ }
+
+ /* allocate a place to store the expanded string */
+ if (field->expanded[buffer] != 0)
+ free(field->expanded[buffer]);
+ field->expanded[buffer] = typeMalloc(char, need + 1);
+
+ /*
+ * Expand the multibyte data.
+ *
+ * It may also be multi-column data. In that case, the data for a row
+ * may be null-padded to align to the dcols/drows layout (or it may
+ * contain embedded wide-character extensions). Change the null-padding
+ * to blanks as needed.
+ */
+ if ((result = field->expanded[buffer]) != 0)
+ {
+ wclear(field->working);
+ wmove(field->working, 0, 0);
+ for (n = 0; n < size; ++n)
+ {
+ if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0')
+ wadd_wch(field->working, &data[n]);
+ }
+ wmove(field->working, 0, 0);
+ winnstr(field->working, result, (int)need);
+ }
+#else
+ result = Address_Of_Nth_Buffer(field, buffer);
+#endif
+ }
+ returnPtr(result);
+}
+
+#if USE_WIDEC_SUPPORT
+
+/*---------------------------------------------------------------------------
+| Convert a multibyte string to a wide-character string. The result must be
+| freed by the caller.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(wchar_t *)
+_nc_Widen_String(char *source, int *lengthp)
+{
+ wchar_t *result = 0;
+ wchar_t wch;
+ size_t given = strlen(source);
+ size_t tries;
+ int pass;
+ int status;
+
+#ifndef state_unused
+ mbstate_t state;
+#endif
+
+ for (pass = 0; pass < 2; ++pass)
+ {
+ unsigned need = 0;
+ size_t passed = 0;
+
+ while (passed < given)
+ {
+ bool found = FALSE;
+
+ for (tries = 1, status = 0; tries <= (given - passed); ++tries)
+ {
+ int save = source[passed + tries];
+
+ source[passed + tries] = 0;
+ reset_mbytes(state);
+ status = check_mbytes(wch, source + passed, tries, state);
+ source[passed + tries] = (char)save;
+
+ if (status > 0)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found)
+ {
+ if (pass)
+ {
+ result[need] = wch;
+ }
+ passed += status;
+ ++need;
+ }
+ else
+ {
+ if (pass)
+ {
+ result[need] = source[passed];
+ }
+ ++need;
+ ++passed;
+ }
+ }
+
+ if (!pass)
+ {
+ if (!need)
+ break;
+ result = typeCalloc(wchar_t, need);
+
+ *lengthp = need;
+ if (result == 0)
+ break;
+ }
+ }
+
+ return result;
+}
+#endif
+
+/* frm_driver.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_hook.c b/apps/lib/curses/pdcurses/form/frm_hook.c
new file mode 100644
index 0000000..7daa396
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_hook.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_hook.c,v 1.15 2010/01/23 21:12:08 tom Exp $")
+
+/* "Template" macro to generate function to set application specific hook */
+#define GEN_HOOK_SET_FUNCTION( typ, name ) \
+NCURSES_IMPEXP int NCURSES_API set_ ## typ ## _ ## name (FORM *form, Form_Hook func)\
+{\
+ T((T_CALLED("set_" #typ"_"#name"(%p,%p)"), form, func));\
+ (Normalize_Form( form ) -> typ ## name) = func ;\
+ RETURN(E_OK);\
+}
+
+/* "Template" macro to generate function to get application specific hook */
+#define GEN_HOOK_GET_FUNCTION( typ, name ) \
+NCURSES_IMPEXP Form_Hook NCURSES_API typ ## _ ## name ( const FORM *form )\
+{\
+ T((T_CALLED(#typ "_" #name "(%p)"), (const void *) form));\
+ returnFormHook( Normalize_Form( form ) -> typ ## name );\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_init(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined initialization function
+| to be called when the form is posted and just after
+| the current field changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(field, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook field_init(const FORM *form)
+|
+| Description : Retrieve field initialization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(field, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_term(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined finalization function
+| to be called when the form is unposted and just before
+| the current field changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(field, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook field_term(const FORM *form)
+|
+| Description : Retrieve field finalization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(field, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_init(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined initialization function
+| to be called when the form is posted and just after
+| a page change.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(form, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook form_init(const FORM *form)
+|
+| Description : Retrieve form initialization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(form, init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_term(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined finalization function
+| to be called when the form is unposted and just before
+| a page change.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(form, term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook form_term(const FORM *form)
+|
+| Description : Retrieve form finalization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(form, term)
+
+/* frm_hook.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_opts.c b/apps/lib/curses/pdcurses/form/frm_opts.c
new file mode 100644
index 0000000..d51f345
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_opts.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_opts.c,v 1.15 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_opts(FORM *form, Form_Options opts)
+|
+| Description : Turns on the named options and turns off all the
+| remaining options for that form.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_opts(FORM *form, Form_Options opts)
+{
+ T((T_CALLED("set_form_opts(%p,%d)"), (void *)form, opts));
+
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form(form)->opts = opts;
+ RETURN(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Options form_opts(const FORM *)
+|
+| Description : Retrieves the current form options.
+|
+| Return Values : The option flags.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(Form_Options)
+form_opts(const FORM *form)
+{
+ T((T_CALLED("form_opts(%p)"), (const void *)form));
+ returnCode((int)(Normalize_Form(form)->opts & ALL_FORM_OPTS));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_opts_on(FORM *form, Form_Options opts)
+|
+| Description : Turns on the named options; no other options are
+| changed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+form_opts_on(FORM *form, Form_Options opts)
+{
+ T((T_CALLED("form_opts_on(%p,%d)"), (void *)form, opts));
+
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form(form)->opts |= opts;
+ RETURN(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_opts_off(FORM *form, Form_Options opts)
+|
+| Description : Turns off the named options; no other options are
+| changed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+form_opts_off(FORM *form, Form_Options opts)
+{
+ T((T_CALLED("form_opts_off(%p,%d)"), (void *)form, opts));
+
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form(form)->opts &= ~opts;
+ RETURN(E_OK);
+ }
+}
+
+/* frm_opts.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_page.c b/apps/lib/curses/pdcurses/form/frm_page.c
new file mode 100644
index 0000000..fdbc94c
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_page.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_page.c,v 1.11 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_page(FORM * form,int page)
+|
+| Description : Set the page number of the form.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer or page number
+| E_BAD_STATE - called from a hook routine
+| E_INVALID_FIELD - current field can't be left
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_page(FORM *form, int page)
+{
+ int err = E_OK;
+
+ T((T_CALLED("set_form_page(%p,%d)"), (void *)form, page));
+
+ if (!form || (page < 0) || (page >= form->maxpage))
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->status & _POSTED))
+ {
+ form->curpage = page;
+ form->current = _nc_First_Active_Field(form);
+ }
+ else
+ {
+ if (form->status & _IN_DRIVER)
+ err = E_BAD_STATE;
+ else
+ {
+ if (form->curpage != page)
+ {
+ if (!_nc_Internal_Validation(form))
+ err = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form, fieldterm);
+ Call_Hook(form, formterm);
+ err = _nc_Set_Form_Page(form, page, (FIELD *)0);
+ Call_Hook(form, forminit);
+ Call_Hook(form, fieldinit);
+ _nc_Refresh_Current_Field(form);
+ }
+ }
+ }
+ }
+ RETURN(err);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_page(const FORM * form)
+|
+| Description : Return the current page of the form.
+|
+| Return Values : >= 0 : current page number
+| -1 : invalid form pointer
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+form_page(const FORM *form)
+{
+ T((T_CALLED("form_page(%p)"), (const void *)form));
+
+ returnCode(Normalize_Form(form)->curpage);
+}
+
+/* frm_page.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_post.c b/apps/lib/curses/pdcurses/form/frm_post.c
new file mode 100644
index 0000000..5e9501e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_post.c
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_post.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int post_form(FORM * form)
+|
+| Description : Writes the form into its associated subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_POSTED - form already posted
+| E_NOT_CONNECTED - no fields connected to form
+| E_NO_ROOM - form doesn't fit into subwindow
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+post_form(FORM *form)
+{
+ WINDOW *formwin;
+ int err;
+ int page;
+
+ T((T_CALLED("post_form(%p)"), (void *)form));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (form->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (!(form->field))
+ RETURN(E_NOT_CONNECTED);
+
+ formwin = Get_Form_Window(form);
+ if ((form->cols > getmaxx(formwin)) || (form->rows > getmaxy(formwin)))
+ RETURN(E_NO_ROOM);
+
+ /* reset form->curpage to an invald value. This forces Set_Form_Page
+ to do the page initialization which is required by post_form.
+ */
+ page = form->curpage;
+ form->curpage = -1;
+ if ((err = _nc_Set_Form_Page(form, page, form->current)) != E_OK)
+ RETURN(err);
+
+ form->status |= _POSTED;
+
+ Call_Hook(form, forminit);
+ Call_Hook(form, fieldinit);
+
+ _nc_Refresh_Current_Field(form);
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int unpost_form(FORM * form)
+|
+| Description : Erase form from its associated subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_NOT_POSTED - form isn't posted
+| E_BAD_STATE - called from a hook routine
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+unpost_form(FORM *form)
+{
+ T((T_CALLED("unpost_form(%p)"), (void *)form));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->status & _POSTED))
+ RETURN(E_NOT_POSTED);
+
+ if (form->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ Call_Hook(form, fieldterm);
+ Call_Hook(form, formterm);
+
+ werase(Get_Form_Window(form));
+ delwin(form->w);
+ form->w = (WINDOW *)0;
+ form->status &= ~_POSTED;
+ RETURN(E_OK);
+}
+
+/* frm_post.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_req_name.c b/apps/lib/curses/pdcurses/form/frm_req_name.c
new file mode 100644
index 0000000..dbef6d7
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_req_name.c
@@ -0,0 +1,170 @@
+/****************************************************************************
+ * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module form_request_name *
+* Routines to handle external names of menu requests *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_req_name.c,v 1.17 2009/10/10 16:17:01 tom Exp $")
+
+static const char *request_names[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
+{
+ "NEXT_PAGE",
+ "PREV_PAGE",
+ "FIRST_PAGE",
+ "LAST_PAGE",
+
+ "NEXT_FIELD",
+ "PREV_FIELD",
+ "FIRST_FIELD",
+ "LAST_FIELD",
+ "SNEXT_FIELD",
+ "SPREV_FIELD",
+ "SFIRST_FIELD",
+ "SLAST_FIELD",
+ "LEFT_FIELD",
+ "RIGHT_FIELD",
+ "UP_FIELD",
+ "DOWN_FIELD",
+
+ "NEXT_CHAR",
+ "PREV_CHAR",
+ "NEXT_LINE",
+ "PREV_LINE",
+ "NEXT_WORD",
+ "PREV_WORD",
+ "BEG_FIELD",
+ "END_FIELD",
+ "BEG_LINE",
+ "END_LINE",
+ "LEFT_CHAR",
+ "RIGHT_CHAR",
+ "UP_CHAR",
+ "DOWN_CHAR",
+
+ "NEW_LINE",
+ "INS_CHAR",
+ "INS_LINE",
+ "DEL_CHAR",
+ "DEL_PREV",
+ "DEL_LINE",
+ "DEL_WORD",
+ "CLR_EOL",
+ "CLR_EOF",
+ "CLR_FIELD",
+ "OVL_MODE",
+ "INS_MODE",
+ "SCR_FLINE",
+ "SCR_BLINE",
+ "SCR_FPAGE",
+ "SCR_BPAGE",
+ "SCR_FHPAGE",
+ "SCR_BHPAGE",
+ "SCR_FCHAR",
+ "SCR_BCHAR",
+ "SCR_HFLINE",
+ "SCR_HBLINE",
+ "SCR_HFHALF",
+ "SCR_HBHALF",
+
+ "VALIDATION",
+ "NEXT_CHOICE",
+ "PREV_CHOICE"
+};
+
+#define A_SIZE (sizeof(request_names)/sizeof(request_names[0]))
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : const char * form_request_name (int request);
+|
+| Description : Get the external name of a form request.
+|
+| Return Values : Pointer to name - on success
+| NULL - on invalid request code
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(const char *)
+form_request_name(int request)
+{
+ T((T_CALLED("form_request_name(%d)"), request));
+
+ if ((request < MIN_FORM_COMMAND) || (request > MAX_FORM_COMMAND))
+ {
+ SET_ERROR(E_BAD_ARGUMENT);
+ returnCPtr((const char *)0);
+ }
+ else
+ returnCPtr(request_names[request - MIN_FORM_COMMAND]);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_request_by_name (const char *str);
+|
+| Description : Search for a request with this name.
+|
+| Return Values : Request Id - on success
+| E_NO_MATCH - request not found
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+form_request_by_name(const char *str)
+{
+ /* because the table is so small, it doesn't really hurt
+ to run sequentially through it.
+ */
+ unsigned int i = 0;
+ char buf[16];
+
+ T((T_CALLED("form_request_by_name(%s)"), _nc_visbuf(str)));
+
+ if (str)
+ {
+ strncpy(buf, str, sizeof(buf));
+ while ((i < sizeof(buf)) && (buf[i] != '\0'))
+ {
+ buf[i] = (char)toupper(UChar(buf[i]));
+ i++;
+ }
+
+ for (i = 0; i < A_SIZE; i++)
+ {
+ if (strncmp(request_names[i], buf, sizeof(buf)) == 0)
+ returnCode(MIN_FORM_COMMAND + (int)i);
+ }
+ }
+ RETURN(E_NO_MATCH);
+}
+
+/* frm_req_name.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_scale.c b/apps/lib/curses/pdcurses/form/frm_scale.c
new file mode 100644
index 0000000..18a565e
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_scale.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_scale.c,v 1.10 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int scale_form( const FORM *form, int *rows, int *cols )
+|
+| Description : Retrieve size of form
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - invalid form pointer
+| E_NOT_CONNECTED - no fields connected to form
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+scale_form(const FORM *form, int *rows, int *cols)
+{
+ T((T_CALLED("scale_form(%p,%p,%p)"),
+ (const void *)form,
+ (void *)rows,
+ (void *)cols));
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->field))
+ RETURN(E_NOT_CONNECTED);
+
+ if (rows)
+ *rows = form->rows;
+ if (cols)
+ *cols = form->cols;
+
+ RETURN(E_OK);
+}
+
+/* frm_scale.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_sub.c b/apps/lib/curses/pdcurses/form/frm_sub.c
new file mode 100644
index 0000000..cf5b82f
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_sub.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995-1997,2009 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_sub.c,v 1.12 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_sub(FORM *form, WINDOW *win)
+|
+| Description : Set the subwindow of the form to win.
+|
+| Return Values : E_OK - success
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_sub(FORM *form, WINDOW *win)
+{
+ T((T_CALLED("set_form_sub(%p,%p)"), (void *)form, (void *)win));
+
+ if (form && (form->status & _POSTED))
+ RETURN(E_POSTED);
+ else
+ {
+#if NCURSES_SP_FUNCS
+ FORM *f = Normalize_Form(form);
+
+ f->sub = win ? win : StdScreen(Get_Form_Screen(f));
+ RETURN(E_OK);
+#else
+ Normalize_Form(form)->sub = win;
+ RETURN(E_OK);
+#endif
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : WINDOW *form_sub(const FORM *)
+|
+| Description : Retrieve the window of the form.
+|
+| Return Values : The pointer to the Subwindow.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(WINDOW *)
+form_sub(const FORM *form)
+{
+ const FORM *f;
+
+ T((T_CALLED("form_sub(%p)"), (const void *)form));
+
+ f = Normalize_Form(form);
+ returnWin(Get_Form_Window(f));
+}
+
+/* frm_sub.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_user.c b/apps/lib/curses/pdcurses/form/frm_user.c
new file mode 100644
index 0000000..5cab224
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_user.c
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_user.c,v 1.15 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_userptr(FORM *form, void *usrptr)
+|
+| Description : Set the pointer that is reserved in any form to store
+| application relevant informations
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_userptr(FORM *form, void *usrptr)
+{
+ T((T_CALLED("set_form_userptr(%p,%p)"), (void *)form, (void *)usrptr));
+
+ Normalize_Form(form)->usrptr = usrptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *form_userptr(const FORM *form)
+|
+| Description : Return the pointer that is reserved in any form to
+| store application relevant informations.
+|
+| Return Values : Value of pointer. If no such pointer has been set,
+| NULL is returned
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(void *)
+form_userptr(const FORM *form)
+{
+ T((T_CALLED("form_userptr(%p)"), (const void *)form));
+ returnVoidPtr(Normalize_Form(form)->usrptr);
+}
+
+/* frm_user.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/frm_win.c b/apps/lib/curses/pdcurses/form/frm_win.c
new file mode 100644
index 0000000..82cf2d3
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/frm_win.c
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer, 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_win.c,v 1.16 2010/01/23 21:14:36 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_win(FORM *form,WINDOW *win)
+|
+| Description : Set the window of the form to win.
+|
+| Return Values : E_OK - success
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+set_form_win(FORM *form, WINDOW *win)
+{
+ T((T_CALLED("set_form_win(%p,%p)"), (void *)form, (void *)win));
+
+ if (form && (form->status & _POSTED))
+ RETURN(E_POSTED);
+ else
+ {
+#if NCURSES_SP_FUNCS
+ FORM *f = Normalize_Form(form);
+
+ f->win = win ? win : StdScreen(Get_Form_Screen(f));
+ RETURN(E_OK);
+#else
+ Normalize_Form(form)->win = win;
+ RETURN(E_OK);
+#endif
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : WINDOW *form_win(const FORM *)
+|
+| Description : Retrieve the window of the form.
+|
+| Return Values : The pointer to the Window or stdscr if there is none.
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(WINDOW *)
+form_win(const FORM *form)
+{
+ WINDOW *result;
+ const FORM *f;
+
+ T((T_CALLED("form_win(%p)"), (const void *)form));
+
+ f = Normalize_Form(form);
+#if NCURSES_SP_FUNCS
+ result = (f->win ? f->win : StdScreen(Get_Form_Screen(f)));
+#else
+ result = (f->win ? f->win : stdscr);
+#endif
+ returnWin(result);
+}
+
+/* frm_win.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_alnum.c b/apps/lib/curses/pdcurses/form/fty_alnum.c
new file mode 100644
index 0000000..cda23dc
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_alnum.c
@@ -0,0 +1,202 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_alnum.c,v 1.24 2010/01/23 21:14:36 tom Exp $")
+
+#define thisARG alnumARG
+
+typedef struct
+ {
+ int width;
+ }
+thisARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_This_Type(void *arg)
+|
+| Description : Allocate structure for alphanumeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_This_Type(void *arg)
+{
+ thisARG *argp = (thisARG *) 0;
+
+ if (arg)
+ {
+ argp = typeMalloc(thisARG, 1);
+
+ if (argp)
+ {
+ T((T_CREATE("thisARG %p"), (void *)argp));
+ argp->width = *((int *)arg);
+ }
+ }
+ return ((void *)argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_This_Type(va_list *ap)
+|
+| Description : Allocate structure for alphanumeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_This_Type(va_list *ap)
+{
+ int w = va_arg(*ap, int);
+
+ return Generic_This_Type((void *)&w);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_ThisType(const void *argp)
+|
+| Description : Copy structure for alphanumeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_This_Type(const void *argp)
+{
+ const thisARG *ap = (const thisARG *)argp;
+ thisARG *result = typeMalloc(thisARG, 1);
+
+ if (result)
+ {
+ T((T_CREATE("thisARG %p"), (void *)result));
+ *result = *ap;
+ }
+
+ return ((void *)result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_This_Type(void *argp)
+|
+| Description : Free structure for alphanumeric type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_This_Type(void *argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Character(
+| int c,
+| const void *argp)
+|
+| Description : Check a character for the alphanumeric type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Character(int c, const void *argp GCC_UNUSED)
+{
+#if USE_WIDEC_SUPPORT
+ if (iswalnum((wint_t) c))
+ return TRUE;
+#endif
+ return (isalnum(UChar(c)) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Field(
+| FIELD *field,
+| const void *argp)
+|
+| Description : Validate buffer content to be a valid alphanumeric value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Field(FIELD *field, const void *argp)
+{
+ int width = ((const thisARG *)argp)->width;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+ bool result = (width < 0);
+
+ Check_CTYPE_Field(result, bp, width, Check_This_Character);
+ return (result);
+}
+
+static FIELDTYPE typeTHIS =
+{
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_This_Type,
+ Copy_This_Type,
+ Free_This_Type,
+ INIT_FT_FUNC(Check_This_Field),
+ INIT_FT_FUNC(Check_This_Character),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ Generic_This_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_ALNUM = &typeTHIS;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_ALNUM(void)
+{
+ return TYPE_ALNUM;
+}
+#endif
+
+/* fty_alnum.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_alpha.c b/apps/lib/curses/pdcurses/form/fty_alpha.c
new file mode 100644
index 0000000..917a9e0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_alpha.c
@@ -0,0 +1,202 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_alpha.c,v 1.26 2010/01/23 21:14:36 tom Exp $")
+
+#define thisARG alphaARG
+
+typedef struct
+ {
+ int width;
+ }
+thisARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_This_Type(va_list *ap)
+|
+| Description : Allocate structure for alpha type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_This_Type(void *arg)
+{
+ thisARG *argp = (thisARG *) 0;
+
+ if (arg)
+ {
+ argp = typeMalloc(thisARG, 1);
+
+ if (argp)
+ {
+ T((T_CREATE("thisARG %p"), (void *)argp));
+ argp->width = *((int *)arg);
+ }
+ }
+ return ((void *)argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_This_Type(va_list *ap)
+|
+| Description : Allocate structure for alpha type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_This_Type(va_list *ap)
+{
+ int w = va_arg(*ap, int);
+
+ return Generic_This_Type((void *)&w);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_This_Type(const void * argp)
+|
+| Description : Copy structure for alpha type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_This_Type(const void *argp)
+{
+ const thisARG *ap = (const thisARG *)argp;
+ thisARG *result = typeMalloc(thisARG, 1);
+
+ if (result)
+ {
+ T((T_CREATE("thisARG %p"), (void *)result));
+ *result = *ap;
+ }
+
+ return ((void *)result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_This_Type(void *argp)
+|
+| Description : Free structure for alpha type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_This_Type(void *argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Character(
+| int c,
+| const void *argp)
+|
+| Description : Check a character for the alpha type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Character(int c, const void *argp GCC_UNUSED)
+{
+#if USE_WIDEC_SUPPORT
+ if (iswalpha((wint_t) c))
+ return TRUE;
+#endif
+ return (isalpha(UChar(c)) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Field(
+| FIELD *field,
+| const void *argp)
+|
+| Description : Validate buffer content to be a valid alpha value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Field(FIELD *field, const void *argp)
+{
+ int width = ((const thisARG *)argp)->width;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+ bool result = (width < 0);
+
+ Check_CTYPE_Field(result, bp, width, Check_This_Character);
+ return (result);
+}
+
+static FIELDTYPE typeTHIS =
+{
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_This_Type,
+ Copy_This_Type,
+ Free_This_Type,
+ INIT_FT_FUNC(Check_This_Field),
+ INIT_FT_FUNC(Check_This_Character),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ Generic_This_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_ALPHA = &typeTHIS;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_ALPHA(void)
+{
+ return TYPE_ALPHA;
+}
+#endif
+
+/* fty_alpha.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_enum.c b/apps/lib/curses/pdcurses/form/fty_enum.c
new file mode 100644
index 0000000..2fd96f0
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_enum.c
@@ -0,0 +1,442 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_enum.c,v 1.26 2010/05/01 21:11:07 tom Exp $")
+
+typedef struct
+ {
+ char **kwds;
+ int count;
+ bool checkcase;
+ bool checkunique;
+ }
+enumARG;
+
+typedef struct
+ {
+ char **kwds;
+ int ccase;
+ int cunique;
+ }
+enumParams;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_Enum_Type(void * arg)
+|
+| Description : Allocate structure for enumeration type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_Enum_Type(void *arg)
+{
+ enumARG *argp = (enumARG *)0;
+ enumParams *params = (enumParams *) arg;
+
+ if (params)
+ {
+ argp = typeMalloc(enumARG, 1);
+
+ if (argp)
+ {
+ int cnt = 0;
+ char **kp = (char **)0;
+ char **kwds = (char **)0;
+ char **kptarget;
+ int ccase, cunique;
+
+ T((T_CREATE("enumARG %p"), (void *)argp));
+ kwds = params->kwds;
+ ccase = params->ccase;
+ cunique = params->cunique;
+
+ argp->checkcase = ccase ? TRUE : FALSE;
+ argp->checkunique = cunique ? TRUE : FALSE;
+ argp->kwds = (char **)0;
+
+ kp = kwds;
+ while (kp && (*kp++))
+ cnt++;
+ argp->count = cnt;
+
+ if (cnt > 0)
+ {
+ /* We copy the keywords, because we can't rely on the fact
+ that the caller doesn't relocate or free the memory used
+ for the keywords (maybe he has GC)
+ */
+ argp->kwds = typeMalloc(char *, cnt + 1);
+
+ kp = kwds;
+ if ((kptarget = argp->kwds) != 0)
+ {
+ while (kp && (*kp))
+ {
+ (*kptarget++) = strdup(*kp++);
+ }
+ *kptarget = (char *)0;
+ }
+ }
+ }
+ }
+ return (void *)argp;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_Enum_Type( va_list * ap )
+|
+| Description : Allocate structure for enumeration type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_Enum_Type(va_list *ap)
+{
+ enumParams params;
+
+ params.kwds = va_arg(*ap, char **);
+ params.ccase = va_arg(*ap, int);
+ params.cunique = va_arg(*ap, int);
+
+ return Generic_Enum_Type((void *)¶ms);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_Enum_Type( const void * argp )
+|
+| Description : Copy structure for enumeration type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_Enum_Type(const void *argp)
+{
+ enumARG *result = (enumARG *)0;
+
+ if (argp)
+ {
+ const enumARG *ap = (const enumARG *)argp;
+
+ result = typeMalloc(enumARG, 1);
+
+ if (result)
+ {
+ T((T_CREATE("enumARG %p"), (void *)result));
+ *result = *ap;
+
+ if (ap->count > 0)
+ {
+ char **kptarget;
+ char **kp = ap->kwds;
+ result->kwds = typeMalloc(char *, 1 + ap->count);
+
+ if ((kptarget = result->kwds) != 0)
+ {
+ while (kp && (*kp))
+ {
+ (*kptarget++) = strdup(*kp++);
+ }
+ *kptarget = (char *)0;
+ }
+ }
+ }
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_Enum_Type( void * argp )
+|
+| Description : Free structure for enumeration type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_Enum_Type(void *argp)
+{
+ if (argp)
+ {
+ const enumARG *ap = (const enumARG *)argp;
+
+ if (ap->kwds && ap->count > 0)
+ {
+ char **kp = ap->kwds;
+ int cnt = 0;
+
+ while (kp && (*kp))
+ {
+ free(*kp++);
+ cnt++;
+ }
+ assert(cnt == ap->count);
+ free(ap->kwds);
+ }
+ free(argp);
+ }
+}
+
+#define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
+#define NOMATCH 0
+#define PARTIAL 1
+#define EXACT 2
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Compare(const unsigned char * s,
+| const unsigned char * buf,
+| bool ccase )
+|
+| Description : Check whether or not the text in 'buf' matches the
+| text in 's', at least partial.
+|
+| Return Values : NOMATCH - buffer doesn't match
+| PARTIAL - buffer matches partially
+| EXACT - buffer matches exactly
++--------------------------------------------------------------------------*/
+static int
+Compare(const unsigned char *s, const unsigned char *buf,
+ bool ccase)
+{
+ SKIP_SPACE(buf); /* Skip leading spaces in both texts */
+ SKIP_SPACE(s);
+
+ if (*buf == '\0')
+ {
+ return (((*s) != '\0') ? NOMATCH : EXACT);
+ }
+ else
+ {
+ if (ccase)
+ {
+ while (*s++ == *buf)
+ {
+ if (*buf++ == '\0')
+ return EXACT;
+ }
+ }
+ else
+ {
+ while (toupper(*s++) == toupper(*buf))
+ {
+ if (*buf++ == '\0')
+ return EXACT;
+ }
+ }
+ }
+ /* At this location buf points to the first character where it no longer
+ matches with s. So if only blanks are following, we have a partial
+ match otherwise there is no match */
+ SKIP_SPACE(buf);
+ if (*buf)
+ return NOMATCH;
+
+ /* If it happens that the reference buffer is at its end, the partial
+ match is actually an exact match. */
+ return ((s[-1] != '\0') ? PARTIAL : EXACT);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Enum_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid enumeration value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_Enum_Field(FIELD *field, const void *argp)
+{
+ char **kwds = ((const enumARG *)argp)->kwds;
+ bool ccase = ((const enumARG *)argp)->checkcase;
+ bool unique = ((const enumARG *)argp)->checkunique;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+ char *s, *t, *p;
+ int res;
+
+ while (kwds && (s = (*kwds++)))
+ {
+ if ((res = Compare((unsigned char *)s, bp, ccase)) != NOMATCH)
+ {
+ p = t = s; /* t is at least a partial match */
+ if ((unique && res != EXACT))
+ {
+ while (kwds && (p = *kwds++))
+ {
+ if ((res = Compare((unsigned char *)p, bp, ccase)) != NOMATCH)
+ {
+ if (res == EXACT)
+ {
+ t = p;
+ break;
+ }
+ else
+ t = (char *)0;
+ }
+ }
+ }
+ if (t)
+ {
+ set_field_buffer(field, 0, t);
+ return TRUE;
+ }
+ if (!p)
+ break;
+ }
+ }
+ return FALSE;
+}
+
+static const char *dummy[] =
+{(char *)0};
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Next_Enum(FIELD * field,
+| const void * argp)
+|
+| Description : Check for the next enumeration value
+|
+| Return Values : TRUE - next value found and loaded
+| FALSE - no next value loaded
++--------------------------------------------------------------------------*/
+static bool
+Next_Enum(FIELD *field, const void *argp)
+{
+ const enumARG *args = (const enumARG *)argp;
+ char **kwds = args->kwds;
+ bool ccase = args->checkcase;
+ int cnt = args->count;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+
+ if (kwds)
+ {
+ while (cnt--)
+ {
+ if (Compare((unsigned char *)(*kwds++), bp, ccase) == EXACT)
+ break;
+ }
+ if (cnt <= 0)
+ kwds = args->kwds;
+ if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
+ {
+ set_field_buffer(field, 0, *kwds);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Previous_Enum(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Check for the previous enumeration value
+|
+| Return Values : TRUE - previous value found and loaded
+| FALSE - no previous value loaded
++--------------------------------------------------------------------------*/
+static bool
+Previous_Enum(FIELD *field, const void *argp)
+{
+ const enumARG *args = (const enumARG *)argp;
+ int cnt = args->count;
+ char **kwds = &args->kwds[cnt - 1];
+ bool ccase = args->checkcase;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+
+ if (kwds)
+ {
+ while (cnt--)
+ {
+ if (Compare((unsigned char *)(*kwds--), bp, ccase) == EXACT)
+ break;
+ }
+
+ if (cnt <= 0)
+ kwds = &args->kwds[args->count - 1];
+
+ if ((cnt >= 0) || (Compare((const unsigned char *)dummy, bp, ccase) == EXACT))
+ {
+ set_field_buffer(field, 0, *kwds);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static FIELDTYPE typeENUM =
+{
+ _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_Enum_Type,
+ Copy_Enum_Type,
+ Free_Enum_Type,
+ INIT_FT_FUNC(Check_Enum_Field),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(Next_Enum),
+ INIT_FT_FUNC(Previous_Enum),
+#if NCURSES_INTEROP_FUNCS
+ Generic_Enum_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE *)
+TYPE_ENUM = &typeENUM;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_ENUM(void)
+{
+ return TYPE_ENUM;
+}
+#endif
+
+/* fty_enum.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_generic.c b/apps/lib/curses/pdcurses/form/fty_generic.c
new file mode 100644
index 0000000..439afcc
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_generic.c
@@ -0,0 +1,297 @@
+/****************************************************************************
+ * Copyright (c) 2008-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_generic.c,v 1.5 2010/01/23 21:14:36 tom Exp $")
+
+/*
+ * This is not a full implementation of a field type, but adds some
+ * support for higher level languages with some restrictions to interop
+ * with C language. Especially the collection of arguments for the
+ * various fieldtypes is not based on the vararg C mechanism, but on a
+ * iterator based callback mechanism that allowes the high level language
+ * to provide the arguments as a structure. Most languages have mechanisms
+ * to layout structures so that they can be passed to C.
+ * The languages can register a new generic fieldtype dynamically and store
+ * a handle (key) to the calling object as an argument. Together with that
+ * it can register a freearg callback, so that the high level language
+ * remains in control of the memory management of the arguments they pass.
+ * The design idea is, that the high-level language - typically a OO
+ * language like C# or Java, uses it's own dispatching mechanisms
+ * (polymorphism) to call the proper check routines responsible for the
+ * argument type. So these language implement typically only one generic
+ * fieldtype they register with the forms library using this call.
+ *
+ * For that purpose we have extended the fieldtype struc by a new element
+ * that gets the arguments from a single struct passed by the caller.
+ *
+ */
+#if NCURSES_INTEROP_FUNCS
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_This_Type( void * arg )
+|
+| Description : We interpret the passed arg just as a handle the
+| calling language uses to keep track of its allocated
+| argument structures. We can simply copy it back.
+|
+| Return Values : Pointer to argument structure
++--------------------------------------------------------------------------*/
+static void *
+Generic_This_Type(void *arg)
+{
+ return (arg);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *_nc_generic_fieldtype(
+| bool (* const field_check)(FIELD *,const void *),
+| bool (* const char_check) (int, const void *),
+| bool (*const next)(FORM*,FIELD*,const void*),
+| bool (*const prev)(FORM*,FIELD*,const void*),
+| void (*freecallback)(void*))
+|
+| Description : Create a new fieldtype. The application programmer must
+| write a field_check and a char_check function and give
+| them as input to this call. A callback to allow the
+| release of the allocated memory must also be provided.
+| For generic field types, we provide some more
+| information about the field as parameters.
+|
+| If an error occurs, errno is set to
+| E_BAD_ARGUMENT - invalid arguments
+| E_SYSTEM_ERROR - system error (no memory)
+|
+| Return Values : Fieldtype pointer or NULL if error occurred
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_generic_fieldtype(bool (*const field_check) (FORM *, FIELD *, const void *),
+ bool (*const char_check) (int, FORM *, FIELD *, const
+ void *),
+ bool (*const next) (FORM *, FIELD *, const void *),
+ bool (*const prev) (FORM *, FIELD *, const void *),
+ void (*freecallback) (void *))
+{
+ int code = E_SYSTEM_ERROR;
+ FIELDTYPE *res = (FIELDTYPE *)0;
+
+ T((T_CALLED("_nc_generic_fieldtype(%p,%p,%p,%p,%p)"),
+ field_check, char_check, next, prev, freecallback));
+
+ if (field_check || char_check)
+ {
+ res = typeMalloc(FIELDTYPE, 1);
+
+ if (res)
+ {
+ *res = *_nc_Default_FieldType;
+ res->status |= (_HAS_ARGS | _GENERIC);
+ res->fieldcheck.gfcheck = field_check;
+ res->charcheck.gccheck = char_check;
+ res->genericarg = Generic_This_Type;
+ res->freearg = freecallback;
+ res->enum_next.gnext = next;
+ res->enum_prev.gprev = prev;
+ code = E_OK;
+ }
+ }
+ else
+ code = E_BAD_ARGUMENT;
+
+ if (E_OK != code)
+ SET_ERROR(code);
+
+ returnFieldType(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static TypeArgument *GenericArgument(
+| const FIELDTYPE* typ,
+| int (*argiterator)(void**),
+| int* err)
+|
+| Description : The iterator callback must browse through all fieldtype
+| parameters that have an argument associated with the
+| type. The iterator returns 1 if the operation to get
+| the next element was successfull, 0 otherwise. If the
+| iterator could move to the next argument, it fills
+| the void* pointer representing the argument into the
+| location provided as argument to the iterator.
+| The err reference is used to keep track of errors.
+|
+| Return Values : Pointer to argument structure
++--------------------------------------------------------------------------*/
+static TypeArgument *
+GenericArgument(const FIELDTYPE *typ,
+ int (*argiterator) (void **), int *err)
+{
+ TypeArgument *res = (TypeArgument *)0;
+
+ if (typ != 0 && (typ->status & _HAS_ARGS) != 0 && err != 0 && argiterator != 0)
+ {
+ if (typ->status & _LINKED_TYPE)
+ {
+ /* Composite fieldtypes keep track internally of their own memory */
+ TypeArgument *p = typeMalloc(TypeArgument, 1);
+
+ if (p)
+ {
+ p->left = GenericArgument(typ->left, argiterator, err);
+ p->right = GenericArgument(typ->right, argiterator, err);
+ return p;
+ }
+ else
+ *err += 1;
+ }
+ else
+ {
+ assert(typ->genericarg != (void *)0);
+ if (typ->genericarg == 0)
+ *err += 1;
+ else
+ {
+ void *argp;
+ int valid = argiterator(&argp);
+
+ if (valid == 0 || argp == 0 ||
+ !(res = (TypeArgument *)typ->genericarg(argp)))
+ {
+ *err += 1;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_set_generic_fieldtype(
+| FIELD* field,
+| FIELDTYPE* ftyp,
+| int (*argiterator)(void**))
+|
+| Description : Assign the fieldtype to the field and use the iterator
+| mechanism to get the arguments when a check is
+| performed.
+|
+| Return Values : E_OK if all went well
+| E_SYSTEM_ERROR if an error occurred
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(int)
+_nc_set_generic_fieldtype(FIELD *field,
+ FIELDTYPE *ftyp,
+ int (*argiterator) (void **))
+{
+ int code = E_SYSTEM_ERROR;
+ int err = 0;
+
+ if (field)
+ {
+ if (field && field->type)
+ _nc_Free_Type(field);
+
+ field->type = ftyp;
+ if (ftyp)
+ {
+ if (argiterator)
+ {
+ /* The precondition is that the iterator is reset */
+ field->arg = (void *)GenericArgument(field->type, argiterator, &err);
+
+ if (err)
+ {
+ _nc_Free_Argument(field->type, (TypeArgument *)(field->arg));
+ field->type = (FIELDTYPE *)0;
+ field->arg = (void *)0;
+ }
+ else
+ {
+ code = E_OK;
+ if (field->type)
+ field->type->ref++;
+ }
+ }
+ }
+ else
+ {
+ field->arg = (void *)0;
+ code = E_OK;
+ }
+ }
+ return code;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : WINDOW* _nc_form_cursor(
+| FORM* form,
+| int *pRow, int *pCol)
+|
+| Description : Get the current position of the form cursor position
+| We also return the field window
+|
+| Return Values : The fields Window or NULL on error
++--------------------------------------------------------------------------*/
+NCURSES_EXPORT(WINDOW *)
+_nc_form_cursor(const FORM *form, int *pRow, int *pCol)
+{
+ int code = E_SYSTEM_ERROR;
+ WINDOW *res = (WINDOW *)0;
+
+ if (!(form == 0 || pRow == 0 || pCol == 0))
+ {
+ *pRow = form->currow;
+ *pCol = form->curcol;
+ res = form->w;
+ code = E_OK;
+ }
+ if (code != E_OK)
+ SET_ERROR(code);
+ return res;
+}
+
+#else
+extern void _nc_fty_generic(void);
+void
+_nc_fty_generic(void)
+{
+}
+#endif
+
+/* fty_generic.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_int.c b/apps/lib/curses/pdcurses/form/fty_int.c
new file mode 100644
index 0000000..0eddedf
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_int.c
@@ -0,0 +1,293 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_int.c,v 1.25 2010/01/23 21:14:36 tom Exp $")
+
+#if USE_WIDEC_SUPPORT
+#define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c)))
+#else
+#define isDigit(c) isdigit(UChar(c))
+#endif
+
+#define thisARG integerARG
+
+typedef struct
+ {
+ int precision;
+ long low;
+ long high;
+ }
+thisARG;
+
+typedef struct
+ {
+ int precision;
+ long low;
+ long high;
+ }
+integerPARM;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_This_Type( void * arg )
+|
+| Description : Allocate structure for integer type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_This_Type(void *arg)
+{
+ thisARG *argp = (thisARG *) 0;
+ thisARG *param = (thisARG *) arg;
+
+ if (param)
+ {
+ argp = typeMalloc(thisARG, 1);
+
+ if (argp)
+ {
+ T((T_CREATE("thisARG %p"), (void *)argp));
+ *argp = *param;
+ }
+ }
+ return (void *)argp;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_This_Type( va_list * ap )
+|
+| Description : Allocate structure for integer type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_This_Type(va_list *ap)
+{
+ thisARG arg;
+
+ arg.precision = va_arg(*ap, int);
+ arg.low = va_arg(*ap, long);
+ arg.high = va_arg(*ap, long);
+
+ return Generic_This_Type((void *)&arg);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_This_Type(const void * argp)
+|
+| Description : Copy structure for integer type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_This_Type(const void *argp)
+{
+ const thisARG *ap = (const thisARG *)argp;
+ thisARG *result = (thisARG *) 0;
+
+ if (argp)
+ {
+ result = typeMalloc(thisARG, 1);
+ if (result)
+ {
+ T((T_CREATE("thisARG %p"), (void *)result));
+ *result = *ap;
+ }
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_This_Type(void * argp)
+|
+| Description : Free structure for integer type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_This_Type(void *argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid integer value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Field(FIELD *field, const void *argp)
+{
+ const thisARG *argi = (const thisARG *)argp;
+ long low = argi->low;
+ long high = argi->high;
+ int prec = argi->precision;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+ char *s = (char *)bp;
+ long val;
+ char buf[100];
+ bool result = FALSE;
+
+ while (*bp && *bp == ' ')
+ bp++;
+ if (*bp)
+ {
+ if (*bp == '-')
+ bp++;
+#if USE_WIDEC_SUPPORT
+ if (*bp)
+ {
+ bool blank = FALSE;
+ int len;
+ int n;
+ wchar_t *list = _nc_Widen_String((char *)bp, &len);
+
+ if (list != 0)
+ {
+ result = TRUE;
+ for (n = 0; n < len; ++n)
+ {
+ if (blank)
+ {
+ if (list[n] != ' ')
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ else if (list[n] == ' ')
+ {
+ blank = TRUE;
+ }
+ else if (!isDigit(list[n]))
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ free(list);
+ }
+ }
+#else
+ while (*bp)
+ {
+ if (!isdigit(UChar(*bp)))
+ break;
+ bp++;
+ }
+ while (*bp && *bp == ' ')
+ bp++;
+ result = (*bp == '\0');
+#endif
+ if (result)
+ {
+ val = atol(s);
+ if (low < high)
+ {
+ if (val < low || val > high)
+ result = FALSE;
+ }
+ if (result)
+ {
+ sprintf(buf, "%.*ld", (prec > 0 ? prec : 0), val);
+ set_field_buffer(field, 0, buf);
+ }
+ }
+ }
+ return (result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Character(
+| int c,
+| const void * argp)
+|
+| Description : Check a character for the integer type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Character(int c, const void *argp GCC_UNUSED)
+{
+ return ((isDigit(UChar(c)) || (c == '-')) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeTHIS =
+{
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_This_Type,
+ Copy_This_Type,
+ Free_This_Type,
+ INIT_FT_FUNC(Check_This_Field),
+ INIT_FT_FUNC(Check_This_Character),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ Generic_This_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_INTEGER = &typeTHIS;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_INTEGER(void)
+{
+ return TYPE_INTEGER;
+}
+#endif
+
+/* fty_int.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_ipv4.c b/apps/lib/curses/pdcurses/form/fty_ipv4.c
new file mode 100644
index 0000000..3def259
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_ipv4.c
@@ -0,0 +1,120 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2009 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Per Foreby, perf@efd.lth.se *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_ipv4.c,v 1.10 2009/11/07 20:17:58 tom Exp $")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_IPV4_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid IP number (Ver. 4)
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_IPV4_Field(FIELD *field, const void *argp GCC_UNUSED)
+{
+ char *bp = field_buffer(field, 0);
+ int num = 0, len;
+ unsigned int d1, d2, d3, d4;
+
+ if (isdigit(UChar(*bp))) /* Must start with digit */
+ {
+ num = sscanf(bp, "%u.%u.%u.%u%n", &d1, &d2, &d3, &d4, &len);
+ if (num == 4)
+ {
+ bp += len; /* Make bp point to what sscanf() left */
+ while (isspace(UChar(*bp)))
+ bp++; /* Allow trailing whitespace */
+ }
+ }
+ return ((num != 4 || *bp || d1 > 255 || d2 > 255
+ || d3 > 255 || d4 > 255) ? FALSE : TRUE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_IPV4_Character(
+| int c,
+| const void *argp )
+|
+| Description : Check a character for unsigned type or period.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_IPV4_Character(int c, const void *argp GCC_UNUSED)
+{
+ return ((isdigit(UChar(c)) || (c == '.')) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeIPV4 =
+{
+ _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ NULL,
+ NULL,
+ NULL,
+ INIT_FT_FUNC(Check_IPV4_Field),
+ INIT_FT_FUNC(Check_IPV4_Character),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ NULL
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_IPV4 = &typeIPV4;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_IPV4(void)
+{
+ return TYPE_IPV4;
+}
+#endif
+
+/* fty_ipv4.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_num.c b/apps/lib/curses/pdcurses/form/fty_num.c
new file mode 100644
index 0000000..4bd7132
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_num.c
@@ -0,0 +1,339 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_num.c,v 1.28 2010/01/23 21:14:36 tom Exp $")
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#if HAVE_LOCALE_H
+#define isDecimalPoint(c) ((c) == ((L && L->decimal_point) ? *(L->decimal_point) : '.'))
+#else
+#define isDecimalPoint(c) ((c) == '.')
+#endif
+
+#if USE_WIDEC_SUPPORT
+#define isDigit(c) (iswdigit((wint_t)(c)) || isdigit(UChar(c)))
+#else
+#define isDigit(c) isdigit(UChar(c))
+#endif
+
+#define thisARG numericARG
+
+typedef struct
+ {
+ int precision;
+ double low;
+ double high;
+ struct lconv *L;
+ }
+thisARG;
+
+typedef struct
+ {
+ int precision;
+ double low;
+ double high;
+ }
+thisPARM;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_This_Type(void * arg)
+|
+| Description : Allocate structure for numeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_This_Type(void *arg)
+{
+ thisARG *argn = (thisARG *) 0;
+ thisPARM *args = (thisPARM *) arg;
+
+ if (args)
+ {
+ argn = typeMalloc(thisARG, 1);
+
+ if (argn)
+ {
+ T((T_CREATE("thisARG %p"), (void *)argn));
+ argn->precision = args->precision;
+ argn->low = args->low;
+ argn->high = args->high;
+
+#if HAVE_LOCALE_H
+ argn->L = localeconv();
+#else
+ argn->L = NULL;
+#endif
+ }
+ }
+ return (void *)argn;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_This_Type(va_list * ap)
+|
+| Description : Allocate structure for numeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_This_Type(va_list *ap)
+{
+ thisPARM arg;
+
+ arg.precision = va_arg(*ap, int);
+ arg.low = va_arg(*ap, double);
+ arg.high = va_arg(*ap, double);
+
+ return Generic_This_Type((void *)&arg);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_This_Type(const void * argp)
+|
+| Description : Copy structure for numeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_This_Type(const void *argp)
+{
+ const thisARG *ap = (const thisARG *)argp;
+ thisARG *result = (thisARG *) 0;
+
+ if (argp)
+ {
+ result = typeMalloc(thisARG, 1);
+ if (result)
+ {
+ T((T_CREATE("thisARG %p"), (void *)result));
+ *result = *ap;
+ }
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_This_Type(void * argp)
+|
+| Description : Free structure for numeric type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_This_Type(void *argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Field(FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid numeric value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Field(FIELD *field, const void *argp)
+{
+ const thisARG *argn = (const thisARG *)argp;
+ double low = argn->low;
+ double high = argn->high;
+ int prec = argn->precision;
+ unsigned char *bp = (unsigned char *)field_buffer(field, 0);
+ char *s = (char *)bp;
+ double val = 0.0;
+ struct lconv *L = argn->L;
+ char buf[64];
+ bool result = FALSE;
+
+ while (*bp && *bp == ' ')
+ bp++;
+ if (*bp)
+ {
+ if (*bp == '-' || *bp == '+')
+ bp++;
+#if USE_WIDEC_SUPPORT
+ if (*bp)
+ {
+ bool blank = FALSE;
+ int state = 0;
+ int len;
+ int n;
+ wchar_t *list = _nc_Widen_String((char *)bp, &len);
+
+ if (list != 0)
+ {
+ result = TRUE;
+ for (n = 0; n < len; ++n)
+ {
+ if (blank)
+ {
+ if (list[n] != ' ')
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ else if (list[n] == ' ')
+ {
+ blank = TRUE;
+ }
+ else if (isDecimalPoint(list[n]))
+ {
+ if (++state > 1)
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ else if (!isDigit(list[n]))
+ {
+ result = FALSE;
+ break;
+ }
+ }
+ free(list);
+ }
+ }
+#else
+ while (*bp)
+ {
+ if (!isdigit(UChar(*bp)))
+ break;
+ bp++;
+ }
+ if (isDecimalPoint(*bp))
+ {
+ bp++;
+ while (*bp)
+ {
+ if (!isdigit(UChar(*bp)))
+ break;
+ bp++;
+ }
+ }
+ while (*bp && *bp == ' ')
+ bp++;
+ result = (*bp == '\0');
+#endif
+ if (result)
+ {
+ val = atof(s);
+ if (low < high)
+ {
+ if (val < low || val > high)
+ result = FALSE;
+ }
+ if (result)
+ {
+ sprintf(buf, "%.*f", (prec > 0 ? prec : 0), val);
+ set_field_buffer(field, 0, buf);
+ }
+ }
+ }
+ return (result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_This_Character(
+| int c,
+| const void * argp)
+|
+| Description : Check a character for the numeric type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_This_Character(int c, const void *argp)
+{
+ const thisARG *argn = (const thisARG *)argp;
+ struct lconv *L = argn->L;
+
+ return ((isDigit(c) ||
+ c == '+' ||
+ c == '-' ||
+ isDecimalPoint(c))
+ ? TRUE
+ : FALSE);
+}
+
+static FIELDTYPE typeTHIS =
+{
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_This_Type,
+ Copy_This_Type,
+ Free_This_Type,
+ INIT_FT_FUNC(Check_This_Field),
+ INIT_FT_FUNC(Check_This_Character),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ Generic_This_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_NUMERIC = &typeTHIS;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_NUMERIC(void)
+{
+ return TYPE_NUMERIC;
+}
+#endif
+
+/* fty_num.c ends here */
diff --git a/apps/lib/curses/pdcurses/form/fty_regex.c b/apps/lib/curses/pdcurses/form/fty_regex.c
new file mode 100644
index 0000000..2c0a4ca
--- /dev/null
+++ b/apps/lib/curses/pdcurses/form/fty_regex.c
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * *
+ * 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. *
+ ****************************************************************************/
+
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: fty_regex.c,v 1.24 2010/01/23 21:14:37 tom Exp $")
+
+#if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */
+#include <regex.h>
+
+typedef struct
+ {
+ regex_t *pRegExp;
+ unsigned long *refCount;
+ }
+RegExp_Arg;
+
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+#undef RETURN
+static int reg_errno;
+
+static char *
+RegEx_Init(char *instring)
+{
+ reg_errno = 0;
+ return instring;
+}
+
+static char *
+RegEx_Error(int code)
+{
+ reg_errno = code;
+ return 0;
+}
+
+#define INIT register char *sp = RegEx_Init(instring);
+#define GETC() (*sp++)
+#define PEEKC() (*sp)
+#define UNGETC(c) (--sp)
+#define RETURN(c) return(c)
+#define ERROR(c) return RegEx_Error(c)
+
+#if HAVE_REGEXP_H_FUNCS
+#include <regexp.h>
+#else
+#include <regexpr.h>
+#endif
+
+typedef struct
+{
+ char *compiled_expression;
+ unsigned long *refCount;
+}
+RegExp_Arg;
+
+/* Maximum Length we allow for a compiled regular expression */
+#define MAX_RX_LEN (2048)
+#define RX_INCREMENT (256)
+
+#endif
+
+#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+# define MAYBE_UNUSED
+#else
+# define MAYBE_UNUSED GCC_UNUSED
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Generic_RegularExpression_Type(void * arg)
+|
+| Description : Allocate structure for regex type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Generic_RegularExpression_Type(void *arg MAYBE_UNUSED)
+{
+#if HAVE_REGEX_H_FUNCS
+ char *rx = (char *)arg;
+ RegExp_Arg *preg = (RegExp_Arg *)0;
+
+ if (rx)
+ {
+ preg = typeMalloc(RegExp_Arg, 1);
+
+ if (preg)
+ {
+ T((T_CREATE("RegExp_Arg %p"), (void *)preg));
+ if (((preg->pRegExp = typeMalloc(regex_t, 1)) != 0)
+ && !regcomp(preg->pRegExp, rx,
+ (REG_EXTENDED | REG_NOSUB | REG_NEWLINE)))
+ {
+ T((T_CREATE("regex_t %p"), (void *)preg->pRegExp));
+ preg->refCount = typeMalloc(unsigned long, 1);
+
+ *(preg->refCount) = 1;
+ }
+ else
+ {
+ if (preg->pRegExp)
+ free(preg->pRegExp);
+ free(preg);
+ preg = (RegExp_Arg *)0;
+ }
+ }
+ }
+ return ((void *)preg);
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ char *rx = (char *)arg;
+ RegExp_Arg *pArg = (RegExp_Arg *)0;
+
+ if (rx)
+ {
+ pArg = typeMalloc(RegExp_Arg, 1);
+
+ if (pArg)
+ {
+ int blen = RX_INCREMENT;
+
+ T((T_CREATE("RegExp_Arg %p"), pArg));
+ pArg->compiled_expression = NULL;
+ pArg->refCount = typeMalloc(unsigned long, 1);
+
+ *(pArg->refCount) = 1;
+
+ do
+ {
+ char *buf = typeMalloc(char, blen);
+
+ if (buf)
+ {
+#if HAVE_REGEXP_H_FUNCS
+ char *last_pos = compile(rx, buf, &buf[blen], '\0');
+
+#else /* HAVE_REGEXPR_H_FUNCS */
+ char *last_pos = compile(rx, buf, &buf[blen]);
+#endif
+ if (reg_errno)
+ {
+ free(buf);
+ if (reg_errno == 50)
+ blen += RX_INCREMENT;
+ else
+ {
+ free(pArg);
+ pArg = NULL;
+ break;
+ }
+ }
+ else
+ {
+ pArg->compiled_expression = buf;
+ break;
+ }
+ }
+ }
+ while (blen <= MAX_RX_LEN);
+ }
+ if (pArg && !pArg->compiled_expression)
+ {
+ free(pArg);
+ pArg = NULL;
+ }
+ }
+ return (void *)pArg;
+#else
+ return 0;
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_RegularExpression_Type(va_list * ap)
+|
+| Description : Allocate structure for regex type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *
+Make_RegularExpression_Type(va_list *ap)
+{
+ char *rx = va_arg(*ap, char *);
+
+ return Generic_RegularExpression_Type((void *)rx);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_RegularExpression_Type(
+| const void * argp)
+|
+| Description : Copy structure for regex type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *
+Copy_RegularExpression_Type(const void *argp MAYBE_UNUSED)
+{
+#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS)
+ const RegExp_Arg *ap = (const RegExp_Arg *)argp;
+ const RegExp_Arg *result = (const RegExp_Arg *)0;
+
+ if (ap)
+ {
+ *(ap->refCount) += 1;
+ result = ap;
+ }
+ return (void *)result;
+#else
+ return 0;
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_RegularExpression_Type(void * argp)
+|
+| Description : Free structure for regex type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void
+Free_RegularExpression_Type(void *argp MAYBE_UNUSED)
+{
+#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ RegExp_Arg *ap = (RegExp_Arg *)argp;
+
+ if (ap)
+ {
+ if (--(*(ap->refCount)) == 0)
+ {
+#if HAVE_REGEX_H_FUNCS
+ if (ap->pRegExp)
+ {
+ free(ap->refCount);
+ regfree(ap->pRegExp);
+ }
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ if (ap->compiled_expression)
+ {
+ free(ap->refCount);
+ free(ap->compiled_expression);
+ }
+#endif
+ free(ap);
+ }
+ }
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_RegularExpression_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid regular expression
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool
+Check_RegularExpression_Field(FIELD *field MAYBE_UNUSED,
+ const void *argp MAYBE_UNUSED)
+{
+ bool match = FALSE;
+
+#if HAVE_REGEX_H_FUNCS
+ const RegExp_Arg *ap = (const RegExp_Arg *)argp;
+
+ if (ap && ap->pRegExp)
+ match = (regexec(ap->pRegExp, field_buffer(field, 0), 0, NULL, 0)
+ ? FALSE
+ : TRUE);
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ RegExp_Arg *ap = (RegExp_Arg *)argp;
+
+ if (ap && ap->compiled_expression)
+ match = (step(field_buffer(field, 0), ap->compiled_expression)
+ ? TRUE
+ : FALSE);
+#endif
+ return match;
+}
+
+static FIELDTYPE typeREGEXP =
+{
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_RegularExpression_Type,
+ Copy_RegularExpression_Type,
+ Free_RegularExpression_Type,
+ INIT_FT_FUNC(Check_RegularExpression_Field),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+ INIT_FT_FUNC(NULL),
+#if NCURSES_INTEROP_FUNCS
+ Generic_RegularExpression_Type
+#endif
+};
+
+NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_REGEXP = &typeREGEXP;
+
+#if NCURSES_INTEROP_FUNCS
+/* The next routines are to simplify the use of ncurses from
+ programming languages with restictions on interop with C level
+ constructs (e.g. variable access or va_list + ellipsis constructs)
+*/
+NCURSES_EXPORT(FIELDTYPE *)
+_nc_TYPE_REGEXP(void)
+{
+ return TYPE_REGEXP;
+}
+#endif
+
+/* fty_regex.c ends here */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 17/20] app: curses: add menu example
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (14 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 16/20] app: pdcurses: add libform Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 18/20] app: curses: add panel example Jean-Christophe PLAGNIOL-VILLARD
` (2 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 4 ++
apps/Makefile | 1 +
| 11 ++++
apps/menu_curses/main.c | 127 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 143 insertions(+)
create mode 100644 apps/menu_curses/Makefile
create mode 100644 apps/menu_curses/main.c
diff --git a/apps/Kconfig b/apps/Kconfig
index 7c0b79e..e47f0c2 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -45,4 +45,8 @@ config APP_TEST_CURSES
bool "test curses"
select APP_LIB_CURSES
+config APP_TEST_CURSES_MENU
+ bool "test curses menu"
+ depends on APP_LIB_MENU
+
endif
diff --git a/apps/Makefile b/apps/Makefile
index 3a222d3..47938ec 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -7,6 +7,7 @@ export APP_CPPFLAGS
apps-$(CONFIG_APP_EXAMPLE) += example
apps-$(CONFIG_APP_TEST_CURSES) += test_curses
+apps-$(CONFIG_APP_TEST_CURSES_MENU) += menu_curses
$(obj)/application: $(apps-lds) $(apps-y)
--git a/apps/menu_curses/Makefile b/apps/menu_curses/Makefile
new file mode 100644
index 0000000..32c1a04
--- /dev/null
+++ b/apps/menu_curses/Makefile
@@ -0,0 +1,11 @@
+targets := menu_curses.map
+
+# Make sure files are removed during clean
+extra-y += menu_curses.map
+
+app-y += main.o
+app-final-y = menu_curses
+
+OBJCOPYFLAGS_menu_curses.app = -O binary
+LDFLAGS_apps := -Map $(obj)/menu_curses.map
+LDFLAGS_apps += -static --gc-sections
diff --git a/apps/menu_curses/main.c b/apps/menu_curses/main.c
new file mode 100644
index 0000000..5b62caa
--- /dev/null
+++ b/apps/menu_curses/main.c
@@ -0,0 +1,127 @@
+#include <string.h>
+#include <malloc.h>
+#include <curses.h>
+#include <menu.h>
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define CTRLD 4
+
+char *choices[] = {
+ "Choice 1",
+ "Choice 2",
+ "Choice 3",
+ "Choice 4",
+ "Choice 5",
+ "Choice 6",
+ "Choice 7",
+ "Choice 8",
+ "Choice 9",
+ "Choice 10",
+ "Exit",
+ (char *)NULL,
+ };
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
+
+int main(int argc, char **argv)
+{ ITEM **my_items;
+ int c;
+ MENU *my_menu;
+ WINDOW *my_menu_win;
+ int n_choices, i;
+
+ /* Initialize curses */
+ initscr();
+ start_color();
+ cbreak();
+ noecho();
+ keypad(stdscr, TRUE);
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+ init_pair(2, COLOR_CYAN, COLOR_BLACK);
+
+ /* Create items */
+ n_choices = ARRAY_SIZE(choices);
+ my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
+ for(i = 0; i < n_choices; ++i)
+ my_items[i] = new_item(choices[i], choices[i]);
+
+ /* Crate menu */
+ my_menu = new_menu((ITEM **)my_items);
+
+ /* Create the window to be associated with the menu */
+ my_menu_win = newwin(10, 40, 4, 4);
+ keypad(my_menu_win, TRUE);
+
+ /* Set main window and sub window */
+ set_menu_win(my_menu, my_menu_win);
+ set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
+ set_menu_format(my_menu, 5, 1);
+
+ /* Set menu mark to the string " * " */
+ set_menu_mark(my_menu, " * ");
+
+ /* Print a border around the main window and print a title */
+ box(my_menu_win, 0, 0);
+ print_in_middle(my_menu_win, 1, 0, 40, "My Menu", COLOR_PAIR(1));
+ mvwaddch(my_menu_win, 2, 0, ACS_LTEE);
+ mvwhline(my_menu_win, 2, 1, ACS_HLINE, 38);
+ mvwaddch(my_menu_win, 2, 39, ACS_RTEE);
+
+ /* Post the menu */
+ post_menu(my_menu);
+ wrefresh(my_menu_win);
+
+ attron(COLOR_PAIR(2));
+ mvprintw(LINES - 2, 0, "Use PageUp and PageDown to scoll down or up a page of items");
+ mvprintw(LINES - 1, 0, "Arrow Keys to navigate (F1 to Exit)");
+ attroff(COLOR_PAIR(2));
+ refresh();
+
+ while((c = wgetch(my_menu_win)) != KEY_F(1)) {
+ switch(c) {
+ case KEY_DOWN:
+ menu_driver(my_menu, REQ_DOWN_ITEM);
+ break;
+ case KEY_UP:
+ menu_driver(my_menu, REQ_UP_ITEM);
+ break;
+ case KEY_NPAGE:
+ menu_driver(my_menu, REQ_SCR_DPAGE);
+ break;
+ case KEY_PPAGE:
+ menu_driver(my_menu, REQ_SCR_UPAGE);
+ break;
+ }
+ wrefresh(my_menu_win);
+ }
+
+ /* Unpost and free all the memory taken up */
+ unpost_menu(my_menu);
+ free_menu(my_menu);
+ for(i = 0; i < n_choices; ++i)
+ free_item(my_items[i]);
+ endwin();
+ return 0;
+}
+
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
+{ int length, x, y;
+ float temp;
+
+ if(win == NULL)
+ win = stdscr;
+ getyx(win, y, x);
+ if(startx != 0)
+ x = startx;
+ if(starty != 0)
+ y = starty;
+ if(width == 0)
+ width = 80;
+
+ length = strlen(string);
+ temp = (width - length)/ 2;
+ x = startx + (int)temp;
+ wattron(win, color);
+ mvwprintw(win, y, x, "%s", string);
+ wattroff(win, color);
+ refresh();
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 18/20] app: curses: add panel example
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (15 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 17/20] app: curses: add menu example Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 19/20] app: curses: add form example Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 20/20] highbank: enable application support Jean-Christophe PLAGNIOL-VILLARD
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 4 ++
apps/Makefile | 1 +
apps/panel_curses/Makefile | 11 +++++
apps/panel_curses/main.c | 118 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+)
create mode 100644 apps/panel_curses/Makefile
create mode 100644 apps/panel_curses/main.c
diff --git a/apps/Kconfig b/apps/Kconfig
index e47f0c2..532b6fb 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -45,6 +45,10 @@ config APP_TEST_CURSES
bool "test curses"
select APP_LIB_CURSES
+config APP_TEST_CURSES_PANEL
+ bool "test curses panel"
+ depends on APP_LIB_PANEL
+
config APP_TEST_CURSES_MENU
bool "test curses menu"
depends on APP_LIB_MENU
diff --git a/apps/Makefile b/apps/Makefile
index 47938ec..a26541a 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -8,6 +8,7 @@ export APP_CPPFLAGS
apps-$(CONFIG_APP_EXAMPLE) += example
apps-$(CONFIG_APP_TEST_CURSES) += test_curses
apps-$(CONFIG_APP_TEST_CURSES_MENU) += menu_curses
+apps-$(CONFIG_APP_TEST_CURSES_PANEL) += panel_curses
$(obj)/application: $(apps-lds) $(apps-y)
diff --git a/apps/panel_curses/Makefile b/apps/panel_curses/Makefile
new file mode 100644
index 0000000..b52c808
--- /dev/null
+++ b/apps/panel_curses/Makefile
@@ -0,0 +1,11 @@
+targets := panel_curses.map
+
+# Make sure files are removed during clean
+extra-y += panel_curses.map
+
+app-y += main.o
+app-final-y = panel_curses
+
+OBJCOPYFLAGS_panel_curses.app = -O binary
+LDFLAGS_apps := -Map $(obj)/panel_curses.map
+LDFLAGS_apps += -static --gc-sections
diff --git a/apps/panel_curses/main.c b/apps/panel_curses/main.c
new file mode 100644
index 0000000..4be732f
--- /dev/null
+++ b/apps/panel_curses/main.c
@@ -0,0 +1,118 @@
+#include <panel.h>
+#include <string.h>
+
+#define NLINES 10
+#define NCOLS 40
+
+void init_wins(WINDOW **wins, int n);
+void win_show(WINDOW *win, char *label, int label_color);
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
+
+int main(int argc, char **argv)
+{ WINDOW *my_wins[3];
+ PANEL *my_panels[3];
+ PANEL *top;
+ int ch;
+
+ /* Initialize curses */
+ initscr();
+ start_color();
+ cbreak();
+ noecho();
+ keypad(stdscr, TRUE);
+
+ /* Initialize all the colors */
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+ init_pair(2, COLOR_GREEN, COLOR_BLACK);
+ init_pair(3, COLOR_BLUE, COLOR_BLACK);
+ init_pair(4, COLOR_CYAN, COLOR_BLACK);
+
+ init_wins(my_wins, 3);
+
+ /* Attach a panel to each window */ /* Order is bottom up */
+ my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
+ my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
+ my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
+
+ /* Set up the user pointers to the next panel */
+ set_panel_userptr(my_panels[0], my_panels[1]);
+ set_panel_userptr(my_panels[1], my_panels[2]);
+ set_panel_userptr(my_panels[2], my_panels[0]);
+
+ /* Update the stacking order. 2nd panel will be on top */
+ update_panels();
+
+ /* Show it on the screen */
+ attron(COLOR_PAIR(4));
+ mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");
+ attroff(COLOR_PAIR(4));
+ doupdate();
+
+ top = my_panels[2];
+ while((ch = getch()) != KEY_F(1))
+ { switch(ch)
+ { case 9:
+ top = (PANEL *)panel_userptr(top);
+ top_panel(top);
+ break;
+ }
+ update_panels();
+ doupdate();
+ }
+ endwin();
+ return 0;
+}
+
+/* Put all the windows */
+void init_wins(WINDOW **wins, int n)
+{ int x, y, i;
+ char label[80];
+
+ y = 2;
+ x = 10;
+ for(i = 0; i < n; ++i)
+ { wins[i] = newwin(NLINES, NCOLS, y, x);
+ sprintf(label, "Window Number %d", i + 1);
+ win_show(wins[i], label, i + 1);
+ y += 3;
+ x += 7;
+ }
+}
+
+/* Show the window with a border and a label */
+void win_show(WINDOW *win, char *label, int label_color)
+{ int startx, starty, height, width;
+
+ getbegyx(win, starty, startx);
+ getmaxyx(win, height, width);
+
+ box(win, 0, 0);
+ mvwaddch(win, 2, 0, ACS_LTEE);
+ mvwhline(win, 2, 1, ACS_HLINE, width - 2);
+ mvwaddch(win, 2, width - 1, ACS_RTEE);
+
+ print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
+}
+
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
+{ int length, x, y;
+ float temp;
+
+ if(win == NULL)
+ win = stdscr;
+ getyx(win, y, x);
+ if(startx != 0)
+ x = startx;
+ if(starty != 0)
+ y = starty;
+ if(width == 0)
+ width = 80;
+
+ length = strlen(string);
+ temp = (width - length)/ 2;
+ x = startx + (int)temp;
+ wattron(win, color);
+ mvwprintw(win, y, x, "%s", string);
+ wattroff(win, color);
+ refresh();
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 19/20] app: curses: add form example
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (16 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 18/20] app: curses: add panel example Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-06 9:29 ` [PATCH 20/20] highbank: enable application support Jean-Christophe PLAGNIOL-VILLARD
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
apps/Kconfig | 4 ++
apps/Makefile | 1 +
apps/form_curses/Makefile | 11 +++++
apps/form_curses/main.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 129 insertions(+)
create mode 100644 apps/form_curses/Makefile
create mode 100644 apps/form_curses/main.c
diff --git a/apps/Kconfig b/apps/Kconfig
index 532b6fb..208978b 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -53,4 +53,8 @@ config APP_TEST_CURSES_MENU
bool "test curses menu"
depends on APP_LIB_MENU
+config APP_TEST_CURSES_FORM
+ bool "test curses form"
+ depends on APP_LIB_FORM
+
endif
diff --git a/apps/Makefile b/apps/Makefile
index a26541a..f7696f0 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -9,6 +9,7 @@ apps-$(CONFIG_APP_EXAMPLE) += example
apps-$(CONFIG_APP_TEST_CURSES) += test_curses
apps-$(CONFIG_APP_TEST_CURSES_MENU) += menu_curses
apps-$(CONFIG_APP_TEST_CURSES_PANEL) += panel_curses
+apps-$(CONFIG_APP_TEST_CURSES_FORM) += form_curses
$(obj)/application: $(apps-lds) $(apps-y)
diff --git a/apps/form_curses/Makefile b/apps/form_curses/Makefile
new file mode 100644
index 0000000..9166c9d
--- /dev/null
+++ b/apps/form_curses/Makefile
@@ -0,0 +1,11 @@
+targets := form_curses.map
+
+# Make sure files are removed during clean
+extra-y += form_curses.map
+
+app-y += main.o
+app-final-y = form_curses
+
+OBJCOPYFLAGS_form_curses.app = -O binary
+LDFLAGS_apps := -Map $(obj)/form_curses.map
+LDFLAGS_apps += -static --gc-sections
diff --git a/apps/form_curses/main.c b/apps/form_curses/main.c
new file mode 100644
index 0000000..d737a20
--- /dev/null
+++ b/apps/form_curses/main.c
@@ -0,0 +1,113 @@
+#include <form.h>
+#include <string.h>
+
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
+
+int main(int argc, char **argv)
+{
+ FIELD *field[3];
+ FORM *my_form;
+ WINDOW *my_form_win;
+ int ch, rows, cols;
+
+ /* Initialize curses */
+ initscr();
+ start_color();
+ cbreak();
+ noecho();
+ keypad(stdscr, TRUE);
+
+ /* Initialize few color pairs */
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+
+ /* Initialize the fields */
+ field[0] = new_field(1, 10, 6, 1, 0, 0);
+ field[1] = new_field(1, 10, 8, 1, 0, 0);
+ field[2] = NULL;
+
+ /* Set field options */
+ set_field_back(field[0], A_UNDERLINE);
+ field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */
+ /* Field is filled up */
+ set_field_back(field[1], A_UNDERLINE);
+ field_opts_off(field[1], O_AUTOSKIP);
+
+ /* Create the form and post it */
+ my_form = new_form(field);
+
+ /* Calculate the area required for the form */
+ scale_form(my_form, &rows, &cols);
+
+ /* Create the window to be associated with the form */
+ my_form_win = newwin(rows + 4, cols + 4, 4, 4);
+ keypad(my_form_win, TRUE);
+
+ /* Set main window and sub window */
+ set_form_win(my_form, my_form_win);
+ set_form_sub(my_form, derwin(my_form_win, rows, cols, 2, 2));
+
+ /* Print a border around the main window and print a title */
+ box(my_form_win, 0, 0);
+ print_in_middle(my_form_win, 1, 0, cols + 4, "My Form", COLOR_PAIR(1));
+
+ post_form(my_form);
+ wrefresh(my_form_win);
+
+ mvprintw(LINES - 2, 0, "Use UP, DOWN arrow keys to switch between fields");
+ refresh();
+
+ /* Loop through to get user requests */
+ while((ch = wgetch(my_form_win)) != KEY_F(1))
+ { switch(ch)
+ { case KEY_DOWN:
+ /* Go to next field */
+ form_driver(my_form, REQ_NEXT_FIELD);
+ /* Go to the end of the present buffer */
+ /* Leaves nicely at the last character */
+ form_driver(my_form, REQ_END_LINE);
+ break;
+ case KEY_UP:
+ /* Go to previous field */
+ form_driver(my_form, REQ_PREV_FIELD);
+ form_driver(my_form, REQ_END_LINE);
+ break;
+ default:
+ /* If this is a normal character, it gets */
+ /* Printed */
+ form_driver(my_form, ch);
+ break;
+ }
+ }
+
+ /* Un post form and free the memory */
+ unpost_form(my_form);
+ free_form(my_form);
+ free_field(field[0]);
+ free_field(field[1]);
+
+ endwin();
+ return 0;
+}
+
+void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
+{ int length, x, y;
+ float temp;
+
+ if(win == NULL)
+ win = stdscr;
+ getyx(win, y, x);
+ if(startx != 0)
+ x = startx;
+ if(starty != 0)
+ y = starty;
+ if(width == 0)
+ width = 80;
+
+ length = strlen(string);
+ temp = (width - length)/ 2;
+ x = startx + (int)temp;
+ wattron(win, color);
+ mvwprintw(win, y, x, "%s", string);
+ wattroff(win, color);
+ refresh();
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 20/20] highbank: enable application support
2013-03-06 9:29 ` [PATCH 01/20] Makefile: x_flags prepare for apps support Jean-Christophe PLAGNIOL-VILLARD
` (17 preceding siblings ...)
2013-03-06 9:29 ` [PATCH 19/20] app: curses: add form example Jean-Christophe PLAGNIOL-VILLARD
@ 2013-03-06 9:29 ` Jean-Christophe PLAGNIOL-VILLARD
18 siblings, 0 replies; 31+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-03-06 9:29 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/configs/highbank_defconfig | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/highbank_defconfig b/arch/arm/configs/highbank_defconfig
index b034ed1..5776c68 100644
--- a/arch/arm/configs/highbank_defconfig
+++ b/arch/arm/configs/highbank_defconfig
@@ -4,15 +4,16 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_PBL_IMAGE=y
CONFIG_MMU=y
CONFIG_MALLOC_SIZE=0xa00000
+CONFIG_EXPERIMENTAL=y
CONFIG_MALLOC_TLSF=y
CONFIG_PROMPT="vexpress: "
CONFIG_LONGHELP=y
-CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
-CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_PARTITION_DISK_EFI=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/highbank/env"
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
@@ -23,10 +24,16 @@ CONFIG_CMD_READLINE=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_PASSWD=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_READLINK=y
CONFIG_CMD_TFTP=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_APPINFO=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
CONFIG_CMD_BOOTM_INITRD=y
@@ -60,3 +67,13 @@ CONFIG_GPIO_PL061=y
CONFIG_FS_TFTP=y
CONFIG_SHA1=y
CONFIG_SHA256=y
+CONFIG_APPLICATIONS=y
+CONFIG_APP_LIB_PANEL=y
+CONFIG_APP_LIB_MENU=y
+CONFIG_APP_LIB_FORM=y
+CONFIG_APP_TEXT_BASE_OFFSET=0x1000000
+CONFIG_APP_EXAMPLE=y
+CONFIG_APP_TEST_CURSES=y
+CONFIG_APP_TEST_CURSES_PANEL=y
+CONFIG_APP_TEST_CURSES_MENU=y
+CONFIG_APP_TEST_CURSES_FORM=y
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 31+ messages in thread