diff --git a/.gitignore b/.gitignore index 6c2c2b0f..3318a27f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/post-install.sh + ################# ## Eclipse ################# @@ -217,10 +219,6 @@ pip-log.txt Makefile Makefile.in -LCDd -lcdproc -lcdexec -lcdvc Doxyfile aclocal.m4 autom4te.cache diff --git a/Makefile.am b/Makefile.am index 85ddf89e..a4df5a90 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,7 +9,6 @@ sysconf_DATA = LCDd.conf EXTRA_DIST = $(sysconf_DATA) CREDITS.md contrib - dist-hook: rm -rf `find $(distdir)/contrib -name CVS` diff --git a/clients/lcdexec/.cvsignore b/clients/lcdexec/.cvsignore deleted file mode 100644 index 5b403431..00000000 --- a/clients/lcdexec/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -.deps -Makefile -Makefile.in -lcdexec diff --git a/clients/lcdexec/.gitignore b/clients/lcdexec/.gitignore new file mode 100644 index 00000000..9c82a77d --- /dev/null +++ b/clients/lcdexec/.gitignore @@ -0,0 +1,8 @@ +.deps +Makefile +Makefile.in +lcdexec +elektragen.c +elektragen.h +lcdexec.mount.sh +lcdexec.spec.eqd diff --git a/clients/lcdexec/Makefile.am b/clients/lcdexec/Makefile.am index e405c390..e89c2487 100644 --- a/clients/lcdexec/Makefile.am +++ b/clients/lcdexec/Makefile.am @@ -3,14 +3,29 @@ sysconf_DATA = lcdexec.conf bin_PROGRAMS = lcdexec +bin_SCRIPTS = lcdexec-setup lcdexec_SOURCES = lcdexec.c menu.c menu.h +nodist_lcdexec_SOURCES = elektragen.c elektragen.h +lcdexec.$(OBJEXT): elektragen.c elektragen.h +BUILT_SOURCES= elektragen.c elektragen.h + +CLEANFILES = elektragen.c elektragen.h lcdexec.spec.eqd lcdexec.mount.sh lcdexec_LDADD = ../../shared/libLCDstuff.a AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -DPIDFILEDIR=\"$(pidfiledir)\" - EXTRA_DIST = $(sysconf_DATA) +scriptsdir = $(prefix)/libexec +scripts_DATA = lcdexec.mount.sh + +specdir = $(prefix)/share/lcdproc +spec_DATA = lcdexec.spec.eqd + +KDB ?= kdb +elektragen.c elektragen.h lcdexec.spec.eqd lcdexec.mount.sh: specification/lcdexec-spec.ini + $(KDB) gen -F ni=specification/lcdexec-spec.ini highlevel "spec/sw/lcdproc/lcdexec/#0/current" elektragen initFn=loadConfiguration helpFn=printHelpMessage embeddedSpec=defaults headers=menu.h tagPrefix=CONF_; mv elektragen.mount.sh lcdexec.mount.sh; mv elektragen.spec.eqd lcdexec.spec.eqd + ## EOF diff --git a/clients/lcdexec/lcdexec-setup b/clients/lcdexec/lcdexec-setup new file mode 100755 index 00000000..2d56a114 --- /dev/null +++ b/clients/lcdexec/lcdexec-setup @@ -0,0 +1,1000 @@ +#!/bin/sh + +VERBOSE=${VERBOSE:-0} +BACKUP="$(mktemp)" + +usage() { + echo "lcdexec-setup [-v] [...]" >&2 + echo "" >&2 + echo "-v Log what is happening to the KDB to stderr." >&2 + echo "" >&2 + echo " menu - to create a new menu" >&2 + echo " command - to create a new command" >&2 + echo " param - to create a new parameter" >&2 + echo " help - to display more help" >&2 + echo " delete - delete a menu/command/parameter" >&2 + echo "[...]" >&2 + echo " Use 'lcdexec-setup help ' to show available values." >&2 + echo " For paramters 'lcdexec-setup help param ' shows even more info." >&2 +} + +usage_menu() { + echo "lcdexec-setup menu [...]" >&2 + echo "" >&2 + echo " The display name for the menu." >&2 + echo "" >&2 + echo " Each is either a reference to a command or a menu." >&2 + echo " Command entries are of the form 'command/#', menu entries 'menu/#'." >&2 +} + +usage_command() { + echo "lcdexec-setup command [-d ] [-f] [...]" >&2 + echo "" >&2 + echo " What the command should do." >&2 + echo "-d The display name for the command." >&2 + echo "-f Set to enable feedback." >&2 + echo "" >&2 + echo " Each is a reference to a parameter." >&2 + echo " All references must be of the form '/#'," >&2 + echo " where is one of the parameter types:" >&2 + echo " alpha, checkbox, ip, numeric, ring, slider" >&2 +} + +usage_param() { + echo "lcdexec-setup param [-d ] [...]" >&2 + echo "" >&2 + echo " One of: alpha, checkbox, ip, numeric, ring, slider" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "[...]" >&2 + echo " Depends on " >&2 + echo " For more info use 'lcdexec-setup help param '" >&2 + echo " where is one of: alpha, checkbox, ip, numeric, ring, slider" >&2 +} + +usage_param_alpha() { + echo "lcdexec-setup param alpha [-d ] [-i ] [-a ] [-m ] [-M ]" >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i The initial value of the parameter." >&2 + echo "-a The set of allowed characters. Any character in the string" >&2 + echo " will be allowed." >&2 + echo "-m (integer) The minimum length." >&2 + echo "-M (integer) The maximum length." >&2 +} + +usage_param_checkbox() { + echo "lcdexec-setup param checkbox [-d ] [-i (on|off|gray)] [-y ] [-n ] [-g []]" >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i (on|off|gray) The initial value of the checkbox. One of: on, off, gray" >&2 + echo "-y Changes the text to display, when in the 'on' state." >&2 + echo "-n Changes the text to display, when in the 'gray' state." >&2 + echo "-g [] Enables the third 'gray' state of the checkbox, and" >&2 + echo " optionally sets the text to display in that state." >&2 +} + +usage_param_ip() { + echo "lcdexec-setup param ip [-d ] [-i ] [-6]" >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i The initial value of the parameter." >&2 + echo "-6 Enables IPv6 mode." >&2 +} + +usage_param_numeric() { + echo "lcdexec-setup param numeric [-d ] [-i ] [-m ] [-M ]" >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i (integer) The initial value of the parameter." >&2 + echo "-m (integer) The minimum value." >&2 + echo "-M (integer) The maximum value." >&2 +} + +usage_param_ring() { + echo "lcdexec-setup param ring [-d ] [-i ] ..." >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i (integer) The initial value of the parameter. This is an" >&2 + echo " index (zero-based) NOT the initial string value." >&2 + echo "... The set of strings that can be chosen from." >&2 +} + +usage_param_slider() { + echo "lcdexec-setup param slider [-d ] [-i ] [-m ] [-M ] [-s ] [-t ] [-T ]" >&2 + echo "" >&2 + echo " The environment variable the parameter uses." >&2 + echo "-d The display name for the parameter." >&2 + echo "-i (integer) The initial value of the parameter." >&2 + echo "-m (integer) The minimum value." >&2 + echo "-M (integer) The maximum value." >&2 + echo "-s (integer) The step size." >&2 + echo "-t The text to display instead of the minimum value." >&2 + echo "-T The text to display instead of the maximum value." >&2 +} + +usage_delete() { + echo "lcdexec-setup delete (menu|command|param/) " >&2 + echo "" >&2 + echo "Delete a menu/command/parameter and move other entries in the array" >&2 + echo "to keep it continuous." >&2 + echo "" >&2 + echo " What kind of parameter should be deleted?" >&2 + echo " One of: alpha, checkbox, ip, numeric, ring, slider" >&2 + echo " Index of the entry to delete." >&2 +} + +show_help() { + if [ "$#" -lt 1 ]; then + usage + return + fi + + case "$1" in + menu) + usage_menu + ;; + command) + usage_command + ;; + param) + case "$2" in + alpha) + usage_param_alpha + ;; + checkbox) + usage_param_checkbox + ;; + ip) + usage_param_ip + ;; + numeric) + usage_param_numeric + ;; + ring) + usage_param_ring + ;; + slider) + usage_param_slider + ;; + *) + usage_param + + if [ -n "$2" ]; then + exit 1 + fi + ;; + esac + ;; + help) + usage + ;; + delete) + usage_delete + ;; + *) + usage + exit 1 + ;; + esac +} + +BASE_KEY="/sw/lcdproc/lcdexec/#0/current/menu" +if [ "$(id -u)" = "0" ]; then + NAMESPACE="system" +else + NAMESPACE="user" +fi + +log() { + [ "$VERBOSE" = "1" ] && echo "$@" +} + +run_kdb() { + log "$ kdb $*" >&2 + kdb "$@" + rc=$? + if [ "$rc" != "0" ]; then + exit_error "FAILED ($rc): kdb $*" + fi +} + +kdb_set() { + run_kdb set -N "$NAMESPACE" "$BASE_KEY/$1" "$2" +} + +kdb_setmeta() { + run_kdb setmeta "$NAMESPACE$BASE_KEY/$1" "$2" "$3" +} + +kdb_rm_r() { + run_kdb rm -r "$NAMESPACE$BASE_KEY/$1" +} + +kdb_exists() { + [ -n "$(run_kdb ls "$NAMESPACE$BASE_KEY/$1")" ] +} + +kdb_array_last() { + kdb getmeta "$BASE_KEY/$1" array 2>/dev/null +} + +kdb_export() { + run_kdb export "$NAMESPACE$BASE_KEY/$1" ni | grep -v '^ internal/' +} + +kdb_import() { + run_kdb import "$NAMESPACE$BASE_KEY/$1" ni +} + +elektra_index() { + echo "$1" | awk '{ i=$0; gsub(".", "_", i); printf("#%s%s", substr(i, 2), $0) }' +} + +prev_index() { + last="$(kdb_array_last "$1")" + last="${last#\#}" + last="${last##*_}" + if [ -z "$last" ] || [ "$last" -eq 0 ]; then + printf "" + else + elektra_index $((last - 1)) + fi +} + +next_index() { + last="$(kdb_array_last "$1")" + last="${last#\#}" + last="${last##*_}" + if [ -z "$last" ]; then + printf "#0" + else + elektra_index $((last + 1)) + fi +} + +exit_error() { + echo "ERROR: $1" >&2 + cleanup 1 + exit 1 +} + +backup() { + kdb_export "" >"$BACKUP" +} + +restore() { + kdb rm -r "$NAMESPACE$BASE_KEY" + kdb import "$NAMESPACE$BASE_KEY" ni <"$BACKUP" +} + +cleanup() { + rc=$1 + shift + + if [ "$rc" != "0" ]; then + if [ "$#" -gt 0 ]; then + log "-- FAILED ($rc): $*" + fi + log "-- Restoring backup $BACKUP" + restore + fi +} + +# create_menu [...] +create_menu() { + if [ -z "$1" ]; then + usage_menu + exit 1 + fi + + name="$1" + shift + + for entry in "$@"; do + if ! echo "$entry" | grep -Eq '(menu|command)/#_*[0-9]+'; then + exit_error "not a valid menu entry: $entry" + fi + done + + index="$(next_index "menu")" + menu="menu/$index" + kdb_setmeta "menu" "array" "$index" + kdb_set "$menu/displayname" "$name" + + if [ "$#" -gt 0 ]; then + count="$#" + kdb_setmeta "$menu/entries" "array" "$(elektra_index $((count - 1)))" + index=0 + for entry in "$@"; do + kdb_set "$menu/entries/$(elektra_index "$index")" "@/menu/$entry" + index=$((index + 1)) + done + fi +} + +# create_command [-d ] [-f] [...] +create_command() { + if [ -z "$1" ]; then + usage_command + exit 1 + fi + + exec_cmd="$1" + shift + + OPTIND=1 + while getopts ":fd:" o; do + case "$o" in + f) + feedback=1 + ;; + d) + name="$OPTARG" + ;; + *) + usage_command + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + for param in "$@"; do + if ! echo "$param" | grep -Eq '(alpha|checkbox|ip|numeric|ring|slider)/#_*[0-9]+'; then + exit_error "not a valid parameter: $param" + fi + done + + index="$(next_index "command")" + cmd="command/$index" + kdb_setmeta "command" "array" "$index" + kdb_set "$cmd/exec" "$exec_cmd" + + if [ -n "$name" ]; then + kdb_set "$cmd/displayname" "$name" + fi + + if [ "$feedback" = "1" ]; then + kdb_set "$cmd/feedback" "1" + fi + + if [ "$#" -gt 0 ]; then + count="$#" + kdb_setmeta "$cmd/parameters" "array" "$(elektra_index $((count - 1)))" + index=0 + for param in "$@"; do + kdb_set "$cmd/parameters/$(elektra_index "$index")" "@/menu/parameter/$param" + index=$((index + 1)) + done + fi +} + +# create_param [-d ] [...] +create_param() { + if [ "$#" -lt 1 ]; then + usage_param + exit 1 + fi + + type="$1" + shift + + case "$type" in + alpha) + create_param_alpha "$@" + ;; + checkbox) + create_param_checkbox "$@" + ;; + ip) + create_param_ip "$@" + ;; + numeric) + create_param_numeric "$@" + ;; + ring) + create_param_ring "$@" + ;; + slider) + create_param_slider "$@" + ;; + *) + usage_param + exit 1 + ;; + esac +} + +# create_param_alpha [-d ] [-i ] [-a ] [-m ] [-M ] +create_param_alpha() { + if [ "$#" -lt 1 ]; then + usage_param_alpha + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:a:m:M:" o; do + case "$o" in + i) + i=1 + initial="$OPTARG" + ;; + a) + a=1 + allowed="$OPTARG" + ;; + m) + m=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "min must be an integer not: $OPTARG" + fi + if [ "$OPTARG" -lt 0 ] 2>/dev/null; then + exit_error "min must be positive: $OPTARG" + fi + min="$OPTARG" + ;; + M) + M=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "max must be an integer not: $OPTARG" + fi + if [ "$OPTARG" -lt 0 ] 2>/dev/null; then + exit_error "max must be positive: $OPTARG" + fi + max="$OPTARG" + ;; + d) + d=1 + name="$OPTARG" + ;; + *) + usage_param_alpha + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ -n "$1" ]; then + exit_error "unknown argument: $1" + fi + + if ! echo "$initial" | grep -qE "^[${allowed:-ABCDEFGHIJKLMNOPQRSTUVWXYZ}]{${min:-0},${max:-100}}$"; then + exit_error "invalid initial value: $initial" + fi + + index="$(next_index "parameter/alpha")" + param="parameter/alpha/$index" + kdb_setmeta "parameter/alpha" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + [ -n "$a" ] && kdb_set "$param/allowed" "$allowed" + [ -n "$m" ] && kdb_set "$param/minlength" "$min" + [ -n "$M" ] && kdb_set "$param/maxlength" "$max" +} + +# create_param_checkbox [-d ] [-i (on|off|gray)] [-y ] [-n ] [-g []] +create_param_checkbox() { + if [ "$#" -lt 1 ]; then + usage_param_checkbox + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:y:n:g:" o; do + case "$o" in + i) + i=1 + if [ "$OPTARG" != "on" ] && [ "$OPTARG" != "off" ] && [ "$OPTARG" != "gray" ]; then + exit_error "illegal initial value: $OPTARG (allowed: on, off, gray)" + fi + initial="$OPTARG" + ;; + y) + y=1 + ontext="$OPTARG" + ;; + n) + n=1 + offtext="$OPTARG" + ;; + g) + g=1 + gray=1 + graytext="$OPTARG" + ;; + d) + d=1 + name="$OPTARG" + ;; + :) + if [ "$OPTARG" = "g" ]; then + g=1 + else + usage_param_checkbox + exit 1 + fi + ;; + *) + usage_param_checkbox + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ -n "$1" ]; then + exit_error "unknown argument $1" + fi + + if [ "$initial" = "gray" ] && [ -z "$g" ]; then + exit_error "initial value 'gray' only allowed with -g" + fi + + index="$(next_index "parameter/checkbox")" + param="parameter/checkbox/$index" + kdb_setmeta "parameter/checkbox" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + [ -n "$y" ] && kdb_set "$param/ontext" "$ontext" + [ -n "$n" ] && kdb_set "$param/offtext" "$offtext" + [ -n "$g" ] && kdb_set "$param/allowgray" "1" + [ -n "$gray" ] && kdb_set "$param/graytext" "$graytext" +} + +# create_param_ip [-d ] [-i ] [-6] +create_param_ip() { + if [ "$#" -lt 1 ]; then + usage_param_ip + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:6" o; do + case "$o" in + i) + i=1 + initial="$OPTARG" + ;; + 6) + v6=1 + ;; + d) + d=1 + name="$OPTARG" + ;; + *) + usage_param_ip + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ -n "$1" ]; then + exit_error "unknown argument $1" + fi + + index="$(next_index "parameter/ip")" + param="parameter/ip/$index" + kdb_setmeta "parameter/ip" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + [ -n "$v6" ] && kdb_set "$param/v6" "1" +} + +# create_param_numeric [-d ] [-i ] [-m ] [-M ] +create_param_numeric() { + if [ "$#" -lt 1 ]; then + usage_param_numeric + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:m:M:" o; do + case "$o" in + i) + i=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "initial must be an integer not: $OPTARG" + fi + initial="$OPTARG" + ;; + m) + m=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "min must be an integer not: $OPTARG" + fi + min="$OPTARG" + ;; + M) + M=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "max must be an integer not: $OPTARG" + fi + max="$OPTARG" + ;; + d) + d=1 + name="$OPTARG" + ;; + *) + usage_param_numeric + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ -n "$1" ]; then + exit_error "unknown argument $1" + fi + + _min=${min:-0} + _max=${max:-0} + _initial=${initial:-0} + + if [ "$_initial" -lt "$_min" ] || [ "$_initial" -gt "$_max" ]; then + exit_error "initial value out of range: $_initial (min: $_min, max: $_max)" + fi + + index="$(next_index "parameter/numeric")" + param="parameter/numeric/$index" + kdb_setmeta "parameter/numeric" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + [ -n "$m" ] && kdb_set "$param/minvalue" "$min" + [ -n "$M" ] && kdb_set "$param/maxvalue" "$max" +} + +# create_param_ring [-d ] [-i ] ... +create_param_ring() { + if [ "$#" -lt 1 ]; then + usage_param_ring + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:" o; do + case "$o" in + i) + i=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "initial must be an integer not: $OPTARG" + fi + if [ "$OPTARG" -lt 0 ] 2>/dev/null; then + exit_error "initial must be positive: $OPTARG" + fi + initial="$OPTARG" + ;; + d) + d=1 + name="$OPTARG" + ;; + *) + usage_param_ring + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + count="$#" + if [ "$count" -lt 1 ]; then + exit_error "at least one string required" + fi + + if [ "$initial" -ge "$count" ]; then + exit_error "initial value out of range: $initial (max: $((count - 1)))" + fi + + index="$(next_index "parameter/ring")" + param="parameter/ring/$index" + kdb_setmeta "parameter/ring" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + + if [ "$count" -gt 0 ]; then + kdb_setmeta "$param/strings" "array" "$(elektra_index $((count - 1)))" + index=0 + for string in "$@"; do + kdb_set "$param/strings/$(elektra_index "$index")" "$string" + index=$((index + 1)) + done + fi +} + +# create_param_slider [-d ] [-i ] [-m ] [-M ] [-s ] [-t ] [-T ] +create_param_slider() { + if [ "$#" -lt 1 ]; then + usage_param_slider + exit 1 + fi + + envname="$1" + shift + + OPTIND=1 + while getopts ":d:i:m:M:s:t:T:" o; do + case "$o" in + i) + i=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "initial must be an integer not: $OPTARG" + fi + initial="$OPTARG" + ;; + m) + m=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "min must be an integer not: $OPTARG" + fi + min="$OPTARG" + ;; + M) + M=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "max must be an integer not: $OPTARG" + fi + max="$OPTARG" + ;; + s) + s=1 + if ! [ "$OPTARG" -eq "$OPTARG" ] 2>/dev/null; then + exit_error "step must be an integer not: $OPTARG" + fi + step="$OPTARG" + ;; + t) + t=1 + min_text="$OPTARG" + ;; + T) + T=1 + max_text="$OPTARG" + ;; + d) + d=1 + name="$OPTARG" + ;; + *) + usage_param_slider + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ -n "$1" ]; then + exit_error "unknown argument $1" + fi + + _min=${min:-0} + _max=${max:-1000} + _step=${step:-1} + _initial=${step:-0} + + if [ "$_min" -ge "$_max" ]; then + exit_error "min must be less than max: $_min >= $_max" + fi + + if [ "$_step" -le 0 ]; then + exit_error "step must be positive (non-zero): $_step" + fi + + if [ "$_step" -gt "$((_max - _min))" ]; then + exit_error "step must not be greater than (max - min): $_step > ($_max - $_min) = $((_max - _min))" + fi + + if [ "$_initial" -lt "$_min" ] || [ "$_initial" -gt "$_max" ]; then + exit_error "initial value out of range: $_initial (min: $_min, max: $_max)" + fi + + index="$(next_index "parameter/slider")" + param="parameter/slider/$index" + kdb_setmeta "parameter/slider" "array" "$index" + kdb_set "$param/envname" "$envname" + [ -n "$d" ] && kdb_set "$param/displayname" "$name" + [ -n "$i" ] && kdb_set "$param/value" "$initial" + [ -n "$m" ] && kdb_set "$param/minvalue" "$min" + [ -n "$M" ] && kdb_set "$param/maxvalue" "$max" + [ -n "$s" ] && kdb_set "$param/stepsize" "$step" + [ -n "$t" ] && kdb_set "$param/mintext" "$min_text" + [ -n "$T" ] && kdb_set "$param/maxtext" "$max_text" +} + +# delete_entry (menu|command|param/) +delete_entry() { + if [ "$#" -lt 2 ]; then + usage_delete + exit 1 + fi + + index="$2" + + case "$1" in + menu) + array="menu" + ;; + command) + array="command" + ;; + param/alpha) + array="parameter/alpha" + ;; + param/checkbox) + array="parameter/checkbox" + ;; + param/ip) + array="parameter/ip" + ;; + param/numeric) + array="parameter/numeric" + ;; + param/ring) + array="parameter/ring" + ;; + param/slider) + array="parameter/slider" + ;; + *) + usage_delete + exit 1 + ;; + esac + + entry="$array/$(elektra_index "$index")" + + if ! kdb_exists "$entry"; then + exit_error "$entry doesn't exist" + fi + + kdb_rm_r "$entry" + + new_last="$(prev_index "$array")" + kdb_setmeta "$array" "array" "$new_last" + + if [ -z "$new_last" ]; then + return + fi + + tmp_file="$(mktemp)" + + kdb_export "$array" >"$tmp_file" + kdb_rm_r "$array" + + mawk -v idx="$index" -F '[/ \]]' ' + /^#_*[0-9]+/ { + n = $1 + sub("^#_*", "", n) + + if (n > idx) { + m = n - 1 + + p = $1 + sub("[0-9]+$", "", p) + + if (length(m) < length(n)) { + p = substr(p, 0, length(p) - 1) + } + + s = $0 + sub("^#_*[0-9]+", "", s) + print p m s + + next + } + } + + /^\[#_*[0-9]+/ { + n = $1 + sub("^\[#_*", "", n) + + if (n > idx) { + m = n - 1 + + p = $1 + sub("[0-9]+$", "", p) + + if (length(m) < length(n)) { + p = substr(p, 0, length(p) - 1) + } + + s = $0 + sub("^\[#_*[0-9]+", "", s) + print p m s + + next + } + } + + { print } + ' "$tmp_file" | kdb_import "$array" + + rm "$tmp_file" +} + +# main [...] +main() { + if [ "$#" -lt 1 ]; then + usage + exit 1 + fi + + OPTIND=1 + while getopts ":v" o; do + case "$o" in + v) + VERBOSE=1 + ;; + *) + usage + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + if [ "$#" -lt 1 ]; then + usage + exit 1 + fi + + type="$1" + shift + + log "-- Creating backup $BACKUP" + backup + + case "$type" in + menu) + create_menu "$@" + ;; + command) + create_command "$@" + ;; + param) + create_param "$@" + ;; + help) + show_help "$@" + ;; + delete) + delete_entry "$@" + ;; + *) + usage + exit 1 + ;; + esac + + log "-- SUCCESS: removing backup $BACKUP" +} + +main "$@" diff --git a/clients/lcdexec/lcdexec.c b/clients/lcdexec/lcdexec.c index ff905a56..8b184b77 100644 --- a/clients/lcdexec/lcdexec.c +++ b/clients/lcdexec/lcdexec.c @@ -26,11 +26,11 @@ #include "shared/str.h" #include "shared/report.h" -#include "shared/configfile.h" #include "shared/sockets.h" #include "menu.h" +#include "elektragen.h" #if !defined(SYSCONFDIR) # define SYSCONFDIR "/etc" @@ -46,7 +46,7 @@ /** information about a process started by lcdexec */ typedef struct ProcInfo { struct ProcInfo *next; /**< pointer to the next ProcInfo entry */ - const MenuEntry *cmd; /**< pointer to the corresponding menu entry */ + const Command *cmd; /**< pointer to the corresponding menu entry */ pid_t pid; /**< PID the process was started with */ time_t starttime; /**< start time of the process */ time_t endtime; /**< finishing time of the process */ @@ -56,21 +56,12 @@ typedef struct ProcInfo { } ProcInfo; -char * help_text = +char * help_prefix = "lcdexec - LCDproc client to execute commands from the LCDd menu\n" "\n" "Copyright (c) 2002, Joris Robijn, 2006-2008 Peter Marschall.\n" "This program is released under the terms of the GNU General Public License.\n" -"\n" -"Usage: lcdexec []\n" -" where are:\n" -" -c Specify configuration file ["DEFAULT_CONFIGFILE"]\n" -" -a
DNS name or IP address of the LCDd server [localhost]\n" -" -p port of the LCDd server [13666]\n" -" -f Run in foreground\n" -" -r Set reporting level (0-5) [2: errors and warnings]\n" -" -s <0|1> Report to syslog (1) or stderr (0, default)\n" -" -h Show this help\n"; +"\n"; char *progname = "lcdexec"; @@ -89,7 +80,7 @@ char *displayname = NULL; char *default_shell = NULL; /* Other global variables */ -MenuEntry *main_menu = NULL; /**< pointer to the main menu */ +Menu *main_menu = NULL; /**< pointer to the main menu */ ProcInfo *proc_queue = NULL; /**< pointer to the list of executed processes */ int lcd_wid = 0; /**< LCD display width reported by the server */ @@ -103,11 +94,10 @@ int Quit = 0; /**< indicate end of main loop */ /* Function prototypes */ static void exit_program(int val); static void sigchld_handler(int signal); -static int process_command_line(int argc, char **argv); -static int process_configfile(char * configfile); +static int process_config(); static int connect_and_setup(void); static int process_response(char *str); -static int exec_command(MenuEntry *cmd); +static int exec_command(Command *cmd); static int show_procinfo_msg(ProcInfo *p); static int main_loop(void); @@ -116,15 +106,12 @@ static int main_loop(void); #define CHAIN_END(e) { if (e<0) { report(RPT_CRIT,"Critical error, abort"); exit(e); }} -int main(int argc, char **argv) +int main(int argc, const char **argv) { int error = 0; struct sigaction sa; - CHAIN(error, process_command_line(argc, argv)); - if (configfile == NULL) - configfile = DEFAULT_CONFIGFILE; - CHAIN(error, process_configfile(configfile)); + CHAIN(error, process_config()); if (report_dest == UNSET_INT || report_level == UNSET_INT) { report_dest = RPT_DEST_STDERR; @@ -214,136 +201,60 @@ static void sigchld_handler(int signal) } } - -static int process_command_line(int argc, char **argv) +static void on_fatal_error(ElektraError * error) // TODO: finalize method { - int c; - int error = 0; - - /* No error output from getopt */ - opterr = 0; - - while ((c = getopt(argc, argv, "c:a:p:fr:s:h")) > 0) { - char *end; - int temp_int; - - switch(c) { - case 'c': - configfile = strdup(optarg); - break; - case 'a': - address = strdup(optarg); - break; - case 'p': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && - (temp_int > 0) && (temp_int <= 0xFFFF)) { - port = temp_int; - } else { - report(RPT_ERR, "Illegal port value %s", optarg); - error = -1; - } - break; - case 'f': - foreground = TRUE; - break; - case 'r': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) { - report_level = temp_int; - } else { - report(RPT_ERR, "Illegal report level value %s", optarg); - error = -1; - } - break; - case 's': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) { - report_dest = (temp_int ? RPT_DEST_SYSLOG : RPT_DEST_STDERR); - } else { - report(RPT_ERR, "Illegal log destination value %s", optarg); - error = -1; - } - break; - case 'h': - fprintf(stderr, "%s", help_text); - exit(EXIT_SUCCESS); - /* NOTREACHED */ - case ':': - report(RPT_ERR, "Missing option argument for %c", optopt); - error = -1; - break; - case '?': - default: - report(RPT_ERR, "Unknown option: %c", optopt); - error = -1; - break; - } - } - return error; + fprintf(stderr, "ERROR: %s\n", elektraErrorDescription(error)); + exit(EXIT_FAILURE); } - -static int process_configfile(char *configfile) +static int process_config() { - const char *tmp; - - if (configfile == NULL) - configfile = DEFAULT_CONFIGFILE; - - if (config_read_file(configfile) < 0) { - report(RPT_WARNING, "Could not read config file: %s", configfile); + ElektraError * error = NULL; + Elektra * elektra; + int rc = loadConfiguration(&elektra, &error); + + if (rc == -1) + { + fprintf(stderr, "An error occurred while initializing elektra: %s\n", elektraErrorDescription(error)); + elektraErrorReset(&error); + return -1; } - if (address == NULL) { - address = strdup(config_get_string(progname, "Address", 0, "localhost")); - } - if (port == UNSET_INT) { - port = config_get_int(progname, "Port", 0, 13666); - } - if (report_level == UNSET_INT) { - report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING); - } - if (report_dest == UNSET_INT) { - report_dest = (config_get_bool(progname, "ReportToSyslog", 0, 0)) - ? RPT_DEST_SYSLOG - : RPT_DEST_STDERR; - } - if (foreground != TRUE) { - foreground = config_get_bool(progname, "Foreground", 0, FALSE); - } - if (pidfile == NULL) { - pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE)); + if (rc == 1) + { + // help mode + printHelpMessage(elektra, NULL, help_prefix); + elektraClose (elektra); + exit(EXIT_SUCCESS); } - if ((tmp = config_get_string(progname, "DisplayName", 0, NULL)) != NULL) - displayname = strdup(tmp); + elektraFatalErrorHandler(elektra, on_fatal_error); - /* try to find a shell that understands the -c COMMAND syntax */ - if ((tmp = config_get_string(progname, "Shell", 0, NULL)) != NULL) - default_shell = strdup(tmp); - else { - /* 1st fallback: SHELL environment variable */ - report(RPT_WARNING, "Shell not set in configuration, falling back to variable SHELL"); - default_shell = getenv("SHELL"); - - /* 2nd fallback: /bin/sh */ - if (default_shell == NULL) { - report(RPT_WARNING, "variable SHELL not set, falling back to /bin/sh"); - default_shell = "/bin/sh"; - } - } + address = strdup(elektraGet(elektra, CONF_LCDEXEC_ADDRESS)); + port = elektraGet(elektra, CONF_LCDEXEC_PORT); + report_level = elektraGet(elektra, CONF_LCDEXEC_REPORTLEVEL); + report_dest = elektraGet(elektra, CONF_LCDEXEC_REPORTTOSYSLOG) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; + foreground = elektraGet(elektra, CONF_LCDEXEC_FOREGROUND); + pidfile = strdup(elektraGet(elektra, CONF_LCDEXEC_PIDFILE)); - main_menu = menu_read(NULL, "MainMenu"); -#if defined(DEBUG) - menu_dump(main_menu); -#endif + displayname = strdup(elektraGet(elektra, CONF_LCDEXEC_DISPLAYNAME)); + + default_shell = strdup(elektraGet(elektra, CONF_LCDEXEC_SHELL)); + main_menu = elektraGet(elektra, CONF_MENU_MAIN); // fail on non-existent main menu; if (main_menu == NULL) { report(RPT_ERR, "no main menu found in configuration"); return -1; } + + main_menu_process(main_menu); + +#if defined(DEBUG) + menu_dump(main_menu, 0); +#endif + + return 0; } @@ -373,19 +284,158 @@ static int connect_and_setup(void) } /* Create our menu */ - if (menu_sock_send(main_menu, NULL, sock) < 0) { + if (main_menu_sock_send(main_menu, sock) < 0) { return -1; } return 0; } +/** + * returns the parameter with the given id, if it is contained in the given command + * returns NULL otherwise + */ +static CommandParameter * find_parameter(Command * command, int id, CommandParameterType * type) +{ + for (kdb_long_long_t i = 0; i < command->parametersSize; i++) + { + switch (command->parameterTypes[i]) + { + case COMMAND_PARAMETER_TYPE_ALPHA: + if(command->parameters[i].alpha->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + case COMMAND_PARAMETER_TYPE_CHECKBOX: + if(command->parameters[i].checkbox->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + case COMMAND_PARAMETER_TYPE_IP: + if(command->parameters[i].ip->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + case COMMAND_PARAMETER_TYPE_NUMERIC: + if(command->parameters[i].numeric->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + case COMMAND_PARAMETER_TYPE_RING: + if(command->parameters[i].ring->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + case COMMAND_PARAMETER_TYPE_SLIDER: + if(command->parameters[i].slider->id == id) { + *type = command->parameterTypes[i]; + return &command->parameters[i]; + } + break; + } + } + return NULL; +} + +/** + * returns true and sets *command to the command, if id found and actually command + * returns true and sets *command = NULL, if id found but not command + * returns false and sets *command = NULL, if id not found + */ +static bool find_triggered_command(Menu * menu, int id, Command ** command) +{ + *command = NULL; + for (kdb_long_long_t i = 0; i < menu->entriesSize; i++) + { + switch (menu->entryTypes[i]) + { + case MENU_ENTRY_TYPE_COMMAND: + if(menu->entries[i].command->id == id) { + *command = menu->entries[i].command; + return true; + } else if(menu->entries[i].command->actionId == id) { + *command = menu->entries[i].command; + return true; + } + CommandParameterType t; + if(find_parameter(menu->entries[i].command, id, &t) != NULL) + { + return true; + } + break; + case MENU_ENTRY_TYPE_MENU: + if(menu->entries[i].menu->id == id) + { + return true; + } + if(find_triggered_command(menu->entries[i].menu, id, command)) + { + return true; + } + break; + } + } + + return false; +} + + +/** + * returns true and sets *parameter to the parameter and *type to the corresponding type, if id found and actually parameter + * returns true and sets *parameter = NULL, if id found but not parameter + * returns false and sets *parameter = NULL, if id not found + */ +static bool find_triggered_parameter(Menu * menu, int id, CommandParameter ** parameter, CommandParameterType * type) +{ + *parameter = NULL; + for (kdb_long_long_t i = 0; i < menu->entriesSize; i++) + { + switch (menu->entryTypes[i]) + { + case MENU_ENTRY_TYPE_COMMAND: + if(menu->entries[i].command->id == id) { + return true; + } else if(menu->entries[i].command->actionId == id) { + return true; + } + *parameter = find_parameter(menu->entries[i].command, id, type); + if(*parameter != NULL) + { + return true; + } + break; + case MENU_ENTRY_TYPE_MENU: + if(menu->entries[i].menu->id == id) + { + return true; + } + if(find_triggered_parameter(menu->entries[i].menu, id, parameter, type)) + { + return true; + } + break; + } + } + + return false; +} static int process_response(char *str) { char *argv[20]; int argc; + char * strCopy = NULL; + if (strncmp(str, "huh?", 4) == 0) { + // for error handling + strCopy = strdup(str); + } + debug(RPT_DEBUG, "Server said: \"%s\"", str); /* Check what the server just said to us... */ @@ -401,79 +451,79 @@ static int process_response(char *str) if ((strcmp(argv[1], "select") == 0) || (strcmp(argv[1], "leave") == 0)) { - MenuEntry *entry; - - if (argc < 3) - goto err_invalid; - - /* Find the entry by id */ - entry = menu_find_by_id(main_menu, atoi(argv[2])); - if (entry == NULL) { - report(RPT_WARNING, "Could not find the item id given by the server"); - return -1; - } - - /* The id has been found. - * We trigger on the following conditions: - * - command entry without args - * - last arg of a command entry with args */ - if (((entry->type == MT_EXEC) && (entry->children == NULL)) || - ((entry->type & MT_ARGUMENT) && (entry->next == NULL))) { - - // last arg => get parent entry - if ((entry->type & MT_ARGUMENT) && (entry->next == NULL)) - entry = entry->parent; + if (argc < 3) + goto err_invalid; + + /* Look for command by id or actionId */ + Command * command; + if (!find_triggered_command(main_menu, atoi(argv[2]), &command)) { + // unknown id + report(RPT_WARNING, "Could not find the item id given by the server"); + return -1; + } - if (entry->type == MT_EXEC) - exec_command(entry); - } + if(command != NULL) { + // found command + exec_command(command); + } else { + // found menu or parameter + debug(RPT_DEBUG, "got %s for %s", argv[1], argv[2]); + return 0; + } } else if ((strcmp(argv[1], "plus") == 0) || (strcmp(argv[1], "minus") == 0) || (strcmp(argv[1], "update") == 0)) { - MenuEntry *entry; if (argc < 4) goto err_invalid; /* Find the entry by id */ - entry = menu_find_by_id(main_menu, atoi(argv[2])); - if (entry == NULL) { + CommandParameter * parameter; + CommandParameterType parameterType; + if (!find_triggered_parameter(main_menu, atoi(argv[2]), ¶meter, ¶meterType)) { + // unknown id report(RPT_WARNING, "Could not find the item id given by the server"); return -1; } - switch (entry->type) { - case MT_ARG_SLIDER: - entry->data.slider.value = atoi(argv[3]); + if(parameter == NULL) { + // found menu or command + debug(RPT_DEBUG, "got %s for %s", argv[1], argv[2]); + return 0; + } + + switch (parameterType) { + case COMMAND_PARAMETER_TYPE_SLIDER: + parameter->slider->value = atoi(argv[3]); break; - case MT_ARG_RING: - entry->data.ring.value = atoi(argv[3]); + case COMMAND_PARAMETER_TYPE_RING: + parameter->ring->value = atoi(argv[3]); break; - case MT_ARG_NUMERIC: - entry->data.numeric.value = atoi(argv[3]); + case COMMAND_PARAMETER_TYPE_NUMERIC: + parameter->numeric->value = atoi(argv[3]); break; - case MT_ARG_ALPHA: - entry->data.alpha.value = realloc(entry->data.alpha.value, + case COMMAND_PARAMETER_TYPE_ALPHA: + parameter->alpha->value = realloc(parameter->alpha->value, strlen(argv[3])); - strcpy(entry->data.alpha.value, argv[3]); + strcpy(parameter->alpha->value, argv[3]); break; - case MT_ARG_IP: - entry->data.ip.value = realloc(entry->data.ip.value, + case COMMAND_PARAMETER_TYPE_IP: + parameter->ip->value = realloc(parameter->ip->value, strlen(argv[3])); - strcpy(entry->data.ip.value, argv[3]); + strcpy(parameter->ip->value, argv[3]); break; - case MT_ARG_CHECKBOX: - if ((entry->data.checkbox.allow_gray) && + case COMMAND_PARAMETER_TYPE_CHECKBOX: + if ((parameter->checkbox->allowgray) && (strcasecmp(argv[3], "gray") == 0)) - entry->data.checkbox.value = 2; + parameter->checkbox->value = 2; else if (strcasecmp(argv[3], "on") == 0) - entry->data.checkbox.value = 1; + parameter->checkbox->value = 1; else - entry->data.checkbox.value = 0; + parameter->checkbox->value = 0; break; default: - report(RPT_WARNING, "Illegal menu entry type for event"); + report(RPT_WARNING, "Illegal parameter type for event %s", argv[1]); return -1; } } @@ -499,11 +549,16 @@ static int process_response(char *str) } else if (strcmp(argv[0], "huh?") == 0) { /* Report errors */ - report(RPT_WARNING, "Server said: \"%s\"", str); + report(RPT_WARNING, "Server said: \"%s\"", strCopy); } else { ; /* Ignore all other responses */ } + + if (strCopy != NULL) { + free(strCopy); + } + return 0; err_invalid: @@ -511,101 +566,111 @@ static int process_response(char *str) return -1; } - -static int exec_command(MenuEntry *cmd) +static int exec_command(Command *cmd) { - if ((cmd != NULL) && (menu_command(cmd) != NULL)) { - const char *command = menu_command(cmd); - const char *argv[4]; - pid_t pid; - ProcInfo *p; - char *envp[cmd->numChildren+1]; - MenuEntry *arg; - int i; - - /* set argument vector */ - argv[0] = default_shell; - argv[1] = "-c"; - argv[2] = command; - argv[3] = NULL; - - /* set environment vector: allocate & fill contents */ - for (arg = cmd->children, i = 0; arg != NULL; arg = arg->next, i++) { - char buf[1025]; - - switch (arg->type) { - case MT_ARG_SLIDER: - snprintf(buf, sizeof(buf)-1, "%s=%d", - arg->name, arg->data.slider.value); - break; - case MT_ARG_RING: - snprintf(buf, sizeof(buf)-1, "%s=%s", arg->name, - arg->data.ring.strings[arg->data.ring.value]); - break; - case MT_ARG_NUMERIC: - snprintf(buf, sizeof(buf)-1, "%s=%d", - arg->name, arg->data.numeric.value); - break; - case MT_ARG_ALPHA: - snprintf(buf, sizeof(buf)-1, "%s=%s", - arg->name, arg->data.alpha.value); - break; - case MT_ARG_IP: - snprintf(buf, sizeof(buf)-1, "%s=%s", - arg->name, arg->data.ip.value); + if (cmd == NULL || strlen(cmd->exec) == 0) { + return -1; + } + + const char *command = cmd->exec; + const char *argv[4]; + pid_t pid; + ProcInfo *p; + char ** envp = malloc((cmd->parametersSize + 1) * sizeof(char*)); + + /* set argument vector */ + argv[0] = default_shell; + argv[1] = "-c"; + argv[2] = command; + argv[3] = NULL; + + /* set environment vector: allocate & fill contents */ + for (kdb_long_long_t i = 0; i < cmd->parametersSize; ++i) { + CommandParameter param = cmd->parameters[i]; + switch (cmd->parameterTypes[i]) { + case COMMAND_PARAMETER_TYPE_SLIDER: + envp[i] = elektraFormat("%s="ELEKTRA_LONG_F, param.slider->envname, param.slider->value); + break; + case COMMAND_PARAMETER_TYPE_RING: + envp[i] = elektraFormat("%s=%s", param.ring->envname, param.ring->strings[param.ring->value]); + break; + case COMMAND_PARAMETER_TYPE_NUMERIC: + envp[i] = elektraFormat("%s="ELEKTRA_LONG_F, param.numeric->envname, param.numeric->value); + break; + case COMMAND_PARAMETER_TYPE_ALPHA: + envp[i] = elektraFormat("%s=%s", param.alpha->envname, param.alpha->value); + break; + case COMMAND_PARAMETER_TYPE_IP: + envp[i] = elektraFormat("%s=%s", param.ip->envname, param.ip->value); + break; + case COMMAND_PARAMETER_TYPE_CHECKBOX: + switch (param.checkbox->value) + { + case CHECKBOX_STATE_ON: + if(strlen(param.checkbox->ontext) > 0) { + envp[i] = elektraFormat("%s", param.checkbox->ontext); + } else { + envp[i] = elektraFormat("%s="ELEKTRA_LONG_F, param.checkbox->envname, param.checkbox->value); + } break; - case MT_ARG_CHECKBOX: - if (arg->data.checkbox.map[arg->data.checkbox.value] != NULL) - strncpy(buf, arg->data.checkbox.map[arg->data.checkbox.value], - sizeof(buf)-1); - else - snprintf(buf, sizeof(buf)-1, "%s=%d", - arg->name, arg->data.checkbox.value); + case CHECKBOX_STATE_OFF: + if(strlen(param.checkbox->offtext) > 0) { + envp[i] = elektraFormat("%s", param.checkbox->offtext); + } else { + envp[i] = elektraFormat("%s="ELEKTRA_LONG_F, param.checkbox->envname, param.checkbox->value); + } break; - default: - /* error ? */ + case CHECKBOX_STATE_GRAY: + if(strlen(param.checkbox->graytext) > 0) { + envp[i] = elektraFormat("%s", param.checkbox->graytext); + } else { + envp[i] = elektraFormat("%s="ELEKTRA_LONG_F, param.checkbox->envname, param.checkbox->value); + } break; - } - buf[sizeof(buf)-1] ='\0'; - envp[i] = strdup(buf); - - debug(RPT_DEBUG, "Environment: %s", envp[i]); + } + break; + default: + /* error ? */ + break; } - envp[cmd->numChildren] = NULL; - debug(RPT_DEBUG, "Executing '%s' via Shell %s", command, default_shell); - - switch (pid = fork()) { - case 0: - /* We're the child: execute the command */ - execve(argv[0], (char **) argv, envp); - exit(EXIT_SUCCESS); - break; - default: - /* We're the parent: setup the ProcInfo structure */ - p = calloc(1, sizeof(ProcInfo)); - if (p != NULL) { - p->cmd = cmd; - p->pid = pid; - p->starttime = time(NULL); - p->feedback = cmd->data.exec.feedback; - /* prepend it to existing queue atomically */ - p->next = proc_queue; - proc_queue = p; - } - break; - case -1: - report(RPT_ERR, "Could not fork"); - return -1; + debug(RPT_DEBUG, "Environment: %s", envp[i]); + } + envp[cmd->parametersSize] = NULL; + + debug(RPT_DEBUG, "Executing '%s' via Shell %s", command, default_shell); + + switch (pid = fork()) { + case 0: + /* We're the child: execute the command */ + execve(argv[0], (char **) argv, envp); + exit(EXIT_SUCCESS); + break; + default: + /* We're the parent: setup the ProcInfo structure */ + p = calloc(1, sizeof(ProcInfo)); + if (p != NULL) { + p->cmd = cmd; + p->pid = pid; + p->starttime = time(NULL); + p->feedback = cmd->feedback; + /* prepend it to existing queue atomically */ + p->next = proc_queue; + proc_queue = p; } + break; + case -1: + report(RPT_ERR, "Could not fork"); + return -1; + } - /* free envp's contents */ - for (i = 0; envp[i] != NULL; i++) - free(envp[i]); - - return 0; + /* free envp's contents */ + for (kdb_long_long_t i = 0; i < cmd->parametersSize; i++) { + elektraFree(envp[i]); } - return -1; + free (envp); + + return 0; } diff --git a/clients/lcdexec/menu.c b/clients/lcdexec/menu.c index 375cf85c..eadb3b65 100644 --- a/clients/lcdexec/menu.c +++ b/clients/lcdexec/menu.c @@ -18,618 +18,396 @@ #include #include "shared/report.h" -#include "shared/configfile.h" #include "shared/sockets.h" #include "menu.h" +#include "elektragen.h" +static int menu_sock_send(Menu *menu, Menu *parent, int sock); +static int menu_entries_sock_send(Menu *menu, int sock); +static int command_sock_send(Command *command, Menu *parent, int sock); -/* names for boolean and tristate values */ -static char *boolValueName[] = { "false", "true" }; -static char *triGrayValueName[] = { "off", "on", "gray" }; +static int id = 0; - -/** recursively read the menu hierarchy */ -MenuEntry *menu_read(MenuEntry *parent, const char *name) +static void command_process(Command *command) { - static int id = 0; - - if ((name != NULL) && (config_has_section(name))) { - MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements - - if (me == NULL) - return NULL; - // set common entries - me->id = id++; - me->name = strdup(name); - if (me->name == NULL) { - //menu_free(me); - return NULL; - } - - me->displayname = strdup(config_get_string(name, "DisplayName", 0, name)); - if (me->displayname == NULL) { - //menu_free(me); - return NULL; - } - - me->parent = parent; - me->next = NULL; - me->children = NULL; - me->numChildren = 0; - - if (config_get_string(name, "Entry", 0, NULL) != NULL) { - MenuEntry **addr = &me->children; - const char *entryname; - - // it is a sub-menu - me->type = MT_MENU; - - // read menu entries - while ((entryname = config_get_string(name, "Entry", me->numChildren, NULL)) != NULL) { - MenuEntry *entry = menu_read(me, entryname); - - if (entry == NULL) { - //menu_free(me); - return NULL; + command->id = id++; + + for (kdb_long_long_t i = 0; i < command->parametersSize; ++i) + { + CommandParameter parameter = command->parameters[i]; + switch (command->parameterTypes[i]) + { + case COMMAND_PARAMETER_TYPE_NUMERIC: + parameter.numeric->id = id++; + break; + case COMMAND_PARAMETER_TYPE_RING: + parameter.ring->id = id++; + size_t stringsLen = 0; + for (size_t i = 0; i < parameter.ring->stringsCount; i++) + { + if (parameter.ring->strings[i] != NULL) { + stringsLen += strlen(parameter.ring->strings[i]); } - - me->numChildren++; - - *addr = entry; - addr = &entry->next; } + parameter.ring->stringsLength = stringsLen; + break; + case COMMAND_PARAMETER_TYPE_SLIDER: + parameter.slider->id = id++; + break; + case COMMAND_PARAMETER_TYPE_CHECKBOX: + parameter.checkbox->id = id++; + break; + case COMMAND_PARAMETER_TYPE_ALPHA: + { + parameter.alpha->id = id++; + parameter.alpha->value = calloc(strlen(parameter.alpha->initialValue) + 1, sizeof(char)); + strcpy(parameter.alpha->value, parameter.alpha->initialValue); } - else if (config_get_string(name, "Exec", 0, NULL) != NULL) { - MenuEntry **addr = &me->children; - const char *entryname; - - // it's a command to execute - me->type = MT_EXEC; - - me->data.exec.command = strdup(config_get_string(name, "Exec", 0, "")); - if (me->data.exec.command == NULL) { - //menu_free(me); - return NULL; - } - me->data.exec.feedback = config_get_bool(name, "Feedback", 0, 0); - - // try to read parameters - while ((entryname = config_get_string(name, "Parameter", me->numChildren, NULL)) != NULL) { - MenuEntry *entry = menu_read(me, entryname); - - if (entry == NULL) { - //menu_free(me); - return NULL; - } - - me->numChildren++; - - *addr = entry; - addr = &entry->next; - } - - // automagically add an "Apply ?" action - if ((me->numChildren > 0) && (addr != NULL)) - *addr = menu_read(me, NULL); + break; + case COMMAND_PARAMETER_TYPE_IP: + { + parameter.ip->id = id++; + parameter.ip->value = calloc(strlen(parameter.ip->initialValue) + 1, sizeof(char)); + strcpy(parameter.ip->value, parameter.ip->initialValue); } - else if (config_get_string(name, "Type", 0, NULL) != NULL) { - // it's a command parameter - const char *type; - - type = config_get_string(name, "Type", 0, ""); - - if (strcasecmp(type, "slider") == 0) { - char buf[35]; - - me->type = MT_ARG_SLIDER; - - me->data.slider.value = config_get_int(name, "Value", 0, 0); - me->data.slider.minval = config_get_int(name, "MinValue", 0, 0); - me->data.slider.maxval = config_get_int(name, "MaxValue", 0, 1000); - - sprintf(buf, "%d", me->data.slider.minval); - me->data.slider.mintext = strdup(config_get_string(name, "MinText", 0, buf)); - sprintf(buf, "%d", me->data.slider.maxval); - me->data.slider.maxtext = strdup(config_get_string(name, "MaxText", 0, buf)); - - me->data.slider.stepsize = config_get_int(name, "StepSize", 0, 1); - } - else if (strcasecmp(type, "ring") == 0) { - const char *tmp; - int numStrings = 0; - int i = 0; + break; + } + } - me->type = MT_ARG_RING; + if(command->parametersSize > 0) { + command->actionId = id++; + } else { + command->actionId = command->id; + } +} - me->data.ring.value = config_get_int(name, "Value", 0, 0); - numStrings = config_has_key(name, "String"); - me->data.ring.strings = calloc(sizeof(char *), numStrings+1); - me->data.ring.strings[numStrings] = NULL; +static void menu_process(Menu *menu) +{ + menu->id = id++; + for (kdb_long_long_t i = 0; i < menu->entriesSize; i++) + { + switch (menu->entryTypes[i]) + { + case MENU_ENTRY_TYPE_MENU: + menu_process(menu->entries[i].menu); + break; + case MENU_ENTRY_TYPE_COMMAND: + command_process(menu->entries[i].command); + break; + } + } +} - while ((tmp = config_get_string(name, "String", i, NULL)) != NULL) { - me->data.ring.strings[i] = strdup(tmp); - i++; - } - me->data.ring.strings[i] = NULL; - } - else if (strcasecmp(type, "numeric") == 0) { - me->type = MT_ARG_NUMERIC; +void main_menu_process(Menu *menu) +{ + id = 0; + menu_process(menu); +} - me->data.numeric.value = config_get_int(name, "Value", 0, 0); - me->data.numeric.minval = config_get_int(name, "MinValue", 0, 0); - me->data.numeric.maxval = config_get_int(name, "MaxValue", 0, 1000); - } - else if (strcasecmp(type, "alpha") == 0) { - me->type = MT_ARG_ALPHA; - - me->data.alpha.value = strdup(config_get_string(name, "Value", 0, "")); - me->data.alpha.minlen = config_get_int(name, "MinLength", 0, 0); - me->data.alpha.maxlen = config_get_int(name, "MaxLength", 0, 100); - me->data.alpha.allowed = strdup(config_get_string(name, "AllowedChars", 0, - "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); - } - else if (strcasecmp(type, "ip") == 0) { - me->type = MT_ARG_IP; +int main_menu_sock_send(Menu *menu, int sock) +{ + // don't create a separate entry for the main menu + return menu_entries_sock_send(menu, sock); +} - me->data.ip.value = strdup(config_get_string(name, "Value", 0, "")); - me->data.ip.v6 = config_get_bool(name, "Value", 0, 0); - } - else if (strcasecmp(type, "checkbox") == 0) { - const char *tmp; - - me->type = MT_ARG_CHECKBOX; - - me->data.checkbox.allow_gray = config_get_bool(name, "AllowGray", 0, 0); - me->data.checkbox.value = (me->data.checkbox.allow_gray) - ? config_get_tristate(name, "Value", 0, "gray", 0) - : config_get_bool(name, "Value", 0, 0); - // get replacement strings for different values - tmp = config_get_string(name, "OffText", 0, NULL); - me->data.checkbox.map[0] = (tmp != NULL) ? strdup(tmp) : NULL; - tmp = config_get_string(name, "OnText", 0, NULL); - me->data.checkbox.map[1] = (tmp != NULL) ? strdup(tmp) : NULL; - tmp = config_get_string(name, "GrayText", 0, NULL); - me->data.checkbox.map[2] = (tmp != NULL) ? strdup(tmp) : NULL; - } - else { - report(RPT_DEBUG, "illegal parameter type"); - //menu_free(me); - return NULL; - } - } - else { - report(RPT_DEBUG, "unknown menu entry type"); - //menu_free(me); - return NULL; - } +static int menu_sock_send(Menu *menu, Menu *parent, int sock) +{ + debug(RPT_DEBUG, "Sending menu %d", menu->id); - return me; + char parent_id[ELEKTRA_MAX_ARRAY_SIZE] = ""; // more than big enough + if (parent != NULL && parent->id > 0) { + snprintf(parent_id, ELEKTRA_MAX_ARRAY_SIZE-1, "%d", parent->id); } - else { - /* the magic stuff: if name is NULL and parent is an EXEC entry, - * then generate an Action entry with the name "Apply" */ - if ((name == NULL) && (parent != NULL) && (parent->type = MT_EXEC)) { - MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements - - if (me == NULL) - return NULL; - // set common entries - me->id = id++; - me->name = malloc(strlen(parent->name) + 10); - if (me->name == NULL) { - //menu_free(me); - return NULL; - } - strcpy(me->name, "Apply_"); - strcat(me->name, parent->name); - me->displayname = strdup("Apply!"); - if (me->displayname == NULL) { - //menu_free(me); - return NULL; - } + // create entry for the menu + if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n", + parent_id, menu->id, menu->displayname) < 0) + return -1; - me->parent = parent; - me->next = NULL; - me->children = NULL; - me->numChildren = 0; - me->type = MT_ACTION; + return menu_entries_sock_send(menu, sock); +} - return me; +static int menu_entries_sock_send(Menu *menu, int sock) +{ + for (kdb_long_long_t i = 0; i < menu->entriesSize; i++) + { + switch (menu->entryTypes[i]) + { + case MENU_ENTRY_TYPE_MENU: + if (menu_sock_send(menu->entries[i].menu, menu, sock) < 0) + return -1; + break; + case MENU_ENTRY_TYPE_COMMAND: + if (command_sock_send(menu->entries[i].command, menu, sock) < 0) + return -1; + break; } } - return NULL; + return 0; } -/* Helper for repetitive code */ -static int menu_set_quit(MenuEntry *me, int sock) { - if (me->next != NULL) - return 0; +static int command_sock_send(Command *command, Menu *parent, int sock) +{ + debug(RPT_DEBUG, "Sending command %d", command->id); - return sock_printf(sock, "menu_set_item {} {%d} -next _quit_\n", - me->id); -} + char parent_id[ELEKTRA_MAX_ARRAY_SIZE] = ""; // more than big enough + if (parent != NULL && parent->id > 0) { + snprintf(parent_id, ELEKTRA_MAX_ARRAY_SIZE-1, "%d", parent->id); + } -/** create LCDproc commands for the menu entry hierarchy and send it to the server */ -int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock) -{ - if ((me != NULL) && (sock > 0)) { - char parent_id[12]; - - // set parent_id depending on the parent given - if ((parent != NULL) && (parent->id != 0)) - sprintf(parent_id, "%d", parent->id); - else - parent_id[0] = 0; - - switch (me->type) { - MenuEntry *entry; - - case MT_MENU: - // don't create a separate entry for the main menu - if ((parent != NULL) && (me->id != 0)) { - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n", - parent_id, me->id, me->displayname) < 0) - return -1; - } + if (command->parametersSize == 0) + { + if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n", + parent_id, command->id, command->displayname) < 0) + return -1; - // recursively do it for the menu's sub-menus - for (entry = me->children; entry != NULL; entry = entry->next) { - if (menu_sock_send(entry, me, sock) < 0) - return -1; - } - break; - case MT_EXEC: - if (me->children == NULL) { - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n", - parent_id, me->id, me->displayname) < 0) - return -1; - - if (sock_printf(sock, "menu_set_item {} {%d} -menu_result quit\n", - me->id) < 0) - return -1; - } - else { - if ((parent != NULL) && (me->id != 0)) { - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n", - parent_id, me->id, me->displayname) < 0) - return -1; - } + if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n", + parent_id, command->id) < 0) + return -1; + } + else + { + if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n", + parent_id, command->id, command->displayname) < 0) + return -1; + + kdb_long_t lastId = 0; + for (kdb_long_long_t i = 0; i < command->parametersSize; i++) + { + CommandParameter param = command->parameters[i]; + switch (command->parameterTypes[i]) + { + case COMMAND_PARAMETER_TYPE_SLIDER: + debug(RPT_DEBUG, "Sending parameter %d", param.slider->id); + lastId = param.slider->id; + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" slider -text \"%s\"" + " -value %d -minvalue %d -maxvalue %d" + " -mintext \"%s\" -maxtext \"%s\" -stepsize %d\n", + command->id, param.slider->id, param.slider->displayname, + param.slider->value, + param.slider->minvalue, + param.slider->maxvalue, + param.slider->mintext, + param.slider->maxtext, + param.slider->stepsize) < 0) + return -1; - // (recursively) do it for the entry's parameters - for (entry = me->children; entry != NULL; entry = entry->next) { - if (menu_sock_send(entry, me, sock) < 0) - return -1; - } - } break; - case MT_ARG_SLIDER: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" slider -text \"%s\"" - " -value %d -minvalue %d -maxvalue %d" - " -mintext \"%s\" -maxtext \"%s\" -stepsize %d\n", - parent_id, me->id, me->displayname, - me->data.slider.value, - me->data.slider.minval, - me->data.slider.maxval, - me->data.slider.mintext, - me->data.slider.maxtext, - me->data.slider.stepsize) <0) + case COMMAND_PARAMETER_TYPE_CHECKBOX: + { + debug(RPT_DEBUG, "Sending parameter %d", param.checkbox->id); + lastId = param.checkbox->id; + const char *strValue = ELEKTRA_TO_CONST_STRING(EnumCheckboxState)(param.checkbox->value); + int ret = sock_printf(sock, "menu_add_item \"%d\" \"%d\" checkbox -text \"%s\"" + " -value %s -allow_gray %s\n", + command->id, param.checkbox->id, param.checkbox->displayname, + strValue, param.checkbox->allowgray ? "true" : "false"); + if (ret < 0) return -1; - - if (menu_set_quit(me, sock) < 0) + + break; + } + case COMMAND_PARAMETER_TYPE_NUMERIC: + debug(RPT_DEBUG, "Sending parameter %d", param.numeric->id); + lastId = param.numeric->id; + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" numeric -text \"%s\"" + " -value %d -minvalue %d -maxvalue %d\n", + command->id, param.numeric->id, param.numeric->displayname, + param.numeric->value, + param.numeric->minvalue, + param.numeric->maxvalue) < 0) return -1; - break; - case MT_ARG_RING: + case COMMAND_PARAMETER_TYPE_RING: + { + debug(RPT_DEBUG, "Sending parameter %d", param.ring->id); + lastId = param.ring->id; + char *strings = malloc((param.ring->stringsLength + param.ring->stringsCount + 1) * sizeof(char)); + strings[0] = '\0'; + + for (kdb_long_long_t j = 0; j < param.ring->stringsCount; j++) { - int i; - char *tmp = strdup(""); - - // join all strings with TAB as separator - for (i = 0; me->data.ring.strings[i] != NULL; i++) { - tmp = realloc(tmp, strlen(tmp) + 1 + - strlen(me->data.ring.strings[i]) + 1); - if (tmp[0] != '\0') - strcat(tmp, "\t"); - strcat(tmp, me->data.ring.strings[i]); + if (param.ring->strings[j] != NULL) + { + if (strings[0] != '\0') + { + strcat(strings, "\t"); + } + strcat(strings, param.ring->strings[j]); } - - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ring -text \"%s\"" - " -value %d -strings \"%s\"\n", - parent_id, me->id, me->displayname, - me->data.ring.value, - tmp) < 0) - return -1; } + strings[param.ring->stringsLength + param.ring->stringsCount] = '\0'; - if (menu_set_quit(me, sock) < 0) + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" ring -text \"%s\"" + " -value %d -strings \"%s\"\n", + command->id, param.ring->id, param.ring->displayname, + param.ring->value, strings) < 0) return -1; - + + free(strings); break; - case MT_ARG_NUMERIC: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" numeric -text \"%s\"" - " -value %d -minvalue %d -maxvalue %d\n", - parent_id, me->id, me->displayname, - me->data.numeric.value, - me->data.numeric.minval, - me->data.numeric.maxval) < 0) - return -1; - - if (menu_set_quit(me, sock) < 0) - return -1; - - break; - case MT_ARG_ALPHA: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" alpha -text \"%s\"" - " -value \"%s\" -minlength %d -maxlength %d" - " -allow_caps false -allow_noncaps false" - " -allow_numbers false -allowed_extra \"%s\"\n", - parent_id, me->id, me->displayname, - me->data.alpha.value, - me->data.alpha.minlen, - me->data.alpha.maxlen, - me->data.alpha.allowed) <0) - return -1; - - if (menu_set_quit(me, sock) < 0) + } + case COMMAND_PARAMETER_TYPE_ALPHA: + debug(RPT_DEBUG, "Sending parameter %d", param.alpha->id); + lastId = param.alpha->id; + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" alpha -text \"%s\"" + " -value \"%s\" -minlength %d -maxlength %d" + " -allow_caps false -allow_noncaps false" + " -allow_numbers false -allowed_extra \"%s\"\n", + command->id, param.alpha->id, param.alpha->displayname, + param.alpha->value, + param.alpha->minlength, + param.alpha->maxlength, + param.alpha->allowedchars) < 0) return -1; - break; - case MT_ARG_IP: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ip -text \"%s\"" - " -value \"%s\" -v6 %s\n", - parent_id, me->id, me->displayname, - me->data.ip.value, - boolValueName[me->data.ip.v6]) < 0) - return -1; - - if (menu_set_quit(me, sock) < 0) + case COMMAND_PARAMETER_TYPE_IP: + debug(RPT_DEBUG, "Sending parameter %d", param.ip->id); + lastId = param.ip->id; + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" ip -text \"%s\"" + " -value \"%s\" -v6 %s\n", + command->id, param.ip->id, param.ip->displayname, + param.ip->value, + param.ip->v6 ? "true" : "false") < 0) return -1; - break; - case MT_ARG_CHECKBOX: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" checkbox -text \"%s\"" - " -value %s -allow_gray %s\n", - parent_id, me->id, me->displayname, - triGrayValueName[me->data.checkbox.value], - boolValueName[me->data.checkbox.allow_gray]) < 0) - return -1; + } + } - if (menu_set_quit(me, sock) < 0) - return -1; + if (sock_printf(sock, "menu_set_item \"%d\" \"%d\" -next _quit_\n", + command->id, lastId) < 0) + return -1; - break; - case MT_ACTION: - if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n", - parent_id, me->id, me->displayname) < 0) - return -1; + if (sock_printf(sock, "menu_add_item \"%d\" \"%d\" action \"%s\"\n", + command->id, command->actionId, "Apply!") < 0) + return -1; - if (sock_printf(sock, "menu_set_item {} {%d} -menu_result quit\n", - me->id) < 0) - return -1; - break; - default: - return -1; - } - return 0; + if (sock_printf(sock, "menu_set_item \"%d\" \"%d\" -menu_result quit\n", + command->id, command->actionId) < 0) + return -1; } - return -1; + return 0; } - -/** find menu entry by its id */ -MenuEntry *menu_find_by_id(MenuEntry *me, int id) +#if defined(DEBUG) +static void command_dump(Command *command, int level) { - if (me != NULL) { - if (me->id == id) - return me; - - if ((me->type == MT_MENU) || (me->type == MT_EXEC)) { - MenuEntry *entry; - - for (entry = me->children; entry != NULL; entry = entry->next) { - MenuEntry *result = menu_find_by_id(entry, id); + if (command == NULL) + { + return; + } - if (result != NULL) - return result; + report(RPT_DEBUG, "%*sCommand("ELEKTRA_LONG_F", "ELEKTRA_LONG_F") {", level, "", command->id, command->actionId); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 1, "", command->displayname); + report(RPT_DEBUG, "%*sexec = \"%s\"", level + 1, "", command->exec); + report(RPT_DEBUG, "%*sfeedback = %s", level + 1, "", command->feedback ? "true" : "false"); + report(RPT_DEBUG, "%*sparameters = [", level + 1, ""); + + for (kdb_long_long_t i = 0; i < command->parametersSize; ++i) + { + CommandParameter parameter = command->parameters[i]; + switch (command->parameterTypes[i]) + { + case COMMAND_PARAMETER_TYPE_NUMERIC: + report(RPT_DEBUG, "%*sNumeric("ELEKTRA_LONG_F") {", level + 2, "", parameter.numeric->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 3, "", parameter.numeric->displayname); + report(RPT_DEBUG, "%*senvname = \"%s\"", level + 3, "", parameter.numeric->envname); + report(RPT_DEBUG, "%*sminvalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.numeric->minvalue); + report(RPT_DEBUG, "%*smaxvalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.numeric->maxvalue); + report(RPT_DEBUG, "%*svalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.numeric->value); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; + case COMMAND_PARAMETER_TYPE_RING: + report(RPT_DEBUG, "%*sRing("ELEKTRA_LONG_F") {", level + 2, "", parameter.ip->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 3, "", parameter.ring->displayname); + report(RPT_DEBUG, "%*senvname = \"%s\"", level + 3, "", parameter.ring->envname); + report(RPT_DEBUG, "%*sstrings = [", level + 3, ""); + for (kdb_long_long_t j = 0; j < parameter.ring->stringsCount; ++j) + { + report(RPT_DEBUG, "%*s\"%s\"", level + 3, "", parameter.ring->strings[j]); } + report(RPT_DEBUG, "%*s]", level + 3, ""); + report(RPT_DEBUG, "%*svalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.ring->value); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; + case COMMAND_PARAMETER_TYPE_SLIDER: + report(RPT_DEBUG, "%*sSlider("ELEKTRA_LONG_F") {", level + 2, "", parameter.slider->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 3, "", parameter.slider->displayname); + report(RPT_DEBUG, "%*senvname = \"%s\"", level + 3, "", parameter.slider->envname); + report(RPT_DEBUG, "%*sminvalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.slider->minvalue); + report(RPT_DEBUG, "%*smaxvalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.slider->maxvalue); + report(RPT_DEBUG, "%*smintext = \"%s\"", level + 3, "", parameter.slider->mintext); + report(RPT_DEBUG, "%*smaxtext = \"%s\"", level + 3, "", parameter.slider->maxtext); + report(RPT_DEBUG, "%*svalue = " ELEKTRA_LONG_F "", level + 3, "", parameter.slider->value); + report(RPT_DEBUG, "%*sstepsize = " ELEKTRA_LONG_F "", level + 3, "", parameter.slider->stepsize); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; + case COMMAND_PARAMETER_TYPE_CHECKBOX: + report(RPT_DEBUG, "%*sCheckbox("ELEKTRA_LONG_F") {", level + 2, "", parameter.checkbox->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 3, "", parameter.checkbox->displayname); + report(RPT_DEBUG, "%*senvname = \"%s\"", level + 3, "", parameter.checkbox->envname); + report(RPT_DEBUG, "%*sallowgray = %s", level + 3, "", parameter.checkbox->allowgray ? "true" : "false"); + report(RPT_DEBUG, "%*sontext = \"%s\"", level + 3, "", parameter.checkbox->ontext); + report(RPT_DEBUG, "%*sofftext = \"%s\"", level + 3, "", parameter.checkbox->offtext); + report(RPT_DEBUG, "%*sgraytext = \"%s\"", level + 3, "", parameter.checkbox->graytext); + const char *strValue = ELEKTRA_TO_CONST_STRING(EnumCheckboxState)(parameter.checkbox->value); + report(RPT_DEBUG, "%*svalue = %s", level + 3, "", strValue); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; + case COMMAND_PARAMETER_TYPE_ALPHA: + report(RPT_DEBUG, "%*sAlpha("ELEKTRA_LONG_F") {", level + 2, "", parameter.alpha->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 3, "", parameter.alpha->displayname); + report(RPT_DEBUG, "%*senvname = \"%s\"", level + 3, "", parameter.alpha->envname); + report(RPT_DEBUG, "%*sallowedchars = \"%s\"", level + 3, "", parameter.alpha->allowedchars); + report(RPT_DEBUG, "%*sminlength = " ELEKTRA_LONG_F "", level + 3, "", parameter.alpha->minlength); + report(RPT_DEBUG, "%*smaxlength = " ELEKTRA_LONG_F "", level + 3, "", parameter.alpha->maxlength); + report(RPT_DEBUG, "%*svalue = \"%s\"", level + 3, "", parameter.alpha->value); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; + case COMMAND_PARAMETER_TYPE_IP: + report(RPT_DEBUG, "%*sIp("ELEKTRA_LONG_F") {", level + 2, "", parameter.ip->id); + report(RPT_DEBUG, "%*sdisplayname = %s", level + 3, "", parameter.ip->displayname); + report(RPT_DEBUG, "%*senvname = %s", level + 3, "", parameter.ip->envname); + report(RPT_DEBUG, "%*sv6 = %s", level + 3, "", parameter.ip->v6 ? "true" : "false"); + report(RPT_DEBUG, "%*svalue = %s", level + 3, "", parameter.ip->value); + report(RPT_DEBUG, "%*s}", level + 2, ""); + break; } } - return NULL; -} - - -/** return command of a menu entry */ -const char *menu_command(MenuEntry *me) -{ - if ((me != NULL) && (me->type == MT_EXEC)) - return me->data.exec.command; - - return NULL; -} - -/** free menu entry hierarchy */ -void menu_free(MenuEntry *me) -{ - if (me != NULL) { - MenuEntry *entry; - int i; - - switch (me->type) { - case MT_EXEC: - if (me->data.exec.command != NULL) - free(me->data.exec.command); - me->data.exec.command = NULL; - /* fall through */ - case MT_MENU: - for (entry = me->children; entry != NULL; ) { - MenuEntry *old = entry; - - entry = entry->next; - old->next = NULL; - menu_free(old); - } - me->children = NULL; - break; - case MT_ARG_SLIDER: - if (me->data.slider.mintext != NULL) - free(me->data.slider.mintext); - me->data.slider.mintext = NULL; - if (me->data.slider.maxtext != NULL) - free(me->data.slider.maxtext); - me->data.slider.maxtext = NULL; - break; - case MT_ARG_RING: - if (me->data.ring.strings != NULL) { - int i; - - for (i = 0; me->data.ring.strings[i] != NULL; i++) - free(me->data.ring.strings[i]); - - free(me->data.ring.strings); - me->data.ring.strings = NULL; - } - break; - case MT_ARG_ALPHA: - if (me->data.alpha.value != NULL) - free(me->data.alpha.value); - me->data.alpha.value = NULL; - if (me->data.alpha.allowed != NULL) - free(me->data.alpha.allowed); - me->data.alpha.allowed = NULL; - break; - case MT_ARG_IP: - if (me->data.ip.value != NULL) - free(me->data.ip.value); - me->data.ip.value = NULL; - break; - case MT_ARG_CHECKBOX: - for (i = 0; i < sizeof(me->data.checkbox.map)/sizeof(me->data.checkbox.map[0]); i++) { - if (me->data.checkbox.map[i] != NULL) { - free(me->data.checkbox.map[i]); - me->data.checkbox.map[i] = NULL; - } - } - default: - break; - } - - if (me->name != NULL) - free(me->name); - me->name = NULL; - - if (me->displayname != NULL) - free(me->displayname); - me->displayname = NULL; - - me->type = MT_UNKNOWN; - - free(me); - } + report(RPT_DEBUG, "%*s]", level + 1, ""); + report(RPT_DEBUG, "%*s}", level, ""); } - -#if defined(DEBUG) /** dump menu entry hierarchy to screen */ -void menu_dump(MenuEntry *me) +void menu_dump(Menu *menu, int level) { - if (me != NULL) { - /* the quick way out */ - if (me->type & MT_ACTION) - return; - - report(RPT_DEBUG, "# menu ID: %d", me->id); - report(RPT_DEBUG, "[%s]", me->name); - if (me->displayname != NULL) - report(RPT_DEBUG, "DisplayName=\"%s\"", me->displayname); - - switch (me->type) { - MenuEntry *entry; - - case MT_MENU: - // dump menu entry references - for (entry = me->children; entry != NULL; entry = entry->next) - report(RPT_DEBUG, "Entry=%s", entry->name); - report(RPT_DEBUG, ""); - - // recursively walk through sub-menus - for (entry = me->children; entry != NULL; entry = entry->next) - menu_dump(entry); - break; - case MT_EXEC: - report(RPT_DEBUG, "Exec=\"%s\"", me->data.exec.command); - report(RPT_DEBUG, "Feedback=%s", boolValueName[me->data.exec.feedback]); - - // dump entry's parameter referencess - for (entry = me->children; entry != NULL; entry = entry->next) - report(RPT_DEBUG, "Parameter=%s", entry->name); - report(RPT_DEBUG, ""); - - // dump entry's parameters - for (entry = me->children; entry != NULL; entry = entry->next) - menu_dump(entry); - break; - case MT_ARG_SLIDER: - report(RPT_DEBUG, "Type=slider"); - report(RPT_DEBUG, "Value=%d", me->data.slider.value); - report(RPT_DEBUG, "MinValue=%d", me->data.slider.minval); - report(RPT_DEBUG, "MaxValue=%d", me->data.slider.maxval); - report(RPT_DEBUG, "Stepsize=%d", me->data.slider.stepsize); - report(RPT_DEBUG, "MinText=%s", me->data.slider.mintext); - report(RPT_DEBUG, "MaxText=%s", me->data.slider.maxtext); - report(RPT_DEBUG, ""); - break; - case MT_ARG_RING: - report(RPT_DEBUG, "Type=ring"); - report(RPT_DEBUG, "Value: %d", me->data.ring.value); - { - int i; + if (menu == NULL) + { + return; + } - for (i = 0; me->data.ring.strings[i] != NULL; i++) - report(RPT_DEBUG, "String=\"%s\"", me->data.ring.strings[i]); - } - report(RPT_DEBUG, ""); - break; - case MT_ARG_NUMERIC: - report(RPT_DEBUG, "Type=numeric"); - report(RPT_DEBUG, "Value=%d", me->data.numeric.value); - report(RPT_DEBUG, "MinValue=%d", me->data.numeric.minval); - report(RPT_DEBUG, "MaxValue=%d", me->data.numeric.maxval); - report(RPT_DEBUG, ""); - break; - case MT_ARG_ALPHA: - report(RPT_DEBUG, "Type:=lpha"); - report(RPT_DEBUG, "Value=\"%s\"", me->data.alpha.value); - report(RPT_DEBUG, "AllowedChars=\"%s\"", me->data.alpha.allowed); - report(RPT_DEBUG, ""); - break; - case MT_ARG_IP: - report(RPT_DEBUG, "Type=ip"); - report(RPT_DEBUG, "Value=\"%s\"", me->data.ip.value); - report(RPT_DEBUG, "V6=%s", boolValueName[me->data.ip.v6]); - report(RPT_DEBUG, ""); - break; - case MT_ARG_CHECKBOX: - report(RPT_DEBUG, "Type=ip"); - report(RPT_DEBUG, "Value=%s", triGrayValueName[me->data.checkbox.value]); - report(RPT_DEBUG, "AllowGray=%s", boolValueName[me->data.checkbox.allow_gray]); - if (me->data.checkbox.map[0] != NULL) - report(RPT_DEBUG, "OffText=%s", me->data.checkbox.map[0]); - if (me->data.checkbox.map[1] != NULL) - report(RPT_DEBUG, "OnText=%s", me->data.checkbox.map[1]); - if (me->data.checkbox.map[2] != NULL) - report(RPT_DEBUG, "GrayText=%s", me->data.checkbox.map[2]); - report(RPT_DEBUG, ""); - break; - default: - report(RPT_DEBUG, "ERROR: unknown menu entry type"); - break; + report(RPT_DEBUG, "%*sMenu("ELEKTRA_LONG_F") {", level, "", menu->id); + report(RPT_DEBUG, "%*sdisplayname = \"%s\"", level + 1, "", menu->displayname); + report(RPT_DEBUG, "%*sentries = [", level + 1, ""); + + for (kdb_long_long_t i = 0; i < menu->entriesSize; ++i) + { + switch (menu->entryTypes[i]) + { + case MENU_ENTRY_TYPE_MENU: + menu_dump(menu->entries[i].menu, level + 2); + break; + case MENU_ENTRY_TYPE_COMMAND: + command_dump(menu->entries[i].command, level + 2); + break; } - } + + report(RPT_DEBUG, "%*s]", level + 1, ""); + report(RPT_DEBUG, "%*s}", level, ""); } #endif diff --git a/clients/lcdexec/menu.h b/clients/lcdexec/menu.h index f0400b7b..a373498d 100644 --- a/clients/lcdexec/menu.h +++ b/clients/lcdexec/menu.h @@ -16,89 +16,144 @@ /* boolean values */ #ifndef TRUE -# define TRUE 1 +#define TRUE 1 #endif #ifndef FALSE -# define FALSE 0 +#define FALSE 0 #endif +#include -/** Symbolic names for the types of a MenuEntry */ -typedef enum { - MT_UNKNOWN = 0x00, /**< Unknown MenuEntry type. */ - MT_MENU = 0x10, /**< MenuEntry representing a menu. */ - MT_EXEC = 0x20, /**< MenuEntry representing an executable command. */ - MT_ARGUMENT = 0x40, /**< Mask denoting a parameter of any type */ - MT_ACTION = 0x80, /**< Automatically generated action menu */ - - MT_ARG_SLIDER = 0x41, /**< MenuEntry representing a slider parameter. */ - MT_ARG_RING = 0x42, /**< MenuEntry representing a ring parameter. */ - MT_ARG_NUMERIC = 0x43, /**< MenuEntry representing a numeric input parameter. */ - MT_ARG_ALPHA = 0x44, /**< MenuEntry representing a alpha input parameter. */ - MT_ARG_IP = 0x45, /**< MenuEntry representing a IP input parameter. */ - MT_ARG_CHECKBOX = 0x46, /**< MenuEntry representing a checkbox input parameter. */ -} MenuType; - - -/** Data structure to hold a menu entry in \c lcdexec */ -typedef struct menu_entry { - // Variables necessary for multiple/all types - char *name; /**< Name of the menu entry (from section name). */ - char *displayname; /**< Visible name of the entry. */ - int id; /**< Internal ID of the entry. */ - MenuType type; /**< Type of the entry. */ - struct menu_entry *parent; /**< Parent menu entry. */ - int numChildren; /**< # of child entries. */ - struct menu_entry *children; /**< Subordinate menu entries (for type \c MT_MENU & \c MT_EXEC). */ - struct menu_entry *next; /**< Next sibling menu entry (for type \c MT_MENU). */ - - // Variables specific to one special type - union data { - struct exec{ // elements necessary for type MT_EXEC - char *command; /**< Command to execute. */ - int feedback; /**< Feedback flag. */ - } exec; - struct slider { // elements necessary for type MT_ARG_SLIDER - int value; /**< Numeric value of slider. */ - int minval; /**< Minimal allowed value. */ - int maxval; /**< Maximal allowed value. */ - int stepsize; /**< Increments/decrement for value. */ - char *mintext; /**< Label for the min. value. */ - char *maxtext; /**< Label for the max. value. */ - } slider; - struct ring { // elements necessary for type MT_ARG_RING - int value; /**< Index into list of alternatives. */ - char **strings; /**< List of alternatives. */ - } ring; - struct numeric { // elements necessary for type MT_ARG_NUMERIC - int value; /**< Numeric input value. */ - int minval; /**< Minimal allowed value. */ - int maxval; /**< Maximal allowed value. */ - } numeric; - struct alpha { // elements necessary for type MT_ARG_ALPHA - char *value; /**< Text value. */ - int minlen; /**< Maximal allowed length. */ - int maxlen; /**< Minimal required length. */ - char *allowed; /**< Characters allowed in input. */ - } alpha; - struct ip { // elements necessary for type MT_ARG_IP - char *value; /**< IP address value. */ - int v6; /**< Flag: use IPv6 editing logic. */ - } ip; - struct checkbox { // elements necessary for type MT_ARG_CHECKBOX - int value; /**< Checkbox value. */ - int allow_gray; /**< Flag for tristate chechboxes. */ - char *map[3]; /**< Replacement strings for each value. */ - } checkbox; - } data; +typedef enum +{ + MENU_ENTRY_TYPE_COMMAND = 0, + MENU_ENTRY_TYPE_MENU = 1, +} MenuEntryType; + +typedef enum +{ + COMMAND_PARAMETER_TYPE_SLIDER = 0, + COMMAND_PARAMETER_TYPE_CHECKBOX = 1, + COMMAND_PARAMETER_TYPE_NUMERIC = 2, + COMMAND_PARAMETER_TYPE_RING = 3, + COMMAND_PARAMETER_TYPE_ALPHA = 4, + COMMAND_PARAMETER_TYPE_IP = 5, +} CommandParameterType; + +typedef enum +{ + CHECKBOX_STATE_OFF = 0, + CHECKBOX_STATE_ON = 1, + CHECKBOX_STATE_GRAY = 2, +} CheckboxState; + +typedef union +{ + struct SliderParameter * slider; + struct CheckboxParameter * checkbox; + struct NumericParameter * numeric; + struct RingParameter * ring; + struct AlphaParameter * alpha; + struct IpParameter * ip; +} CommandParameter; + +typedef union +{ + struct Command * command; + struct Menu * menu; } MenuEntry; +typedef struct Command +{ + kdb_long_t id; + kdb_long_t actionId; + const char *displayname; + const char *exec; + kdb_boolean_t feedback; + kdb_long_long_t parametersSize; + CommandParameterType *parameterTypes; + CommandParameter *parameters; +} Command; + +typedef struct Menu +{ + kdb_long_t id; + const char *displayname; + kdb_long_long_t entriesSize; + MenuEntryType *entryTypes; + MenuEntry *entries; +} Menu; + +typedef struct AlphaParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + const char *allowedchars; + kdb_long_t minlength; + kdb_long_t maxlength; + const char *initialValue; + char *value; +} AlphaParameter; + +typedef struct CheckboxParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + kdb_boolean_t allowgray; + const char *offtext; + const char *ontext; + const char *graytext; + CheckboxState value; +} CheckboxParameter; + +typedef struct IpParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + kdb_boolean_t v6; + const char *initialValue; + char *value; +} IpParameter; + +typedef struct NumericParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + kdb_long_t minvalue; + kdb_long_t maxvalue; + kdb_long_t value; +} NumericParameter; + +typedef struct RingParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + kdb_long_long_t stringsCount; + const char **strings; + size_t stringsLength; + kdb_long_t value; +} RingParameter; + +typedef struct SliderParameter +{ + kdb_long_t id; + const char *displayname; + const char *envname; + const char *mintext; + const char *maxtext; + kdb_long_t minvalue; + kdb_long_t maxvalue; + kdb_long_t stepsize; + kdb_long_t value; +} SliderParameter; -MenuEntry *menu_read(MenuEntry *parent, const char *name); -int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock); -MenuEntry *menu_find_by_id(MenuEntry *me, int id); -const char *menu_command(MenuEntry *me); -void menu_free(MenuEntry *me); -void menu_dump(MenuEntry *me); +int main_menu_sock_send(Menu *menu, int sock); +void main_menu_process(Menu *menu); +void menu_dump(Menu *menu, int level); #endif diff --git a/clients/lcdexec/specification/lcdexec-spec.ini b/clients/lcdexec/specification/lcdexec-spec.ini new file mode 100644 index 00000000..5d965b4c --- /dev/null +++ b/clients/lcdexec/specification/lcdexec-spec.ini @@ -0,0 +1,531 @@ +; using /_/ is not possible with current spec setup + +[] +mountpoint = lcdexec.conf +infos/plugins = ni type range reference network ; path + +[lcdexec/address] +check/ipaddr = +type = string +check/type = string +default = 127.0.0.1 +description = Address of the LCDd server +opt = a +opt/long = address + +[lcdexec/port] +check/port = +type = unsigned_short +check/type = unsigned_short +default = 13666 +description = Port to attach to LCDd server +opt = p +opt/long = port + +[lcdexec/reportlevel] +type = unsigned_short +check/type = unsigned_short +check/range = 0-5 +default = 2 +description = Sets the reporting level, defaults to warnings and errors only. +opt = r +opt/long = report-level + +[lcdexec/reporttosyslog] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Should we report to syslog instead of stderr? +opt = s +opt/long = report-to-syslog + +[lcdexec/foreground] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "whether to run in foreground" +opt = f +opt/long = foreground +opt/arg = none + +[lcdexec/pidfile] +type = string +check/type = string +;check/path = ; TODO (elektra): too many plugins, does not have to exist +default = /var/run/lcdexec.pid +description = "PidFile location when running as daemon" + +[lcdexec/shell] +type = string +check/type = string +;check/path = ; TODO (elektra): too many plugins +default = /bin/sh +description = "shell to use for executing programs; any shell that understands: -c COMMAND" +env = SHELL + +[lcdexec/displayname] +type = string +check/type = string +default = lcdexec +description = "display name for the main menu" + +[menu/main] +type = struct_ref +check/type = any +require = +check/reference = single +check/reference/restrict = ../menu/# +description = "reference to the main menu" + +[menu/menu/#] +type = struct +check/type = any +default = "" +gen/struct/type = Menu +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/menu/#/type] +type = discriminator +check/type = enum +check/enum = #1 +check/enum/#0 = command +check/enum/#1 = menu +default = menu ; TODO (elektra): should be constant +gen/enum/type = MenuEntryType +gen/enum/create = 0 + +[menu/menu/#/displayname] +type = string +check/type = string +require = +description = "name to display in the parent menu" + +[menu/menu/#/entries] +check/reference = recursive +check/reference/restrict = #1 +check/reference/restrict/#0 = ../../../command/# +check/reference/restrict/#1 = ../../../menu/# +description = "array of references to entries (commands or sub-menus) in this menu" + +[menu/menu/#/entries/#] +type = struct_ref +check/type = any +default = "" +gen/reference/discriminator = entryTypes +gen/reference/discriminator/key = type +gen/reference/discriminator/enum = MenuEntryType +gen/reference/discriminator/union = MenuEntry +gen/reference/restrict/#0/discriminator = command +gen/reference/restrict/#1/discriminator = menu +gen/union/create = 0 + +[menu/command/#] +type = struct +check/type = any +default = "" +gen/struct/type = Command +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/command/#/type] +type = discriminator +check/type = enum +check/enum = #1 +check/enum/#0 = command +check/enum/#1 = menu +default = command ; TODO (elektra): should be constant +gen/enum/type = MenuEntryType +gen/enum/create = 0 + +[menu/command/#/entries] +check/reference/restrict = + +[menu/command/#/parameters] +check/reference = single +check/reference/restrict = #5 +check/reference/restrict/#0 = ../../../parameter/slider/# +check/reference/restrict/#1 = ../../../parameter/checkbox/# +check/reference/restrict/#2 = ../../../parameter/numeric/# +check/reference/restrict/#3 = ../../../parameter/ring/# +check/reference/restrict/#4 = ../../../parameter/alpha/# +check/reference/restrict/#5 = ../../../parameter/ip/# + +[menu/command/#/parameters/#] +type = struct_ref +check/type = any +default = "" +gen/reference/discriminator = parameterTypes +gen/reference/discriminator/key = type +gen/reference/discriminator/enum = CommandParameterType +gen/reference/discriminator/union = CommandParameter +gen/reference/restrict/#0/discriminator = slider +gen/reference/restrict/#1/discriminator = checkbox +gen/reference/restrict/#2/discriminator = numeric +gen/reference/restrict/#3/discriminator = ring +gen/reference/restrict/#4/discriminator = alpha +gen/reference/restrict/#5/discriminator = ip +gen/union/create = 0 + +[menu/command/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the menu" + +[menu/command/#/exec] +type = string +check/type = string +require = +description = "what the command should do" + +[menu/command/#/feedback] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "show a temporary feedback screen upon completion" + +[menu/parameter/slider/#] +type = struct +check/type = any +default = "" +gen/struct/type = SliderParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/slider/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = slider ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/slider/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/slider/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/slider/#/value] +type = long +check/type = long +default = 0 +description = "initial value of the argument" + +[menu/parameter/slider/#/minvalue] +type = long +check/type = long +default = 0 +description = "minimum value of the argument" + +[menu/parameter/slider/#/maxvalue] +type = long +check/type = long +default = 1000 +description = "maximum value of the argument" + +[menu/parameter/slider/#/stepsize] +type = long +check/type = long +default = 1 +description = "step size used" + +[menu/parameter/slider/#/mintext] +type = string +check/type = string +default = "" +description = "Text at minimal value" + +[menu/parameter/slider/#/maxtext] +type = string +check/type = string +default = "" +description = "Text at maximal value" + +[menu/parameter/checkbox/#] +type = struct +check/type = any +default = "" +gen/struct/type = CheckboxParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/checkbox/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = checkbox ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/checkbox/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/checkbox/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/checkbox/#/value] +type = enum +check/type = enum +check/enum = #2 +check/enum/#0 = off +check/enum/#1 = on +check/enum/#2 = gray +default = off +description = "initial value of the argument" +gen/enum/type = CheckboxState +gen/enum/create = 0 + +[menu/parameter/checkbox/#/allowgray] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = whether to allow the third (gray) state + +[menu/parameter/checkbox/#/offtext] +type = string +check/type = string +description = text to display when in off state +default = "" ; TODO: has very weird behaviour + +[menu/parameter/checkbox/#/ontext] +type = string +check/type = string +description = text to display when in on state +default = "" ; TODO: has very weird behaviour + +[menu/parameter/checkbox/#/graytext] +type = string +check/type = string +description = text to display when in gray state +default = "" ; TODO: has very weird behaviour + +[menu/parameter/numeric/#] +type = struct +check/type = any +default = "" +gen/struct/type = NumericParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/numeric/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = numeric ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/numeric/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/numeric/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/numeric/#/value] +type = long +check/type = long +default = 0 +description = "initial value of the argument" + +[menu/parameter/numeric/#/minvalue] +type = long +check/type = long +default = 0 +description = "minimum value of the argument" + +[menu/parameter/numeric/#/maxvalue] +type = long +check/type = long +default = 1000 +description = "maximum value of the argument" + +[menu/parameter/ring/#] +type = struct +check/type = any +default = "" +gen/struct/type = RingParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/ring/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = ring ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/ring/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/ring/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/ring/#/value] +type = long +check/type = long +default = 0 +description = "initial value of the argument" + +[menu/parameter/ring/#/strings/#] +type = string +check/type = string +description = "list of alternative strings to choose from" +require = +gen/struct/array/sizefield = stringsCount + +[menu/parameter/alpha/#] +type = struct +check/type = any +default = "" +gen/struct/type = AlphaParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/alpha/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = alpha ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/alpha/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/alpha/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/alpha/#/value] +type = string +check/type = string +default = "" +description = "initial value of the argument" +gen/struct/field = initialValue + +[menu/parameter/alpha/#/allowedchars] +type = string +check/type = string +default = ABCDEFGHIJKLMNOPQRSTUVWXYZ +description = "range of characters allowed" + +[menu/parameter/alpha/#/minlength] +type = long +check/type = long +default = 0 +description = "minimum length of the argument" + +[menu/parameter/alpha/#/maxlength] +type = long +check/type = long +default = 100 +description = "maximum length of the argument" + +[menu/parameter/ip/#] +type = struct +check/type = any +default = "" +gen/struct/type = IpParameter +gen/struct/alloc = 1 +gen/struct/create = 0 + +[menu/parameter/ip/#/type] +type = discriminator +check/type = enum +check/enum = #5 +check/enum/#0 = slider +check/enum/#1 = checkbox +check/enum/#2 = numeric +check/enum/#3 = ring +check/enum/#4 = alpha +check/enum/#5 = ip +default = ip ; TODO (elektra): should be constant +gen/enum/type = CommandParameterType +gen/enum/create = 0 + +[menu/parameter/ip/#/displayname] +type = string +check/type = string +default = "" +description = "name to display in the command" + +[menu/parameter/ip/#/envname] +type = string +check/type = string +require = +description = "name of the environment variable used by the parameter" + +[menu/parameter/ip/#/value] +type = string +check/type = string +default = "" +description = "initial value of the argument" +gen/struct/field = initialValue + +[menu/parameter/ip/#/v6] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "whether or not to use IPv6" \ No newline at end of file diff --git a/clients/lcdproc/.cvsignore b/clients/lcdproc/.cvsignore deleted file mode 100644 index 74899372..00000000 --- a/clients/lcdproc/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -.deps -Makefile -Makefile.in -lcdproc diff --git a/clients/lcdproc/.gitignore b/clients/lcdproc/.gitignore new file mode 100644 index 00000000..30fd6dab --- /dev/null +++ b/clients/lcdproc/.gitignore @@ -0,0 +1,8 @@ +.deps +Makefile +Makefile.in +lcdproc +elektragen.c +elektragen.h +lcdproc.mount.sh +lcdproc.spec.eqd diff --git a/clients/lcdproc/Makefile.am b/clients/lcdproc/Makefile.am index 1141367c..b9184529 100644 --- a/clients/lcdproc/Makefile.am +++ b/clients/lcdproc/Makefile.am @@ -1,10 +1,14 @@ ## Process this file with automake to produce Makefile.in - sysconf_DATA = lcdproc.conf bin_PROGRAMS = lcdproc lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h eyebox.c eyebox.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c util.c util.h iface.c iface.h +nodist_lcdproc_SOURCES = elektragen.c elektragen.h +lcdproc.$(OBJEXT): elektragen.c elektragen.h +BUILT_SOURCES= elektragen.c elektragen.h + +CLEANFILES = elektragen.c elektragen.h lcdproc.spec.eqd lcdproc.mount.sh lcdproc_LDADD = ../../shared/libLCDstuff.a @@ -14,7 +18,17 @@ endif AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -DPIDFILEDIR=\"$(pidfiledir)\" - EXTRA_DIST = $(sysconf_DATA) +scriptsdir = $(prefix)/libexec +scripts_DATA = lcdproc.mount.sh + +specdir = $(prefix)/share/lcdproc +spec_DATA = lcdproc.spec.eqd + +KDB ?= kdb +elektragen.c elektragen.h lcdproc.spec.eqd lcdproc.mount.sh: specification/lcdproc-spec.ini + $(KDB) gen -F ni=specification/lcdproc-spec.ini highlevel "spec/sw/lcdproc/lcdproc/#0/current" elektragen initFn=loadConfiguration helpFn=printHelpMessage embeddedSpec=defaults headers=screen_config.h tagPrefix=CONF_; mv elektragen.mount.sh lcdproc.mount.sh; mv elektragen.spec.eqd lcdproc.spec.eqd + + ## EOF diff --git a/clients/lcdproc/batt.c b/clients/lcdproc/batt.c index 83dea90d..edeb89e8 100644 --- a/clients/lcdproc/batt.c +++ b/clients/lcdproc/batt.c @@ -23,6 +23,8 @@ #include "batt.h" #include "machine.h" +#include "elektragen.h" + /** Map status code > status text */ typedef struct { int status; @@ -98,10 +100,11 @@ battery_status(int status) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -battery_screen(int rep, int display, int *flags_ptr) +battery_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { int acstat = 0, battstat = 0, percent = 0; int gauge_wid = lcd_wid - 2; diff --git a/clients/lcdproc/batt.h b/clients/lcdproc/batt.h index baec58bb..51fa2791 100644 --- a/clients/lcdproc/batt.h +++ b/clients/lcdproc/batt.h @@ -1,6 +1,8 @@ #ifndef BATT_H #define BATT_H -int battery_screen(int rep, int display, int *flags_ptr); +#include + +int battery_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/chrono.c b/clients/lcdproc/chrono.c index 99150c2c..48e83f03 100644 --- a/clients/lcdproc/chrono.c +++ b/clients/lcdproc/chrono.c @@ -37,7 +37,6 @@ # endif #endif -#include "shared/configfile.h" #include "shared/sockets.h" #include "main.h" @@ -45,6 +44,7 @@ #include "machine.h" #include "chrono.h" +#include "elektragen.h" static char *tickTime(char *time, int heartbeat); @@ -66,10 +66,11 @@ static char *tickTime(char *time, int heartbeat); * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -time_screen(int rep, int display, int *flags_ptr) +time_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { char now[40]; char today[40]; @@ -86,8 +87,8 @@ time_screen(int rep, int display, int *flags_ptr) *flags_ptr |= INITIALIZED; /* get config values */ - timeFormat = config_get_string("TimeDate", "TimeFormat", 0, "%H:%M:%S"); - dateFormat = config_get_string("TimeDate", "DateFormat", 0, "%b %d %Y"); + timeFormat = elektraGet(elektra, CONF_TIMEDATE_TIMEFORMAT); + dateFormat = elektraGet(elektra, CONF_TIMEDATE_DATEFORMAT); sock_send_string(sock, "screen_add T\n"); sock_printf(sock, "screen_set T -name {Time Screen: %s}\n", get_hostname()); @@ -120,7 +121,7 @@ time_screen(int rep, int display, int *flags_ptr) tickTime(now, heartbeat); if (lcd_hgt >= 4) { - char tmp[40]; /* should be large enough */ + char tmp[64]; /* should be large enough */ machine_get_uptime(&uptime, &idle); @@ -146,7 +147,8 @@ time_screen(int rep, int display, int *flags_ptr) sock_printf(sock, "widget_set T two %i 3 {%s}\n", xoffs, today); /* display the time & idle time... */ - sprintf(tmp, "%s %3i%% idle", now, (int) idle); + int idle_int = max(0, min(100, (int) idle)); + sprintf(tmp, "%s %3i%% idle", now, idle_int); xoffs = (lcd_wid > strlen(tmp)) ? ((lcd_wid - strlen(tmp)) / 2) + 1 : 1; if (display) sock_printf(sock, "widget_set T three %i 4 {%s}\n", xoffs, tmp); @@ -186,10 +188,11 @@ time_screen(int rep, int display, int *flags_ptr) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -clock_screen(int rep, int display, int *flags_ptr) +clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { char now[40]; char today[40]; @@ -207,9 +210,9 @@ clock_screen(int rep, int display, int *flags_ptr) *flags_ptr |= INITIALIZED; /* get config values */ - timeFormat = config_get_string("OldTime", "TimeFormat", 0, "%H:%M:%S"); - dateFormat = config_get_string("OldTime", "DateFormat", 0, "%b %d %Y"); - showTitle = config_get_bool("OldTime", "ShowTitle", 0, 1); + timeFormat = elektraGet(elektra, CONF_OLDTIME_TIMEFORMAT); + dateFormat = elektraGet(elektra, CONF_OLDTIME_DATEFORMAT); + showTitle = elektraGet(elektra, CONF_OLDTIME_SHOWTITLE); sock_send_string(sock, "screen_add O\n"); sock_printf(sock, "screen_set O -name {Old Clock Screen: %s}\n", get_hostname()); @@ -297,10 +300,11 @@ clock_screen(int rep, int display, int *flags_ptr) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -uptime_screen(int rep, int display, int *flags_ptr) +uptime_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { int xoffs; int days, hour, min, sec; @@ -389,10 +393,11 @@ uptime_screen(int rep, int display, int *flags_ptr) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -big_clock_screen(int rep, int display, int *flags_ptr) +big_clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { time_t thetime; struct tm *rtime; @@ -405,7 +410,7 @@ big_clock_screen(int rep, int display, int *flags_ptr) int digits = (lcd_wid >= 20) ? 6 : 4; int xoffs = 0; - int showSecs = config_get_bool("BigClock", "showSecs", 0, 1); + int showSecs = elektraGet(elektra, CONF_BIGCLOCK_SHOWSECS); if (!showSecs) { digits = 4; } @@ -480,10 +485,11 @@ big_clock_screen(int rep, int display, int *flags_ptr) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -mini_clock_screen(int rep, int display, int *flags_ptr) +mini_clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { char now[40]; time_t thetime; @@ -499,7 +505,7 @@ mini_clock_screen(int rep, int display, int *flags_ptr) *flags_ptr |= INITIALIZED; /* get config values */ - timeFormat = config_get_string("MiniClock", "TimeFormat", 0, "%H:%M"); + timeFormat = elektraGet(elektra, CONF_MINICLOCK_TIMEFORMAT); sock_send_string(sock, "screen_add N\n"); sock_send_string(sock, "screen_set N -name {Mini Clock Screen} -heartbeat off\n"); diff --git a/clients/lcdproc/chrono.h b/clients/lcdproc/chrono.h index 2732c173..800c7bd6 100644 --- a/clients/lcdproc/chrono.h +++ b/clients/lcdproc/chrono.h @@ -1,10 +1,12 @@ #ifndef CHRONO_H #define CHRONO_H -int clock_screen(int rep, int display, int *flags_ptr); -int uptime_screen(int rep, int display, int *flags_ptr); -int time_screen(int rep, int display, int *flags_ptr); -int big_clock_screen(int rep, int display, int *flags_ptr); -int mini_clock_screen(int rep, int display, int *flags_ptr); +#include + +int clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int uptime_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int time_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int big_clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int mini_clock_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/cpu.c b/clients/lcdproc/cpu.c index 5576ab2d..02fe3dc4 100644 --- a/clients/lcdproc/cpu.c +++ b/clients/lcdproc/cpu.c @@ -27,6 +27,7 @@ #include "cpu.h" #include "util.h" +#include "elektragen.h" /** * CPU screen shows info about percentage of the CPU being used @@ -45,10 +46,11 @@ * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -cpu_screen(int rep, int display, int *flags_ptr) +cpu_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { #undef CPU_BUF_SIZE #define CPU_BUF_SIZE 4 @@ -190,10 +192,11 @@ cpu_screen(int rep, int display, int *flags_ptr) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -cpu_graph_screen(int rep, int display, int *flags_ptr) +cpu_graph_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { #undef CPU_BUF_SIZE #define CPU_BUF_SIZE 2 diff --git a/clients/lcdproc/cpu.h b/clients/lcdproc/cpu.h index 961c5dd9..b5c1c666 100644 --- a/clients/lcdproc/cpu.h +++ b/clients/lcdproc/cpu.h @@ -1,7 +1,9 @@ #ifndef CPU_H #define CPU_H -int cpu_screen(int rep, int display, int *flags_ptr); -int cpu_graph_screen(int rep, int display, int *flags_ptr); +#include + +int cpu_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int cpu_graph_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/cpu_smp.c b/clients/lcdproc/cpu_smp.c index c5f362c9..50fa330d 100644 --- a/clients/lcdproc/cpu_smp.c +++ b/clients/lcdproc/cpu_smp.c @@ -41,6 +41,7 @@ #include "machine.h" #include "cpu_smp.h" +#include "elektragen.h" /** * CPU screen shows info about percentage of the CPU being used @@ -48,10 +49,11 @@ * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -cpu_smp_screen (int rep, int display, int *flags_ptr) +cpu_smp_screen (int rep, int display, int *flags_ptr, Elektra * elektra) { #undef CPU_BUF_SIZE #define CPU_BUF_SIZE 4 diff --git a/clients/lcdproc/cpu_smp.h b/clients/lcdproc/cpu_smp.h index 2a66c770..d53903da 100644 --- a/clients/lcdproc/cpu_smp.h +++ b/clients/lcdproc/cpu_smp.h @@ -1,6 +1,8 @@ #ifndef CPU_SMP_H #define CPU_SMP_H -int cpu_smp_screen(int rep, int display, int *flags_ptr); +#include + +int cpu_smp_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/disk.c b/clients/lcdproc/disk.c index 4d776aee..ee1dec27 100644 --- a/clients/lcdproc/disk.c +++ b/clients/lcdproc/disk.c @@ -30,6 +30,7 @@ #include "disk.h" #include "util.h" +#include "elektragen.h" /** * Gives disk stats. @@ -49,10 +50,11 @@ * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -disk_screen(int rep, int display, int *flags_ptr) +disk_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { mounts_type mnt[256]; int count = 0; diff --git a/clients/lcdproc/disk.h b/clients/lcdproc/disk.h index e934b531..8399a15f 100644 --- a/clients/lcdproc/disk.h +++ b/clients/lcdproc/disk.h @@ -1,6 +1,8 @@ #ifndef DISK_H #define DISK_H -int disk_screen(int rep, int display, int *flags_ptr); +#include + +int disk_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/iface.c b/clients/lcdproc/iface.c index 40e50cb7..0b71f33b 100644 --- a/clients/lcdproc/iface.c +++ b/clients/lcdproc/iface.c @@ -23,29 +23,43 @@ #include "shared/sockets.h" #include "shared/report.h" -#include "shared/configfile.h" #include "main.h" #include "machine.h" #include "util.h" #include "iface.h" +#include "elektragen.h" + #define UNSET_INT -1 #define UNSET_STR "\01" - static int iface_count = 0; /* number of interfaces */ -static char unit_label[10] = "B"; /* default unit label is Bytes */ +static IfaceUnit unit = IFACE_UNIT_BYTE; /* default unit label is Bytes */ static int transfer_screen = 0; /* by default, transfer screen is not shown */ +static inline char * +unit_label(IfaceUnit unit) +{ + switch (unit) + { + case IFACE_UNIT_BYTE: + return "B"; + case IFACE_UNIT_BIT: + return "b"; + case IFACE_UNIT_PACKET: + return "pkt"; + default: + return NULL; + } +} + /** Reads and parses configuration file. * \return 0 on success, -1 on error */ static int -iface_process_configfile(void) +iface_process_config(Elektra * elektra) { - const char *unit; - debug(RPT_DEBUG, "%s()", __FUNCTION__); /* Read config settings */ @@ -54,42 +68,19 @@ iface_process_configfile(void) sprintf(iface_label, "Interface%i", iface_count); debug(RPT_DEBUG, "Label %s count %i", iface_label, iface_count); - iface[iface_count].name = strdup(config_get_string("Iface", iface_label, 0, "")); - if (iface[iface_count].name == NULL) { - report(RPT_CRIT, "malloc failure"); - return -1; - } - if (*iface[iface_count].name == '\0') - break; + iface[iface_count].name = strdup(elektraGetV(elektra, CONF_IFACE_INTERFACE_NAME, iface_count)); + sprintf(iface_label, "Alias%i", iface_count); - iface[iface_count].alias = strdup(config_get_string("Iface", iface_label, 0, iface[iface_count].name)); - if (iface[iface_count].alias == NULL) - /* - * make alias the same as the interface name in case - * strdup() failed - */ + iface[iface_count].alias = strdup(elektraGetV(elektra, CONF_IFACE_INTERFACE_ALIAS, iface_count)); + if (strlen(iface[iface_count].alias) == 0) iface[iface_count].alias = iface[iface_count].name; + debug(RPT_DEBUG, "Interface %i: %s alias %s", iface_count, iface[iface_count].name, iface[iface_count].alias); } - unit = config_get_string("Iface", "Unit", 0, "byte"); - if ((strcasecmp(unit, "byte") == 0) || - (strcasecmp(unit, "bytes") == 0)) - strncpy(unit_label, "B", sizeof(unit_label)); - else if ((strcasecmp(unit, "bit") == 0) || - (strcasecmp(unit, "bits") == 0)) - strncpy(unit_label, "b", sizeof(unit_label)); - else if ((strcasecmp(unit, "packet") == 0) || - (strcasecmp(unit, "packets") == 0)) - strncpy(unit_label, "pkt", sizeof(unit_label)); - else { - report(RPT_ERR, "illegal Unit value: %s", unit); - return -1; - } - unit_label[sizeof(unit_label) - 1] = '\0'; - - transfer_screen = config_get_bool("Iface", "Transfer", 0, 0); + unit = elektraGet(elektra, CONF_IFACE_UNIT); + transfer_screen = elektraGet(elektra, CONF_IFACE_TRANSFER); return 0; } @@ -113,10 +104,11 @@ iface_process_configfile(void) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -iface_screen(int rep, int display, int *flags_ptr) +iface_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { /* interval since last update */ unsigned int interval = difftime(time(NULL), iface[0].last_online); @@ -129,7 +121,7 @@ iface_screen(int rep, int display, int *flags_ptr) *flags_ptr |= INITIALIZED; /* get configuration options */ - iface_process_configfile(); + iface_process_config(elektra); /* set initial speed screen with widgets */ initialize_speed_screen(); @@ -198,16 +190,19 @@ initialize_speed_screen(void) /* multi-interfaces mode: one line per interface */ else { /* Set title */ - if (strstr(unit_label, "B")) { + switch (unit) + { + case IFACE_UNIT_BIT: + sock_printf(sock, "widget_set I title {Net Load (bits)}\n"); + break; + case IFACE_UNIT_BYTE: sock_printf(sock, "widget_set I title {Net Load (bytes)}\n"); - } - else { - if (strstr(unit_label, "b")) { - sock_printf(sock, "widget_set I title {Net Load (bits)}\n"); - } - else { - sock_printf(sock, "widget_set I title {Net Load (packets)}\n"); - } + break; + case IFACE_UNIT_PACKET: + sock_printf(sock, "widget_set I title {Net Load (packets)}\n"); + break; + default: + break; } /* frame from (2, left) to (width, height) that is iface_count lines high */ @@ -238,16 +233,16 @@ initialize_speed_screen(void) * to binary multiples (1024 bytes = 1 KiB). */ void -format_value (char *buff, double value, char *unit) +format_value (char *buff, double value, IfaceUnit unit) { char *mag; /* Convert bytes to bits, if necessary */ - if (strstr(unit, "b")) + if (unit == IFACE_UNIT_BIT) value *= 8; /* If units are bytes, then divide by 2^10, otherwise by 10^3 */ - mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f); + mag = convert_double(&value, (unit == IFACE_UNIT_BYTE) ? 1024 : 1000, 1.0f); /*- * Formatting rules: @@ -255,9 +250,9 @@ format_value (char *buff, double value, char *unit) * - otherwise format with 3 precision */ if (mag[0] == 0) - sprintf(buff, "%8ld %s", (long) value, unit); + sprintf(buff, "%8ld %s", (long) value, unit_label(unit)); else - sprintf(buff, "%7.3f %s%s", value, mag, unit); + sprintf(buff, "%7.3f %s%s", value, mag, unit_label(unit)); } @@ -272,14 +267,14 @@ format_value (char *buff, double value, char *unit) * to binary multiples (1024 bytes = 1 KiB). */ void -format_value_multi_interface(char *buff, double value, char *unit) +format_value_multi_interface(char *buff, double value, IfaceUnit unit) { char *mag; - if (strstr(unit, "b")) + if (unit == IFACE_UNIT_BIT) value *= 8; - mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f); + mag = convert_double(&value, (unit == IFACE_UNIT_BYTE) ? 1024 : 1000, 1.0f); /*- * Formatting rules: @@ -351,33 +346,33 @@ actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index) if ((iface_count == 1) && ( lcd_hgt >= 4)) { if (iface->status == up) { /* Calculate and actualize download speed */ - if (strstr(unit_label, "pkt")) { + if (unit == IFACE_UNIT_PACKET) { rc_speed = (iface->rc_pkt - iface->rc_pkt_old) / interval; - sprintf(speed, "%8ld %s", (long) rc_speed, unit_label); + sprintf(speed, "%8ld %s", (long) rc_speed, unit_label(unit)); } else { rc_speed = (iface->rc_byte - iface->rc_byte_old) / interval; - format_value(speed, rc_speed, unit_label); + format_value(speed, rc_speed, unit); } sock_printf(sock, "widget_set I dl 1 2 {DL: %*s/s}\n", lcd_wid - 6, speed); /* Calculate and actualize upload speed */ - if (strstr(unit_label, "pkt")) { + if (unit == IFACE_UNIT_PACKET) { tr_speed = (iface->tr_pkt - iface->tr_pkt_old) / interval; - sprintf(speed, "%8ld %s", (long)tr_speed, unit_label); + sprintf(speed, "%8ld %s", (long)tr_speed, unit_label(unit)); } else { tr_speed = (iface->tr_byte - iface->tr_byte_old) / interval; - format_value(speed, tr_speed, unit_label); + format_value(speed, tr_speed, unit); } sock_printf(sock, "widget_set I ul 1 3 {UL: %*s/s}\n", lcd_wid - 6, speed); /* Calculate and actualize total speed */ - if (strstr(unit_label, "pkt")) { - sprintf(speed, "%7ld %s", (long)(rc_speed + tr_speed), unit_label); + if (unit == IFACE_UNIT_PACKET) { + sprintf(speed, "%7ld %s", (long)(rc_speed + tr_speed), unit_label(unit)); } else { - format_value(speed, rc_speed + tr_speed, unit_label); + format_value(speed, rc_speed + tr_speed, unit); } sock_printf(sock, "widget_set I total 1 4 {Total: %*s/s}\n", lcd_wid - 9, speed); } @@ -393,7 +388,7 @@ actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index) char speed1[20]; /* buffer to store the formated speed string */ if (iface->status == up) { - if (strstr(unit_label, "pkt")) { + if (unit == IFACE_UNIT_PACKET) { rc_speed = (iface->rc_pkt - iface->rc_pkt_old) / interval; tr_speed = (iface->tr_pkt - iface->tr_pkt_old) / interval; } @@ -401,8 +396,8 @@ actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index) rc_speed = (iface->rc_byte - iface->rc_byte_old) / interval; tr_speed = (iface->tr_byte - iface->tr_byte_old) / interval; } - format_value_multi_interface(speed, rc_speed, unit_label); - format_value_multi_interface(speed1, tr_speed, unit_label); + format_value_multi_interface(speed, rc_speed, unit); + format_value_multi_interface(speed1, tr_speed, unit); if (lcd_wid > 16) sock_printf(sock, "widget_set I i%1d 1 %1d {%5.5s U:%.4s D:%.4s}\n", index, index+1, iface->alias, speed1, speed); @@ -478,15 +473,15 @@ actualize_transfer_screen(IfaceInfo *iface, int index) if ((iface_count == 1) && (lcd_hgt >= 4)) { if (iface->status == up) { /* download traffic */ - format_value(transfer, iface->rc_byte, "B"); + format_value(transfer, iface->rc_byte, IFACE_UNIT_BYTE); sock_printf(sock, "widget_set NT dl 1 2 {DL: %*s}\n", lcd_wid - 4, transfer); /* upload traffic */ - format_value(transfer, iface->tr_byte, "B"); + format_value(transfer, iface->tr_byte, IFACE_UNIT_BYTE); sock_printf(sock, "widget_set NT ul 1 3 {UL: %*s}\n", lcd_wid - 4, transfer); /* total traffic */ - format_value(transfer, iface->rc_byte + iface->tr_byte, "B"); + format_value(transfer, iface->rc_byte + iface->tr_byte, IFACE_UNIT_BYTE); sock_printf(sock, "widget_set NT total 1 4 {Total: %*s}\n", lcd_wid - 7, transfer); } else { @@ -501,8 +496,8 @@ actualize_transfer_screen(IfaceInfo *iface, int index) char transfer1[20]; /* buffer to store the formated traffic string */ if (iface->status == up) { - format_value_multi_interface(transfer, iface->rc_byte, "B"); - format_value_multi_interface(transfer1, iface->tr_byte, "B"); + format_value_multi_interface(transfer, iface->rc_byte, IFACE_UNIT_BYTE); + format_value_multi_interface(transfer1, iface->tr_byte, IFACE_UNIT_BYTE); if (lcd_wid > 16) sock_printf(sock, "widget_set NT i%1d 1 %1d {%5.5s U:%.4s D:%.4s}\n", index, index+1, iface->alias, transfer1, transfer); diff --git a/clients/lcdproc/iface.h b/clients/lcdproc/iface.h index cc6dbaaf..a708db5d 100644 --- a/clients/lcdproc/iface.h +++ b/clients/lcdproc/iface.h @@ -15,13 +15,15 @@ #ifndef IFACE_H #define IFACE_H +#include "elektragen.h" + /** max number of interfaces in multi-interface mode */ #define MAX_INTERFACES 3 IfaceInfo iface[MAX_INTERFACES]; /* interface info */ /** Update screen content */ -int iface_screen(int rep, int display, int *flags_ptr); +int iface_screen(int rep, int display, int *flags_ptr, Elektra * elektra); /** read interface stats from /proc/net/dev */ int get_iface_stats(IfaceInfo *interface); /** send initial commands to server to add the speed screen */ @@ -31,10 +33,10 @@ void initialize_transfer_screen(void); /** format the time in ASCII */ void get_time_string(char *buff, time_t last_online); /** format value, scaling value and adding proper suffixes */ -void format_value(char *buff, double value, char *unit); +void format_value(char *buff, double value, IfaceUnit unit); /** format value, scaling value and adding proper suffixes (for multi-interface * mode) */ -void format_value_multi_interface(char *buff, double value, char *unit); +void format_value_multi_interface(char *buff, double value, IfaceUnit unit); /** actualize widgets values in speed screen */ void actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index); /** actualize widgets values in transfer screen */ diff --git a/clients/lcdproc/load.c b/clients/lcdproc/load.c index d807def2..6e821c0d 100644 --- a/clients/lcdproc/load.c +++ b/clients/lcdproc/load.c @@ -19,13 +19,13 @@ # include "config.h" #endif -#include "shared/configfile.h" #include "shared/sockets.h" #include "main.h" #include "mode.h" #include "machine.h" #include "load.h" +#include "elektragen.h" /** * Shows a display very similar to "xload"'s histogram. @@ -44,10 +44,11 @@ * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return The backlight state */ int -xload_screen(int rep, int display, int *flags_ptr) +xload_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { static int gauge_hgt = 0; static double loads[LCD_MAX_WIDTH]; @@ -61,8 +62,8 @@ xload_screen(int rep, int display, int *flags_ptr) *flags_ptr |= INITIALIZED; /* get config values */ - lowLoad = config_get_float("Load", "LowLoad", 0, LOAD_MIN); - highLoad = config_get_float("Load", "HighLoad", 0, LOAD_MAX); + lowLoad = elektraGet(elektra, CONF_LOAD_LOWLOAD); + highLoad = elektraGet(elektra, CONF_LOAD_HIGHLOAD); gauge_hgt = (lcd_hgt > 2) ? (lcd_hgt - 1) : lcd_hgt; memset(loads, '\0', sizeof(double) * LCD_MAX_WIDTH); diff --git a/clients/lcdproc/load.h b/clients/lcdproc/load.h index 93bbe647..22d27f23 100644 --- a/clients/lcdproc/load.h +++ b/clients/lcdproc/load.h @@ -8,6 +8,8 @@ #define LOAD_MIN 0.05 #endif -int xload_screen(int rep, int display, int *flags_ptr); +#include + +int xload_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/machine_Linux.c b/clients/lcdproc/machine_Linux.c index 7bb72669..b5aa0e8a 100644 --- a/clients/lcdproc/machine_Linux.c +++ b/clients/lcdproc/machine_Linux.c @@ -419,10 +419,14 @@ machine_get_procs(LinkedList * procs) char buf[128]; /* ignore everything in proc except process ids */ - if (!strchr("1234567890", procdir->d_name[0])) + /* (pids are never longer than 7 characters) */ + if (!strchr("1234567890", procdir->d_name[0]) || strlen(procdir->d_name) > 7) continue; + + strcpy(buf, "/proc/"); + strcpy(&buf[6], procdir->d_name); + strcat(buf, "/status"); - sprintf(buf, "/proc/%s/status", procdir->d_name); if ((StatusFile = fopen(buf, "r")) == NULL) { /* * Not a serious error; process has finished before diff --git a/clients/lcdproc/main.c b/clients/lcdproc/main.c index 01b02baf..17095ada 100644 --- a/clients/lcdproc/main.c +++ b/clients/lcdproc/main.c @@ -36,8 +36,8 @@ #include "mode.h" #include "shared/sockets.h" #include "shared/report.h" -#include "shared/configfile.h" -#include "getopt.h" /* This is our local getopt.h! */ + +#include "elektragen.h" /* Import screens */ #include "batt.h" @@ -73,8 +73,15 @@ static struct utsname unamebuf; static void HelpScreen(int exit_state); static void exit_program(int val); static void main_loop(void); -static int process_configfile(char *cfgfile); +static int process_config(); + +static const char * help_prefix = + "lcdproc - LCDproc system status information viewer\n" + "\n" + "Copyright (c) 1999-2017 Selene Scriven, William Ferrell, and misc. contributors.\n" + "This program is released under the terms of the GNU General Public License.\n" + "\n"; #define TIME_UNIT 125000 /**< 1/8th second is a single time unit. */ @@ -97,23 +104,23 @@ static int process_configfile(char *cfgfile); ScreenMode sequence[] = { /* flags default ACTIVE will run by default */ - /* longname which on off inv timer flags */ - { "CPU", 'C', 1, 2, 0, 0xffff, ACTIVE, cpu_screen }, // [C]PU - { "Iface", 'I', 1, 2, 0, 0xffff, 0, iface_screen }, // [I]face - { "Memory", 'M', 4, 16, 0, 0xffff, ACTIVE, mem_screen }, // [M]emory - { "Load", 'L', 64, 128, 1, 0xffff, ACTIVE, xload_screen }, // [L]oad (load histogram) - { "TimeDate", 'T', 4, 64, 0, 0xffff, ACTIVE, time_screen }, // [T]ime/Date - { "About", 'A', 999, 9999, 0, 0xffff, ACTIVE, credit_screen }, // [A]bout (credits) - { "SMP-CPU", 'P', 1, 2, 0, 0xffff, 0, cpu_smp_screen }, // CPU_SM[P] - { "OldTime", 'O', 4, 64, 0, 0xffff, 0, clock_screen }, // [O]ld Timescreen - { "BigClock", 'K', 4, 64, 0, 0xffff, 0, big_clock_screen }, // big cloc[K] - { "Uptime", 'U', 4, 128, 0, 0xffff, 0, uptime_screen }, // Old [U]ptime Screen - { "Battery", 'B', 32, 256, 1, 0xffff, 0, battery_screen }, // [B]attery Status - { "CPUGraph", 'G', 1, 2, 0, 0xffff, 0, cpu_graph_screen }, // CPU histogram [G]raph - { "ProcSize", 'S', 16, 256, 1, 0xffff, 0, mem_top_screen }, // [S]ize of biggest processes - { "Disk", 'D', 256, 256, 1, 0xffff, 0, disk_screen }, // [D]isk stats - { "MiniClock", 'N', 4, 64, 0, 0xffff, 0, mini_clock_screen }, // Mi[n]i clock - { NULL, 0, 0, 0, 0, 0, 0, NULL}, // No more.. all done. + /* screen longname which on off inv timer flags func base_conf*/ + { LCDPROC_SCREEN_CPU, "CPU", 'C', 1, 2, 0, 0xffff, ACTIVE, cpu_screen, "cpu" }, // [C]PU + { LCDPROC_SCREEN_IFACE, "Iface", 'I', 1, 2, 0, 0xffff, 0, iface_screen, "iface" }, // [I]face + { LCDPROC_SCREEN_MEMORY, "Memory", 'M', 4, 16, 0, 0xffff, ACTIVE, mem_screen, "memory" }, // [M]emory + { LCDPROC_SCREEN_LOAD, "Load", 'L', 64, 128, 1, 0xffff, ACTIVE, xload_screen, "load" }, // [L]oad (load histogram) + { LCDPROC_SCREEN_TIME_DATE, "TimeDate", 'T', 4, 64, 0, 0xffff, ACTIVE, time_screen, "timedate" }, // [T]ime/Date + { LCDPROC_SCREEN_ABOUT, "About", 'A', 999, 9999, 0, 0xffff, ACTIVE, credit_screen, "about" }, // [A]bout (credits) + { LCDPROC_SCREEN_SMP_CPU, "SMP-CPU", 'P', 1, 2, 0, 0xffff, 0, cpu_smp_screen, "smpcpu" }, // CPU_SM[P] + { LCDPROC_SCREEN_OLD_TIME, "OldTime", 'O', 4, 64, 0, 0xffff, 0, clock_screen, "oldtime" }, // [O]ld Timescreen + { LCDPROC_SCREEN_BIG_CLOCK, "BigClock", 'K', 4, 64, 0, 0xffff, 0, big_clock_screen, "bigclock" }, // big cloc[K] + { LCDPROC_SCREEN_UPTIME, "Uptime", 'U', 4, 128, 0, 0xffff, 0, uptime_screen, "uptime" }, // Old [U]ptime Screen + { LCDPROC_SCREEN_BATTERY, "Battery", 'B', 32, 256, 1, 0xffff, 0, battery_screen, "battery" }, // [B]attery Status + { LCDPROC_SCREEN_CPU_GRAPH, "CPUGraph", 'G', 1, 2, 0, 0xffff, 0, cpu_graph_screen, "cpugraph" }, // CPU histogram [G]raph + { LCDPROC_SCREEN_PROC_SIZE, "ProcSize", 'S', 16, 256, 1, 0xffff, 0, mem_top_screen, "procsize" }, // [S]ize of biggest processes + { LCDPROC_SCREEN_DISK, "Disk", 'D', 256, 256, 1, 0xffff, 0, disk_screen, "disk" }, // [D]isk stats + { LCDPROC_SCREEN_MINI_CLOCK, "MiniClock", 'N', 4, 64, 0, 0xffff, 0, mini_clock_screen, "miniclock" }, // Mi[n]i clock + { 0, NULL, 0, 0, 0, 0, 0, 0, NULL}, // No more.. all done. }; @@ -130,6 +137,8 @@ char *pidfile = NULL; int pidfile_written = FALSE; char *displayname = NULL; /**< display name for the main menu */ +static Elektra * elektra = NULL; + /** Returns the network name of this machine */ const char * get_hostname(void) @@ -169,14 +178,12 @@ bool check_protocol_version(int major, int minor) /** Enables or disables (and deletes) a screen */ static int -set_mode(int shortname, char *longname, int state) +set_mode(LcdprocScreen screen, int state) { int k; for (k = 0; sequence[k].which != 0; k++) { - if (((sequence[k].longname != NULL) && - (0 == strcasecmp(longname, sequence[k].longname))) || - (toupper(shortname) == sequence[k].which)) { + if (sequence[k].screen == screen) { if (!state) { /* * clean both the active and initialized bits @@ -188,8 +195,9 @@ set_mode(int shortname, char *longname, int state) sock_printf(sock, "screen_del %c\n", sequence[k].which); } } - else + else { sequence[k].flags |= ACTIVE; + } return 1; /* found */ } } @@ -210,10 +218,9 @@ clear_modes(void) int -main(int argc, char **argv) +main(int argc, const char **argv) { int cfgresult; - int c; /* set locale for cwdate & time formatting in chrono.c */ setlocale(LC_TIME, ""); @@ -231,60 +238,9 @@ main(int argc, char **argv) signal(SIGPIPE, exit_program); /* write to closed socket */ signal(SIGKILL, exit_program); /* kill -9 [cannot be trapped; but ...] */ - /* No error output from getopt */ - opterr = 0; - - /* get options from command line */ - while ((c = getopt(argc, argv, "s:p:e:c:fhv")) > 0) { - char *end; - - switch (c) { - /* c is for config file */ - case 'c': - configfile = optarg; - break; - /* s is for server */ - case 's': - server = optarg; - break; - /* p is for port */ - case 'p': - port = strtol(optarg, &end, 0); - if ((*optarg == '\0') || (*end != '\0') || - (port <= 0) || (port >= 0xFFFF)) { - fprintf(stderr, "Illegal port value %s\n", optarg); - exit(EXIT_FAILURE); - } - break; - case 'e': - islow = strtol(optarg, &end, 0); - if ((*optarg == '\0') || (*end != '\0') || (islow < 0)) { - fprintf(stderr, "Illegal delay value %s\n", optarg); - exit(EXIT_FAILURE); - } - break; - case 'f': - foreground = TRUE; - break; - case 'h': - HelpScreen(EXIT_SUCCESS); - break; - case 'v': - fprintf(stderr, "LCDproc %s\n", version); - exit(EXIT_SUCCESS); - break; - /* otherwise... Get help! */ - case '?': /* unknown option or missing argument */ - /* FALLTHROUGH */ - default: - HelpScreen(EXIT_FAILURE); - break; - } - } - /* Read config file */ - cfgresult = process_configfile(configfile); - if (cfgresult < 0) { + cfgresult = process_config(); + if (cfgresult != 0) { fprintf(stderr, "Error reading config file\n"); exit(EXIT_FAILURE); } @@ -298,34 +254,6 @@ main(int argc, char **argv) /* Set reporting settings */ set_reporting("lcdproc", report_level, report_dest); - /* parse non-option arguments: modes to add/delete */ - if (argc > max(optind, 1)) { - int i; - - /* - * if no config file was read, ignore hard coded default - * modes - */ - if (cfgresult == 0) - clear_modes(); - - /* turn additional options on or off (using ! as prefix) */ - for (i = max(optind, 1); i < argc; i++) { - int state = (*argv[i] == '!') ? 0 : 1; - char *name = (state) ? argv[i] : argv[i] + 1; - int shortname = (strlen(name) == 1) ? name[0] : '\0'; - int found = set_mode(shortname, name, state); - - if (!found) { - fprintf(stderr, "Invalid Screen: %s\n", name); - return (EXIT_FAILURE); - } - } - } - - if (server == NULL) - server = DEFAULT_SERVER; - /* Connect to the server... */ sock = sock_connect(server, port); if (sock < 0) { @@ -377,96 +305,91 @@ main(int argc, char **argv) return EXIT_SUCCESS; } +static void on_fatal_error(ElektraError * error) // TODO: finalize method +{ + fprintf(stderr, "ERROR: %s\n", elektraErrorDescription(error)); + exit(EXIT_FAILURE); +} /** - * Reads and parses configuration file. - * \param configfile The configfile to read or NULL for the default config. - * \retval 1 if configfile was read, - * \retval 0 if default configfile doesn't exist - * \retval <0 on error + * Loads the configuration from the KDB. + * + * If Elektra reports help mode, we print the help message and call exit(EXIT_SUCCESS); + * + * \retval 0 on success + * \retval !=0 on error */ static int -process_configfile(char *configfile) +process_config() { - int k; - const char *tmp; - - debug(RPT_DEBUG, "%s(%s)", __FUNCTION__, (configfile) ? configfile : ""); - - /* Read config settings */ + ElektraError * error = NULL; + int rc = loadConfiguration(&elektra, &error); - if (configfile == NULL) { - struct stat statbuf; - - /* - * if default config file does not exist, do not consider - * this an error and continue - */ - if ((lstat(DEFAULT_CONFIGFILE, &statbuf) == -1) && (errno = ENOENT)) - return 0; - - configfile = DEFAULT_CONFIGFILE; - } - - if (config_read_file(configfile) != 0) { - report(RPT_CRIT, "Could not read config file: %s", configfile); + if (rc == -1) + { + fprintf(stderr, "An error occurred while initializing elektra: %s\n", elektraErrorDescription(error)); + elektraErrorReset(&error); return -1; } - if (server == NULL) { - server = strdup(config_get_string(progname, "Server", 0, DEFAULT_SERVER)); - } - if (port == UNSET_INT) { - port = config_get_int(progname, "Port", 0, LCDPORT); + if (rc == 1) + { + // help mode + printHelpMessage(elektra, NULL, help_prefix); + elektraClose (elektra); + exit(EXIT_SUCCESS); } - if (report_level == UNSET_INT) { - report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING); - } - if (report_dest == UNSET_INT) { - if (config_get_bool(progname, "ReportToSyslog", 0, 0)) { - report_dest = RPT_DEST_SYSLOG; - } - else { - report_dest = RPT_DEST_STDERR; - } - } - if (foreground != TRUE) { - foreground = config_get_bool(progname, "Foreground", 0, FALSE); - } - if (pidfile == NULL) { - pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE)); - } - if (islow < 0) { - islow = config_get_int(progname, "Delay", 0, -1); - } + elektraFatalErrorHandler(elektra, on_fatal_error); - if ((tmp = config_get_string(progname, "DisplayName", 0, NULL)) != NULL) - displayname = strdup(tmp); + server = strdup(elektraGet(elektra, CONF_LCDPROC_SERVER)); + port = elektraGet(elektra, CONF_LCDPROC_PORT); + report_level = elektraGet(elektra, CONF_LCDPROC_REPORTLEVEL); + report_dest = elektraGet(elektra, CONF_LCDPROC_REPORTTOSYSLOG) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; + foreground = elektraGet(elektra, CONF_LCDPROC_FOREGROUND); + pidfile = strdup(elektraGet(elektra, CONF_LCDPROC_PIDFILE)); + islow = elektraGet(elektra, CONF_LCDPROC_DELAY); + displayname = strdup(elektraGet(elektra, CONF_LCDPROC_DISPLAYNAME)); /* * check for config file variables to override all the sequence * defaults */ - for (k = 0; sequence[k].which != 0; k++) { - if (sequence[k].longname != NULL) { - sequence[k].on_time = config_get_int(sequence[k].longname, "OnTime", 0, sequence[k].on_time); - sequence[k].off_time = config_get_int(sequence[k].longname, "OffTime", 0, sequence[k].off_time); - sequence[k].show_invisible = config_get_bool(sequence[k].longname, "ShowInvisible", 0, sequence[k].show_invisible); - if (config_get_bool(sequence[k].longname, "Active", 0, sequence[k].flags & ACTIVE)) - sequence[k].flags |= ACTIVE; - else - sequence[k].flags &= (~ACTIVE); + for (int k = 0; sequence[k].which != 0; k++) { + ScreenBaseConfig base_config; + ELEKTRA_GET (StructScreenBaseConfig) (elektra, sequence[k].base_config_name, &base_config); + + sequence[k].on_time = base_config.on_time; + sequence[k].off_time = base_config.off_time; + sequence[k].show_invisible = base_config.show_invisible; + if (base_config.active) + sequence[k].flags |= ACTIVE; + else + sequence[k].flags &= (~ACTIVE); + } + + /* read enabled screens, if defined */ + kdb_long_long_t screen_count = elektraSize(elektra, CONF_LCDPROC_SCREENS); + if(screen_count > 0) + { + /* unset defaults */ + clear_modes(); + + for (kdb_long_long_t i = 0; i < screen_count; ++i) + { + LcdprocScreen screen = elektraGetV(elektra, CONF_LCDPROC_SCREENS, i); + set_mode(screen, 1); } } - return 1; + return 0; } /** Print help screen and exit */ void HelpScreen(int exit_state) { + // TODO: screen arg fprintf(stderr, "lcdproc - LCDproc system status information viewer\n" "\n" @@ -522,6 +445,10 @@ exit_program(int val) mode_close(); if ((foreground != TRUE) && (pidfile != NULL) && (pidfile_written == TRUE)) unlink(pidfile); + if (elektra != NULL) { + elektraClose(elektra); + } + exit(val); } @@ -705,14 +632,14 @@ main_loop(void) if (sequence[i].timer >= sequence[i].on_time) { sequence[i].timer = 0; /* Now, update the screen... */ - update_screen(&sequence[i], 1); + update_screen(&sequence[i], 1, elektra); } } else { if (sequence[i].timer >= sequence[i].off_time) { sequence[i].timer = 0; /* Now, update the screen... */ - update_screen(&sequence[i], sequence[i].show_invisible); + update_screen(&sequence[i], sequence[i].show_invisible, elektra); } } if (islow > 0) diff --git a/clients/lcdproc/main.h b/clients/lcdproc/main.h index c7f427f8..8b0c34e7 100644 --- a/clients/lcdproc/main.h +++ b/clients/lcdproc/main.h @@ -14,6 +14,8 @@ #include "shared/defines.h" +#include "elektragen.h" + #ifndef TRUE # define TRUE 1 #endif @@ -46,6 +48,7 @@ extern int lcd_cellhgt; /** Screen data structure */ typedef struct _screen_mode { + LcdprocScreen screen; /** < Which screen is it (enum)? */ char *longname; /**< Which screen is it (long name)? */ char which; /**< Which screen is it (short name)? */ int on_time; /**< How often to update while visible? */ @@ -53,7 +56,8 @@ typedef struct _screen_mode int show_invisible; /**< Send stats while not visible? */ int timer; /**< Time since last update */ int flags; /**< See mode flags defines */ - int (*func)(int,int,int *); /**< Pointer to init / update function */ + int (*func)(int,int,int *, Elektra *); /**< Pointer to init / update function */ + const char * base_config_name; /**< Key name of base config, will be read with ELEKTRA_GET (StructScreenBaseConfig) */ } ScreenMode; /* mode flags */ diff --git a/clients/lcdproc/mem.c b/clients/lcdproc/mem.c index ddec98c4..3ad26b7d 100644 --- a/clients/lcdproc/mem.c +++ b/clients/lcdproc/mem.c @@ -28,6 +28,7 @@ #include "mem.h" #include "util.h" +#include "elektragen.h" /** * Mem Screen displays info about memory and swap usage... @@ -46,10 +47,11 @@ * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -mem_screen(int rep, int display, int *flags_ptr) +mem_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { const char *title_sep = "####################################################################################################"; static int which_title = 0; @@ -240,10 +242,11 @@ sort_procs(void *a, void *b) * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags + * \param elektra Elektra instance holding the configuration * \return Always 0 */ int -mem_top_screen(int rep, int display, int *flags_ptr) +mem_top_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { LinkedList *procs; int lines; diff --git a/clients/lcdproc/mem.h b/clients/lcdproc/mem.h index 20bf6d2d..0df7d89d 100644 --- a/clients/lcdproc/mem.h +++ b/clients/lcdproc/mem.h @@ -1,7 +1,9 @@ #ifndef MEM_H #define MEM_H -int mem_screen(int rep, int display, int *flags_ptr); -int mem_top_screen(int rep, int display, int *flags_ptr); +#include + +int mem_screen(int rep, int display, int *flags_ptr, Elektra * elektra); +int mem_top_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/mode.c b/clients/lcdproc/mode.c index db83808c..feee953f 100644 --- a/clients/lcdproc/mode.c +++ b/clients/lcdproc/mode.c @@ -58,10 +58,11 @@ mode_close(void) * * \param m The screen mode * \param display Flag whether to update screen even if not visible. + * \param elektra Elektra instace holding configuration * \return Backlight state */ int -update_screen(ScreenMode *m, int display) +update_screen(ScreenMode *m, int display, Elektra * elektra) { static int status = -1; int old_status = status; @@ -71,7 +72,7 @@ update_screen(ScreenMode *m, int display) /* Save the initialized flag (may be modified by m->func) */ int init_flag = (m->flags & INITIALIZED); #endif - status = m->func(m->timer, display, &(m->flags)); + status = m->func(m->timer, display, &(m->flags), elektra); #ifdef LCDPROC_EYEBOXONE /* Eyebox Init */ if (init_flag == 0) @@ -103,7 +104,7 @@ update_screen(ScreenMode *m, int display) * \return Always 0 */ int -credit_screen(int rep, int display, int *flags_ptr) +credit_screen(int rep, int display, int *flags_ptr, Elektra * elektra) { /* * List of persons who contributed to LCDproc. Keep in sync with diff --git a/clients/lcdproc/mode.h b/clients/lcdproc/mode.h index 0b183907..dbbc6c31 100644 --- a/clients/lcdproc/mode.h +++ b/clients/lcdproc/mode.h @@ -1,9 +1,11 @@ #ifndef MODE_H #define MODE_H +#include + int mode_init(void); void mode_close(void); -int update_screen(ScreenMode *m, int display); -int credit_screen(int rep, int display, int *flags_ptr); +int update_screen(ScreenMode *m, int display, Elektra * elektra); +int credit_screen(int rep, int display, int *flags_ptr, Elektra * elektra); #endif diff --git a/clients/lcdproc/screen_config.h b/clients/lcdproc/screen_config.h new file mode 100644 index 00000000..6ff3fae4 --- /dev/null +++ b/clients/lcdproc/screen_config.h @@ -0,0 +1,13 @@ +#ifndef SCREEN_CONFIG_H +#define SCREEN_CONFIG_H + +#include + +typedef struct _screen_base_config { + kdb_boolean_t active; + kdb_unsigned_long_t on_time; + kdb_unsigned_long_t off_time; + kdb_boolean_t show_invisible; +} ScreenBaseConfig; + +#endif \ No newline at end of file diff --git a/clients/lcdproc/specification/lcdproc-spec.ini b/clients/lcdproc/specification/lcdproc-spec.ini new file mode 100644 index 00000000..bc8fa3cf --- /dev/null +++ b/clients/lcdproc/specification/lcdproc-spec.ini @@ -0,0 +1,723 @@ +[] +mountpoint = ldcproc.conf +infos/plugins = ni type range network ; path + +;lcdproc +;================================================== +[lcdproc/server] +type = string +check/type = string +default = localhost +check/ipaddr = +description = address of the LCDd server to connect to +opt = s +opt/long = server + +[lcdproc/port] +type = unsigned_short +check/port = +check/type = unsigned_short +default = 13666 +description = Port of the server to connect to +opt = p +opt/long = port + +[lcdproc/reportlevel] +type = unsigned_short +check/type = unsigned_short +check/range = 0-5 +default = 2 +description = set reporting level + +[lcdproc/reporttosyslog] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = report to syslog ? + +[lcdproc/foreground] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = report to syslog ? +opt = f +opt/long = foreground +opt/arg = none + +[lcdproc/pidfile] +type = string +default = /var/run/lcdproc.pid +;check/path = ; TODO (elektra): does not have to exist +description = "PidFile location when running as daemon [default: /var/run/lcdproc.pid]" + +[lcdproc/delay] +type = unsigned_long +check/type = unsigned_long +description = slow down initial announcement of screens (in 1/100s) +default = 0 +opt = e +opt/long = delay + +[lcdproc/displayname] +type = string +check/type = string +default = LCDproc HOST +description = display name for the main menu [default: LCDproc HOST] + +[lcdproc/printversion] +type = boolean +default = 0 +description = print version information and exit +opt = v +opt/long = version + +[lcdproc/screens/#] +type = enum +check/type = enum +check/enum = #_15 +check/enum/#1 = cpu +check/enum/#2 = iface +check/enum/#3 = memory +check/enum/#4 = load +check/enum/#5 = time_date +check/enum/#6 = about +check/enum/#7 = smp_cpu +check/enum/#8 = old_time +check/enum/#9 = big_clock +check/enum/#_10 = uptime +check/enum/#_11 = battery +check/enum/#_12 = cpu_graph +check/enum/#_13 = proc_size +check/enum/#_14 = disk +check/enum/#_15 = mini_clock +gen/enum/type = LcdprocScreen +require = +args = remaining + +;CPU +;================================================== +[cpu] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[cpu/active] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[cpu/ontime] +type = unsigned_long +check/type = unsigned_long +default = 1 +gen/struct/field = on_time + +[cpu/offtime] +type = unsigned_long +check/type = unsigned_long +default = 2 +gen/struct/field = off_time + +[cpu/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;Iface +;================================================== +[iface] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[iface/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[iface/ontime] +type = unsigned_long +check/type = unsigned_long +default = 1 +gen/struct/field = on_time + +[iface/offtime] +type = unsigned_long +check/type = unsigned_long +default = 2 +gen/struct/field = off_time + +[iface/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[iface/interface] +type = string +check/type = any +default = "" +array = #2 +gen/struct/field/ignore = 1 + +[iface/interface/#/name] +type = string +check/type = string +default = "" +description = Interface name +gen/struct/field/ignore = 1 + +[iface/interface/#/alias] +type = string +check/type = string +default = "" +description = Interface alias name to display +gen/struct/field/ignore = 1 + +[iface/unit] +type = enum +check/enum = #2 +check/enum/#0 = byte +check/enum/#1 = bit +check/enum/#2 = packet +gen/enum/type = IfaceUnit +default = byte +description = Units to display [default: byte ... legal: byte, bit, packet] +gen/struct/field/ignore = 1 + +[iface/transfer] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = add screen with transferred traffic +gen/struct/field/ignore = 1 + +;Memory +;================================================== +[memory] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[memory/active] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[memory/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[memory/offtime] +type = unsigned_long +check/type = unsigned_long +default = 16 +gen/struct/field = off_time + +[memory/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;Load +;================================================== +[load] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[load/active] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[load/ontime] +type = unsigned_long +check/type = unsigned_long +default = 64 +gen/struct/field = on_time + +[load/offtime] +type = unsigned_long +check/type = unsigned_long +default = 128 +gen/struct/field = off_time + +[load/showinvisible] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[load/lowload] +type = float +check/type = float +default = 0.05 +description = Min Load Avg at which the backlight will be turned off [default: 0.05] +gen/struct/field/ignore = 1 + +[load/highload] +type = float +check/type = float +default = 1.3 +description = Max Load Avg at which the backlight will start blinking [default: 1.3] +gen/struct/field/ignore = 1 + +;TimeDate +;================================================== +[timedate] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[timedate/active] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[timedate/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[timedate/offtime] +type = unsigned_long +check/type = unsigned_long +default = 64 +gen/struct/field = off_time + +[timedate/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[timedate/timeformat] +type = string +check/type = string +default = "%H:%M:%S" +description = "time format [default: %H:%M:%S; legal: see strftime(3)]" +gen/struct/field/ignore = 1 + +[timedate/dateformat] +type = string +check/type = string +default = "%x" +description = "date format [default: %x; legal: see strftime(3)]" +gen/struct/field/ignore = 1 + +;About +;================================================== +[about] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[about/active] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[about/ontime] +type = unsigned_long +check/type = unsigned_long +default = 999 +gen/struct/field = on_time + +[about/offtime] +type = unsigned_long +check/type = unsigned_long +default = 9999 +gen/struct/field = off_time + +[about/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;SMP-CPU +;================================================== +[smpcpu] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[smpcpu/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[smpcpu/ontime] +type = unsigned_long +check/type = unsigned_long +default = 1 +gen/struct/field = on_time + +[smpcpu/offtime] +type = unsigned_long +check/type = unsigned_long +default = 2 +gen/struct/field = off_time + +[smpcpu/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;OldTime +;================================================== +[oldtime] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[oldtime/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[oldtime/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[oldtime/offtime] +type = unsigned_long +check/type = unsigned_long +default = 64 +gen/struct/field = off_time + +[oldtime/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[oldtime/showtitle] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Display the title bar in two-line mode. Note that with four lines or more +the title is always shown. [default: true; legal: true, false]" +gen/struct/field/ignore = 1 + +[oldtime/timeformat] +type = string +check/type = string +default = "%H:%M:%S" +description = "time format [default: %H:%M:%S; legal: see strftime(3)]" +gen/struct/field/ignore = 1 + +[oldtime/dateformat] +type = string +check/type = string +default = "%x" +description = "date format [default: %x; legal: see strftime(3)]" +gen/struct/field/ignore = 1 + +;BigClock +;================================================== +[bigclock] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[bigclock/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[bigclock/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[bigclock/offtime] +type = unsigned_long +check/type = unsigned_long +default = 64 +gen/struct/field = off_time + +[bigclock/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[bigclock/showsecs] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Show seconds +gen/struct/field/ignore = 1 + +;Battery +;================================================== +[battery] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[battery/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[battery/ontime] +type = unsigned_long +check/type = unsigned_long +default = 32 +gen/struct/field = on_time + +[battery/offtime] +type = unsigned_long +check/type = unsigned_long +default = 256 +gen/struct/field = off_time + +[battery/showinvisible] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;Uptime +;================================================== +[uptime] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[uptime/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[uptime/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[uptime/offtime] +type = unsigned_long +check/type = unsigned_long +default = 128 +gen/struct/field = off_time + +[uptime/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;CPUGraph +;================================================== +[cpugraph] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[cpugraph/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[cpugraph/ontime] +type = unsigned_long +check/type = unsigned_long +default = 1 +gen/struct/field = on_time + +[cpugraph/offtime] +type = unsigned_long +check/type = unsigned_long +default = 2 +gen/struct/field = off_time + +[cpugraph/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;ProcSize +;================================================== +[procsize] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[procsize/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[procsize/ontime] +type = unsigned_long +check/type = unsigned_long +default = 16 +gen/struct/field = on_time + +[procsize/offtime] +type = unsigned_long +check/type = unsigned_long +default = 256 +gen/struct/field = off_time + +[procsize/showinvisible] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;Disk +;================================================== +[disk] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[disk/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[disk/ontime] +type = unsigned_long +check/type = unsigned_long +default = 256 +gen/struct/field = on_time + +[disk/offtime] +type = unsigned_long +check/type = unsigned_long +default = 256 +gen/struct/field = off_time + +[disk/showinvisible] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +;MiniClock +;================================================== +[miniclock] +type = struct +check/type = any +default = "" +gen/struct/type = ScreenBaseConfig +gen/struct/alloc = 0 +gen/struct/create = 0 + +[miniclock/active] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = active +description = Show screen + +[miniclock/ontime] +type = unsigned_long +check/type = unsigned_long +default = 4 +gen/struct/field = on_time + +[miniclock/offtime] +type = unsigned_long +check/type = unsigned_long +default = 64 +gen/struct/field = off_time + +[miniclock/showinvisible] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +gen/struct/field = show_invisible + +[miniclock/timeformat] +type = string +check/type = string +default = "%H:%M" +description = "time format [default: %H:%M; legal: see strftime(3)]" +gen/struct/field/ignore = 1 diff --git a/clients/lcdvc/.cvsignore b/clients/lcdvc/.cvsignore deleted file mode 100644 index 4ba0d9dd..00000000 --- a/clients/lcdvc/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -.deps -Makefile -Makefile.in -lcdvc diff --git a/clients/lcdvc/.gitignore b/clients/lcdvc/.gitignore new file mode 100644 index 00000000..f5b0710b --- /dev/null +++ b/clients/lcdvc/.gitignore @@ -0,0 +1,8 @@ +.deps +Makefile +Makefile.in +lcdvc +elektragen.c +elektragen.h +lcdvc.spec.eqd +lcdvc.mount.sh diff --git a/clients/lcdvc/Makefile.am b/clients/lcdvc/Makefile.am index bc5c4f60..53902249 100644 --- a/clients/lcdvc/Makefile.am +++ b/clients/lcdvc/Makefile.am @@ -1,10 +1,13 @@ ## Process this file with automake to produce Makefile.in - sysconf_DATA = lcdvc.conf bin_PROGRAMS = lcdvc lcdvc_SOURCES = lcdvc.c lcdvc.h lcd_link.c lcd_link.h vc_link.c vc_link.h +nodist_lcdvc_SOURCES = elektragen.c elektragen.h +lcdvc.$(OBJEXT): elektragen.c elektragen.h + +CLEANFILES = elektragen.c elektragen.h lcdvc.spec.eqd lcdvc.mount.sh lcdvc_LDADD = ../../shared/libLCDstuff.a @@ -20,4 +23,15 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir EXTRA_DIST = $(sysconf_DATA) +scriptsdir = $(prefix)/libexec +scripts_DATA = lcdvc.mount.sh + +specdir = $(prefix)/share/lcdproc +spec_DATA = lcdvc.spec.eqd + +KDB ?= kdb +elektragen.c elektragen.h lcdvc.spec.eqd lcdvc.mount.sh: specification/lcdvc-spec.ini + $(KDB) gen -F ni=specification/lcdvc-spec.ini highlevel "spec/sw/lcdproc/lcdvc/#0/current" elektragen initFn=loadConfiguration helpFn=printHelpMessage embeddedSpec=defaults tagPrefix=CONF_; mv elektragen.mount.sh lcdvc.mount.sh; mv elektragen.spec.eqd lcdvc.spec.eqd + + ## EOF diff --git a/clients/lcdvc/lcdvc.c b/clients/lcdvc/lcdvc.c index 2ae28757..6f31e67d 100644 --- a/clients/lcdvc/lcdvc.c +++ b/clients/lcdvc/lcdvc.c @@ -25,38 +25,19 @@ #include "getopt.h" #include "shared/report.h" -#include "shared/configfile.h" #include "shared/sockets.h" #include "lcd_link.h" #include "vc_link.h" #include "lcdvc.h" -#if !defined(SYSCONFDIR) -# define SYSCONFDIR "/etc" -#endif -#if !defined(PIDFILEDIR) -# define PIDFILEDIR "/var/run" -#endif - -#define DEFAULT_CONFIGFILE SYSCONFDIR "/lcdvc.conf" -#define DEFAULT_PIDFILE PIDFILEDIR "/lcdvc.pid" - +#include "elektragen.h" -char *help_text = +char * help_prefix = "lcdvc - LCDproc virtual console\n" "\n" "Copyright (c) 2002, Joris Robijn, 2006-2008 Peter Marschall.\n" "This program is released under the terms of the GNU General Public License.\n" -"\n" -"Usage: lcdvc []\n" -" where are:\n" -" -c Specify configuration file ["DEFAULT_CONFIGFILE"]\n" -" -a
DNS name or IP address of the LCDd server [localhost]\n" -" -p port of the LCDd server [13666]\n" -" -f Run in foreground\n" -" -r Set reporting level (0-5) [2: errors and warnings]\n" -" -s <0|1> Report to syslog (1) or stderr (0, default)\n" -" -h Show this help\n"; +"\n"; /* Variables set by config */ int foreground = FALSE; @@ -68,7 +49,6 @@ char *keys[4]; /* Other global variables */ char *progname = "lcdvc"; -char *configfile = UNSET_STR; char *pidfile = NULL; int pidfile_written = FALSE; @@ -77,24 +57,16 @@ int Quit = 0; /**< indicate end of main loop */ /* Function prototypes */ static void exit_program(int val); static int process_command_line(int argc, char **argv); -static int process_configfile(char *configfile); +static int process_config (); static int main_loop(void); -int main(int argc, char **argv) +int main(int argc, const char **argv) { int e = 0; struct sigaction sa; - CHAIN( e, process_command_line( argc, argv )); - if (strcmp( configfile, UNSET_STR ) == 0) { - configfile = DEFAULT_CONFIGFILE; - } - CHAIN( e, process_configfile( configfile )); - if (report_dest == UNSET_INT || report_level == UNSET_INT) { - report_dest = RPT_DEST_STDERR; - report_level = RPT_ERR; - } + CHAIN( e, process_config ()); set_reporting( progname, report_level, report_dest ); CHAIN( e, open_vcs() ); @@ -152,115 +124,51 @@ static void exit_program(int val) exit(val); } - -static int process_command_line(int argc, char **argv) +static void on_fatal_error(ElektraError * error) // TODO: finalize method { - int c; - int error = 0; - - /* No error output from getopt */ - opterr = 0; - - while ((c = getopt(argc, argv, "hc:a:p:fr:s:")) > 0) { - char *end; - int temp_int; - - switch (c) { - case 'h': - fprintf(stderr, "%s", help_text); - exit(EXIT_SUCCESS); - /* NOTREACHED */ - case 'c': - configfile = strdup(optarg); - break; - case 'a': - address = strdup(optarg); - break; - case 'p': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && - (temp_int > 0) && (temp_int <= 0xFFFF)) { - port = temp_int; - } else { - report(RPT_ERR, "Illegal port value %s", optarg); - error = -1; - } - break; - case 'f': - foreground = TRUE; - break; - case 'r': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) { - report_level = temp_int; - } else { - report(RPT_ERR, "Illegal report level value %s", optarg); - error = -1; - } - break; - case 's': - temp_int = strtol(optarg, &end, 0); - if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) { - report_dest = (temp_int ? RPT_DEST_SYSLOG : RPT_DEST_STDERR); - } else { - report(RPT_ERR, "Illegal log destination value %s", optarg); - error = -1; - } - break; - case ':': - report(RPT_ERR, "Missing option argument for %c", optopt); - error = -1; - break; - case '?': - default: - report(RPT_ERR, "Unknown option: %c", optopt); - error = -1; - break; - } - } - return error; + fprintf(stderr, "ERROR: %s\n", elektraErrorDescription(error)); + exit(EXIT_FAILURE); } - -static int process_configfile(char *configfile) +static int process_config() { - if (strcmp(configfile, UNSET_STR) == 0) { - configfile = DEFAULT_CONFIGFILE; - } - if (config_read_file( configfile ) < 0) { - report( RPT_WARNING, "Could not read config file: %s", configfile); + ElektraError * error = NULL; + Elektra * elektra = NULL; + int rc = loadConfiguration(&elektra, &error); + + if (rc == -1) + { + fprintf(stderr, "An error occurred while initializing elektra: %s\n", elektraErrorDescription(error)); + elektraErrorReset(&error); + return EXIT_FAILURE; } - if (strcmp(address, UNSET_STR ) == 0) { - address = strdup(config_get_string( progname, "Address", 0, "localhost")); - } - if (port == UNSET_INT) { - port = config_get_int(progname, "Port", 0, 13666); - } - if (report_level == UNSET_INT ) { - report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING); - } - if (report_dest == UNSET_INT) { - if (config_get_bool(progname, "ReportToSyslog", 0, 0)) { - report_dest = RPT_DEST_SYSLOG; - } else { - report_dest = RPT_DEST_STDERR; - } - } - if (foreground != TRUE) { - foreground = config_get_bool(progname, "Foreground", 0, FALSE); - } - if (pidfile == NULL) { - pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE)); + if (rc == 1) + { + // help mode + printHelpMessage(elektra, NULL, help_prefix); + elektraClose (elektra); + exit(EXIT_SUCCESS); } - vcs_device = strdup(config_get_string(progname, "vcsDevice", 0, "/dev/vcs")); - vcsa_device = strdup(config_get_string(progname, "vcsaDevice", 0, "/dev/vcsa")); + elektraFatalErrorHandler(elektra, on_fatal_error); + + address = strdup(elektraGet(elektra, CONF_LCDVC_ADDRESS)); + port = elektraGet(elektra, CONF_LCDVC_PORT); + report_level = elektraGet(elektra, CONF_LCDVC_REPORTLEVEL); + report_dest = elektraGet(elektra, CONF_LCDVC_REPORTTOSYSLOG) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; + foreground = elektraGet(elektra, CONF_LCDVC_FOREGROUND); + pidfile = strdup(elektraGet(elektra, CONF_LCDVC_PIDFILE)); + + vcs_device = strdup(elektraGet(elektra, CONF_LCDVC_VCSDEVICE)); + vcsa_device = strdup(elektraGet(elektra, CONF_LCDVC_VCSADEVICE)); + + keys[0] = strdup(elektraGet(elektra, CONF_LCDVC_UPKEY)); + keys[1] = strdup(elektraGet(elektra, CONF_LCDVC_DOWNKEY)); + keys[2] = strdup(elektraGet(elektra, CONF_LCDVC_LEFTKEY)); + keys[3] = strdup(elektraGet(elektra, CONF_LCDVC_RIGHTKEY)); - keys[0] = strdup(config_get_string( progname, "UpKey", 0, "Up")); - keys[1] = strdup(config_get_string( progname, "DownKey", 0, "Down")); - keys[2] = strdup(config_get_string( progname, "LeftKey", 0, "Left")); - keys[3] = strdup(config_get_string( progname, "RightKey", 0, "Right")); + elektraClose(elektra); return 0; } diff --git a/clients/lcdvc/specification/lcdvc-spec.ini b/clients/lcdvc/specification/lcdvc-spec.ini new file mode 100644 index 00000000..cc1e4b52 --- /dev/null +++ b/clients/lcdvc/specification/lcdvc-spec.ini @@ -0,0 +1,94 @@ +[] +mountpoint = lcdvc.conf +infos/plugins = ni type range network path + +[lcdvc/address] +check/ipaddr = +type = string +check/type = string +default = 127.0.0.1 +description = Address of the LCDd server +opt=a +opt/long=address + +[lcdvc/port] +check/ipaddr = +type = unsigned_short +check/type = unsigned_short +check/port = +default = 13666 +description = Port to attach to LCDd server +opt=p +opt/long=port + +[lcdvc/reportlevel] +type = unsigned_short +check/type = unsigned_short +check/range = 0-5 +default = 2 +description = Sets the reporting level, defaults to warnings and errors only. +opt=r +opt/long=report-level + +[lcdvc/reporttosyslog] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Should we report to syslog instead of stderr? +opt=s +opt/long=report-to-syslog +opt/arg=none + +[lcdvc/upkey] +type = string +check/type = string +default = Up +description = "Key to move the visible area of the screen upwards" + +[lcdvc/downkey] +type = string +check/type = string +default = Down +description = "Key to move the visible area of the screen downwards" + +[lcdvc/leftkey] +type = string +check/type = string +default = Left +description = "Key to move the visible area of the screen left" + +[lcdvc/rightkey] +type = string +check/type = string +default = Right +description = "Key to move the visible area of the screen right" + +[lcdvc/vcsdevice] +type = string +check/type = string +check/path = +default = /dev/vcs +description = "vcs device to use" + +[lcdvc/vcsadevice] +type = string +check/type = string +check/path = +default = /dev/vcsa +description = "vcsa device to use" + +[lcdvc/foreground] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "whether to run in foreground" +opt=f +opt/long=foreground +opt/arg=none + +[lcdvc/pidfile] +type = string +check/type = string +;check/path = ; TODO (elektra): does not have to exist +default = /var/run/lcdvc.pid +description = "PidFile location when running as daemon" \ No newline at end of file diff --git a/configure.ac b/configure.ac index 98a2fb1c..61852e99 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,18 @@ AC_PROG_RANLIB AM_PROG_CC_C_O AC_PATH_PROG([XMLTO], [xmlto], [no]) +dnl elektra +ifdef([PKG_CHECK_MODULES], + [PKG_CHECK_MODULES([ELEKTRA], [elektra-codegen], [ELEKTRA_LIBDIR=`pkg-config --variable=libdir elektra-codegen`],)], + [AC_MSG_ERROR([pkg-config not (fully) installed, but needed to find Elektra])]) +AC_SUBST([ELEKTRA_CFLAGS]) +AC_SUBST([ELEKTRA_LIBS]) + +AC_CONFIG_FILES([post-install.sh], [chmod +x post-install.sh]) + +CFLAGS="$ELEKTRA_CFLAGS $CFLAGS" +LIBS="$ELEKTRA_LIBS $LIBS -Wl,-rpath $ELEKTRA_LIBDIR" + dnl Avoid unused static function warnings CFLAGS="-Wall $CFLAGS" AX_CFLAGS_GCC_OPTION(-Wno-unused-function) @@ -214,25 +226,6 @@ AC_PROG_GCC_TRADITIONAL AC_TYPE_SIGNAL AC_CHECK_FUNCS(select socket strdup strerror strtol uname cfmakeraw snprintf) -dnl Many people on non-GNU/Linux systems don't have getopt -AC_CONFIG_LIBOBJ_DIR(shared) -AC_CHECK_FUNC(getopt, - [ - AC_ARG_WITH(included-getopt, - [AS_HELP_STRING([--with-included-getopt], [Use the included getopt rather than glibc's])], - with_getopt=$withval, - with_getopt=$no) - if test "x$with_getopt" = xyes; then - AC_LIBOBJ(getopt) - AC_LIBOBJ(getopt1) - fi - ], - [ - AC_LIBOBJ(getopt) - AC_LIBOBJ(getopt1) - ]) - - dnl Check how to find the mtab file and how to get filesystem staticstics AC_FIND_MTAB_FILE AC_GET_FS_INFO diff --git a/docs/elektra/README.md b/docs/elektra/README.md new file mode 100644 index 00000000..206f8c4b --- /dev/null +++ b/docs/elektra/README.md @@ -0,0 +1,69 @@ +# LCDproc with Elektra + +## Setting up Elektra + +- Checkout the latest version of Elektra's `master` branch (commit `79408a3509d4e8f97369c877ff08709f7de04976` + or later). +- Compile Elektra + ```sh + # inside Elektra source directory + mkdir build && cd build + cmake .. -DPLUGINS="c;cache;dump;gopts;hexnumber;ini;list;mmapstorage;network;ni;noresolver;path;quickdump;range;reference;resolver;resolver_fm_hpu_b;spec;specload;type;validation;sync" -DBUILD_TESTING=OFF -DENABLE_TESTING=OFF -DINSTALL_TESTING=OFF + ``` + This builds Elektra with the minimal set of plugins required for LCDproc and with testing disabled to speed up the build process. +- Install Elektra + ```sh + # inside Elektra build directory + sudo make install + ``` + +## Setting up LCDproc + +The basic instructions from `INSTALL.md` are still valid. The quickest way to get started is: + +```sh +# inside LCDproc source directory +sh ./autogen.sh +./configure +make +``` + +You may need to configure you're `PKG_CONFIG_PATH` such that `pkgconfig` is able to find Elektra. +For example this may work `PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure`, instead of +`./configure`. + +**Note:** Not all drivers have been updated yet. These drivers should work: bayrad, CFontz, +CFontzPacket, curses, CwLnx, glk, lb216, lcdm001, MtxOrb, pyramid, text, linux_input, xosd, hd44780 + +Once you built the server and/or the clients, you need to configure Elektra, so that it knows about +LCDprocs configuration. This process is called mounting (since it is similar to mounting a new file +system, but for configurations). + +You could do this for the binaries directly in your source/build directory, but we recommend you +install LCDproc instead. + +To install LCDproc run: + +```sh +# inside LCDproc source directory +sudo make install +./post-install.sh +``` + +The script `post-install.sh` sets up Elektra such that it knows about LCDprocs specifications. + +If you run `LCDd` now, you will see an error: + +``` +An error occurred while initializing elektra: Validation Semantic: Required key /sw/lcdproc/lcdd/#0/current/server/drivers/#0 is missing. +``` + +This simply means that you haven't chosen a driver yet. To choose a driver run: + +```sh +kdb set '/sw/lcdproc/lcdd/#0/current/server/drivers/#0' '@/curses/#0' +``` + +This chooses the `curses` driver. Specifically it choses the first configuration of the `curses` driver, +which is stored below `/sw/lcdproc/lcdd/#0/current/curses/#0` (`@` stands for the parent key +`/sw/lcdproc/lcdd/#0/current`). diff --git a/docs/elektra/drivers.md b/docs/elektra/drivers.md new file mode 100644 index 00000000..78c92abf --- /dev/null +++ b/docs/elektra/drivers.md @@ -0,0 +1,135 @@ +# Drivers + +## Configuration specification + +The whole server uses a single specification. This specification also includes all the drivers. +To add a new driver (e.g. `newdriver`) to the specification, you need to add at least these lines: + +```ini +[newdriver] +default = "" +array = #0 + +[newdriver/#] +type = struct +check/type = any +default = "" +gen/struct/type = NewdriverDriverConfig +gen/struct/alloc = 0 +description = Configuration for a newdriver driver. + +[newdriver/#/file] +type = string +default = "newdriver" +description = name of the shared library to load (without prefix and extension) +``` + +This declares a new array called `newdriver` which will contain all of the different configurations +for the `newdriver` driver. It then specifies that each of the array elements is a struct of type +`NewdriverDriverConfig` (currently the standard is to call the struct `[DriverName]DriverConfig`). +Lastly we define that each array element has the subkey `file`. The driver itself can probably ignore +this key, but it is needed nonetheless. This key is used by the driver loading mechanism to determine +which `.so` file to load. + +Now you can add any configuration parameters your driver needs. For example if `newdriver` has a +contrast parameter, we could add: + +```ini +[newdriver/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 500 +check/range = 0-1000 +description = contrast value +``` + +**Note:** It is recommended to use a struct with `gen/struct/alloc = 0`, but there is no technical +need for it. It just makes loading the config easier and the code a bit more readable. You may also +use `gen/struct/alloc = 1` or not use structs at all, if you have a reason. + +After you added the specification for your driver, you need to update the list of known drivers in the +server part of the specification. The key `server/drivers` is an array of the active drivers. The +specification contains restrictions, so that only known drivers are allowed. + +```ini +[server/drivers] +default = "" +array = #0 +check/reference = single +check/reference/restrict = #_51 +check/reference/restrict/#0 = @/bayrad/# +check/reference/restrict/#1 = @/cfontz/# +; ... +check/reference/restrict/#_51 = @/yard2lcd/# +description = "Tells the server to load a driver. +The given value is a reference the configuration of the driver, e.g. @/curses/#0" +``` + +To add your driver to the list of allowed drivers, just increment the value of `check/reference/restrict` +and add a new entry to `check/reference/restrict/#` of the form `@/[DriverName]/#`. This tells Elektra +to only allow references to existing keys inside the `[DriverName]` array. The `@` just makes says the +reference is relative to the parent keys. Similar to what `~` does in the shell. For the `newdriver` driver +we would get: + +```ini +[server/drivers] +default = "" +array = #0 +check/reference = single +check/reference/restrict = #_52 +check/reference/restrict/#0 = @/bayrad/# +check/reference/restrict/#1 = @/cfontz/# +; ... +check/reference/restrict/#_51 = @/yard2lcd/# +check/reference/restrict/#_52 = @/newdriver/# +description = "Tells the server to load a driver. +The given value is a reference the configuration of the driver, e.g. @/curses/#0" +``` + +**Note:** To make it easier to maintain this list of driver, please keep the drivers in alphabetical order. So in the above example `newdriver` should be somewhere in the omitted part of the array. + +## Elektrifying drivers + +The process of elektrifying a driver is rather simple. As before, each driver must have an `init` +function, but now this function receives an `Elektra *` handle in addition to the `Driver *` handle. + +The `Driver` struct was modified as well. It no longer provides the `config_get_*` function pointers, +since they are not needed anymore. Instead use the `elektraGet*` functions to access configuration. +To distinguish between multiple configurations for the same driver, we store the `index` in the +`Driver` struct. + +**Note:** Please load the whole configuration during `init` and don't store the `Elektra *` handle, +it may become invalid after you return from `init`. + +There are various ways to access the configuration using Elektra. The easiest one is to use +`elektraFillStructV` to read the whole configuration into a struct, from which you can then copy +values into the driver specific data structures. + +For example for the `curses` driver we use: + +```c +CursesDriverConfig config; +elektraFillStructV(elektra, &config, ELEKTRA_TAG_CURSES, drvthis->index); +``` + +Since we use a stack allocated struct with `elektraFillStructV`, we don't have to do any memory +management. There is one caveat however. If our config struct contains any strings, they may become +invalid, so we need to `strcpy` or `strdup` them, if we want to store them. For more information on +the pointer lifespan see the documentation of `elektraGetString`. + +Not all kinds of specifications are compatible with the struct mechanism of Elektra's +code-generation, especially not with the `elektraFillStruct` version. If you have a more complicated +case, for example certain kinds of arrays, you will want to use the more basic `elektraGetV`. + +For example `linux_input` reads its keymap like this: + +```c +kdb_long_long_t size = elektraSizeV(elektra, ELEKTRA_TAG_LINUX_INPUT_KEYS, drvthis->index); + +for (kdb_long_long_t i = 0; i < size; ++i) { + struct keycode * key = malloc(sizeof(struct keycode)); + key->code = elektraGetV(elektra, ELEKTRA_TAG_LINUX_INPUT_KEYS_CODE, drvthis->index, i); + key->button = strdup(elektraGetV(elektra, ELEKTRA_TAG_LINUX_INPUT_KEYS_BUTTON, drvthis->index, i)); + LL_AddNode(p->buttonmap, key); +} +``` \ No newline at end of file diff --git a/post-install.sh.in b/post-install.sh.in new file mode 100644 index 00000000..e8e2a892 --- /dev/null +++ b/post-install.sh.in @@ -0,0 +1,56 @@ +#!/bin/sh + +INSTALL_PREFIX="@prefix@" + +exit_usage() { + echo "Usage: $(basename "$0") [-h|--help] [app...]" 1>&2 + echo "" 1>&2 + echo "supported apps: lcdproc lcdexec lcdvc LCDd" 1>&2 + echo "if no app is given: use all apps" 1>&2 + exit 1 +} + +if [ "$#" -eq 0 ]; then + APPS="lcdproc lcdexec lcdvc LCDd" +elif [ "$#" -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then + exit_usage +else + APPS=$* +fi + +run_mount_script() { + SPEC_FILE="$INSTALL_PREFIX/share/lcdproc/$1.spec.eqd" sh "$INSTALL_PREFIX/libexec/$1.mount.sh" +} + +for APP in $APPS; do + case "$APP" in + lcdproc) + if [ ! "$lcdproc_done" ]; then + run_mount_script lcdproc + fi + lcdproc_done=1 + ;; + lcdexec) + if [ ! "$lcdexec_done" ]; then + run_mount_script lcdexec + fi + lcdexec_done=1 + ;; + lcdvc) + if [ ! "$lcdvc_done" ]; then + run_mount_script lcdvc + fi + lcdvc_done=1 + ;; + LCDd) + if [ ! "$LCDd_done" ]; then + run_mount_script LCDd && kdb set "/sw/lcdproc/lcdd/#0/current/server/driverpath" "$INSTALL_PREFIX/lib/lcdproc/" + fi + LCDd_done=1 + ;; + *) + echo "Unknown application $APP" 1>&2 + exit_usage + ;; + esac +done diff --git a/readconf.py b/readconf.py new file mode 100755 index 00000000..c2c14ca6 --- /dev/null +++ b/readconf.py @@ -0,0 +1,249 @@ +#!/usr/bin/python3 + +import sys +import configparser +import subprocess +import argparse +import os +import collections + + +def array_index(index): + return "#" + "_" * (len(str(index)) - 1) + str(index) + + +def read_lcdd(file): + class ConfigParserMultiValues(collections.OrderedDict): + def __setitem__(self, key, value): + if key in self and isinstance(value, list): + self[key].extend(value) + else: + super().__setitem__(key, value) + + @staticmethod + def getlist(value): + return value.split(os.linesep) + + config = configparser.RawConfigParser(strict=False, empty_lines_in_values=False, dict_type=ConfigParserMultiValues, converters={ + "list": ConfigParserMultiValues.getlist}) + config.read_file(file) + + kdb_config = {} + for section in config.sections(): + if section == "server": + section_key = "server/" + elif section == "menu": + section_key = "menu/" + else: + section_key = "driver/" + section.lower() + "/" + + for key in config[section]: + kdb_key = section_key + key.lower() + + if (section == "server" and key.lower() in ["hello", "goodbye"]) or \ + (section.lower() == "hd44780" and key.lower() == "backlight") or \ + (section.lower() == "linux_input" and key.lower() == "key"): + kdb_config[kdb_key] = config[section].getlist(key) + elif section == "server" and key.lower() == "driver": + kdb_config[kdb_key] = ["driver/" + d for d in config[section].getlist(key)] + else: + kdb_config[kdb_key] = config[section][key] + + return kdb_config + + +def read_lcdproc(file): + config = configparser.RawConfigParser() + config.read_file(file) + + kdb_config = {} + for section in config.sections(): + for key in config[section]: + kdb_key = section.lower() + "/" + key.lower() + kdb_config[kdb_key] = config[section][key] + + return kdb_config + + +class LcdexecReader(): + def __init__(self, config): + self.kdb_config = {} + self.config = config + self.menu_index = 1 + self.command_index = 0 + self.parameter_index = { + "slider": 0, + "checkbox": 0, + "numeric": 0, + "ring": 0, + "alpha": 0, + "ip": 0 + } + + def read_param(self, param, param_key): + for key in self.config[param]: + self.kdb_config[param_key + key.lower()] = self.config[param][key] + + def read_command(self, section, command_key): + if "DisplayName" in self.config[section]: + self.kdb_config[command_key + "displayname"] = self.config[section]["DisplayName"] + + self.kdb_config[command_key + "exec"] = self.config[section]["Exec"] + if "Feedback" in self.config[section]: + self.kdb_config[command_key + "feedback"] = self.config[section]["Feedback"] + if "Parameter" in self.config[section]: + params = self.config.getlist(section, "Parameter") + + self.kdb_config[command_key + "parameters"] = [] + for param in params: + param_type = self.config[param]["Type"].lower() + param_key = "menu/parameter/" + param_key += param_type + "/" + array_index(self.parameter_index[param_type]) + self.parameter_index[param_type] += 1 + self.kdb_config[command_key + "parameters"].append(param_key) + self.read_param(param, param_key + "/") + + def read_menu_entries(self, section, menu_key): + entries = self.config.getlist(section, "Entry") + self.kdb_config[menu_key + "entries"] = [] + for entry in entries: + if "Exec" in self.config[entry]: + entry_key = "menu/command/" + array_index(self.command_index) + self.command_index += 1 + self.read_command(entry, entry_key + "/") + else: + entry_key = "menu/menu/" + array_index(self.menu_index) + self.menu_index += 1 + self.read_menu(entry, entry_key + "/") + self.kdb_config["menu/menu/#0/entries"].append(entry_key) + + def read_menu(self, section, menu_key): + if "DisplayName" in self.config[section]: + self.kdb_config[menu_key + "displayname"] = self.config[section]["DisplayName"] + + self.read_menu_entries(section, menu_key) + + def read_main_menu(self): + self.kdb_config["menu/main"] = "menu/menu/#0" + self.read_menu_entries("MainMenu", "menu/menu/#0/") + self.kdb_config["menu/menu"] = [""] * self.menu_index + self.kdb_config["menu/command"] = [""] * self.command_index + for param_type, param_index in self.parameter_index.items(): + self.kdb_config["menu/parameter/" + param_type] = [""] * param_index + return self.kdb_config + + +def read_lcdexec(file): + class ConfigParserMultiValues(collections.OrderedDict): + + def __setitem__(self, key, value): + if key in self and isinstance(value, list): + self[key].extend(value) + else: + super().__setitem__(key, value) + + @staticmethod + def getlist(value): + return value.split(os.linesep) + + config = configparser.ConfigParser(strict=False, empty_lines_in_values=False, dict_type=ConfigParserMultiValues, + converters={"list": ConfigParserMultiValues.getlist}) + config.read_file(file) + + kdb_config = {} + if "lcdexec" in config.sections(): + for key in config["lcdexec"]: + kdb_key = "lcdexec/" + key.lower() + kdb_config[kdb_key] = config["lcdexec"][key] + + if "MainMenu" in config.sections(): + kdb_config.update(LcdexecReader(config).read_main_menu()) + + return kdb_config + + +def read_lcdvc(file): + config = configparser.RawConfigParser() + config.read_file(file) + + kdb_config = {} + for section in config.sections(): + for key in config[section]: + kdb_key = "lcdvc/" + key.lower() + kdb_config[kdb_key] = config[section][key] + + return kdb_config + + +def check_kdb_tmp(): + cmd = ["kdb", "ls", "user/sw/lcdproc/tmp"] + proc = subprocess.run(cmd, stdout=subprocess.PIPE) + if len(proc.stdout.decode("utf-8")) > 0: + print("Please ensure that user/sw/lcdproc/tmp is empty", file=sys.stderr) + exit(1) + + +def write_to_kdb(kdb_config): + def write_value(key, value): + if value.startswith('"') and value.endswith('"'): + value = value[1:-1] + cmd = ["kdb", "set", "--", "user/sw/lcdproc/tmp/" + str(key), str(value)] + subprocess.run(cmd, stdout=subprocess.DEVNULL) + + def write_meta(key, meta, value): + if value.startswith('"') and value.endswith('"'): + value = value[1:-1] + cmd = ["kdb", "setmeta", "--", "user/sw/lcdproc/tmp/" + str(key), str(meta), str(value)] + subprocess.run(cmd, stdout=subprocess.DEVNULL) + + for key, value in kdb_config.items(): + if isinstance(value, list): + write_meta(key, "array", array_index(len(value) - 1)) + for index, item in enumerate(value): + write_value(str(key) + "/" + array_index(index), item) + elif value.lower() in ["false", "n", "no", "off", "true", "y", "yes", "on"]: + write_value(key, value.lower()) + else: + write_value(key, value) + + +def export_kdb_tmp(outfile): + cmd = ["kdb", "export", "user/sw/lcdproc/tmp", "ini", outfile.name] + subprocess.run(cmd, stdout=subprocess.DEVNULL) + + +def clean_kdb_tmp(): + cmd = ["kdb", "rm", "-r", "user/sw/lcdproc/tmp"] + subprocess.run(cmd, stdout=subprocess.DEVNULL) + + +parser = argparse.ArgumentParser() +parser.add_argument("mode") +parser.add_argument("infile", type=argparse.FileType('r', encoding="UTF-8")) +parser.add_argument("outfile", type=argparse.FileType('w', encoding="UTF-8")) + +args = parser.parse_args() +mode = args.mode.lower() + +check_kdb_tmp() + +if mode == "lcdd": + print("Not supported right now", file=sys.stderr) + exit(1) + kdb_config = read_lcdd(args.infile) +elif mode == "lcdproc": + kdb_config = read_lcdproc(args.infile) +elif mode == "lcdvc": + kdb_config = read_lcdvc(args.infile) +elif mode == "lcdexec": + kdb_config = read_lcdexec(args.infile) +else: + print("unknown mode", file=sys.stderr) + exit(1) + +write_to_kdb(kdb_config) + +export_kdb_tmp(args.outfile) +clean_kdb_tmp() + +print("Success: Please import '" + args.outfile.name + "' with ini into '/sw/lcdproc/" + mode + "/#0/current'") diff --git a/server/.cvsignore b/server/.cvsignore deleted file mode 100644 index 63df6b10..00000000 --- a/server/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -.deps -LCDd -Makefile -Makefile.in -main.d diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 00000000..1110fd45 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,9 @@ +.deps +LCDd +Makefile +Makefile.in +main.d +elektragen.c +elektragen.h +LCDd.mount.sh +LCDd.spec.eqd diff --git a/server/Makefile.am b/server/Makefile.am index 849ab926..278db7f9 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -1,10 +1,15 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS=drivers commands +SUBDIRS=commands . drivers sbin_PROGRAMS=LCDd LCDd_SOURCES= client.c client.h clients.c clients.h input.c input.h main.c main.h menuitem.c menuitem.h menu.c menu.h menuscreens.c menuscreens.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h drivers.c drivers.h driver.c driver.h +nodist_LCDd_SOURCES = elektragen.c elektragen.h +LCDd.$(OBJEXT): elektragen.c elektragen.h +BUILT_SOURCES = elektragen.c elektragen.h + +CLEANFILES = elektragen.c elektragen.h LCDd.spec.eqd LCDd.mount.sh LDADD = ../shared/libLCDstuff.a commands/libLCDcommands.a @LIBPTHREAD_LIBS@ @@ -14,4 +19,14 @@ endif AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" +scriptsdir = $(prefix)/libexec +scripts_DATA = LCDd.mount.sh + +specdir = $(prefix)/share/lcdproc +spec_DATA = LCDd.spec.eqd + +KDB ?= kdb +elektragen.c elektragen.h LCDd.spec.eqd LCDd.mount.sh: specification/LCDd-spec.ini + $(KDB) gen -F ni=specification/LCDd-spec.ini highlevel "spec/sw/lcdproc/lcdd/#0/current" elektragen initFn=loadConfiguration helpFn=printHelpMessage embeddedSpec=defaults tagPrefix=CONF_; mv elektragen.mount.sh LCDd.mount.sh; mv elektragen.spec.eqd LCDd.spec.eqd + ## EOF diff --git a/server/commands/client_commands.c b/server/commands/client_commands.c index 39f4ac09..9e20a77f 100644 --- a/server/commands/client_commands.c +++ b/server/commands/client_commands.c @@ -132,7 +132,7 @@ client_set_func(Client *c, int argc, char **argv) /* Handle the "name" option */ if (strcmp(p, "name") == 0) { i++; - if (argv[i] == '\0') { + if (argv[i][0] == '\0') { sock_printf_error(c->sock, "internal error: no parameter #%d\n", i); continue; } diff --git a/server/driver.c b/server/driver.c index bf971c7b..1315c80c 100644 --- a/server/driver.c +++ b/server/driver.c @@ -25,7 +25,6 @@ #include "main.h" /* for timer */ #include "shared/report.h" -#include "shared/configfile.h" #include "widget.h" #include "driver.h" @@ -33,6 +32,10 @@ #include "drivers/lcd.h" /* lcd.h is used for the driver API definition */ +#include +#include +#include "elektragen.h" + /** property / method symbols in a Driver structure */ typedef struct driver_symbols { @@ -91,46 +94,93 @@ static int driver_store_private_ptr(Driver *driver, void *private_data); * \return Pointer to the freshly created driver; \c NULL on error. */ Driver * -driver_load(const char *name, const char *filename) +driver_load(Elektra * elektra, const char * driverpath, kdb_long_long_t index) { - Driver *driver = NULL; - int res; - - report(RPT_DEBUG, "%s(name=\"%.40s\", filename=\"%.80s\")", - __FUNCTION__, name, filename); + report(RPT_DEBUG, "%s(driverpath=\"%.40s\", index=\"%.80s\")", + __FUNCTION__, driverpath, index); /* fail on wrong / missing parameters */ - if ((name == NULL) || (filename == NULL)) + if (elektra == NULL || driverpath == NULL || index < 0) { return NULL; + } - /* Allocate memory for new driver struct */ - driver = calloc(1, sizeof(Driver)); - if (driver == NULL) { - report(RPT_ERR, "%s: error allocating driver", __FUNCTION__); + /* resolve reference */ + char * buf = malloc(sizeof("server/drivers/") + ELEKTRA_MAX_ARRAY_SIZE); + strcpy(buf, "server/drivers/"); + elektraWriteArrayNumber(&buf[sizeof("server/drivers/") - 1], index); + + const char * filekey = elektraFindReference(elektra, buf); + + if(filekey == NULL) { + report(RPT_ERR, "could not resolve reference stored in '%s'", buf); + free(buf); + return NULL; + } + free(buf); + + size_t len_filekey = strlen(filekey); + buf = malloc(strlen(filekey) + sizeof("/file")); + strcpy(buf, filekey); + strcpy(&buf[len_filekey], "/file"); + + /* construct full path for module file */ + const char * file = elektraGetString(elektra, buf); + free(buf); + + size_t len_driverpath = strlen(driverpath); + size_t len_file = strlen(file); + + char * filename = malloc(len_driverpath + len_file + sizeof(MODULE_EXTENSION)); + if (filename == NULL) { + report(RPT_ERR, "%s: error allocating driver filename", __FUNCTION__); return NULL; } - /* And store its name and filename */ - driver->name = malloc(strlen(name) + 1); - if (driver->name == NULL) { - report(RPT_ERR, "%s: error allocating driver name", __FUNCTION__); - free(driver); + strcpy(filename, driverpath); + strcpy(&filename[len_driverpath], file); + strcpy(&filename[len_driverpath + len_file], MODULE_EXTENSION); + + /* extract name for passing to driver */ + const char * reference = elektraGetV(elektra, CONF_SERVER_DRIVERS, index); + const char * index_start = strrchr(reference, '#') - 1; + const char * name_start = index_start - 1; + while (*name_start != '/') { + --name_start; + } + ++name_start; + + /* extract index for passing to driver */ + kdb_long_long_t driver_index; + int offset = elektraArrayValidateBaseNameString(index_start + 1); + if (offset < 1) { + report(RPT_ERR, "%s: error getting index", __FUNCTION__); + return NULL; + } + Key * index_key = keyNew("", KEY_VALUE, &index_start[offset + 1], KEY_END); + if(!elektraKeyToLongLong(index_key, &driver_index)) { + report(RPT_ERR, "%s: error getting index", __FUNCTION__); return NULL; } - strcpy(driver->name, name); + keyDel(index_key); - driver->filename = malloc(strlen(filename) + 1); - if (driver->filename == NULL) { - report(RPT_ERR, "%s: error allocating driver filename", __FUNCTION__); - free(driver->name); - free(driver); + Driver *driver = NULL; + int res; + + /* Allocate memory for new driver struct */ + driver = calloc(1, sizeof(Driver)); + if (driver == NULL) { + report(RPT_ERR, "%s: error allocating driver", __FUNCTION__); return NULL; } - strcpy(driver->filename, filename); + + /* And store its name, index and filename */ + driver->name = strdup(name_start); + driver->index = driver_index; + driver->filename = filename; /* Load and bind the driver module and locate the symbols */ if (driver_bind_module(driver) < 0) { - report(RPT_ERR, "Driver [%.40s] binding failed", name); + report(RPT_ERR, "Driver [%.40s] binding failed", reference); free(driver->name); free(driver->filename); free(driver); @@ -139,7 +189,7 @@ driver_load(const char *name, const char *filename) /* Check module version */ if (strcmp(*(driver->api_version), API_VERSION) != 0) { - report(RPT_ERR, "Driver [%.40s] is of an incompatible version", name); + report(RPT_ERR, "Driver [%.40s] is of an incompatible version", reference); driver_unbind_module(driver); free(driver->name); free(driver->filename); @@ -149,12 +199,12 @@ driver_load(const char *name, const char *filename) /* Call the init function */ debug(RPT_DEBUG, "%s: Calling driver [%.40s] init function", - __FUNCTION__, driver->name); + __FUNCTION__, reference); - res = driver->init(driver); + res = driver->init(driver, elektra); if (res < 0) { report(RPT_ERR, "Driver [%.40s] init failed, return code %d", - driver->name, res); + reference, res); /* Driver load failed, driver should not be added to list * Free driver structure again */ @@ -165,7 +215,7 @@ driver_load(const char *name, const char *filename) return NULL; } - debug(RPT_NOTICE, "Driver [%.40s] loaded", driver->name); + debug(RPT_NOTICE, "Driver [%.40s] loaded", reference); return driver; } @@ -179,7 +229,7 @@ driver_load(const char *name, const char *filename) int driver_unload(Driver *driver) { - debug(RPT_NOTICE, "Closing driver [%.40s]", driver->name); + debug(RPT_NOTICE, "Closing driver [%.40s, #"ELEKTRA_LONG_LONG_F"]", driver->name, driver->index); /* close the driver, if its \c close method is [already] defined */ if (driver->close != NULL) @@ -213,7 +263,7 @@ driver_bind_module(Driver *driver) int i; int missing_symbols = 0; - debug(RPT_DEBUG, "%s(driver=[%.40s])", __FUNCTION__, driver->name); + debug(RPT_DEBUG, "%s(driver=[%.40s, #"ELEKTRA_LONG_LONG_F"])", __FUNCTION__, driver->index); /* Load the module */ driver->module_handle = dlopen(driver->filename, RTLD_NOW); @@ -268,14 +318,6 @@ driver_bind_module(Driver *driver) /* Add our exported functions */ - /* Config file functions */ - driver->config_get_bool = config_get_bool; - driver->config_get_int = config_get_int; - driver->config_get_float = config_get_float; - driver->config_get_string = config_get_string; - driver->config_has_section = config_has_section; - driver->config_has_key = config_has_key; - /* Driver private data */ driver->store_private_ptr = driver_store_private_ptr; diff --git a/server/driver.h b/server/driver.h index 18471298..394cf7ee 100644 --- a/server/driver.h +++ b/server/driver.h @@ -23,7 +23,7 @@ #include "shared/defines.h" Driver * -driver_load(const char *name, const char *filename); +driver_load(Elektra * elektra, const char * driverpath, kdb_long_long_t index); int driver_unload(Driver *driver); diff --git a/server/drivers.c b/server/drivers.c index aed79ccf..73bb0a5d 100644 --- a/server/drivers.c +++ b/server/drivers.c @@ -22,7 +22,10 @@ #include "shared/LL.h" #include "shared/report.h" -#include "shared/configfile.h" + +#include "elektragen.h" +#include +#include #include "driver.h" #include "drivers.h" @@ -38,18 +41,17 @@ DisplayProps *display_props = NULL; /**< properties of the display */ /** * Load driver based on "DriverPath" config setting and section name or * "File" configuration setting in the driver's section. - * \param name Driver section name. + * \param reference Driver configuration reference. * \retval <0 error. * \retval 0 OK * \retval 2 OK, driver needs to run in the foreground. */ int -drivers_load_driver(const char *name) +drivers_load_driver(Elektra * elektra, kdb_long_long_t index) { Driver *driver; - const char *s; - debug(RPT_DEBUG, "%s(name=\"%.40s\")", __FUNCTION__, name); + debug(RPT_DEBUG, "%s(index=\"%.40s\")", __FUNCTION__, index); /* First driver ? */ if (!loaded_drivers) { @@ -62,22 +64,13 @@ drivers_load_driver(const char *name) } /* Retrieve data from config file */ - s = config_get_string("server", "DriverPath", 0, ""); - char driverpath[strlen(s) + 1]; - strcpy(driverpath, s); - - s = config_get_string(name, "File", 0, name); - char filename[strlen(driverpath) + strlen(s) + sizeof(MODULE_EXTENSION)]; - strcpy(filename, driverpath); - strcat(filename, s); - if (s == name) - strcat(filename, MODULE_EXTENSION); + const char * driverpath = elektraGet(elektra, CONF_SERVER_DRIVERPATH); /* Load the module */ - driver = driver_load(name, filename); + driver = driver_load(elektra, driverpath, index); if (driver == NULL) { /* It failed. The message has already been given by driver_load() */ - report(RPT_INFO, "Module %.40s could not be loaded", filename); + report(RPT_INFO, "Driver #"ELEKTRA_LONG_LONG_F" could not be loaded", index); return -1; } diff --git a/server/drivers.h b/server/drivers.h index c2efe705..78790334 100644 --- a/server/drivers.h +++ b/server/drivers.h @@ -23,7 +23,7 @@ typedef struct DisplayProps { extern DisplayProps *display_props; int -drivers_load_driver(const char *name); +drivers_load_driver(Elektra * elektra, kdb_long_long_t index); void drivers_unload_all(void); diff --git a/server/drivers/.cvsignore b/server/drivers/.gitignore similarity index 100% rename from server/drivers/.cvsignore rename to server/drivers/.gitignore diff --git a/server/drivers/CFontz.c b/server/drivers/CFontz.c index 8c5ec9b6..16a3a062 100644 --- a/server/drivers/CFontz.c +++ b/server/drivers/CFontz.c @@ -45,14 +45,13 @@ #include "CFontz-charmap.h" #include "adv_bignum.h" +#include "../elektragen.h" /* Constants for userdefchar_mode */ #define NUM_CCs 8 /* max. number of custom characters */ /** private data for the \c CFontz driver */ typedef struct CFontz_private_data { - char device[200]; - int fd; int model; @@ -100,14 +99,13 @@ static void CFontz_raw_chr(Driver *drvthis, int x, int y, unsigned char c); * \retval <0 Error. */ MODULE_EXPORT int -CFontz_init(Driver *drvthis) +CFontz_init(Driver *drvthis, Elektra * elektra) { struct termios portset; - int tmp, w, h; + int w, h; int reboot = 0; int usb = 0; int speed = DEFAULT_SPEED; - char size[200] = DEFAULT_SIZE; PrivateData *p; @@ -126,80 +124,52 @@ CFontz_init(Driver *drvthis) debug(RPT_INFO, "CFontz: init(%p)", drvthis); - /* Read config file */ + /* Read config */ + + CFontzDriverConfig config; + elektraFillStructV (elektra, &config, CONF_CFONTZ, drvthis->index); + /* Which device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* Which size */ - strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); - size[sizeof(size)-1] = '\0'; - if ((sscanf(size, "%dx%d", &w, &h) != 2) + if ((sscanf(config.size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", - drvthis->name, size, DEFAULT_SIZE); + drvthis->name, config.size, DEFAULT_SIZE); sscanf(DEFAULT_SIZE, "%dx%d", &w, &h); } p->width = w; p->height = h; /* Which contrast */ - tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Contrast must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_CONTRAST); - tmp = DEFAULT_CONTRAST; - } - p->contrast = tmp; + p->contrast = config.contrast; /* Which backlight brightness */ - tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_BRIGHTNESS); - tmp = DEFAULT_BRIGHTNESS; - } - p->brightness = tmp; + p->brightness = config.brightness; /* Which backlight-off "brightness" */ - tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: OffBrightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_OFFBRIGHTNESS); - tmp = DEFAULT_OFFBRIGHTNESS; - } - p->offbrightness = tmp; + p->offbrightness = config.offbrightness; /* Which speed */ - tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); - if (tmp == 1200) speed = B1200; - else if (tmp == 2400) speed = B2400; - else if (tmp == 9600) speed = B9600; - else if (tmp == 19200) speed = B19200; - else if (tmp == 115200) speed = B115200; - else { - report(RPT_WARNING, "%s: Speed must be 1200, 2400, 9600, 19200 or 115200; using default %d", - drvthis->name, DEFAULT_SPEED); - speed = DEFAULT_SPEED; - } + speed = config.speed; /* New firmware version? */ - p->newfirmware = drvthis->config_get_bool(drvthis->name, "NewFirmware", 0, 0); + p->newfirmware = config.newfirmware; /* Reboot display? */ - reboot = drvthis->config_get_bool(drvthis->name, "Reboot", 0, 0); - + reboot = config.reboot; + /* Am I USB or not? */ - usb = drvthis->config_get_bool(drvthis->name, "USB", 0, 0); + usb = config.usb; /* Set up io port correctly, and open it... */ - debug(RPT_DEBUG, "CFontz: Opening device: %s", p->device); - p->fd = open(p->device, (usb) ? (O_RDWR | O_NOCTTY) : (O_RDWR | O_NOCTTY | O_NDELAY)); + debug(RPT_DEBUG, "CFontz: Opening device: %s", config.device); + p->fd = open(config.device, (usb) ? (O_RDWR | O_NOCTTY) : (O_RDWR | O_NOCTTY | O_NDELAY)); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", - drvthis->name, p->device, strerror(errno)); + report(RPT_ERR, "%s/#"ELEKTRA_LONG_LONG_F": open(%s) failed (%s)", + drvthis->name, drvthis->index, config.device, strerror(errno)); return -1; } diff --git a/server/drivers/CFontz.h b/server/drivers/CFontz.h index 6c957423..ad6f72cd 100644 --- a/server/drivers/CFontz.h +++ b/server/drivers/CFontz.h @@ -1,6 +1,8 @@ #ifndef CFONTZ_H #define CFONTZ_H +#include + #define DEFAULT_CELL_WIDTH 6 #define DEFAULT_CELL_HEIGHT 8 #define DEFAULT_CONTRAST 560 @@ -41,7 +43,7 @@ #define CFONTZ_Show_Information_Screen 0x1F -MODULE_EXPORT int CFontz_init(Driver *drvthis); +MODULE_EXPORT int CFontz_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void CFontz_close(Driver *drvthis); MODULE_EXPORT int CFontz_width(Driver *drvthis); MODULE_EXPORT int CFontz_height(Driver *drvthis); diff --git a/server/drivers/CFontzPacket.c b/server/drivers/CFontzPacket.c index af48644d..eb248919 100644 --- a/server/drivers/CFontzPacket.c +++ b/server/drivers/CFontzPacket.c @@ -51,6 +51,8 @@ #include "CFontz-charmap.h" #include "adv_bignum.h" +#include "../elektragen.h" + /* LEDs dispatch */ #define CF635_NUM_LEDs 8 @@ -60,8 +62,6 @@ /** private data for the \c CFontzPacket driver */ typedef struct CFontzPacket_private_data { - char device[200]; - int fd; int model; @@ -92,11 +92,11 @@ typedef struct CFontzPacket_private_data { /** List of known models and their default settings and features */ static CFA_Model CFA_ModelList[] = { - {533, "16x2", 5, 19200 , HD44780_charmap, CFA_HAS_TEMP | CFA_HAS_4_TEMP_SLOTS}, - {631, "20x2", 5, 115200, CFontz_charmap , CFA_HAS_FAN | CFA_HAS_TEMP | + {C_FONTZ_PACKET_MODEL_533, "16x2", 5, 19200 , HD44780_charmap, CFA_HAS_TEMP | CFA_HAS_4_TEMP_SLOTS}, + {C_FONTZ_PACKET_MODEL_631, "20x2", 5, 115200, CFontz_charmap , CFA_HAS_FAN | CFA_HAS_TEMP | CFA_HAS_KS0073 | CFA_HAS_4_TEMP_SLOTS}, - {633, "16x2", 5, 19200 , HD44780_charmap, CFA_HAS_FAN | CFA_HAS_TEMP}, - {635, "20x4", 5, 115200, CFontz_charmap , CFA_HAS_KS0073}, + {C_FONTZ_PACKET_MODEL_633, "16x2", 5, 19200 , HD44780_charmap, CFA_HAS_FAN | CFA_HAS_TEMP}, + {C_FONTZ_PACKET_MODEL_635, "20x4", 5, 115200, CFontz_charmap , CFA_HAS_KS0073}, {0, NULL, 0, 0, NULL, 0} }; @@ -122,12 +122,11 @@ static void CFontzPacket_raw_chr (Driver *drvthis, int x, int y, unsigned char c * \retval <0 Error. */ MODULE_EXPORT int -CFontzPacket_init (Driver *drvthis) +CFontzPacket_init (Driver *drvthis, Elektra * elektra) { struct termios portset; - int tmp, w, h, i; + int w, h, i; int cf_reboot = 0; - char size[200] = ""; PrivateData *p; @@ -149,38 +148,35 @@ CFontzPacket_init (Driver *drvthis) EmptyKeyRing(&keyring); EmptyReceiveBuffer(&receivebuffer); - /* Read config file */ + /* Read config */ + CFontzPacketDriverConfig config; + elektraFillStructV(elektra, &config, CONF_CFONTZPACKET, drvthis->index); /* Try to find a matching model from our list of known modules */ - tmp = drvthis->config_get_int(drvthis->name, "Model", 0, 633); - debug(RPT_INFO, "%s: Model (in config) is '%d'", __FUNCTION__, tmp); + debug(RPT_INFO, "%s: Model (in config) is '%d'", __FUNCTION__, config.model); i = 0; - while ((CFA_ModelList[i].model != 0) && (CFA_ModelList[i].model != tmp)) { + while ((CFA_ModelList[i].model != 0) && (CFA_ModelList[i].model != config.model)) { i++; } if (CFA_ModelList[i].model == 0) { - report(RPT_ERR, "%s: Invalid model configured", drvthis->name); + report(RPT_ERR, "%s/#"ELEKTRA_LONG_LONG_F": Invalid model configured", drvthis->name, drvthis->index); return -1; } - p->model = tmp; + p->model = config.model; p->model_desc = &(CFA_ModelList[i]); report(RPT_INFO, "%s: Found configuration for %d", __FUNCTION__, p->model_desc->model); debug(RPT_INFO, "%s: Flags are 0x%04X", __FUNCTION__, p->model_desc->flags); /* Which device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* Size setting */ - strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, p->model_desc->size), sizeof(size)); - size[sizeof(size)-1] = '\0'; - debug(RPT_INFO, "%s: Size (in config) is '%s'", __FUNCTION__, size); - if ((sscanf(size, "%dx%d", &w, &h) != 2) + debug(RPT_INFO, "%s: Size (in config) is '%s'", __FUNCTION__, config.size); + if ((sscanf(config.size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot parse Size: %s; using default %s", - drvthis->name, size, p->model_desc->size); + drvthis->name, config.size, p->model_desc->size); sscanf(p->model_desc->size, "%dx%d", &w, &h); } p->width = w; @@ -191,61 +187,33 @@ CFontzPacket_init (Driver *drvthis) p->cellwidth = p->model_desc->cell_width; /* Which contrast */ - tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); - debug(RPT_INFO, "%s: Contrast (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Contrast must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_CONTRAST); - tmp = DEFAULT_CONTRAST; - } - p->contrast = tmp; + p->contrast = config.contrast; /* Which backlight brightness */ - tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); - debug(RPT_INFO, "%s: Brightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_BRIGHTNESS); - tmp = DEFAULT_BRIGHTNESS; - } - p->brightness = tmp; + p->brightness = config.brightness; /* Which backlight-off "brightness" */ - tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS); - debug(RPT_INFO, "%s: OffBrightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: OffBrightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_OFFBRIGHTNESS); - tmp = DEFAULT_OFFBRIGHTNESS; - } - p->offbrightness = tmp; + p->offbrightness = config.offbrightness; /* Get speed setting. */ - tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, p->model_desc->speed); - debug(RPT_INFO, "%s: Speed (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp != 19200) && (tmp != 115200)) { - report(RPT_WARNING, "%s: Speed must be 19200 or 115200; using default %d", - drvthis->name, p->model_desc->speed); - tmp = p->model_desc->speed; - } - p->speed = (tmp == 19200) ? B19200 : B115200; + p->speed = (config.speed == 19200) ? B19200 : B115200; /* Does the display has an old firmware (<= 0.6)? */ - p->oldfirmware = drvthis->config_get_bool(drvthis->name, "OldFirmware", 0, 0); + p->oldfirmware = config.oldfirmware; /* Reboot display? */ - cf_reboot = drvthis->config_get_bool(drvthis->name, "Reboot", 0, 0); + cf_reboot = config.reboot; /* Am I USB or not? */ - p->usb = drvthis->config_get_bool(drvthis->name, "USB", 0, 0); + p->usb = config.usb; if (p->usb) - report(RPT_INFO, "%s: USB is indicated (in config)", drvthis->name); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": USB is indicated (in config)", drvthis->name, drvthis->index); /* Set up io port correctly, and open it... */ - debug(RPT_INFO, "%s: Opening device: %s", __FUNCTION__, p->device); - p->fd = open(p->device, (p->usb) ? (O_RDWR | O_NOCTTY) : (O_RDWR | O_NOCTTY | O_NDELAY)); + debug(RPT_INFO, "%s: Opening device: %s", __FUNCTION__, config.device); + p->fd = open(config.device, (p->usb) ? (O_RDWR | O_NOCTTY) : (O_RDWR | O_NOCTTY | O_NDELAY)); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, p->device, strerror(errno)); + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, config.device, strerror(errno)); return -1; } diff --git a/server/drivers/CFontzPacket.h b/server/drivers/CFontzPacket.h index 58b7bfaa..a401dd74 100644 --- a/server/drivers/CFontzPacket.h +++ b/server/drivers/CFontzPacket.h @@ -1,6 +1,8 @@ #ifndef CFONTZPACKET_H #define CFONTZPACKET_H +#include + #define DEFAULT_CELL_HEIGHT 8 #define DEFAULT_CONTRAST 560 #define DEFAULT_DEVICE "/dev/lcd" @@ -22,7 +24,7 @@ typedef struct CFA_Model { int flags; /**< Bitmap of display features, see CFA_HAS_* above */ } CFA_Model; -MODULE_EXPORT int CFontzPacket_init (Driver *drvthis); +MODULE_EXPORT int CFontzPacket_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void CFontzPacket_close (Driver *drvthis); MODULE_EXPORT int CFontzPacket_width (Driver *drvthis); MODULE_EXPORT int CFontzPacket_height (Driver *drvthis); diff --git a/server/drivers/CwLnx.c b/server/drivers/CwLnx.c index 1c0a8d1d..651cc63d 100644 --- a/server/drivers/CwLnx.c +++ b/server/drivers/CwLnx.c @@ -67,13 +67,13 @@ /* for the icon definitions & the big numbers */ #include "adv_bignum.h" +#include "../elektragen.h" + #define ValidX(x) if ((x) > p->width) { (x) = p->width; } else (x) = (x) < 1 ? 1 : (x); #define ValidY(y) if ((y) > p->height) { (y) = p->height; } else (y) = (y) < 1 ? 1 : (y); #define MaxKeyMap 6 -static char *defaultKeyMap[MaxKeyMap] = { "Up", "Down", "Left", "Right", "Enter", "Escape" }; - /** private data for the \c CwLnx driver */ typedef struct CwLnx_private_data { @@ -83,7 +83,7 @@ typedef struct CwLnx_private_data { int keypad_test_mode; char *KeyMap[MaxKeyMap]; - int model; + CwLnxModel model; /* dimensions */ int width, height; @@ -438,18 +438,14 @@ static void CwLnx_reboot(int fd) * \retval <0 Error. */ MODULE_EXPORT int -CwLnx_init(Driver *drvthis) +CwLnx_init(Driver *drvthis, Elektra * elektra) { - char device[200] = DEFAULT_DEVICE; int speed = DEFAULT_SPEED; - char size[200] = DEFAULT_SIZE; int default_speed = DEFAULT_SPEED; char *default_size = DEFAULT_SIZE; - int tmp; int w; int h; - const char *s; PrivateData *p; @@ -473,51 +469,48 @@ CwLnx_init(Driver *drvthis) p->saved_brightness = -1; p->brightness = DEFAULT_BRIGHTNESS; - debug(RPT_INFO, "%s: init(%p)", drvthis->name, drvthis); + debug(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": init(%p)", drvthis->name, drvthis->index, drvthis); + + /* Read config */ - /* Read config file */ + CwLnxDriverConfig config; + elektraFillStructV(elektra, &config, CONF_CWLNX, drvthis->index); /* Which model is it (1602, 12232 or 12832)? */ - tmp = drvthis->config_get_int(drvthis->name, "Model", 0, 12232); - debug(RPT_INFO, "%s: Model (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp != 1602) && (tmp != 12232) && (tmp != 12832)) { - tmp = 12232; - report(RPT_WARNING, "%s: Model must be 12232, 12832 or 1602; using default %d", - drvthis->name, tmp); - } - p->model = tmp; + p->model = config.model; /* Which size & cell dimensions */ - if (p->model == 1602) { - default_size = DEFAULT_SIZE_1602; - default_speed = DEFAULT_SPEED_1602; - p->cellwidth = DEFAULT_CELL_WIDTH_1602; - p->cellheight = DEFAULT_CELL_HEIGHT_1602; - } else if (p->model == 12232) { - default_size = DEFAULT_SIZE_12232; - default_speed = DEFAULT_SPEED_12232; - p->cellwidth = DEFAULT_CELL_WIDTH_12232; - p->cellheight = DEFAULT_CELL_HEIGHT_12232; - } else if (p->model == 12832) { - default_size = DEFAULT_SIZE_12832; - default_speed = DEFAULT_SPEED_12832; - p->cellwidth = DEFAULT_CELL_WIDTH_12832; - p->cellheight = DEFAULT_CELL_HEIGHT_12832; - } + switch (p->model) + { + case CW_LNX_MODEL_1602: + default_size = DEFAULT_SIZE_1602; + default_speed = DEFAULT_SPEED_1602; + p->cellwidth = DEFAULT_CELL_WIDTH_1602; + p->cellheight = DEFAULT_CELL_HEIGHT_1602; + break; + case CW_LNX_MODEL_12232: + default_size = DEFAULT_SIZE_12232; + default_speed = DEFAULT_SPEED_12232; + p->cellwidth = DEFAULT_CELL_WIDTH_12232; + p->cellheight = DEFAULT_CELL_HEIGHT_12232; + break; + case CW_LNX_MODEL_12832: + default_size = DEFAULT_SIZE_12832; + default_speed = DEFAULT_SPEED_12832; + p->cellwidth = DEFAULT_CELL_WIDTH_12832; + p->cellheight = DEFAULT_CELL_HEIGHT_12832; + break; + } /* Which device should be used */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device) - 1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* Which size */ - strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, default_size), sizeof(size)); - size[sizeof(size) - 1] = '\0'; - if ((sscanf(size, "%dx%d", &w, &h) != 2) + if ((sscanf(config.size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", - drvthis->name, size, default_size); + drvthis->name, config.size, default_size); sscanf(default_size, "%dx%d", &w, &h); } p->width = w; @@ -526,9 +519,7 @@ CwLnx_init(Driver *drvthis) /* Contrast of the LCD can be changed by adjusting the trimpot R7 */ /* Which speed */ - tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, default_speed); - - switch (tmp) { + switch (config.speed) { case 9600: speed = B9600; break; @@ -542,46 +533,41 @@ CwLnx_init(Driver *drvthis) } /* do we have a keypad? */ - if (drvthis->config_get_bool(drvthis->name , "Keypad", 0, 0)) { - report(RPT_INFO, "%s: Config tells us we have a keypad", drvthis->name); - p->have_keypad = 1; + if (config.keypad) { + report(RPT_INFO, "%s: Config tells us we have a keypad", drvthis->name); + p->have_keypad = 1; } /* keypad test mode? */ - if (drvthis->config_get_bool(drvthis->name , "keypad_test_mode", 0, 0)) { - report(RPT_INFO, "%s: Config tells us to test the keypad mapping", drvthis->name); - p->keypad_test_mode = 1; - stay_in_foreground = 1; + if (config.keypadTestMode) { + report(RPT_INFO, "%s: Config tells us to test the keypad mapping", drvthis->name); + p->keypad_test_mode = 1; + stay_in_foreground = 1; } /* read the keypad mapping only if we have a keypad. */ if (p->have_keypad) { - int x; - - /* Read keymap */ - for (x = 0; x < MaxKeyMap; x++) { - char buf[40]; + /* Read keymap */ + p->KeyMap[0] = strdup(config.keymapA); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'A' to \"%s\"", drvthis->name, drvthis->index, config.keymapA); - /* First fill with default value */ + p->KeyMap[1] = strdup(config.keymapB); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'B' to \"%s\"", drvthis->name, drvthis->index, config.keymapB); - p->KeyMap[x] = defaultKeyMap[x]; -/* The line above make a warning... the code is comming from hd44780.c */ + p->KeyMap[2] = strdup(config.keymapC); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'C' to \"%s\"", drvthis->name, drvthis->index, config.keymapC); -/* printf("%s-%s\n", defaultKeyMap[x], p->KeyMap[x]); */ + p->KeyMap[3] = strdup(config.keymapD); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'D' to \"%s\"", drvthis->name, drvthis->index, config.keymapD); - /* Read config value */ - sprintf(buf, "KeyMap_%c", x+'A'); - s = drvthis->config_get_string(drvthis->name, buf, 0, NULL); + p->KeyMap[4] = strdup(config.keymapE); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'E' to \"%s\"", drvthis->name, drvthis->index, config.keymapE); - /* Was a key specified in the config file ? */ - if (s != NULL) { - p->KeyMap[x] = strdup(s); - report(RPT_INFO, "%s: Key '%c' to \"%s\"", drvthis->name, x+'A', s); - } - } + p->KeyMap[5] = strdup(config.keymapF); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key 'F' to \"%s\"", drvthis->name, drvthis->index, config.keymapF); } - /* End of config file parsing */ + /* End of config processing */ /* Allocate framebuffer memory */ p->framebuf = (unsigned char *) malloc(p->width * p->height); @@ -601,13 +587,13 @@ CwLnx_init(Driver *drvthis) /* Set up io port correctly, and open it... */ - debug(RPT_DEBUG, "%s: Opening device: %s", drvthis->name, device); - p->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + debug(RPT_DEBUG, "%s: Opening device: %s", drvthis->name, config.device); + p->fd = open(config.device, O_RDWR | O_NOCTTY | O_NDELAY); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno)); + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, config.device, strerror(errno)); return -1; } - report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); + report(RPT_INFO, "%s: opened display on %s", drvthis->name, config.device); /* Since we don't know what speed the display is using when diff --git a/server/drivers/CwLnx.h b/server/drivers/CwLnx.h index af458d75..e9ff69e9 100644 --- a/server/drivers/CwLnx.h +++ b/server/drivers/CwLnx.h @@ -22,6 +22,8 @@ #ifndef CWLNX_H #define CWLNX_H +#include + #define DEFAULT_DEVICE "/dev/lcd" #define DEFAULT_BACKLIGHT 1 #define DEFAULT_BRIGHTNESS 700 @@ -47,7 +49,7 @@ #define DEFAULT_SIZE DEFAULT_SIZE_12232 -MODULE_EXPORT int CwLnx_init(Driver *drvthis); +MODULE_EXPORT int CwLnx_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void CwLnx_close(Driver *drvthis); MODULE_EXPORT int CwLnx_width(Driver *drvthis); MODULE_EXPORT int CwLnx_height(Driver *drvthis); diff --git a/server/drivers/EyeboxOne.c b/server/drivers/EyeboxOne.c index fe448e3b..4b4754fd 100644 --- a/server/drivers/EyeboxOne.c +++ b/server/drivers/EyeboxOne.c @@ -126,7 +126,7 @@ EyeboxOne_parse_keypad_setting (Driver *drvthis, char * keyname, char default_va * Called to initialize driver settings */ MODULE_EXPORT int -EyeboxOne_init (Driver *drvthis) +EyeboxOne_init (Driver *drvthis, Elektra * elektra) { struct termios portset; diff --git a/server/drivers/EyeboxOne.h b/server/drivers/EyeboxOne.h index 4810a577..4c1baf50 100644 --- a/server/drivers/EyeboxOne.h +++ b/server/drivers/EyeboxOne.h @@ -1,7 +1,9 @@ #ifndef EYEBOXONE_H #define EYEBOXONE_H -MODULE_EXPORT int EyeboxOne_init (Driver *drvthis); +#include + +MODULE_EXPORT int EyeboxOne_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void EyeboxOne_close (Driver *drvthis); MODULE_EXPORT int EyeboxOne_width (Driver *drvthis); MODULE_EXPORT int EyeboxOne_height (Driver *drvthis); diff --git a/server/drivers/IOWarrior.c b/server/drivers/IOWarrior.c index ca23c2b8..5ea3c4cc 100644 --- a/server/drivers/IOWarrior.c +++ b/server/drivers/IOWarrior.c @@ -236,7 +236,7 @@ static int iowled_on_off(PrivateData *p, unsigned int pattern) * \retval <0 Error. */ MODULE_EXPORT int -IOWarrior_init(Driver *drvthis) +IOWarrior_init(Driver *drvthis, Elektra * elektra) { char serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO; char size[LCD_MAX_WIDTH+1] = DEFAULT_SIZE; diff --git a/server/drivers/IOWarrior.h b/server/drivers/IOWarrior.h index 511cf2f0..6b42a975 100644 --- a/server/drivers/IOWarrior.h +++ b/server/drivers/IOWarrior.h @@ -27,6 +27,8 @@ #ifndef IOWARRIOR_H #define IOWARRIOR_H +#include + #define DEFAULT_SERIALNO "" #define DEFAULT_SIZE "20x4" #define DEFAULT_BACKLIGHT 1 @@ -116,7 +118,7 @@ MODULE_EXPORT int supports_multiple = 1; MODULE_EXPORT char *symbol_prefix = "IOWarrior_"; /* API: functions for the server core */ -MODULE_EXPORT int IOWarrior_init(Driver *drvthis); +MODULE_EXPORT int IOWarrior_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void IOWarrior_close(Driver *drvthis); MODULE_EXPORT int IOWarrior_width(Driver *drvthis); MODULE_EXPORT int IOWarrior_height(Driver *drvthis); diff --git a/server/drivers/MD8800.c b/server/drivers/MD8800.c index a5b958cc..d7d4bf74 100644 --- a/server/drivers/MD8800.c +++ b/server/drivers/MD8800.c @@ -3,7 +3,7 @@ */ /* - Copyright (C) 2006 Stefan Herdler in collaboration with Martin Møller. + Copyright (C) 2006 Stefan Herdler in collaboration with Martin Møller. This source Code is based on the NoritakeVFD, the serialVFD and the CFontzPacket Driver of this package. @@ -28,7 +28,7 @@ ============================================================================== Known hardware-commands of the MD8800 display - discovered by Martin Møller (listed in octal notation): + discovered by Martin Møller (listed in octal notation): \33\0abcdef (abcdef can be anything, it seems) - set clock, I think. The mapping is: bb:aa dd.cc.eeff @@ -224,7 +224,7 @@ MODULE_EXPORT char *symbol_prefix = "MD8800_"; // Opens com port and sets baud correctly... // MODULE_EXPORT int -MD8800_init (Driver *drvthis) +MD8800_init (Driver *drvthis, Elektra * elektra) { struct termios portset; int tmp, w, h; diff --git a/server/drivers/MD8800.h b/server/drivers/MD8800.h index 5f9701a9..c4d19c31 100644 --- a/server/drivers/MD8800.h +++ b/server/drivers/MD8800.h @@ -1,6 +1,6 @@ /* This is the LCDproc driver for the VFD of the Medion MD8800 PC - Copyright (C) 2006 Stefan Herdler in collaboration with Martin Møller. + Copyright (C) 2006 Stefan Herdler in collaboration with Martin Møller. This source Code is based on the NoritakeVFD, the serialVFD and the CFontzPacket Driver of this package. @@ -23,13 +23,15 @@ #ifndef MD8800_H #define MD8800_H +#include + #define DEFAULT_CELL_WIDTH 5 #define DEFAULT_CELL_HEIGHT 7 #define DEFAULT_DEVICE "/dev/ttyS1" #define DEFAULT_SPEED 9600 #define DEFAULT_SIZE "16x2" -MODULE_EXPORT int MD8800_init (Driver *drvthis); +MODULE_EXPORT int MD8800_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void MD8800_close (Driver *drvthis); MODULE_EXPORT int MD8800_width (Driver *drvthis); MODULE_EXPORT int MD8800_height (Driver *drvthis); diff --git a/server/drivers/MtxOrb.c b/server/drivers/MtxOrb.c index dbd7abf9..186fd0af 100644 --- a/server/drivers/MtxOrb.c +++ b/server/drivers/MtxOrb.c @@ -62,6 +62,8 @@ #include "shared/report.h" +#include "../elektragen.h" + /* MO displays allow 25 keys that map by default to 'A' - 'Y' */ #define MAX_KEY_MAP 25 @@ -208,6 +210,18 @@ static void MtxOrb_cursorblink(Driver *drvthis, int on); static void MtxOrb_cursor_goto(Driver *drvthis, int x, int y); +static void read_keymap_key(Driver *drvthis, PrivateData *p, int index, char key, const char * mapped_key) +{ + if(strlen(mapped_key) > 0) { + p->keymap[index] = strdup(mapped_key); + p->keys++; + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": Key '%c' mapped to \"%s\"", drvthis->name, drvthis->index, key, mapped_key); + } else { + p->keymap[index] = NULL; + } +} + + /** * Initialize the driver. * \param drvthis Pointer to driver structure. @@ -215,15 +229,11 @@ static void MtxOrb_cursor_goto(Driver *drvthis, int x, int y); * \retval <0 Error. */ MODULE_EXPORT int -MtxOrb_init (Driver *drvthis) +MtxOrb_init (Driver *drvthis, Elektra *elektra) { struct termios portset; - - char device[256] = DEFAULT_DEVICE; int speed = DEFAULT_SPEED; - char size[256] = DEFAULT_SIZE; - char buf[256] = ""; - int tmp, w, h; + int w, h; PrivateData *p; @@ -252,62 +262,37 @@ MtxOrb_init (Driver *drvthis) debug(RPT_INFO, "MtxOrb: init(%p)", drvthis); /* READ CONFIG FILE */ + MtxOrbDriverConfig config; + elektraFillStructV(elektra, &config, CONF_MTXORB, drvthis->index); /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* Get display size */ - strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); - size[sizeof(size)-1] = '\0'; - if ((sscanf(size, "%dx%d", &w, &h) != 2) + if ((sscanf(config.size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", - drvthis->name, size, DEFAULT_SIZE); + drvthis->name, config.size, DEFAULT_SIZE); sscanf(DEFAULT_SIZE , "%dx%d", &w, &h); } p->width = w; p->height = h; /* Get contrast */ - tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Contrast must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_CONTRAST); - tmp = DEFAULT_CONTRAST; - } - p->contrast = tmp; + p->contrast = config.contrast; /* Does it have an adjustable backlight */ - tmp = drvthis->config_get_bool(drvthis->name, "hasAdjustableBacklight", 0, DEFAULT_ADJ_BACKLIGHT); - debug(RPT_INFO, "%s: hasAdjustableBacklight is '%d'", __FUNCTION__, tmp); - p->adjustable_backlight = tmp; + p->adjustable_backlight = config.hasAdjustableBacklight; /* Which backlight brightness */ - tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); - debug(RPT_INFO, "%s: Brightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_BRIGHTNESS); - tmp = DEFAULT_BRIGHTNESS; - } - p->brightness = tmp; + p->brightness = config.brightness; /* Which backlight-off "brightness" */ - tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS); - debug(RPT_INFO, "%s: OffBrightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: OffBrightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_OFFBRIGHTNESS); - tmp = DEFAULT_OFFBRIGHTNESS; - } - p->offbrightness = tmp; + p->offbrightness = config.offbrightness; /* Get speed */ - tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); - switch (tmp) { + switch (config.speed) { case 1200: speed = B1200; break; @@ -323,30 +308,30 @@ MtxOrb_init (Driver *drvthis) default: speed = B19200; report(RPT_WARNING, "%s: Speed must be 1200, 2400, 9600 or 19200; using default %d", - drvthis->name, tmp); + drvthis->name, config.speed); } /* Get display type */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Type", 0, DEFAULT_TYPE), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - if (strncasecmp(buf, "lcd", 3) == 0) { + switch (config.type) + { + case ELEKTRA_ENUM_MTXORB_TYPE_LCD: p->MtxOrb_type = MTXORB_LCD; - } else if (strncasecmp(buf, "lkd", 3) == 0) { + break; + case ELEKTRA_ENUM_MTXORB_TYPE_LKD: p->MtxOrb_type = MTXORB_LKD; - } else if (strncasecmp(buf, "vfd", 3) == 0) { + break; + case ELEKTRA_ENUM_MTXORB_TYPE_VFD: p->MtxOrb_type = MTXORB_VFD; - } else if (strncasecmp(buf, "vkd", 3) == 0) { + break; + case ELEKTRA_ENUM_MTXORB_TYPE_VKD: p->MtxOrb_type = MTXORB_VKD; - } else { - report(RPT_ERR, "%s: unknown display Type %s; must be one of lcd, lkd, vfd, or vkd", - drvthis->name, buf); - return -1; + break; } /* Get keypad settings */ /* keypad test mode? */ - if (drvthis->config_get_bool(drvthis->name, "keypad_test_mode", 0, 0)) { + if (config.keypadTestMode) { fprintf(stdout, "MtxOrb: Entering keypad test mode...\n"); p->keypad_test_mode = 1; stay_in_foreground = 1; @@ -358,42 +343,28 @@ MtxOrb_init (Driver *drvthis) * test mode. */ - int i; - /* assume no mapped keys */ p->keys = 0; /* read the keymap */ - for (i = 0; i < MAX_KEY_MAP; i++) { - const char *s; - - /* First fill with NULL; */ - p->keymap[i] = NULL; - - /* Read config value */ - sprintf(buf, "KeyMap_%c", i+'A'); - s = drvthis->config_get_string(drvthis->name, buf, 0, NULL); - - /* Was a key specified in the config file ? */ - if (s != NULL) { - p->keys++; - p->keymap[i] = strdup(s); - report(RPT_INFO, "%s: Key '%c' mapped to \"%s\"", - drvthis->name, i+'A', s ); - } - } + read_keymap_key(drvthis, p, 0, 'A', config.keymapA); + read_keymap_key(drvthis, p, 1, 'B', config.keymapB); + read_keymap_key(drvthis, p, 2, 'C', config.keymapC); + read_keymap_key(drvthis, p, 3, 'D', config.keymapD); + read_keymap_key(drvthis, p, 4, 'E', config.keymapE); + read_keymap_key(drvthis, p, 5, 'F', config.keymapF); } - /* End of config file parsing */ + /* End of config processing */ /* Set up io port correctly, and open it... */ - p->fd = open(device, O_RDWR | O_NOCTTY); + p->fd = open(config.device, O_RDWR | O_NOCTTY); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno)); + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, config.device, strerror(errno)); if (errno == EACCES) - report(RPT_ERR, "%s: %s device could not be opened...", drvthis->name, device); + report(RPT_ERR, "%s: %s device could not be opened...", drvthis->name, config.device); return -1; } - report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); + report(RPT_INFO, "%s: opened display on %s", drvthis->name, config.device); tcgetattr(p->fd, &portset); diff --git a/server/drivers/MtxOrb.h b/server/drivers/MtxOrb.h index 216a4ae5..7241733c 100644 --- a/server/drivers/MtxOrb.h +++ b/server/drivers/MtxOrb.h @@ -1,6 +1,8 @@ #ifndef MTXORB_H #define MTXORB_H +#include + #define DEFAULT_CONTRAST 480 #define DEFAULT_ADJ_BACKLIGHT 1 #define DEFAULT_BRIGHTNESS 1000 @@ -20,7 +22,7 @@ typedef struct MtxOrbModule { int flags; } MtxOrbModuleEntry; -MODULE_EXPORT int MtxOrb_init (Driver *drvthis); +MODULE_EXPORT int MtxOrb_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void MtxOrb_close (Driver *drvthis); MODULE_EXPORT int MtxOrb_width (Driver *drvthis); MODULE_EXPORT int MtxOrb_height (Driver *drvthis); diff --git a/server/drivers/NoritakeVFD.c b/server/drivers/NoritakeVFD.c index b847a387..743656d2 100644 --- a/server/drivers/NoritakeVFD.c +++ b/server/drivers/NoritakeVFD.c @@ -107,7 +107,7 @@ static void NoritakeVFD_cursor_goto (Driver *drvthis, int x, int y); * \retval <0 Error. */ MODULE_EXPORT int -NoritakeVFD_init (Driver *drvthis) +NoritakeVFD_init (Driver *drvthis, Elektra * elektra) { struct termios portset; int tmp, w, h; diff --git a/server/drivers/NoritakeVFD.h b/server/drivers/NoritakeVFD.h index f5957801..4bec01bd 100644 --- a/server/drivers/NoritakeVFD.h +++ b/server/drivers/NoritakeVFD.h @@ -22,6 +22,8 @@ #ifndef NORITAKEVFD_H #define NORITAKEVFD_H +#include + #define DEFAULT_CELL_WIDTH 5 #define DEFAULT_CELL_HEIGHT 7 #define DEFAULT_DEVICE "/dev/lcd" @@ -31,7 +33,7 @@ #define DEFAULT_SIZE "20x4" #define DEFAULT_PARITY 0 -MODULE_EXPORT int NoritakeVFD_init (Driver *drvthis); +MODULE_EXPORT int NoritakeVFD_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void NoritakeVFD_close (Driver *drvthis); MODULE_EXPORT int NoritakeVFD_width (Driver *drvthis); MODULE_EXPORT int NoritakeVFD_height (Driver *drvthis); diff --git a/server/drivers/Olimex_MOD_LCD1x9.c b/server/drivers/Olimex_MOD_LCD1x9.c index 8aeed349..12781eb8 100644 --- a/server/drivers/Olimex_MOD_LCD1x9.c +++ b/server/drivers/Olimex_MOD_LCD1x9.c @@ -58,7 +58,7 @@ MODULE_EXPORT char *symbol_prefix = "olimex1x9_"; * \retval <0 Error. */ MODULE_EXPORT int -olimex1x9_init (Driver *drvthis) +olimex1x9_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; const char *configvalue; diff --git a/server/drivers/Olimex_MOD_LCD1x9.h b/server/drivers/Olimex_MOD_LCD1x9.h index 87d5c66e..8f14a5d0 100644 --- a/server/drivers/Olimex_MOD_LCD1x9.h +++ b/server/drivers/Olimex_MOD_LCD1x9.h @@ -1,7 +1,9 @@ #ifndef OLIMEX_LCD1x9_H #define OLIMEX_LCD1x9_H -MODULE_EXPORT int olimex1x9_init (Driver *drvthis); +#include + +MODULE_EXPORT int olimex1x9_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void olimex1x9_close (Driver *drvthis); MODULE_EXPORT int olimex1x9_width (Driver *drvthis); MODULE_EXPORT int olimex1x9_height (Driver *drvthis); diff --git a/server/drivers/SureElec.h b/server/drivers/SureElec.h index 7e1d3bf2..2729ceb3 100644 --- a/server/drivers/SureElec.h +++ b/server/drivers/SureElec.h @@ -4,6 +4,8 @@ #ifndef SUREELEC_H #define SUREELEC_H +#include + #define DEFAULT_DEVICE "/dev/ttyUSB0" #define DEFAULT_SPEED 9600 #define DEFAULT_LINEWRAP 1 @@ -26,7 +28,7 @@ #define NUM_CC 8 -MODULE_EXPORT int SureElec_init (Driver *drvthis); +MODULE_EXPORT int SureElec_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void SureElec_close (Driver *drvthis); MODULE_EXPORT int SureElec_width (Driver *drvthis); MODULE_EXPORT int SureElec_height (Driver *drvthis); diff --git a/server/drivers/bayrad.c b/server/drivers/bayrad.c index d0f0dcd1..4cc079e9 100644 --- a/server/drivers/bayrad.c +++ b/server/drivers/bayrad.c @@ -37,6 +37,8 @@ #include "shared/report.h" #include "lcd_lib.h" +#include "../elektragen.h" + #define NUM_CCs 8 /* number of characters */ #define BAYRAD_DEFAULT_DEVICE "/dev/lcd" @@ -44,7 +46,6 @@ /** private data for the \c bayrad driver */ typedef struct bayrad_private_data { - char device[256]; int speed; int fd; int width; @@ -70,7 +71,7 @@ MODULE_EXPORT char *symbol_prefix = "bayrad_"; * \retval <0 Error. */ MODULE_EXPORT int -bayrad_init(Driver *drvthis) +bayrad_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; @@ -93,31 +94,21 @@ bayrad_init(Driver *drvthis) p->ccmode = standard; - /* Read config file */ + /* Read config */ + + BayradDriverConfig config; + elektraFillStructV (elektra, &config, CONF_BAYRAD, drvthis->index); /* What device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, - BAYRAD_DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* What speed to use */ - p->speed = drvthis->config_get_int(drvthis->name, "Speed", 0, 9600); - - if (p->speed == 1200) p->speed = B1200; - else if (p->speed == 2400) p->speed = B2400; - else if (p->speed == 9600) p->speed = B9600; - else if (p->speed == 19200) p->speed = B19200; - else { - report(RPT_WARNING, "%s: illegal Speed %d; must be one of 1200, 2400, 9600 or 19200; using default %d", - drvthis->name, p->speed, 9600); - p->speed = B9600; - } + p->speed = config.speed; // Set up io port correctly, and open it... - p->fd = open(p->device, O_RDWR | O_NOCTTY | O_NDELAY); + p->fd = open(config.device, O_RDWR | O_NOCTTY | O_NDELAY); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, p->device, strerror(errno)); + report(RPT_ERR, "%s#"ELEKTRA_LONG_LONG_F": open(%s) failed (%s)", drvthis->name, drvthis->index, config.device, strerror(errno)); return -1; } diff --git a/server/drivers/bayrad.h b/server/drivers/bayrad.h index 44ec2c58..a4109e3c 100644 --- a/server/drivers/bayrad.h +++ b/server/drivers/bayrad.h @@ -8,7 +8,9 @@ #ifndef _BAYRAD_H #define _BAYRAD_H -MODULE_EXPORT int bayrad_init(Driver *drvthis); +#include + +MODULE_EXPORT int bayrad_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void bayrad_close(Driver *drvthis); MODULE_EXPORT int bayrad_width(Driver *drvthis); MODULE_EXPORT int bayrad_height(Driver *drvthis); diff --git a/server/drivers/curses_drv.c b/server/drivers/curses_drv.c index ed04e8c2..bb1a30b4 100644 --- a/server/drivers/curses_drv.c +++ b/server/drivers/curses_drv.c @@ -49,6 +49,11 @@ Different implementations of (n)curses available on: #include "config.h" #endif +#include "lcd.h" +#include "curses_drv.h" + +#define ELEKTRA_KEY_END 0 + #include #include #include @@ -61,10 +66,10 @@ Different implementations of (n)curses available on: #include #endif -#include "lcd.h" -#include "curses_drv.h" #include "shared/report.h" +#include "../elektragen.h" + // ACS_S9 and ACS_S1 are defined as part of XSI Curses standard, Issue 4. // However, ACS_S3 and ACS_S7 are not; these definitions were created to support // commonly available graphics found in many terminfo definitions. The acsc character @@ -131,7 +136,7 @@ MODULE_EXPORT char *symbol_prefix = "curses_"; /* local helper functions */ static void curses_wborder (Driver *drvthis); -static chtype get_color_by_name (char *colorname, chtype default_color); +static chtype map_color_to_curses (CursesColor color); static void curses_restore_screen (Driver *drvthis); @@ -142,11 +147,9 @@ static void curses_restore_screen (Driver *drvthis); * \retval <0 Error. */ MODULE_EXPORT int -curses_init (Driver *drvthis) +curses_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; - char buf[256]; - int tmp; // Colors.... chtype back_color = DEFAULT_BACKGROUND_COLOR, @@ -173,35 +176,30 @@ curses_init (Driver *drvthis) p->cellheight = LCD_DEFAULT_CELLHEIGHT; p->drawBorder = CONF_DEF_DRAWBORDER; - /* Get settings from config file */ + /* Get settings from config */ + + CursesDriverConfig config; + elektraFillStructV(elektra, &config, CONF_CURSES, drvthis->index); /* Get color settings */ /* foreground color */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Foreground", 0, CONF_DEF_FOREGR), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - fore_color = get_color_by_name(buf, DEFAULT_FOREGROUND_COLOR); - debug(RPT_DEBUG, "%s: using foreground color %s", drvthis->name, buf); + fore_color = map_color_to_curses(config.foreground); + debug(RPT_DEBUG, "%s: using foreground color %s", drvthis->name, ELEKTRA_TO_CONST_STRING(EnumCursesColor) (config.foreground)); /* background color */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Background", 0, CONF_DEF_BACKGR), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - back_color = get_color_by_name(buf, DEFAULT_BACKGROUND_COLOR); - debug(RPT_DEBUG, "%s: using background color %s", drvthis->name, buf); + back_color = map_color_to_curses(config.background); + debug(RPT_DEBUG, "%s: using background color %s", drvthis->name, ELEKTRA_TO_CONST_STRING(EnumCursesColor) (config.background)); /* backlight color */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Backlight", 0, CONF_DEF_BACKLIGHT), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - backlight_color = get_color_by_name(buf, DEFAULT_BACKGROUND_COLOR); - debug(RPT_DEBUG, "%s: using backlight color %s", drvthis->name, buf); + backlight_color = map_color_to_curses(config.backlight); + debug(RPT_DEBUG, "%s: using backlight color %s", drvthis->name, ELEKTRA_TO_CONST_STRING(EnumCursesColor) (config.backlight)); /* use ACS characters? */ - p->useACS = drvthis->config_get_bool(drvthis->name, "UseACS", 0, CONF_DEF_USEACS); - debug(RPT_DEBUG, "%s: using ACS %s", drvthis->name, (p->useACS) ? "ON" : "OFF"); + p->useACS = config.useacs; /* draw border ? */ - p->drawBorder = drvthis->config_get_bool(drvthis->name, "DrawBorder", 0, CONF_DEF_DRAWBORDER); - debug(RPT_DEBUG, "%s: drawing Border %s", drvthis->name, (p->drawBorder) ? "ON" : "OFF"); + p->drawBorder = config.drawborder; /* Get size settings */ if ((drvthis->request_display_width() > 0) @@ -212,33 +210,29 @@ curses_init (Driver *drvthis) } else { /* Use our own size from config file */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Size", 0, CONF_DEF_SIZE), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - if ((sscanf(buf , "%dx%d", &p->width, &p->height) != 2) + if ((sscanf(config.size , "%dx%d", &p->width, &p->height) != 2) || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", - drvthis->name, buf, CONF_DEF_SIZE); + drvthis->name, config.size, CONF_DEF_SIZE); sscanf(CONF_DEF_SIZE, "%dx%d", &p->width, &p->height); } } /*Get position settings*/ - tmp = drvthis->config_get_int(drvthis->name, "TopLeftX", 0, CONF_DEF_TOP_LEFT_X); - if ((tmp < 0) || (tmp > 255)) { + if ((config.topleftx < 0) || (config.topleftx > 255)) { report(RPT_WARNING, "%s: TopLeftX must be between 0 and 255; using default %d", drvthis->name, CONF_DEF_TOP_LEFT_X); - tmp = CONF_DEF_TOP_LEFT_X; + config.topleftx = CONF_DEF_TOP_LEFT_X; } - p->xoffs = tmp; + p->xoffs = config.topleftx; - tmp = drvthis->config_get_int(drvthis->name, "TopLeftY", 0, CONF_DEF_TOP_LEFT_Y); - if ((tmp < 0) || (tmp > 255)) { + if ((config.toplefty < 0) || (config.toplefty > 255)) { report(RPT_WARNING, "%s: TopLeftY must be between 0 and 255; using default %d", drvthis->name, CONF_DEF_TOP_LEFT_Y); - tmp = CONF_DEF_TOP_LEFT_Y; + config.toplefty = CONF_DEF_TOP_LEFT_Y; } - p->yoffs = tmp; + p->yoffs = config.toplefty; //debug: sleep(1); @@ -705,25 +699,27 @@ curses_wborder (Driver *drvthis) static chtype -get_color_by_name (char *colorname, chtype default_color) { - if (strcasecmp(colorname, "red") == 0) - return COLOR_RED; - else if (strcasecmp(colorname, "black") == 0) - return COLOR_BLACK; - else if (strcasecmp(colorname, "green") == 0) - return COLOR_GREEN; - else if (strcasecmp(colorname, "yellow") == 0) - return COLOR_YELLOW; - else if (strcasecmp(colorname, "blue") == 0) - return COLOR_BLUE; - else if (strcasecmp(colorname, "magenta") == 0) - return COLOR_MAGENTA; - else if (strcasecmp(colorname, "cyan") == 0) - return COLOR_CYAN; - else if (strcasecmp(colorname, "white") == 0) - return COLOR_WHITE; - - return default_color; +map_color_to_curses (CursesColor color) { + switch(color) { + case CURSES_COLOR_RED: + return COLOR_RED; + case CURSES_COLOR_BLACK: + return COLOR_BLACK; + case CURSES_COLOR_GREEN: + return COLOR_GREEN; + case CURSES_COLOR_YELLOW: + return COLOR_YELLOW; + case CURSES_COLOR_BLUE: + return COLOR_BLUE; + case CURSES_COLOR_MAGENTA: + return COLOR_MAGENTA; + case CURSES_COLOR_CYAN: + return COLOR_CYAN; + case CURSES_COLOR_WHITE: + return COLOR_WHITE; + default: + return -1; + } } diff --git a/server/drivers/curses_drv.h b/server/drivers/curses_drv.h index 54c04a1a..45eacc09 100644 --- a/server/drivers/curses_drv.h +++ b/server/drivers/curses_drv.h @@ -1,7 +1,9 @@ #ifndef LCD_CURSES_H #define LCD_CURSES_H -MODULE_EXPORT int curses_init (Driver *drvthis); +#include + +MODULE_EXPORT int curses_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void curses_close (Driver *drvthis); MODULE_EXPORT int curses_width (Driver *drvthis); MODULE_EXPORT int curses_height (Driver *drvthis); @@ -21,7 +23,7 @@ MODULE_EXPORT void curses_backlight (Driver *drvthis, int on); MODULE_EXPORT const char *curses_get_key (Driver *drvthis); MODULE_EXPORT const char *curses_get_info(Driver *drvthis); -/* Default settings for config file parsing */ +/* Default settings for config */ #define CONF_DEF_FOREGR "blue" #define CONF_DEF_BACKGR "cyan" #define CONF_DEF_BACKLIGHT "red" diff --git a/server/drivers/debug.c b/server/drivers/debug.c index aaf652ff..827167f6 100644 --- a/server/drivers/debug.c +++ b/server/drivers/debug.c @@ -71,7 +71,7 @@ MODULE_EXPORT char *symbol_prefix = "debug_"; * \retval <0 Error. */ MODULE_EXPORT int -debug_init(Driver *drvthis) +debug_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; diff --git a/server/drivers/debug.h b/server/drivers/debug.h index a4eeb00e..593eb773 100644 --- a/server/drivers/debug.h +++ b/server/drivers/debug.h @@ -1,7 +1,9 @@ #ifndef LCD_DEBUG_H #define LCD_DEBUG_H -MODULE_EXPORT int debug_init (Driver *drvthis); +#include + +MODULE_EXPORT int debug_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void debug_close (Driver *drvthis); MODULE_EXPORT int debug_width (Driver *drvthis); MODULE_EXPORT int debug_height (Driver *drvthis); diff --git a/server/drivers/ea65.c b/server/drivers/ea65.c index 44c27dec..e2a07de1 100644 --- a/server/drivers/ea65.c +++ b/server/drivers/ea65.c @@ -68,7 +68,7 @@ MODULE_EXPORT char *symbol_prefix = "EA65_"; * \retval <0 Error. */ MODULE_EXPORT int -EA65_init (Driver *drvthis) +EA65_init (Driver *drvthis, Elektra * elektra) { struct termios portset; /* device is fixed */ diff --git a/server/drivers/ea65.h b/server/drivers/ea65.h index c3d764c4..327a7c50 100644 --- a/server/drivers/ea65.h +++ b/server/drivers/ea65.h @@ -1,10 +1,12 @@ #ifndef EA65_H #define EA65_H +#include + #define DEFAULT_BRIGHTNESS 500 #define DEFAULT_OFFBRIGHTNESS 0 -MODULE_EXPORT int EA65_init (Driver *drvthis); +MODULE_EXPORT int EA65_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void EA65_close (Driver *drvthis); MODULE_EXPORT int EA65_width (Driver *drvthis); MODULE_EXPORT int EA65_height (Driver *drvthis); diff --git a/server/drivers/futaba.c b/server/drivers/futaba.c index 6edeb0ad..3c53558e 100644 --- a/server/drivers/futaba.c +++ b/server/drivers/futaba.c @@ -491,7 +491,7 @@ futaba_shutdown(Driver *drvthis) * \return 0 on success, -1 on error. */ MODULE_EXPORT int -futaba_init(Driver *drvthis) +futaba_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; diff --git a/server/drivers/futaba.h b/server/drivers/futaba.h index 0febe852..2ef20b60 100644 --- a/server/drivers/futaba.h +++ b/server/drivers/futaba.h @@ -23,6 +23,7 @@ #define USB_CLOSE_DEVICE usb_close #define USB_CONTROL_TRANSFER usb_control_msg #endif +#include /* DEFINITIONS----------------------------------- */ #define FUTABA_REPORT_LENGTH 64 @@ -91,7 +92,7 @@ int futaba_set_icon(Driver *drvthis); void futaba_shutdown(Driver *drvthis); -MODULE_EXPORT int futaba_init(Driver *drvthis); +MODULE_EXPORT int futaba_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void futaba_close(Driver *drvthis); MODULE_EXPORT int futaba_width(Driver *drvthis); MODULE_EXPORT int futaba_height(Driver *drvthis); diff --git a/server/drivers/g15.c b/server/drivers/g15.c index 154e253d..2c3d3d19 100644 --- a/server/drivers/g15.c +++ b/server/drivers/g15.c @@ -96,7 +96,7 @@ static const struct lib_hidraw_id hidraw_ids[] = { // Find the proper usb device and initialize it // -MODULE_EXPORT int g15_init (Driver *drvthis) +MODULE_EXPORT int g15_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; diff --git a/server/drivers/g15.h b/server/drivers/g15.h index 7efbe5da..00c9f3f0 100644 --- a/server/drivers/g15.h +++ b/server/drivers/g15.h @@ -24,6 +24,7 @@ //#include #include #include "lcd.h" +#include #include "hidraw_lib.h" /** private data for the \c g15 driver */ @@ -74,7 +75,7 @@ typedef struct g15_private_data { extern short g15_bignum_data[11][G15_BIGNUM_LEN]; -MODULE_EXPORT int g15_init (Driver *drvthis); +MODULE_EXPORT int g15_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void g15_close (Driver *drvthis); MODULE_EXPORT int g15_width (Driver *drvthis); MODULE_EXPORT int g15_height (Driver *drvthis); diff --git a/server/drivers/glcd-drivers.h b/server/drivers/glcd-drivers.h index 93f71505..58c037c5 100644 --- a/server/drivers/glcd-drivers.h +++ b/server/drivers/glcd-drivers.h @@ -12,22 +12,24 @@ # include "config.h" #endif +#include + /* Include prototypes for initialization functions below */ #ifdef HAVE_PCSTYLE_LPT_CONTROL -int glcd_t6963_init(Driver *drvthis); +int glcd_t6963_init(Driver *drvthis, Elektra * elektra); #endif #ifdef HAVE_LIBPNG -int glcd_png_init(Driver *drvthis); +int glcd_png_init(Driver *drvthis, Elektra * elektra); #endif #ifdef HAVE_SERDISPLIB -int glcd_serdisp_init(Driver *drvthis); +int glcd_serdisp_init(Driver *drvthis, Elektra * elektra); #endif #ifdef HAVE_LIBUSB -int glcd2usb_init(Driver *drvthis); -int glcd_picolcdgfx_init(Driver *drvthis); +int glcd2usb_init(Driver *drvthis, Elektra * elektra); +int glcd_picolcdgfx_init(Driver *drvthis, Elektra * elektra); #endif #ifdef HAVE_LIBX11 -int glcd_x11_init(Driver *drvthis); +int glcd_x11_init(Driver *drvthis, Elektra * elektra); #endif /* symbolic names for connection types */ diff --git a/server/drivers/glcd-glcd2usb.c b/server/drivers/glcd-glcd2usb.c index 0a3e024a..d0651ade 100644 --- a/server/drivers/glcd-glcd2usb.c +++ b/server/drivers/glcd-glcd2usb.c @@ -337,7 +337,7 @@ glcd2usb_poll_keys(PrivateData *p) * API: Initialize glcd2usb connection type. */ int -glcd2usb_init(Driver *drvthis) +glcd2usb_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *)drvthis->private_data; CT_glcd2usb_data *ctd; diff --git a/server/drivers/glcd-picolcdgfx.c b/server/drivers/glcd-picolcdgfx.c index 33611712..612175ba 100644 --- a/server/drivers/glcd-picolcdgfx.c +++ b/server/drivers/glcd-picolcdgfx.c @@ -88,7 +88,7 @@ picolcdgfx_write(usb_dev_handle * lcd, unsigned char *data, int size) * \retval <0 Error. */ int -glcd_picolcdgfx_init(Driver *drvthis) +glcd_picolcdgfx_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *) drvthis->private_data; CT_picolcdgfx_data *ct_data; diff --git a/server/drivers/glcd-png.c b/server/drivers/glcd-png.c index 916f1fb4..3ca9dee7 100644 --- a/server/drivers/glcd-png.c +++ b/server/drivers/glcd-png.c @@ -44,7 +44,7 @@ typedef struct glcd_png_data { * \retval <0 Error. */ int -glcd_png_init(Driver *drvthis) +glcd_png_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *)drvthis->private_data; CT_png_data *ct_data; diff --git a/server/drivers/glcd-render.c b/server/drivers/glcd-render.c index b11f00b2..4232ecf5 100644 --- a/server/drivers/glcd-render.c +++ b/server/drivers/glcd-render.c @@ -53,7 +53,7 @@ static int icon2unicode(int icon); * \note This function must be implemented, even if not compiled with Freetype! */ int -glcd_render_init(Driver *drvthis) +glcd_render_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = drvthis->private_data; p->cellwidth = GLCD_DEFAULT_CELLWIDTH; diff --git a/server/drivers/glcd-render.h b/server/drivers/glcd-render.h index 2085a276..9d0712fb 100644 --- a/server/drivers/glcd-render.h +++ b/server/drivers/glcd-render.h @@ -1,7 +1,9 @@ #ifndef GLCD_RENDER_H #define GLCD_RENDER_H -int glcd_render_init(Driver *drvthis); +#include + +int glcd_render_init(Driver *drvthis, Elektra * elektra); void glcd_render_close(Driver *drvthis); void glcd_render_char(Driver *drvthis, int x, int y, unsigned char c); int glcd_render_icon(Driver *drvthis, int x, int y, int icon); diff --git a/server/drivers/glcd-serdisp.c b/server/drivers/glcd-serdisp.c index ce1716f3..cd37b26c 100644 --- a/server/drivers/glcd-serdisp.c +++ b/server/drivers/glcd-serdisp.c @@ -57,7 +57,7 @@ typedef struct glcd_serdisp_data { * \retval <0 Error. */ int -glcd_serdisp_init(Driver *drvthis) +glcd_serdisp_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *)drvthis->private_data; CT_serdisp_data *ct_data; diff --git a/server/drivers/glcd-t6963.c b/server/drivers/glcd-t6963.c index d97d1b89..2b144780 100644 --- a/server/drivers/glcd-t6963.c +++ b/server/drivers/glcd-t6963.c @@ -46,7 +46,7 @@ typedef struct glcd_t6963_data { * \retval <0 Error. */ int -glcd_t6963_init(Driver *drvthis) +glcd_t6963_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *)drvthis->private_data; T6963_port *port_config; diff --git a/server/drivers/glcd-x11.c b/server/drivers/glcd-x11.c index 7e8727fe..1bd710d3 100755 --- a/server/drivers/glcd-x11.c +++ b/server/drivers/glcd-x11.c @@ -155,7 +155,7 @@ x11w_adj_contrast_brightness(unsigned long *pfgc, unsigned long *pbgc, int contr * \retval <0 Error. */ int -glcd_x11_init(Driver *drvthis) +glcd_x11_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = (PrivateData *) drvthis->private_data; CT_x11_data *ct_data; diff --git a/server/drivers/glcd_drv.c b/server/drivers/glcd_drv.c index cce71250..12cddfb5 100644 --- a/server/drivers/glcd_drv.c +++ b/server/drivers/glcd_drv.c @@ -69,7 +69,7 @@ static char *defaultKeyMap[GLCD_KEYPAD_MAX] = {"Up", "Down", "Left", "Right", "E * \retval <0 Error. */ MODULE_EXPORT int -glcd_init(Driver *drvthis) +glcd_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int i; diff --git a/server/drivers/glcd_drv.h b/server/drivers/glcd_drv.h index be3717d0..9067a060 100644 --- a/server/drivers/glcd_drv.h +++ b/server/drivers/glcd_drv.h @@ -1,7 +1,9 @@ #ifndef GLCD_DRV_H #define GLCD_DRV_H -MODULE_EXPORT int glcd_init(Driver *drvthis); +#include + +MODULE_EXPORT int glcd_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void glcd_close(Driver *drvthis); MODULE_EXPORT int glcd_width(Driver *drvthis); MODULE_EXPORT int glcd_height(Driver *drvthis); diff --git a/server/drivers/glcdlib.c b/server/drivers/glcdlib.c index 900bf7ee..f6415275 100644 --- a/server/drivers/glcdlib.c +++ b/server/drivers/glcdlib.c @@ -50,7 +50,7 @@ MODULE_EXPORT int supports_multiple = 0; MODULE_EXPORT char *symbol_prefix = "glcdlib_"; -MODULE_EXPORT int glcdlib_init (Driver *drvthis) +MODULE_EXPORT int glcdlib_init (Driver *drvthis, Elektra * elektra) { glcdlibPD * pPD; diff --git a/server/drivers/glcdlib.h b/server/drivers/glcdlib.h index 7799e9cb..4b48a67c 100644 --- a/server/drivers/glcdlib.h +++ b/server/drivers/glcdlib.h @@ -16,6 +16,7 @@ #define GLCDLIBLCDPROCDRIVER_H #include "lcd.h" +#include @@ -27,7 +28,7 @@ typedef unsigned char u8; // **************************************************************************************** -MODULE_EXPORT int glcdlib_init (Driver *drvthis); +MODULE_EXPORT int glcdlib_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void glcdlib_close (Driver *drvthis); MODULE_EXPORT int glcdlib_width (Driver *drvthis); MODULE_EXPORT int glcdlib_height (Driver *drvthis); diff --git a/server/drivers/glk.c b/server/drivers/glk.c index 668a0f6f..d4be8400 100644 --- a/server/drivers/glk.c +++ b/server/drivers/glk.c @@ -42,6 +42,8 @@ #include "shared/report.h" #include "adv_bignum.h" +#include "../elektragen.h" + #define GLK_DEFAULT_DEVICE "/dev/lcd" #define GLK_DEFAULT_SPEED 19200 #define GLK_DEFAULT_CONTRAST 500 @@ -51,7 +53,6 @@ /** private data for the \c glk driver */ typedef struct glk_private_data { - char device[256]; GLKDisplay *fd; speed_t speed; @@ -91,7 +92,7 @@ MODULE_EXPORT char *symbol_prefix = "glk_"; * \retval <0 Error. */ MODULE_EXPORT int -glk_init(Driver *drvthis) +glk_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int i; @@ -115,16 +116,15 @@ glk_init(Driver *drvthis) p->contrast = GLK_DEFAULT_CONTRAST; p->clearcount = 0; - /* Read config file */ + /* Read config */ + GlkDriverConfig config; + elektraFillStructV(elektra, &config, CONF_GLK, drvthis->index); /* What device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, - GLK_DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* What speed to use */ - p->speed = drvthis->config_get_int(drvthis->name, "Speed", 0, 19200); + p->speed = config.speed; if (p->speed == 9600) p->speed = B9600; else if (p->speed == 19200) p->speed = B19200; @@ -138,19 +138,14 @@ glk_init(Driver *drvthis) } /* Which contrast */ - p->contrast = drvthis->config_get_int(drvthis->name, "Contrast" , 0 , GLK_DEFAULT_CONTRAST); - if ((p->contrast < 0) || (p->contrast > 1000)) { - report(RPT_WARNING, "%s: Contrast must be between 0 and 1000. Using default %d", - drvthis->name, GLK_DEFAULT_CONTRAST); - p->contrast = GLK_DEFAULT_CONTRAST; - } + p->contrast = config.contrast; - /* End of config file parsing */ + /* End of config processing */ /* open device */ - p->fd = glkopen(p->device, p->speed); + p->fd = glkopen(config.device, p->speed); if (p->fd == NULL) { - report(RPT_ERR, "%s: unable to open device %s", drvthis->name, p->device); + report(RPT_ERR, "%s: unable to open device %s", drvthis->name, config.device); return -1; } diff --git a/server/drivers/glk.h b/server/drivers/glk.h index a182e1a2..3e5f0063 100644 --- a/server/drivers/glk.h +++ b/server/drivers/glk.h @@ -1,7 +1,9 @@ #ifndef GLK_H #define GLK_H -MODULE_EXPORT int glk_init(Driver *drvthis); +#include + +MODULE_EXPORT int glk_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void glk_close(Driver *drvthis); MODULE_EXPORT int glk_width(Driver *drvthis); MODULE_EXPORT int glk_height(Driver *drvthis); diff --git a/server/drivers/glkproto.c b/server/drivers/glkproto.c index f6802ff3..7e0a0165 100644 --- a/server/drivers/glkproto.c +++ b/server/drivers/glkproto.c @@ -36,7 +36,7 @@ unsigned char GLKBufferEmpty = 0xff; * Open and configure a serial port for communication with * a Matrix Orbital module (GLK or otherwise) */ -GLKDisplay *glkopen(char *name, tcflag_t speed) +GLKDisplay *glkopen(const char *name, tcflag_t speed) { int fd; struct termios new; diff --git a/server/drivers/glkproto.h b/server/drivers/glkproto.h index d777ef59..b1ccd6d5 100644 --- a/server/drivers/glkproto.h +++ b/server/drivers/glkproto.h @@ -42,7 +42,7 @@ typedef struct { #define GLK_TIMEOUT (254) /* Functions */ -GLKDisplay * glkopen( char * name, tcflag_t speed ); +GLKDisplay * glkopen( const char * name, tcflag_t speed ); int glktimeout( GLKDisplay * fd, int timeout ); int glkclose( GLKDisplay * ); int glkput_confirm( GLKDisplay * fd, int c ); diff --git a/server/drivers/hd44780-4bit.c b/server/drivers/hd44780-4bit.c index 76e9d947..4287f589 100644 --- a/server/drivers/hd44780-4bit.c +++ b/server/drivers/hd44780-4bit.c @@ -112,7 +112,7 @@ static const unsigned char EnMask[] = { EN1, EN2, EN3, STRB, LF, INIT, SEL }; * \retval -1 Error. */ int -hd_init_4bit(Driver *drvthis) +hd_init_4bit(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; diff --git a/server/drivers/hd44780-4bit.h b/server/drivers/hd44780-4bit.h index 28da3bac..df9cdfb1 100644 --- a/server/drivers/hd44780-4bit.h +++ b/server/drivers/hd44780-4bit.h @@ -2,8 +2,9 @@ #define HD_LCDSTAT_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_4bit(Driver *drvthis); +int hd_init_4bit(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-bwct-usb.c b/server/drivers/hd44780-bwct-usb.c index a052f67f..96b3661c 100644 --- a/server/drivers/hd44780-bwct-usb.c +++ b/server/drivers/hd44780-bwct-usb.c @@ -38,24 +38,20 @@ void bwct_usb_HD44780_close(PrivateData *p); * \retval -1 Error. */ int -hd_init_bwct_usb(Driver *drvthis) +hd_init_bwct_usb(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; struct usb_bus *bus; //char device_manufacturer[LCD_MAX_WIDTH+1] = ""; char device_serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO; - char serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO; p->hd44780_functions->senddata = bwct_usb_HD44780_senddata; p->hd44780_functions->close = bwct_usb_HD44780_close; p->hd44780_functions->set_contrast = bwct_usb_HD44780_set_contrast; - /* Read config file's contents: serial number and contrast */ - - strncpy(serial, drvthis->config_get_string(drvthis->name, "SerialNumber", - 0, DEFAULT_SERIALNO), sizeof(serial)); - serial[sizeof(serial)-1] = '\0'; + /* Read config */ + const char * serial = config->usbSerialnumber; if (*serial != '\0') { report(RPT_INFO, "hd_init_bwct_usb: Using serial number: %s", serial); } diff --git a/server/drivers/hd44780-bwct-usb.h b/server/drivers/hd44780-bwct-usb.h index e8c2c3a8..1b2a70a2 100644 --- a/server/drivers/hd44780-bwct-usb.h +++ b/server/drivers/hd44780-bwct-usb.h @@ -2,6 +2,7 @@ #define HD_BWCT_USB_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* vendor and product id */ #define BWCT_USB_VENDORID 0x03DA @@ -15,6 +16,6 @@ #define DEFAULT_SERIALNO "" // initialise this particular driver -int hd_init_bwct_usb(Driver *drvthis); +int hd_init_bwct_usb(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-charmap.h b/server/drivers/hd44780-charmap.h index 3e23bbff..fc779ab0 100644 --- a/server/drivers/hd44780-charmap.h +++ b/server/drivers/hd44780-charmap.h @@ -20,6 +20,8 @@ * Refer to the COPYING file distributed with this package. */ +#include "../elektragen.h" + /* * The 'none' charmap does map each character to itself, not replacing @@ -536,28 +538,24 @@ const unsigned char WEH001602A_1_charmap[] = { }; #endif /* EXTRA_CHARMAPS */ -#define MAX_CHARMAP_NAME_LENGTH 16 - struct charmap { - char name[MAX_CHARMAP_NAME_LENGTH]; /**< Name of the mapping table */ - const unsigned char *charmap; /**< Pointer to mapping table */ + ElektraEnumHd44780Charmap elektraCharmap; /**< Config value of the mapping table */ + const unsigned char *charmap; /**< Pointer to mapping table */ }; /** List of available character mappings. This list is sorted by relevance! */ const struct charmap available_charmaps[] = { - { "hd44780_default", HD44780_charmap }, - { "hd44780_euro", HD44780_euro_charmap }, - { "ea_ks0073", EA_KS0073_charmap }, - { "sed1278f_0b", SED1278F_0B_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_HD44780_DEFAULT, HD44780_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_HD44780_EURO, HD44780_euro_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_EA_KS0073, EA_KS0073_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_SED1278F_0B, SED1278F_0B_charmap }, #ifdef EXTRA_CHARMAPS - { "hd44780_koi8_r", HD44780_KOI8R_charmap }, - { "hd44780_cp1251", HD44780_CP1251_charmap }, - { "hd44780_8859_5", HD44780_ISO_8859_5_charmap}, - { "upd16314", uPD16314_charmap }, - { "weh001602a_1", WEH001602A_1_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_HD44780_KOI8_R, HD44780_KOI8R_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_HD44780_CP1251, HD44780_CP1251_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_HD44780_8859_5, HD44780_ISO_8859_5_charmap}, + { ELEKTRA_ENUM_HD44780_CHARMAP_UPD16314, uPD16314_charmap }, + { ELEKTRA_ENUM_HD44780_CHARMAP_WEH001602A_1, WEH001602A_1_charmap }, #endif - /* This is the last entry. */ - { "none", none_charmap } }; /** @@ -571,15 +569,12 @@ const struct charmap available_charmaps[] = { * algorithm (e.g. binary search) should be used. */ static int -charmap_get_index(const char * req_charmap) +charmap_get_index(ElektraEnumHd44780Charmap req_charmap) { int i; - if (req_charmap == NULL) - return -1; - for (i = 0; i < (sizeof(available_charmaps)/sizeof(struct charmap)); i++) { - if (strcasecmp(req_charmap, available_charmaps[i].name) == 0) { + if (req_charmap == available_charmaps[i].elektraCharmap) { return i; } } diff --git a/server/drivers/hd44780-drivers.h b/server/drivers/hd44780-drivers.h index d03a31ae..d7cc0452 100644 --- a/server/drivers/hd44780-drivers.h +++ b/server/drivers/hd44780-drivers.h @@ -50,6 +50,7 @@ #endif /* add new connection type header files to the correct section above or here */ +#include "../elektragen.h" /** connectionType mapping table: * - string to identify connection in config file @@ -60,57 +61,58 @@ static const ConnectionMapping connectionMapping[] = { #ifdef HAVE_PCSTYLE_LPT_CONTROL /* parallel connection types */ - { "4bit", HD44780_CT_4BIT, IF_TYPE_PARPORT, hd_init_4bit }, - { "8bit", HD44780_CT_8BIT, IF_TYPE_PARPORT, hd_init_ext8bit }, - { "serialLpt", HD44780_CT_SERIALLPT, IF_TYPE_PARPORT, hd_init_serialLpt }, - { "winamp", HD44780_CT_WINAMP, IF_TYPE_PARPORT, hd_init_winamp }, - { "lcm162", HD44780_CT_LCM162, IF_TYPE_PARPORT, hd_init_lcm162 }, + { HD44780_CONNECTION_TYPE_4BIT, HD44780_CT_4BIT, IF_TYPE_PARPORT, hd_init_4bit }, + { HD44780_CONNECTION_TYPE_8BIT, HD44780_CT_8BIT, IF_TYPE_PARPORT, hd_init_ext8bit }, + { HD44780_CONNECTION_TYPE_SERIAL_LPT, HD44780_CT_SERIALLPT, IF_TYPE_PARPORT, hd_init_serialLpt }, + { HD44780_CONNECTION_TYPE_WINAMP, HD44780_CT_WINAMP, IF_TYPE_PARPORT, hd_init_winamp }, + { HD44780_CONNECTION_TYPE_LCM162, HD44780_CT_LCM162, IF_TYPE_PARPORT, hd_init_lcm162 }, #endif /* serial connection types */ - { "picanlcd", HD44780_CT_PICANLCD, IF_TYPE_SERIAL, hd_init_serial }, - { "lcdserializer", HD44780_CT_LCDSERIALIZER, IF_TYPE_SERIAL, hd_init_serial }, - { "los-panel", HD44780_CT_LOS_PANEL, IF_TYPE_SERIAL, hd_init_serial }, - { "vdr-lcd", HD44780_CT_VDR_LCD, IF_TYPE_SERIAL, hd_init_serial }, - { "vdr-wakeup", HD44780_CT_VDR_WAKEUP, IF_TYPE_SERIAL, hd_init_serial }, - { "pertelian", HD44780_CT_PERTELIAN, IF_TYPE_SERIAL, hd_init_serial }, - { "ezio", HD44780_CT_EZIO, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_4BIT, HD44780_CT_PICANLCD, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_LCDSERIALIZER, HD44780_CT_LCDSERIALIZER, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_LOS_PANEL, HD44780_CT_LOS_PANEL, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_VDR_LCD, HD44780_CT_VDR_LCD, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_VDR_WAKEUP, HD44780_CT_VDR_WAKEUP, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_PERTELIAN, HD44780_CT_PERTELIAN, IF_TYPE_SERIAL, hd_init_serial }, + { HD44780_CONNECTION_TYPE_EZIO, HD44780_CT_EZIO, IF_TYPE_SERIAL, hd_init_serial }, /* USB connection types */ - { "lis2", HD44780_CT_LIS2, IF_TYPE_USB, hd_init_lis2 }, - { "mplay", HD44780_CT_MPLAY, IF_TYPE_USB, hd_init_lis2 }, - { "usblcd", HD44780_CT_USBLCD, IF_TYPE_USB, hd_init_usblcd }, + { HD44780_CONNECTION_TYPE_LIS2, HD44780_CT_LIS2, IF_TYPE_USB, hd_init_lis2 }, + { HD44780_CONNECTION_TYPE_MPLAY, HD44780_CT_MPLAY, IF_TYPE_USB, hd_init_lis2 }, + { HD44780_CONNECTION_TYPE_USBLCD, HD44780_CT_USBLCD, IF_TYPE_USB, hd_init_usblcd }, #ifdef HAVE_LIBUSB - { "bwctusb", HD44780_CT_BWCTUSB, IF_TYPE_USB, hd_init_bwct_usb }, - { "lcd2usb", HD44780_CT_LCD2USB, IF_TYPE_USB, hd_init_lcd2usb }, - { "usbtiny", HD44780_CT_USBTINY, IF_TYPE_USB, hd_init_usbtiny }, - { "uss720", HD44780_CT_USS720, IF_TYPE_USB, hd_init_uss720 }, - { "usb4all", HD44780_CT_USB4ALL, IF_TYPE_USB, hd_init_usb4all }, + { HD44780_CONNECTION_TYPE_BWCTUSB, HD44780_CT_BWCTUSB, IF_TYPE_USB, hd_init_bwct_usb }, + { HD44780_CONNECTION_TYPE_LCD2USB, HD44780_CT_LCD2USB, IF_TYPE_USB, hd_init_lcd2usb }, + { HD44780_CONNECTION_TYPE_USBTINY, HD44780_CT_USBTINY, IF_TYPE_USB, hd_init_usbtiny }, + { HD44780_CONNECTION_TYPE_USS720, HD44780_CT_USS720, IF_TYPE_USB, hd_init_uss720 }, + { HD44780_CONNECTION_TYPE_U_S_B_4_ALL, HD44780_CT_USB4ALL, IF_TYPE_USB, hd_init_usb4all }, #endif #ifdef HAVE_LIBFTDI - { "ftdi", HD44780_CT_FTDI, IF_TYPE_USB, hd_init_ftdi }, + { HD44780_CONNECTION_TYPE_FTDI, HD44780_CT_FTDI, IF_TYPE_USB, hd_init_ftdi }, #endif /* I2C connection types */ #ifdef HAVE_I2C - { "i2c", HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c }, - { "piplate", HD44780_CT_PIPLATE, IF_TYPE_I2C, hd_init_i2c_piplate }, + { HD44780_CONNECTION_TYPE_I2C, HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c }, + { HD44780_CONNECTION_TYPE_PIPLATE, HD44780_CT_PIPLATE, IF_TYPE_I2C, hd_init_i2c_piplate }, #endif #ifdef HAVE_SPI - { "spi", HD44780_CT_SPI, IF_TYPE_SPI, hd_init_spi }, - { "pifacecad", HD44780_CT_PIFACECAD, IF_TYPE_SPI, hd_init_pifacecad }, + { HD44780_CONNECTION_TYPE_SPI, HD44780_CT_SPI, IF_TYPE_SPI, hd_init_spi }, + { HD44780_CONNECTION_TYPE_PIFACECAD, HD44780_CT_PIFACECAD, IF_TYPE_SPI, hd_init_pifacecad }, #endif /* TCP socket connection types */ #ifdef WITH_ETHLCD - { "ethlcd", HD44780_CT_ETHLCD, IF_TYPE_TCP, hd_init_ethlcd }, + { HD44780_CONNECTION_TYPE_ETHLCD, HD44780_CT_ETHLCD, IF_TYPE_TCP, hd_init_ethlcd }, #endif #ifdef WITH_RASPBERRYPI - { "raspberrypi", HD44780_CT_RASPBERRYPI, IF_TYPE_PARPORT, hd_init_rpi }, + { HD44780_CONNECTION_TYPE_RASPBERRYPI, HD44780_CT_RASPBERRYPI, IF_TYPE_PARPORT, hd_init_rpi }, #endif #ifdef HAVE_UGPIO - { "gpio", HD44780_CT_GPIO, IF_TYPE_PARPORT, hd_init_gpio }, + { HD44780_CONNECTION_TYPE_GPIO, HD44780_CT_GPIO, IF_TYPE_PARPORT, hd_init_gpio }, #endif /* add new connection types in the correct section above or here */ /* default, end of structure element (do not delete) */ - { NULL, HD44780_CT_UNKNOWN, IF_TYPE_UNKNOWN, NULL } + /* init_fn must be != NULL everywhere else in the array */ + { 0, HD44780_CT_UNKNOWN, IF_TYPE_UNKNOWN, NULL } }; #endif diff --git a/server/drivers/hd44780-ethlcd.c b/server/drivers/hd44780-ethlcd.c index 2fa7588b..ccd287be 100644 --- a/server/drivers/hd44780-ethlcd.c +++ b/server/drivers/hd44780-ethlcd.c @@ -49,9 +49,8 @@ ethlcd_HD44780_uPause(PrivateData *p, int usecs) * \retval -1 Error. */ int -hd_init_ethlcd(Driver *drvthis) +hd_init_ethlcd(Driver *drvthis, const Hd44780DriverConfig * config) { - char hostname[256]; unsigned long flags = 0; struct timeval tv; @@ -65,8 +64,7 @@ hd_init_ethlcd(Driver *drvthis) hd44780_functions->close = ethlcd_HD44780_close; /* reading configuration file */ - strncpy(hostname, drvthis->config_get_string(drvthis->name, "Device", 0, "ethlcd"), sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; + const char * hostname = strlen(config->device) == 0 ? "ethlcd" : config->device; p->sock = sock_connect(hostname, DEFAULT_ETHLCD_PORT); if (p->sock < 0) { diff --git a/server/drivers/hd44780-ethlcd.h b/server/drivers/hd44780-ethlcd.h index 71a6686c..0ee7aed4 100644 --- a/server/drivers/hd44780-ethlcd.h +++ b/server/drivers/hd44780-ethlcd.h @@ -1,8 +1,11 @@ #ifndef HD_ETHLCD_H #define HD_ETHLCD_H +#include "lcd.h" +#include "../elektragen.h" + /* initialise this particular driver */ -int hd_init_ethlcd(Driver *drvthis); +int hd_init_ethlcd(Driver *drvthis, const Hd44780DriverConfig * config); #define ETHLCD_DRV_NAME "ethlcd" #define DEFAULT_ETHLCD_PORT 2425 diff --git a/server/drivers/hd44780-ext8bit.c b/server/drivers/hd44780-ext8bit.c index 90d37cb5..642f0241 100644 --- a/server/drivers/hd44780-ext8bit.c +++ b/server/drivers/hd44780-ext8bit.c @@ -86,7 +86,7 @@ void lcdtime_HD44780_output(PrivateData *p, int data); * \retval -1 Error. */ int -hd_init_ext8bit(Driver *drvthis) +hd_init_ext8bit(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; diff --git a/server/drivers/hd44780-ext8bit.h b/server/drivers/hd44780-ext8bit.h index c1348216..e2b2526a 100644 --- a/server/drivers/hd44780-ext8bit.h +++ b/server/drivers/hd44780-ext8bit.h @@ -2,8 +2,9 @@ #define HD_EXT8BIT_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_ext8bit(Driver *drvthis); +int hd_init_ext8bit(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-ftdi.c b/server/drivers/hd44780-ftdi.c index 1c127e8d..a3d770d1 100644 --- a/server/drivers/hd44780-ftdi.c +++ b/server/drivers/hd44780-ftdi.c @@ -63,11 +63,10 @@ void ftdi_HD44780_close(PrivateData *p); * \retval -1 Error. */ int -hd_init_ftdi(Driver *drvthis) +hd_init_ftdi(Driver *drvthis, const Hd44780DriverConfig * config) { int vendor_id, product_id; int f; - const char *s; char *usb_description, *serial_number; PrivateData *p = (PrivateData *)drvthis->private_data; @@ -78,21 +77,21 @@ hd_init_ftdi(Driver *drvthis) usb_description = serial_number = NULL; /* Load config */ - vendor_id = drvthis->config_get_int(drvthis->name, "VendorID", 0, 0x0403); - product_id = drvthis->config_get_int(drvthis->name, "ProductID", 0, 0x6001); - if ((s = drvthis->config_get_string(drvthis->name, "UsbDescription", 0, NULL)) != NULL) { - usb_description = strdup(s); + vendor_id = config->usbVendorid == 0 ? 0x0403 : config->usbVendorid; + product_id = config->usbProductid == 0 ? 0x6001 : config->usbProductid; + if (strlen(config->usbDescription) != 0) { + usb_description = strdup(config->usbDescription); } - if ((s = drvthis->config_get_string(drvthis->name, "SerialNumber", 0, NULL)) != NULL) { - serial_number = strdup(s); + if (strlen(config->usbSerialnumber) != 0) { + serial_number = strdup(config->usbSerialnumber); } /* these config settings are not documented intentionally */ - p->ftdi_mode = drvthis->config_get_int(drvthis->name, "ftdi_mode", 0, 8); - p->ftdi_line_RS = drvthis->config_get_int(drvthis->name, "ftdi_line_RS", 0, 0x01); - p->ftdi_line_RW = drvthis->config_get_int(drvthis->name, "ftdi_line_RW", 0, 0x02); - p->ftdi_line_EN = drvthis->config_get_int(drvthis->name, "ftdi_line_EN", 0, 0x04); - p->ftdi_line_backlight = drvthis->config_get_int(drvthis->name, "ftdi_line_backlight", 0, 0x08); + p->ftdi_mode = config->ftdiMode; + p->ftdi_line_RS = config->ftdiLineRs; + p->ftdi_line_RW = config->ftdiLineRw; + p->ftdi_line_EN = config->ftdiLineEn; + p->ftdi_line_backlight = config->ftdiLineBacklight; p->backlight_bit = 0; /* some foolproof check */ diff --git a/server/drivers/hd44780-ftdi.h b/server/drivers/hd44780-ftdi.h index 6a6b6cc5..ef12a937 100644 --- a/server/drivers/hd44780-ftdi.h +++ b/server/drivers/hd44780-ftdi.h @@ -2,8 +2,9 @@ #define HD_FTDI_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_ftdi(Driver *drvthis); +int hd_init_ftdi(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-gpio.c b/server/drivers/hd44780-gpio.c index 448f819d..c38ed869 100644 --- a/server/drivers/hd44780-gpio.c +++ b/server/drivers/hd44780-gpio.c @@ -56,13 +56,8 @@ typedef struct { * \return 0 on success; -1 on error. */ static int -init_gpio_pin(Driver *drvthis, ugpio_t **pin, const char *name) +init_gpio_pin(kdb_long_t number, ugpio_t **pin, const char * name) { - char config_key[8]; - int number; - - snprintf(config_key, sizeof(config_key), "pin_%s", name); - number = drvthis->config_get_int(drvthis->name, config_key, 0, -1); if (number == -1) return -1; @@ -125,7 +120,7 @@ send_nibble(PrivateData *p, unsigned char ch, unsigned char displayID) * \return 0 on success; -1 on error. */ int -hd_init_gpio(Driver *drvthis) +hd_init_gpio(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; gpio_pins *pins = malloc(sizeof(gpio_pins)); @@ -137,19 +132,19 @@ hd_init_gpio(Driver *drvthis) p->connection_data = pins; - if (init_gpio_pin(drvthis, &pins->en, "EN") != 0 || - init_gpio_pin(drvthis, &pins->rs, "RS") != 0 || - init_gpio_pin(drvthis, &pins->d7, "D7") != 0 || - init_gpio_pin(drvthis, &pins->d6, "D6") != 0 || - init_gpio_pin(drvthis, &pins->d5, "D5") != 0 || - init_gpio_pin(drvthis, &pins->d4, "D4") != 0) { + if (init_gpio_pin(config->gpioPinEn, &pins->en, "EN") != 0 || + init_gpio_pin(config->gpioPinRs, &pins->rs, "RS") != 0 || + init_gpio_pin(config->gpioPinD7, &pins->d7, "D7") != 0 || + init_gpio_pin(config->gpioPinD6, &pins->d6, "D6") != 0 || + init_gpio_pin(config->gpioPinD5, &pins->d5, "D5") != 0 || + init_gpio_pin(config->gpioPinD4, &pins->d4, "D4") != 0) { report(RPT_ERR, "hd_init_gpio: unable to initialize GPIO pins"); gpio_HD44780_close(p); return -1; } if (p->numDisplays > 1) { /* For displays with two controllers */ - if (init_gpio_pin(drvthis, &pins->en2, "EN2") != 0) { + if (init_gpio_pin(config->gpioPinEn2, &pins->en2, "EN2") != 0) { report(RPT_ERR, "hd_init_gpio: unable to initialize GPIO pins"); gpio_HD44780_close(p); return -1; @@ -160,7 +155,7 @@ hd_init_gpio(Driver *drvthis) p->hd44780_functions->close = gpio_HD44780_close; if (have_backlight_pin(p)) { - if (init_gpio_pin(drvthis, &pins->bl, "BL") != 0) { + if (init_gpio_pin(config->gpioPinBl, &pins->bl, "BL") != 0) { report(RPT_WARNING, "hd_init_gpio: unable to initialize pin_BL - disabling backlight"); set_have_backlight_pin(p, 0); @@ -171,7 +166,7 @@ hd_init_gpio(Driver *drvthis) } /* This is enough to set the RW pin to low, if it is available. */ - init_gpio_pin(drvthis, &pins->rw, "RW"); + init_gpio_pin(config->gpioPinRw, &pins->rw, "RW"); ugpio_set_value(pins->rs, 0); diff --git a/server/drivers/hd44780-gpio.h b/server/drivers/hd44780-gpio.h index 3eec1ebf..9187f6c2 100644 --- a/server/drivers/hd44780-gpio.h +++ b/server/drivers/hd44780-gpio.h @@ -2,8 +2,9 @@ #define HD_GPIO_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialize this particular driver */ -int hd_init_gpio(Driver *drvthis); +int hd_init_gpio(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-i2c.c b/server/drivers/hd44780-i2c.c index 232f0800..f360a50c 100644 --- a/server/drivers/hd44780-i2c.c +++ b/server/drivers/hd44780-i2c.c @@ -95,17 +95,6 @@ void i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char void i2c_HD44780_backlight(PrivateData *p, unsigned char state); void i2c_HD44780_close(PrivateData *p); -#define RS 0x10 -#define RW 0x20 -#define EN 0x40 -#define BL 0x80 -#define D4 0x01 -#define D5 0x02 -#define D6 0x04 -#define D7 0x08 -#define BL_INVERT 0 -// note that the above bits are all meant for the data port of PCF8574 - #define I2C_ADDR_MASK 0x7f #define I2C_PCAX_MASK 0x80 @@ -140,21 +129,20 @@ i2c_out(PrivateData *p, unsigned char val) * \retval -1 Error. */ int -hd_init_i2c(Driver *drvthis) +hd_init_i2c(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; - char device[256] = I2C_DEFAULT_DEVICE; - - p->i2c_backlight_invert = drvthis->config_get_bool(drvthis->name, "BacklightInvert", 0, BL_INVERT); - p->i2c_line_RS = drvthis->config_get_int(drvthis->name, "i2c_line_RS", 0, RS); - p->i2c_line_RW = drvthis->config_get_int(drvthis->name, "i2c_line_RW", 0, RW); - p->i2c_line_EN = drvthis->config_get_int(drvthis->name, "i2c_line_EN", 0, EN); - p->i2c_line_BL = drvthis->config_get_int(drvthis->name, "i2c_line_BL", 0, BL); - p->i2c_line_D4 = drvthis->config_get_int(drvthis->name, "i2c_line_D4", 0, D4); - p->i2c_line_D5 = drvthis->config_get_int(drvthis->name, "i2c_line_D5", 0, D5); - p->i2c_line_D6 = drvthis->config_get_int(drvthis->name, "i2c_line_D6", 0, D6); - p->i2c_line_D7 = drvthis->config_get_int(drvthis->name, "i2c_line_D7", 0, D7); + + p->i2c_backlight_invert = config->i2cBacklightInvert; + p->i2c_line_RS = config->i2cLineRs; + p->i2c_line_RW = config->i2cLineRw; + p->i2c_line_EN = config->i2cLineEn; + p->i2c_line_BL = config->i2cLineBl; + p->i2c_line_D4 = config->i2cLineD4; + p->i2c_line_D5 = config->i2cLineD5; + p->i2c_line_D6 = config->i2cLineD6; + p->i2c_line_D7 = config->i2cLineD7; report(RPT_INFO, "HD44780: I2C: Init using D4 and D5, and or'd lines, invert", p->i2c_line_RS); report(RPT_INFO, "HD44780: I2C: Pin RS mapped to 0x%02X", p->i2c_line_RS); @@ -169,11 +157,10 @@ hd_init_i2c(Driver *drvthis) p->backlight_bit = p->i2c_line_BL; - /* READ CONFIG FILE */ + /* READ CONFIG */ /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, I2C_DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device)-1] = '\0'; + const char * device = strlen(config->device) == 0 ? I2C_DEFAULT_DEVICE : config->device; report(RPT_INFO,"HD44780: I2C: Using device '%s' and address 0x%02X for a %s", device, p->port & I2C_ADDR_MASK, (p->port & I2C_PCAX_MASK) ? "PCA9554(A)" : "PCF8574(A)"); diff --git a/server/drivers/hd44780-i2c.h b/server/drivers/hd44780-i2c.h index abd5b045..7a76376e 100644 --- a/server/drivers/hd44780-i2c.h +++ b/server/drivers/hd44780-i2c.h @@ -2,8 +2,9 @@ #define HD_I2C_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_i2c(Driver *drvthis); +int hd_init_i2c(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-lcd2usb.c b/server/drivers/hd44780-lcd2usb.c index c3af65fe..5817eafa 100644 --- a/server/drivers/hd44780-lcd2usb.c +++ b/server/drivers/hd44780-lcd2usb.c @@ -50,7 +50,7 @@ lcd2usb_HD44780_uPause(PrivateData *p, int usecs) * \retval -1 Error. */ int -hd_init_lcd2usb(Driver *drvthis) +hd_init_lcd2usb(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; diff --git a/server/drivers/hd44780-lcd2usb.h b/server/drivers/hd44780-lcd2usb.h index 9271c498..951d4c82 100644 --- a/server/drivers/hd44780-lcd2usb.h +++ b/server/drivers/hd44780-lcd2usb.h @@ -2,6 +2,7 @@ #define HD_LCD2USB_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* vendor and product id */ #define LCD2USB_VENDORID 0x0403 @@ -34,6 +35,6 @@ #define LCD2USB_GET_RESERVED1 (LCD2USB_GET | (3<<3)) // initialise this particular driver -int hd_init_lcd2usb(Driver *drvthis); +int hd_init_lcd2usb(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-lcm162.c b/server/drivers/hd44780-lcm162.c index 2aebd893..b9879e6b 100644 --- a/server/drivers/hd44780-lcm162.c +++ b/server/drivers/hd44780-lcm162.c @@ -50,7 +50,7 @@ void lcm162_HD44780_output(PrivateData *p, int data); // initialise the driver int -hd_init_lcm162(Driver *drvthis) +hd_init_lcm162(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; diff --git a/server/drivers/hd44780-lcm162.h b/server/drivers/hd44780-lcm162.h index fb1d0049..af69fb24 100644 --- a/server/drivers/hd44780-lcm162.h +++ b/server/drivers/hd44780-lcm162.h @@ -2,8 +2,9 @@ #define HD_LCM162_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_lcm162(Driver *drvthis); +int hd_init_lcm162(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-lis2.c b/server/drivers/hd44780-lis2.c index e6fce87a..3f83ea7f 100644 --- a/server/drivers/hd44780-lis2.c +++ b/server/drivers/hd44780-lis2.c @@ -67,18 +67,16 @@ static void writeChar(int fd, unsigned char code); * \retval 0 Success. * \retval -1 Error. */ -int hd_init_lis2(Driver *drvthis) +int hd_init_lis2(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; struct termios portset; - char device[256] = DEFAULT_DEVICE; - /* READ CONFIG FILE */ + /* READ CONFIG */ /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device)-1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : device; report(RPT_INFO, "HD44780: lis2: Using device: %s", device); // Set up io port correctly, and open it... @@ -117,7 +115,7 @@ int hd_init_lis2(Driver *drvthis) unsigned int conf_bitrate; size_t bitrate; - conf_bitrate = drvthis->config_get_int(drvthis->name, "Speed", 0, 38400); + conf_bitrate = config->speed == 0 ? 38400 : config->speed; if (convert_bitrate(conf_bitrate, &bitrate)) { report(RPT_ERR, "HD44780: lis2: invalid configured bitrate speed"); return -1; diff --git a/server/drivers/hd44780-lis2.h b/server/drivers/hd44780-lis2.h index 2fd58248..0a10f39a 100644 --- a/server/drivers/hd44780-lis2.h +++ b/server/drivers/hd44780-lis2.h @@ -2,8 +2,9 @@ #define HD_LIS2_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_lis2(Driver *drvthis); +int hd_init_lis2(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h index e3231d93..7b946efc 100644 --- a/server/drivers/hd44780-low.h +++ b/server/drivers/hd44780-low.h @@ -31,6 +31,8 @@ #include "i2c.h" +#include "../elektragen.h" + /** \name Symbolic names for connection types *@{*/ #define HD44780_CT_UNKNOWN 0 @@ -135,7 +137,7 @@ /** \name Maximum sizes of the keypad *@{*/ -/* DO NOT CHANGE THESE VALUES, unless you change the functions too! */ +/* DO NOT CHANGE THESE VALUES, unless you change the functions and the config specification too! */ #define KEYPAD_MAXX 5 #define KEYPAD_MAXY 11 /**@}*/ @@ -158,13 +160,13 @@ typedef struct cgram_cache { */ typedef struct ConnectionMapping { /** Name (string) of connection type as used in LCDd.conf */ - char *name; + Hd44780ConnectionType elektraType; /** Registered number of connection type, see above */ int connectiontype; /** Numeric type (serial, parallel, etc), see above */ int if_type; /** Pointer to connection type's initialization function */ - int (*init_fn) (Driver *drvthis); + int (*init_fn) (Driver *drvthis, const Hd44780DriverConfig * config); } ConnectionMapping; diff --git a/server/drivers/hd44780-pifacecad.c b/server/drivers/hd44780-pifacecad.c index 55139124..e0af28ac 100644 --- a/server/drivers/hd44780-pifacecad.c +++ b/server/drivers/hd44780-pifacecad.c @@ -205,17 +205,15 @@ write_and_pulse(PrivateData *p, unsigned char data) * \retval -1 Error. */ int -hd_init_pifacecad(Driver *drvthis) +hd_init_pifacecad(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; - char device[256] = DEFAULT_DEVICE; p->backlight_bit = BL; /* Backlight on during init */ - /* READ CONFIG FILE */ + /* READ CONFIG */ /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device) - 1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : config->device; report(RPT_INFO, "HD44780: PiFaceCAD: Using device '%s'", device); /* Open the SPI device */ diff --git a/server/drivers/hd44780-pifacecad.h b/server/drivers/hd44780-pifacecad.h index 1b608e68..0d9750e2 100644 --- a/server/drivers/hd44780-pifacecad.h +++ b/server/drivers/hd44780-pifacecad.h @@ -2,8 +2,9 @@ #define HD_PIFACECAD_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialise this particular driver */ -int hd_init_pifacecad(Driver *drvthis); +int hd_init_pifacecad(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-piplate.c b/server/drivers/hd44780-piplate.c index 170c147c..f618098c 100644 --- a/server/drivers/hd44780-piplate.c +++ b/server/drivers/hd44780-piplate.c @@ -159,19 +159,17 @@ i2c_write_reg(PrivateData *p, unsigned char reg, unsigned char val) * \retval -1 Error. */ int -hd_init_i2c_piplate(Driver *drvthis) +hd_init_i2c_piplate(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; - char device[256] = DEFAULT_DEVICE; #ifdef HAVE_DEV_IICBUS_IIC_H struct iiccmd cmd; bzero(&cmd, sizeof(cmd)); #endif /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device) - 1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : config->device; report(RPT_INFO, "HD44780: piplate: Using device '%s' and address 0x%02X for a MCP23017", device, p->port & I2C_ADDR_MASK); diff --git a/server/drivers/hd44780-piplate.h b/server/drivers/hd44780-piplate.h index 3d41c331..3de86966 100644 --- a/server/drivers/hd44780-piplate.h +++ b/server/drivers/hd44780-piplate.h @@ -2,8 +2,9 @@ #define HD_PIPLATE_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialise this particular driver */ -int hd_init_i2c_piplate(Driver *drvthis); +int hd_init_i2c_piplate(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-rpi.c b/server/drivers/hd44780-rpi.c index 30b30709..64defa43 100644 --- a/server/drivers/hd44780-rpi.c +++ b/server/drivers/hd44780-rpi.c @@ -353,7 +353,7 @@ lcdrpi_HD44780_close(PrivateData *p) * \retval -1 Error. */ int -hd_init_rpi(Driver *drvthis) +hd_init_rpi(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; const int *allowed_gpio_pins = NULL; @@ -369,12 +369,12 @@ hd_init_rpi(Driver *drvthis) return -1; } - p->rpi_gpio->en = drvthis->config_get_int(drvthis->name, "pin_EN", 0, RPI_DEF_EN); - p->rpi_gpio->rs = drvthis->config_get_int(drvthis->name, "pin_RS", 0, RPI_DEF_RS); - p->rpi_gpio->d7 = drvthis->config_get_int(drvthis->name, "pin_D7", 0, RPI_DEF_D7); - p->rpi_gpio->d6 = drvthis->config_get_int(drvthis->name, "pin_D6", 0, RPI_DEF_D6); - p->rpi_gpio->d5 = drvthis->config_get_int(drvthis->name, "pin_D5", 0, RPI_DEF_D5); - p->rpi_gpio->d4 = drvthis->config_get_int(drvthis->name, "pin_D4", 0, RPI_DEF_D4); + p->rpi_gpio->en = config->gpioPinEn > 0 ? config->gpioPinEn : RPI_DEF_EN; + p->rpi_gpio->rs = config->gpioPinRs > 0 ? config->gpioPinRs : RPI_DEF_RS; + p->rpi_gpio->d7 = config->gpioPinD7 > 0 ? config->gpioPinD7 : RPI_DEF_D7; + p->rpi_gpio->d6 = config->gpioPinD6 > 0 ? config->gpioPinD6 : RPI_DEF_D6; + p->rpi_gpio->d5 = config->gpioPinD5 > 0 ? config->gpioPinD5 : RPI_DEF_D5; + p->rpi_gpio->d4 = config->gpioPinD4 > 0 ? config->gpioPinD4 : RPI_DEF_D4; report(RPT_INFO, "hd_init_rpi: Pin EN mapped to GPIO%d", p->rpi_gpio->en); report(RPT_INFO, "hd_init_rpi: Pin RS mapped to GPIO%d", p->rpi_gpio->rs); @@ -394,7 +394,7 @@ hd_init_rpi(Driver *drvthis) } if (p->numDisplays > 1) { /* For displays with two controllers */ - p->rpi_gpio->en2 = drvthis->config_get_int(drvthis->name, "pin_EN2", 0, RPI_DEF_EN2); + p->rpi_gpio->en2 = config->gpioPinEn2 > 0 ? config->gpioPinEn2 : RPI_DEF_EN2; debug(RPT_INFO, "hd_init_rpi: Pin EN2 mapped to GPIO%d", p->rpi_gpio->en2); if (check_pin(drvthis, p->rpi_gpio->en2, allowed_gpio_pins, used_pins)) { free(p->rpi_gpio); @@ -403,7 +403,7 @@ hd_init_rpi(Driver *drvthis) } if (have_backlight_pin(p)) { /* Backlight setup is optional */ - p->backlight_bit = drvthis->config_get_int(drvthis->name, "pin_BL", 0, RPI_DEF_BL); + p->backlight_bit = config->gpioPinBl > 0 ? config->gpioPinBl : RPI_DEF_BL; debug(RPT_INFO, "hd_init_rpi: Backlight mapped to GPIO%d", p->backlight_bit); if (check_pin(drvthis, p->backlight_bit, allowed_gpio_pins, used_pins) != 0) { diff --git a/server/drivers/hd44780-rpi.h b/server/drivers/hd44780-rpi.h index 259ae990..51e56ef2 100644 --- a/server/drivers/hd44780-rpi.h +++ b/server/drivers/hd44780-rpi.h @@ -2,9 +2,10 @@ #define HD_LCDRPI_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialize this particular driver */ -int hd_init_rpi(Driver *drvthis); +int hd_init_rpi(Driver *drvthis, const Hd44780DriverConfig * config); /** * rpi_gpio_map is addressed through the hd44780_private_data struct. Data diff --git a/server/drivers/hd44780-serial.c b/server/drivers/hd44780-serial.c index a0c7d27a..cf7b970b 100644 --- a/server/drivers/hd44780-serial.c +++ b/server/drivers/hd44780-serial.c @@ -157,17 +157,15 @@ void serial_HD44780_close(PrivateData *p); * \retval -1 Error. */ int -hd_init_serial(Driver *drvthis) +hd_init_serial(Driver *drvthis, const Hd44780DriverConfig * config) { struct termios portset; - char device[256] = DEFAULT_DEVICE; - unsigned int conf_bitrate; size_t bitrate; int i; PrivateData *p = (PrivateData*) drvthis->private_data; - /* READ CONFIG FILE */ + /* READ CONFIG */ /* Get interface type */ p->serial_type = 0; @@ -195,18 +193,19 @@ hd_init_serial(Driver *drvthis) } /* Get bitrate */ - conf_bitrate = drvthis->config_get_int(drvthis->name, "Speed", 0, SERIAL_IF.default_bitrate); - if (conf_bitrate == 0) - conf_bitrate = SERIAL_IF.default_bitrate; - if (convert_bitrate(conf_bitrate, &bitrate)) { + kdb_unsigned_long_t speed = config->speed; + if (speed == 0) { + speed = SERIAL_IF.default_bitrate; + } + + if (convert_bitrate(speed, &bitrate)) { report(RPT_ERR, "HD44780: serial: invalid configured bitrate speed"); return -1; } - report(RPT_INFO,"HD44780: serial: using speed: %d", conf_bitrate); + report(RPT_INFO,"HD44780: serial: using speed: %d", speed); /* Get serial device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device)-1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : config->device; report(RPT_INFO,"HD44780: serial: using device: %s", device); /* Set up io port correctly, and open it... */ diff --git a/server/drivers/hd44780-serial.h b/server/drivers/hd44780-serial.h index a75f868b..bc6ce07f 100644 --- a/server/drivers/hd44780-serial.h +++ b/server/drivers/hd44780-serial.h @@ -9,6 +9,8 @@ #define SERIALIF_NAME_LENGTH 20 #define DEFAULT_DEVICE "/dev/lcd" +#include "../elektragen.h" + /** Declares one configuration entry in the serial_interfaces table */ struct hd44780_SerialInterface { int connectiontype; /**< Connection type from hd44780 config */ @@ -79,6 +81,6 @@ static const struct hd44780_SerialInterface serial_interfaces[] = { }; /* initialize this particular driver */ -int hd_init_serial(Driver *drvthis); +int hd_init_serial(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-serialLpt.c b/server/drivers/hd44780-serialLpt.c index 350672ee..e34b5c9e 100644 --- a/server/drivers/hd44780-serialLpt.c +++ b/server/drivers/hd44780-serialLpt.c @@ -81,7 +81,7 @@ static void shiftreg(PrivateData *p, unsigned char displayID, unsigned char r); * \retval -1 Error. */ int -hd_init_serialLpt(Driver *drvthis) +hd_init_serialLpt(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; diff --git a/server/drivers/hd44780-serialLpt.h b/server/drivers/hd44780-serialLpt.h index 2d592e95..9d803879 100644 --- a/server/drivers/hd44780-serialLpt.h +++ b/server/drivers/hd44780-serialLpt.h @@ -2,8 +2,9 @@ #define HD_SERIALLPT_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_serialLpt(Driver *drvthis); +int hd_init_serialLpt(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-spi.c b/server/drivers/hd44780-spi.c index 74c85fb0..a5829317 100644 --- a/server/drivers/hd44780-spi.c +++ b/server/drivers/hd44780-spi.c @@ -111,20 +111,15 @@ spi_transfer(PrivateData *p, const unsigned char *outbuf, unsigned char *inbuf, * \retval -1 Error. */ int -hd_init_spi(Driver *drvthis) +hd_init_spi(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; - char device[256] = DEFAULT_DEVICE; - char backlight_device[256] = ""; - - /* READ CONFIG FILE */ + /* READ CONFIG */ /* Get and open SPI device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), - sizeof(device)); - device[sizeof(device) - 1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : config->device; report(RPT_INFO, "HD44780: SPI: Using device '%s'", device); p->fd = open(device, O_RDWR); @@ -136,10 +131,7 @@ hd_init_spi(Driver *drvthis) /* Get and open the backlight device */ p->backlight_bit = -1; - strncpy(backlight_device, - drvthis->config_get_string(drvthis->name, "BacklightDevice", 0, ""), - sizeof(backlight_device)); - backlight_device[sizeof(backlight_device) - 1] = '\0'; + const char * backlight_device = config->spiBacklightDevice; if (strlen(backlight_device) > 0) { report(RPT_INFO, "HD44780: SPI: Using backlight_device '%s'", backlight_device); diff --git a/server/drivers/hd44780-spi.h b/server/drivers/hd44780-spi.h index 9b5f83de..139d1393 100644 --- a/server/drivers/hd44780-spi.h +++ b/server/drivers/hd44780-spi.h @@ -2,8 +2,9 @@ #define HD_SPI_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialise this particular driver */ -int hd_init_spi(Driver *drvthis); +int hd_init_spi(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-usb4all.c b/server/drivers/hd44780-usb4all.c index 74392302..a4aca6f0 100644 --- a/server/drivers/hd44780-usb4all.c +++ b/server/drivers/hd44780-usb4all.c @@ -273,7 +273,7 @@ usb4all_HD44780_uPause(PrivateData *p, int usecs) * \retval -1 Error. */ int -hd_init_usb4all(Driver *drvthis) +hd_init_usb4all(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; diff --git a/server/drivers/hd44780-usb4all.h b/server/drivers/hd44780-usb4all.h index 988704a7..0a9699f3 100644 --- a/server/drivers/hd44780-usb4all.h +++ b/server/drivers/hd44780-usb4all.h @@ -18,6 +18,7 @@ #define HD_USB4ALL_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* vendor and product id */ #define USB4ALL_VENDORID 0x004D8 @@ -41,6 +42,6 @@ #define USB4ALL_RESET 0xFF /* initialise this particular driver */ -int hd_init_usb4all(Driver *drvthis); +int hd_init_usb4all(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-usblcd.c b/server/drivers/hd44780-usblcd.c index 8dcbc3dd..85a7a537 100644 --- a/server/drivers/hd44780-usblcd.c +++ b/server/drivers/hd44780-usblcd.c @@ -53,17 +53,15 @@ void usblcd_HD44780_close(PrivateData *p); * \retval -3 Error reading or unsupported hardware version. */ int -hd_init_usblcd(Driver *drvthis) +hd_init_usblcd(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; - char device[256] = DEFAULT_DEVICE; char buf[128]; int major, minor; /* Get device to use */ - strncpy(device, drvthis->config_get_string(drvthis->name, "device", 0, DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device) - 1] = '\0'; + const char * device = strlen(config->device) == 0 ? DEFAULT_DEVICE : config->device; report(RPT_INFO, "HD44780: USBLCD: using device: %s", device); /* Set up io port correctly, and open it... */ diff --git a/server/drivers/hd44780-usblcd.h b/server/drivers/hd44780-usblcd.h index 35b2834c..01150238 100644 --- a/server/drivers/hd44780-usblcd.h +++ b/server/drivers/hd44780-usblcd.h @@ -2,8 +2,9 @@ #define HD_USBLCD_H #include "lcd.h" /* for lcd_logical_driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_usblcd(Driver *drvthis); +int hd_init_usblcd(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-usbtiny.c b/server/drivers/hd44780-usbtiny.c index 755eb50a..827e44d3 100644 --- a/server/drivers/hd44780-usbtiny.c +++ b/server/drivers/hd44780-usbtiny.c @@ -48,7 +48,7 @@ usbtiny_HD44780_uPause(PrivateData *p, int usecs) * \retval -1 Error. */ int -hd_init_usbtiny(Driver *drvthis) +hd_init_usbtiny(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData *) drvthis->private_data; diff --git a/server/drivers/hd44780-usbtiny.h b/server/drivers/hd44780-usbtiny.h index 9d8704cc..db6311d0 100644 --- a/server/drivers/hd44780-usbtiny.h +++ b/server/drivers/hd44780-usbtiny.h @@ -2,6 +2,7 @@ #define HD_USBTINY_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* vendor and product id */ #define USBTINY_VENDORID 0x03EB @@ -13,6 +14,6 @@ /* initialise this particular driver */ -int hd_init_usbtiny(Driver *drvthis); +int hd_init_usbtiny(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-uss720.c b/server/drivers/hd44780-uss720.c index 050d5785..2781ca2d 100644 --- a/server/drivers/hd44780-uss720.c +++ b/server/drivers/hd44780-uss720.c @@ -110,7 +110,7 @@ int uss720_set_1284_mode(usb_dev_handle *usbHandle, unsigned int mode); * \retval -1 Error. */ int -hd_init_uss720(Driver *drvthis) +hd_init_uss720(Driver *drvthis, const Hd44780DriverConfig * config) { unsigned int vendor_id, product_id; struct usb_bus *bus; @@ -123,8 +123,8 @@ hd_init_uss720(Driver *drvthis) p->hd44780_functions->uPause = uss720_HD44780_uPause; /* load config */ - vendor_id = drvthis->config_get_int(drvthis->name, "VendorID", 0, 0x1293); - product_id = drvthis->config_get_int(drvthis->name, "ProductID", 0, 0x0002); + vendor_id = config->usbVendorid == 0 ? 0x1293 : config->usbVendorid; + product_id = config->usbProductid == 0 ? 0x0002 : config->usbProductid; /* Hardware Init */ diff --git a/server/drivers/hd44780-uss720.h b/server/drivers/hd44780-uss720.h index c8c3e38f..4e25ba96 100644 --- a/server/drivers/hd44780-uss720.h +++ b/server/drivers/hd44780-uss720.h @@ -2,7 +2,8 @@ #define HD_USS720_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" /* initialise this particular driver */ -int hd_init_uss720(Driver *drvthis); +int hd_init_uss720(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780-winamp.c b/server/drivers/hd44780-winamp.c index d1170f25..796dded9 100644 --- a/server/drivers/hd44780-winamp.c +++ b/server/drivers/hd44780-winamp.c @@ -102,7 +102,7 @@ static const unsigned char EnMask[] = { EN1, EN2, EN3 }; * \retval -1 Error. */ int -hd_init_winamp(Driver *drvthis) +hd_init_winamp(Driver *drvthis, const Hd44780DriverConfig * config) { PrivateData *p = (PrivateData*) drvthis->private_data; HD44780_functions *hd44780_functions = p->hd44780_functions; diff --git a/server/drivers/hd44780-winamp.h b/server/drivers/hd44780-winamp.h index defda6d5..1a6547e4 100644 --- a/server/drivers/hd44780-winamp.h +++ b/server/drivers/hd44780-winamp.h @@ -2,8 +2,9 @@ #define HD_WINAMP_H #include "lcd.h" /* for Driver */ +#include "../elektragen.h" // initialise this particular driver -int hd_init_winamp(Driver *drvthis); +int hd_init_winamp(Driver *drvthis, const Hd44780DriverConfig * config); #endif diff --git a/server/drivers/hd44780.c b/server/drivers/hd44780.c index c38200a6..3c6068fa 100644 --- a/server/drivers/hd44780.c +++ b/server/drivers/hd44780.c @@ -69,6 +69,8 @@ # include "config.h" #endif +#include "../elektragen.h" + #include "lcd.h" #include "lcd_lib.h" #include "hd44780.h" @@ -87,13 +89,13 @@ static char *defaultKeyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = { { "4", "5", "6", "B", "F" }, { "7", "8", "9", "C", "G" }, { "*", "0", "#", "D", "H" }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL }}; + { "", "", "", "", "" }, + { "", "", "", "", "" }, + { "", "", "", "", "" }, + { "", "", "", "", "" }, + { "", "", "", "", "" }, + { "", "", "", "", "" }, + { "", "", "", "", "" }}; /* Vars for the server core */ @@ -113,182 +115,152 @@ static int parse_span_list(int *spanListArray[], int *spLsize, int *dispOffsets[ static const struct ModelMapping { - const char *name; + ElektraEnumHd44780Model elektraModel; int model; } model_mapping[] = { - { "default", HD44780_MODEL_DEFAULT }, - { "standard", HD44780_MODEL_DEFAULT }, - - { "extended", HD44780_MODEL_EXTENDED }, - { "ks0073", HD44780_MODEL_EXTENDED }, - { "hd66710", HD44780_MODEL_EXTENDED }, + { ELEKTRA_ENUM_HD44780_MODEL_DEFAULT, HD44780_MODEL_DEFAULT }, + { ELEKTRA_ENUM_HD44780_MODEL_STANDARD, HD44780_MODEL_DEFAULT }, - { "winstar_oled", HD44780_MODEL_WINSTAR_OLED }, - { "weh00xxyya", HD44780_MODEL_WINSTAR_OLED }, + { ELEKTRA_ENUM_HD44780_MODEL_EXTENDED, HD44780_MODEL_EXTENDED }, + { ELEKTRA_ENUM_HD44780_MODEL_KS0073, HD44780_MODEL_EXTENDED }, + { ELEKTRA_ENUM_HD44780_MODEL_HD66710, HD44780_MODEL_EXTENDED }, - { "pt6314_vfd", HD44780_MODEL_PT6314_VFD }, + { ELEKTRA_ENUM_HD44780_MODEL_WINSTAR_OLED, HD44780_MODEL_WINSTAR_OLED }, + { ELEKTRA_ENUM_HD44780_MODEL_WEH00XXYYA, HD44780_MODEL_WINSTAR_OLED }, - { "", HD44780_MODEL_DEFAULT } + { ELEKTRA_ENUM_HD44780_MODEL_PT6314_VFD, HD44780_MODEL_PT6314_VFD } }; -static int model_by_name( const char *name ) +static int map_model ( ElektraEnumHd44780Model elektraModel ) { int i; for (i=0; iprivate_data; - /* allow multiple occurences of option Backlight, with values specified above - * in bl_value_mapping, first one occurrence may be also boolean for backward compability */ - - for (opt_idx=0; /* nop */; opt_idx++) { - const char *def_value; - /* for first occurence of option 'backlight' default value depends - * on model (which should be read before invoking this function) */ - if (opt_idx != 0) - def_value = NULL; - else if (p->model == (HD44780_MODEL_WINSTAR_OLED || p->model == HD44780_MODEL_PT6314_VFD)) - def_value = "internal"; - else - def_value = "none"; - value = drvthis->config_get_string(drvthis->name, "backlight", opt_idx, def_value); - - if (value == NULL) - /* this is for second and next occurrences */ - break; - - /* find option name. */ - for (i=0; ibacklight == ELEKTRA_ENUM_HD44780_BACKLIGHT_DEFAULT) + { + return p->model == HD44780_MODEL_WINSTAR_OLED || p->model == HD44780_MODEL_PT6314_VFD ? BACKLIGHT_INTERNAL : BACKLIGHT_NONE; + } - if (i == sizeof(bl_value_mapping)/sizeof(bl_value_mapping[0])) { - /* name not recognized */ - if (opt_idx == 0) { - /* not found - try boolean for backward compability. If found, ignore other occurences */ - short tmp = drvthis->config_get_bool(drvthis->name, "backlight", opt_idx, -1); - if (tmp < 0) { - report(RPT_ERR, "%s: unknown Backlight type: %s", drvthis->name, value); - return -1; - } - result = tmp ? BACKLIGHT_EXTERNAL_PIN : BACKLIGHT_NONE; - report(RPT_WARNING, "%s: deprecated boolean '%s' for 'Backlight' option found, consider updating configuration !!", drvthis->name, value); - return result; - } - else { - /* invalid option value */ - report(RPT_ERR, "%s: unknown Backlight type: %s", drvthis->name, value); - return -1; - } - } + if(config->backlight == ELEKTRA_ENUM_HD44780_BACKLIGHT_DISABLED) + { + return BACKLIGHT_NONE; } - if (result != BACKLIGHT_NONE && was_none) { - report(RPT_ERR, "%s: conflicting types of 'Backlight' option provided", drvthis->name); - return -2; + int result = BACKLIGHT_NONE; + kdb_long_long_t size = elektraSizeV(elektra, CONF_HD44780_BACKLIGHTMODE, drvthis->index); + for (kdb_long_long_t i = 0; i < size; ++i) + { + ElektraEnumHd44780Backlightmode elektraMode = elektraGetV(elektra, CONF_HD44780_BACKLIGHTMODE, drvthis->index, i); + int mode = map_backlight_mode(elektraMode); + if (mode < 0) { + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): unknown Backlight mode: %d", drvthis->name, drvthis->index, elektraMode); + return -1; + } + result |= mode; } return result; } -static void strappend(char *dst, size_t dsize, const char *src) { - - size_t dlen = strlen(dst); - size_t slen = strlen(src); - - if (slen + dlen < dsize) { - memcpy(dst + dlen, src, slen); - dst[dlen+slen] = 0; - } - else if (dlen < dsize) { - memcpy(dst + dlen, src, dsize - dlen); - dst[dsize-1] = 0; - } -} - /* reports textually setting of backlight */ static void report_backlight_type(int report_level, int backlight_type) { - /* should be enough for current options set and all possible combinations */ - const char *text_value = NULL; - char buffer[256] = ""; int i; /* first find just whole option name */ for (i=0; ifd = -1; - /* READ THE CONFIG FILE */ + /* READ THE CONFIG */ + Hd44780DriverConfig config; + elektraFillStructV(elektra, &config, CONF_HD44780, drvthis->index); - p->port = drvthis->config_get_int(drvthis->name, "port", 0, LPTPORT); - s = drvthis->config_get_string(drvthis->name, "model", 0, "default"); - p->model = model_by_name(s); + // TODO (elektra): use hexnumber? + p->port = (unsigned int)strtoul(config.port, NULL, 16); /* works because, spec enforces hex string */ + p->model = map_model(config.model); if (p->model < 0) { - report(RPT_ERR, "%s: unknown Model: %s", drvthis->name, s); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): unknown Model: %s", drvthis->name, drvthis->index, model_name(config.model)); return -1; } /* config file compability stuff */ if (p->model == HD44780_MODEL_DEFAULT) { - ext_mode = drvthis->config_get_bool(drvthis->name, "extendedmode", 0, 0); - if (ext_mode) + if (config.extendedmode) p->model = HD44780_MODEL_EXTENDED; } else { - tmp = (p->model == HD44780_MODEL_EXTENDED); - ext_mode = !!drvthis->config_get_bool(drvthis->name, "extendedmode", 0, tmp); - if (ext_mode != tmp) { - report(RPT_ERR, "%s: conflicting Model %s and extended mode: %d", drvthis->name, model_name(p->model), ext_mode); + if (config.extendedmode != (p->model == HD44780_MODEL_EXTENDED)) { + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): conflicting Model %s and extended mode: %d", drvthis->name, drvthis->index, model_name(config.model), config.extendedmode); return -1; } } - p->line_address = drvthis->config_get_int(drvthis->name, "lineaddress", 0, LADDR); - p->have_keypad = drvthis->config_get_bool(drvthis->name, "keypad", 0, 0); + // TODO (elektra): use hexnumber? + p->line_address = (int)strtol(config.lineaddress, NULL, 16); /* works because, spec enforces hex string */ + p->have_keypad = config.keypad; /* parse backlight option. Default is model specific */ - p->backlight_type = get_config_backlight_type(drvthis); + p->backlight_type = get_config_backlight_type(drvthis, &config, elektra); if (p->backlight_type < 0) { /* error already logged in get_config_backlight_type() */ return -1; } - p->backlight_cmd_on = drvthis->config_get_int(drvthis->name, "backlightcmdon", 0, 0); - p->backlight_cmd_off = drvthis->config_get_int(drvthis->name, "backlightcmdoff", 0, 0); + // TODO (elektra): use hexnumber? + p->backlight_cmd_on = (int)strtol(config.backlightcmdon, NULL, 16); /* works because, spec enforces hex string */ + p->backlight_cmd_off = (int)strtol(config.backlightcmdoff, NULL, 16); /* works because, spec enforces hex string */ if ((p->backlight_type & BACKLIGHT_CONFIG_CMDS) && (!p->backlight_cmd_on || !p->backlight_cmd_off)) { - report(RPT_ERR, "%s: No commands for enabling or disabling backlight specified for backlight type internalCmds", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): No commands for enabling or disabling backlight specified for backlight type internalCmds", drvthis->name, drvthis->index); return -1; } - p->have_output = drvthis->config_get_bool(drvthis->name, "outputport", 0, 0); - p->delayMult = drvthis->config_get_int(drvthis->name, "delaymult", 0, 1); - p->delayBus = drvthis->config_get_bool(drvthis->name, "delaybus", 0, 1); - p->lastline = drvthis->config_get_bool(drvthis->name, "lastline", 0, 1); + p->have_output = config.outputport; + p->delayMult = config.delaymult; + p->delayBus = config.delaybus; + p->lastline = config.lastline; p->nextrefresh = 0; - p->refreshdisplay = drvthis->config_get_int(drvthis->name, "refreshdisplay", 0, 0); + p->refreshdisplay = config.refreshdisplay; p->nextkeepalive = 0; - p->keepalivedisplay = drvthis->config_get_int(drvthis->name, "keepalivedisplay", 0, 0); + p->keepalivedisplay = config.keepalivedisplay; /* Get and search for the connection type */ - s = drvthis->config_get_string(drvthis->name, "ConnectionType", 0, "4bit"); - for (i = 0; (connectionMapping[i].name != NULL) && - (strcasecmp(s, connectionMapping[i].name) != 0); i++) - ; - if (connectionMapping[i].name == NULL) { - report(RPT_ERR, "%s: unknown ConnectionType: %s", drvthis->name, s); + const ConnectionMapping * connectionMapping = map_connection_type(config.connectiontype); + + if (connectionMapping == NULL) { + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): unknown ConnectionType: %s", drvthis->name, drvthis->index, ELEKTRA_TO_CONST_STRING(EnumHd44780ConnectionType)(config.connectiontype)); return -1; - } else { - /* set connection type */ - p->connectiontype = connectionMapping[i].connectiontype; + } - report(RPT_INFO, "HD44780: using ConnectionType: %s", connectionMapping[i].name); + /* set connection type */ + p->connectiontype = connectionMapping->connectiontype; - if_type = connectionMapping[i].if_type; - init_fn = connectionMapping[i].init_fn; - } - report(RPT_INFO, "HD44780: selecting Model: %s", model_name(p->model)); + report(RPT_INFO, "HD44780: using ConnectionType: %s", ELEKTRA_TO_CONST_STRING(EnumHd44780ConnectionType)(config.connectiontype)); + + if_type = connectionMapping->if_type; + init_fn = connectionMapping->init_fn; + + report(RPT_INFO, "HD44780: selecting Model: %d", reverse_map_model(p->model)); report_backlight_type(RPT_INFO, p->backlight_type); if (p->backlight_type & BACKLIGHT_CONFIG_CMDS) { report(RPT_INFO, "HD44780: backlight config commands: on: %02x, off: %02x", p->backlight_cmd_on, p->backlight_cmd_off); } /* Get and parse vspan only when specified */ - s = drvthis->config_get_string(drvthis->name, "vspan", 0, ""); - if (s[0] != '\0') { - if (parse_span_list(&(p->spanList), &(p->numLines), &(p->dispVOffset), &(p->numDisplays), &(p->dispSizes), s) == -1) { - report(RPT_ERR, "%s: invalid vspan value: %s", drvthis->name, s); + if (strlen(config.vspan) > 0) { + if (parse_span_list(&(p->spanList), &(p->numLines), &(p->dispVOffset), &(p->numDisplays), &(p->dispSizes), config.vspan) == -1) { + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): invalid vspan value: %s", drvthis->name, drvthis->index, config.vspan); return -1; } } /* Get and parse size */ - s = drvthis->config_get_string(drvthis->name, "size", 0, "20x4"); - if (sscanf(s, "%dx%d", &(p->width), &(p->height)) != 2 + if (sscanf(config.size, "%dx%d", &(p->width), &(p->height)) != 2 || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { - report(RPT_ERR, "%s: cannot read Size %s", drvthis->name, s); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): cannot read Size %s", drvthis->name, drvthis->index, config.size); } /* set contrast */ - tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); - if ((tmp < 0) || (tmp > MAX_CONTRAST)) { - report(RPT_WARNING, "%s: Contrast must be between 0 and %d; using default %d", - drvthis->name, MAX_CONTRAST, DEFAULT_CONTRAST); - tmp = DEFAULT_CONTRAST; - } - p->contrast = tmp; + p->contrast = config.contrast; /* set brightness */ - tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); - if ((tmp < 0) || (tmp > MAX_BRIGHTNESS)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and %d; using default %d", - drvthis->name, MAX_BRIGHTNESS, DEFAULT_BRIGHTNESS); - tmp = DEFAULT_BRIGHTNESS; - } - p->brightness = tmp; + p->brightness = config.brightness; /* set backlight-off "brightness" */ - tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS); - if ((tmp < 0) || (tmp > MAX_BRIGHTNESS)) { - report(RPT_WARNING, "%s: OffBrightness must be between 0 and %d; using default %d", - drvthis->name, MAX_BRIGHTNESS, DEFAULT_OFFBRIGHTNESS); - tmp = DEFAULT_OFFBRIGHTNESS; - } - p->offbrightness = tmp; + p->offbrightness = config.offbrightness; /* default case for when spans aren't indicated */ if (p->numLines == 0) { @@ -456,12 +404,12 @@ HD44780_init(Driver *drvthis) p->numLines = p->height; } } else - report(RPT_ERR, "%s: error allocing", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): error allocing", drvthis->name, drvthis->index); } else { /* sanity check against p->height */ if (p->numLines != p->height) - report(RPT_ERR, "%s: height in Size does not match vSpan", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): height in Size does not match vSpan", drvthis->name, drvthis->index); } if (p->numDisplays == 0) { @@ -471,19 +419,19 @@ HD44780_init(Driver *drvthis) p->dispSizes[0] = p->height; p->numDisplays = 1; } else - report(RPT_ERR, "%s: error mallocing", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): error mallocing", drvthis->name, drvthis->index); } /* Set up timing */ if (timing_init() == -1) { - report(RPT_ERR, "%s: timing_init() failed (%s)", drvthis->name, strerror(errno)); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): timing_init() failed (%s)", drvthis->name, drvthis->index, strerror(errno)); return -1; } /* Allocate framebuffer */ p->framebuf = (unsigned char *) calloc(p->width * p->height, sizeof(char)); if (p->framebuf == NULL) { - report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): unable to allocate framebuffer", drvthis->name, drvthis->index); //HD44780_close(); return -1; } @@ -491,7 +439,7 @@ HD44780_init(Driver *drvthis) /* Allocate and clear the buffer for incremental updates */ p->backingstore = (unsigned char *) calloc(p->width * p->height, sizeof(char)); if (p->backingstore == NULL) { - report(RPT_ERR, "%s: unable to allocate framebuffer backing store", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): unable to allocate framebuffer backing store", drvthis->name, drvthis->index); return -1; } @@ -501,70 +449,53 @@ HD44780_init(Driver *drvthis) /* Read keymap */ for (x = 0; x < KEYPAD_MAXX; x++) { - char buf[40]; - - /* First fill with default value */ - p->keyMapDirect[x] = defaultKeyMapDirect[x]; - - /* Read config value */ - sprintf(buf, "keydirect_%1d", x+1); - s = drvthis->config_get_string(drvthis->name, buf, 0, NULL); + const char * key = elektraGetV(elektra, CONF_HD44780_KEYDIRECT, drvthis->index, x); /* Was a key specified in the config file ? */ - if (s) { - p->keyMapDirect[x] = strdup(s); - report(RPT_INFO, "HD44780: Direct key %d: \"%s\"", x, s); + if (strlen(key) == 0) { + key = defaultKeyMapDirect[x]; + } else { + report(RPT_INFO, "HD44780: Direct key %d: \"%s\"", x, key); } - } - - for (x = 0; x < KEYPAD_MAXX; x++) { - for (y = 0; y < KEYPAD_MAXY; y++) { - char buf[40]; - /* First fill with default value */ - p->keyMapMatrix[y][x] = defaultKeyMapMatrix[y][x]; - - /* Read config value */ - sprintf(buf, "keymatrix_%1d_%d", x+1, y+1); - s = drvthis->config_get_string(drvthis->name, buf, 0, NULL); + p->keyMapDirect[x] = strdup(key); + for (y = 0; y < KEYPAD_MAXY; y++) { + key = elektraGetV(elektra, CONF_HD44780_KEYMATRIX, drvthis->index, x, y); + /* Was a key specified in the config file ? */ - if (s) { - p->keyMapMatrix[y][x] = strdup(s); - report(RPT_INFO, "HD44780: Matrix key %d %d: \"%s\"", x+1, y+1, s); + if (strlen(key) == 0) { + key = defaultKeyMapMatrix[y][x]; + } else { + report(RPT_INFO, "HD44780: Matrix key %d %d: \"%s\"", x+1, y+1, key); } + + p->keyMapMatrix[y][x] = strdup(key); } } } /* Get configured charmap */ - strncpy(conf_charmap, drvthis->config_get_string(drvthis->name, "charmap", 0, "hd44780_default"), MAX_CHARMAP_NAME_LENGTH); - conf_charmap[MAX_CHARMAP_NAME_LENGTH-1] = '\0'; - p->charmap = charmap_get_index(conf_charmap); + p->charmap = charmap_get_index(config.charmap); if (p->charmap == -1) { - report(RPT_ERR, "%s: Charmap %s is unknown", drvthis->name, conf_charmap); - report(RPT_ERR, "%s: Available charmaps:", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): Charmap %d is unknown", drvthis->name, drvthis->index, config.charmap); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): Available charmaps:", drvthis->name, drvthis->index); for (i = 0; i < (sizeof(available_charmaps)/sizeof(struct charmap)); i++) { - report(RPT_ERR, " %s", available_charmaps[i].name); + report(RPT_ERR, " %s", ELEKTRA_TO_CONST_STRING(EnumHd44780Charmap)(available_charmaps[i].elektraCharmap)); } return -1; } - report(RPT_INFO, "%s: Using %s charmap", drvthis->name, available_charmaps[p->charmap].name); + report(RPT_INFO, "%s ("ELEKTRA_LONG_LONG_F"): Using %s charmap", drvthis->name, drvthis->index, ELEKTRA_TO_CONST_STRING(EnumHd44780Charmap)(config.charmap)); /* Get configured font bank */ - tmp = drvthis->config_get_int(drvthis->name, "FontBank", 0, 0); - if ((tmp < 0) || (tmp > 3)) { - report(RPT_WARNING, "%s: FontBank must be between 0 and 3; using default %d", drvthis->name, 0); - tmp = 0; - } - p->font_bank = tmp; + p->font_bank = config.fontbank; /* Output latch state - init to a non-valid value */ p->output_state = 999999; /* allocate local function pointers */ if ((p->hd44780_functions = (HD44780_functions *) calloc(1, sizeof(HD44780_functions))) == NULL) { - report(RPT_ERR, "%s: error mallocing", drvthis->name); + report(RPT_ERR, "%s ("ELEKTRA_LONG_LONG_F"): error mallocing", drvthis->name, drvthis->index); return -1; } /* @@ -584,7 +515,7 @@ HD44780_init(Driver *drvthis) p->hd44780_functions->flush = NULL; /* Do local (=connection type specific) display init */ - if (init_fn(drvthis) != 0) + if (init_fn(drvthis, &config) != 0) return -1; /* consistency check: fail if local senddata function was not defined */ @@ -942,7 +873,7 @@ HD44780_flush(Driver *drvthis) } if (p->hd44780_functions->flush != NULL) p->hd44780_functions->flush(p); - debug(RPT_DEBUG, "%s: flushed %d custom chars", drvthis->name, count); + debug(RPT_DEBUG, "%s ("ELEKTRA_LONG_LONG_F"): flushed %d custom chars", drvthis->name, drvthis->index, count); } diff --git a/server/drivers/hd44780.h b/server/drivers/hd44780.h index 6d6d20ef..7959170d 100644 --- a/server/drivers/hd44780.h +++ b/server/drivers/hd44780.h @@ -17,7 +17,9 @@ #ifndef HD44780_H #define HD44780_H -MODULE_EXPORT int HD44780_init(Driver *drvthis); +#include + +MODULE_EXPORT int HD44780_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void HD44780_close(Driver *drvthis); MODULE_EXPORT int HD44780_width(Driver *drvthis); MODULE_EXPORT int HD44780_height(Driver *drvthis); diff --git a/server/drivers/i2500vfd.c b/server/drivers/i2500vfd.c index 46ba19b7..d029e259 100644 --- a/server/drivers/i2500vfd.c +++ b/server/drivers/i2500vfd.c @@ -101,7 +101,7 @@ drawchar2fb (Driver *drvthis, int x, int y, unsigned char z) // This initialises the stuff. // MODULE_EXPORT int -i2500vfd_init (Driver *drvthis) +i2500vfd_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; int i; diff --git a/server/drivers/i2500vfd.h b/server/drivers/i2500vfd.h index c63ebb18..e9652cd6 100644 --- a/server/drivers/i2500vfd.h +++ b/server/drivers/i2500vfd.h @@ -1,7 +1,9 @@ #ifndef I2500VFD_H #define I2500VFD_H -MODULE_EXPORT int i2500vfd_init (Driver *drvthis); +#include + +MODULE_EXPORT int i2500vfd_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void i2500vfd_close (Driver *drvthis); MODULE_EXPORT int i2500vfd_width (Driver *drvthis); MODULE_EXPORT int i2500vfd_height (Driver *drvthis); diff --git a/server/drivers/icp_a106.c b/server/drivers/icp_a106.c index d568dc46..f8c43ebd 100644 --- a/server/drivers/icp_a106.c +++ b/server/drivers/icp_a106.c @@ -89,7 +89,7 @@ MODULE_EXPORT char *symbol_prefix = "icp_a106_"; * \retval <0 Error. */ MODULE_EXPORT int -icp_a106_init(Driver *drvthis) +icp_a106_init(Driver *drvthis, Elektra * elektra) { char device[200]; int speed = B1200; diff --git a/server/drivers/icp_a106.h b/server/drivers/icp_a106.h index 5a4218df..bc9bd49c 100644 --- a/server/drivers/icp_a106.h +++ b/server/drivers/icp_a106.h @@ -31,7 +31,9 @@ #ifndef ICP_A106_H #define ICP_A106_H -MODULE_EXPORT int icp_a106_init(Driver *drvthis); +#include + +MODULE_EXPORT int icp_a106_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void icp_a106_close(Driver *drvthis); MODULE_EXPORT int icp_a106_width(Driver *drvthis); MODULE_EXPORT int icp_a106_height(Driver *drvthis); diff --git a/server/drivers/imon.c b/server/drivers/imon.c index 42eca447..74273a6a 100644 --- a/server/drivers/imon.c +++ b/server/drivers/imon.c @@ -131,7 +131,7 @@ static char * imon_charmaps[] = { * \retval <0 Error. */ MODULE_EXPORT int -imon_init(Driver *drvthis) +imon_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = NULL; char buf[256]; diff --git a/server/drivers/imon.h b/server/drivers/imon.h index 1c2994c4..0c817be9 100644 --- a/server/drivers/imon.h +++ b/server/drivers/imon.h @@ -26,7 +26,9 @@ #ifndef IMON_H #define IMON_H -MODULE_EXPORT int imon_init(Driver *drvthis); +#include + +MODULE_EXPORT int imon_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void imon_close(Driver *drvthis); MODULE_EXPORT int imon_width(Driver *drvthis); MODULE_EXPORT int imon_height(Driver *drvthis); diff --git a/server/drivers/imonlcd.c b/server/drivers/imonlcd.c index 9241ab83..c1802472 100644 --- a/server/drivers/imonlcd.c +++ b/server/drivers/imonlcd.c @@ -231,7 +231,7 @@ typedef struct imonlcd_private_data { /* prototypes for driver internal functions */ -static void imonlcd_display_init(Driver *drvthis); +static void imonlcd_display_init(Driver *drvthis, Elektra * elektra); static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, PrivateData *p); static void setLineLength(int topLine, int botLine, int topProgress, int botProgress, PrivateData *p); static void setBuiltinProgressBars(int topLine, int botLine, int topProgress, int botProgress, PrivateData *p); @@ -246,7 +246,7 @@ static int send_packet(PrivateData *p); * \retval <0 Error. */ MODULE_EXPORT int -imonlcd_init(Driver *drvthis) +imonlcd_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = NULL; char buf[256]; @@ -413,7 +413,7 @@ imonlcd_init(Driver *drvthis) * \param drvthis Pointer to driver structure. */ static void -imonlcd_display_init(Driver *drvthis) +imonlcd_display_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = drvthis->private_data; diff --git a/server/drivers/imonlcd.h b/server/drivers/imonlcd.h index 3d9ba011..a174bfe6 100644 --- a/server/drivers/imonlcd.h +++ b/server/drivers/imonlcd.h @@ -16,8 +16,10 @@ #ifndef IMONLCD_H #define IMONLCD_H +#include + /* mandatory functions (necessary for all drivers) */ -MODULE_EXPORT int imonlcd_init (Driver *drvthis); +MODULE_EXPORT int imonlcd_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void imonlcd_close (Driver *drvthis); /* essential output functions (necessary for output drivers) */ diff --git a/server/drivers/irmanin.c b/server/drivers/irmanin.c index 7ef09064..187488d1 100644 --- a/server/drivers/irmanin.c +++ b/server/drivers/irmanin.c @@ -72,7 +72,7 @@ MODULE_EXPORT char *symbol_prefix = "irmanin_"; * \retval <0 Error. */ MODULE_EXPORT int -irmanin_init (Driver *drvthis) +irmanin_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; char *ptrdevice = NULL; diff --git a/server/drivers/irmanin.h b/server/drivers/irmanin.h index 76a08879..9f1e6e42 100644 --- a/server/drivers/irmanin.h +++ b/server/drivers/irmanin.h @@ -1,7 +1,9 @@ #ifndef LCD_IRMANIN__H #define LCD_IRMANIN_H -MODULE_EXPORT int irmanin_init (Driver *drvthis); +#include + +MODULE_EXPORT int irmanin_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void irmanin_close (Driver *drvthis); MODULE_EXPORT const char *irmanin_get_key (Driver *drvthis); diff --git a/server/drivers/irtrans.c b/server/drivers/irtrans.c index 38939b5d..4e02a55e 100644 --- a/server/drivers/irtrans.c +++ b/server/drivers/irtrans.c @@ -85,7 +85,7 @@ int InitClientSocket(char host[], SOCKET *sock, unsigned long id); int SendCommand(Driver *drvthis, LCDCOMMAND *com, STATUSBUFFER *stat); -MODULE_EXPORT int irtrans_init(Driver *drvthis) +MODULE_EXPORT int irtrans_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; char buf[256]; diff --git a/server/drivers/irtrans.h b/server/drivers/irtrans.h index 78cb2a08..e8923ff6 100644 --- a/server/drivers/irtrans.h +++ b/server/drivers/irtrans.h @@ -31,7 +31,9 @@ #ifndef LCD_TEXT_H #define LCD_TEXT_H -MODULE_EXPORT int irtrans_init(Driver *drvthis); +#include + +MODULE_EXPORT int irtrans_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void irtrans_close(Driver *drvthis); MODULE_EXPORT int irtrans_width(Driver *drvthis); MODULE_EXPORT int irtrans_height(Driver *drvthis); diff --git a/server/drivers/joy.c b/server/drivers/joy.c index ade7f5de..11f48334 100644 --- a/server/drivers/joy.c +++ b/server/drivers/joy.c @@ -75,7 +75,7 @@ MODULE_EXPORT char *symbol_prefix = "joy_"; * \retval <0 Error. */ MODULE_EXPORT int -joy_init (Driver *drvthis) +joy_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; int i; diff --git a/server/drivers/joy.h b/server/drivers/joy.h index e964ea07..929ea574 100644 --- a/server/drivers/joy.h +++ b/server/drivers/joy.h @@ -1,9 +1,11 @@ #ifndef LCD_JOY_H #define LCD_JOY_H +#include + #include "lcd.h" -MODULE_EXPORT int joy_init (Driver *drvthis); +MODULE_EXPORT int joy_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void joy_close (Driver *drvthis); MODULE_EXPORT const char *joy_get_key (Driver *drvthis); diff --git a/server/drivers/lb216.c b/server/drivers/lb216.c index c02abc64..ab1a86ed 100644 --- a/server/drivers/lb216.c +++ b/server/drivers/lb216.c @@ -34,13 +34,14 @@ #include "lcd_lib.h" #include "shared/report.h" +#include "../elektragen.h" + #define LB216_DEFAULT_DEVICE "/dev/lcd" #define LB216_DEFAULT_SPEED 9600 #define LB216_DEFAULT_BRIGHTNESS 255 /** private data for the \c lb216 driver */ typedef struct LB216_private_data { - char device[256]; int speed; int fd; char *framebuf; @@ -69,7 +70,7 @@ MODULE_EXPORT char *symbol_prefix = "LB216_"; // Opens com port and sets baud correctly... // MODULE_EXPORT int -LB216_init(Driver *drvthis) +LB216_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; @@ -92,16 +93,15 @@ LB216_init(Driver *drvthis) p->cellheight = LCD_DEFAULT_CELLHEIGHT; p->custom = standard; - /* Read config file */ + /* Read config */ + Lb216DriverConfig config; + elektraFillStructV(elektra, &config, CONF_LB216, drvthis->index); /* What device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, - LB216_DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* What speed to use */ - p->speed = drvthis->config_get_int(drvthis->name, "Speed", 0, LB216_DEFAULT_SPEED); + p->speed = config.speed; if (p->speed == 2400) p->speed = B2400; else if (p->speed == 9600) p->speed = B9600; @@ -112,25 +112,20 @@ LB216_init(Driver *drvthis) } /* Which backlight brightness */ - p->backlight_brightness = drvthis->config_get_int(drvthis->name, "Brightness", 0, LB216_DEFAULT_BRIGHTNESS); - if ((p->backlight_brightness < 0) || (p->backlight_brightness > 255)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and 255; using default %d", - drvthis->name, LB216_DEFAULT_BRIGHTNESS); - p->backlight_brightness = LB216_DEFAULT_BRIGHTNESS; - } + p->backlight_brightness = config.brightness; /* Reboot display? */ - reboot = drvthis->config_get_bool(drvthis->name , "Reboot", 0, 0); + reboot = config.reboot; - /* End of config file parsing */ + /* End of config processing */ // Set up io port correctly, and open it... - p->fd = open(p->device, O_RDWR | O_NOCTTY | O_NDELAY); + p->fd = open(config.device, O_RDWR | O_NOCTTY | O_NDELAY); if (p->fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, p->device, strerror(errno)); + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, config.device, strerror(errno)); return -1; } - report(RPT_DEBUG, "%s: opened device %s", drvthis->name, p->device); + report(RPT_DEBUG, "%s: opened device %s", drvthis->name, config.device); tcgetattr(p->fd, &portset); diff --git a/server/drivers/lb216.h b/server/drivers/lb216.h index df95908c..2ef2d14e 100644 --- a/server/drivers/lb216.h +++ b/server/drivers/lb216.h @@ -1,7 +1,9 @@ #ifndef LB216_H #define LB216_H -MODULE_EXPORT int LB216_init(Driver *drvthis); +#include + +MODULE_EXPORT int LB216_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void LB216_close(Driver *drvthis); MODULE_EXPORT int LB216_width (Driver *drvthis); MODULE_EXPORT int LB216_height (Driver *drvthis); diff --git a/server/drivers/lcd.h b/server/drivers/lcd.h index a4ad6d48..6562d3fe 100644 --- a/server/drivers/lcd.h +++ b/server/drivers/lcd.h @@ -30,6 +30,7 @@ #define LCD_H #include +#include /* Maximum supported sizes */ #define LCD_MAX_WIDTH 256 @@ -139,7 +140,7 @@ typedef struct lcd_logical_driver { /* The driver loader will look for symbols with these names ! */ /* mandatory functions (necessary for all drivers) */ - int (*init) (struct lcd_logical_driver *drvthis); + int (*init) (struct lcd_logical_driver *drvthis, Elektra * elektra); void (*close) (struct lcd_logical_driver *drvthis); /* essential output functions (necessary for output drivers) */ @@ -183,6 +184,7 @@ typedef struct lcd_logical_driver { /******** Variables in server core available for drivers ********/ char *name; /* Name of this driver */ + kdb_long_long_t index; /* Index of this driver's config */ char *filename; /* Filename of the shared module */ MODULE_HANDLE module_handle; /* The handle of the loaded shared module @@ -198,16 +200,6 @@ typedef struct lcd_logical_driver { int (*store_private_ptr) (struct lcd_logical_driver * driver, void * private_data); /* Store the driver's private data */ - /* Configfile functions */ - /* See configfile.h for descriptions and usage. */ - - short (*config_get_bool) (const char *sectionname, const char *keyname, int skip, short default_value); - long int (*config_get_int) (const char *sectionname, const char *keyname, int skip, long int default_value); - double (*config_get_float) (const char *sectionname, const char *keyname, int skip, double default_value); - const char *( *config_get_string)(const char *sectionname, const char *keyname, int skip, const char *default_value); - int (*config_has_section) (const char *sectionname); - int (*config_has_key) (const char *sectionname, const char *keyname); - /* Display properties functions (for drivers that adapt to other loaded drivers) */ int (*request_display_width) (); int (*request_display_height) (); diff --git a/server/drivers/lcdm001.c b/server/drivers/lcdm001.c index 388899ed..46124e20 100644 --- a/server/drivers/lcdm001.c +++ b/server/drivers/lcdm001.c @@ -46,10 +46,10 @@ #include "lcdm001.h" #include "shared/report.h" +#include "../elektragen.h" /** private data for the \c lcdm001 driver */ typedef struct lcdm001_private_data { - char device[200]; int fd; int speed; @@ -85,32 +85,21 @@ static char lcdm001_parse_keypad_setting(Driver *drvthis, char * keyname, char * * pressed. */ static char -lcdm001_parse_keypad_setting(Driver *drvthis, char * keyname, char * default_value) +map_key(Lcdm001Keys key) { - char return_val = 0; - - if (strcmp(drvthis->config_get_string(drvthis->name, keyname, 0, default_value), "LeftKey") == 0) { - return_val = LEFT_KEY; - } else if (strcmp(drvthis->config_get_string(drvthis->name, keyname, 0, default_value), "RightKey") == 0) { - return_val = RIGHT_KEY; - } else if (strcmp(drvthis->config_get_string(drvthis->name, keyname, 0, default_value), "UpKey") == 0) { - return_val = UP_KEY; - } else if (strcmp(drvthis->config_get_string(drvthis->name, keyname, 0, default_value), "DownKey") == 0) { - return_val = DOWN_KEY; - } else { - report(RPT_WARNING, "%s: invalid config setting for %s; using default %s", - drvthis->name, keyname, default_value); - if (strcmp(default_value, "LeftKey") == 0) { - return_val = LEFT_KEY; - } else if (strcmp(default_value, "RightKey") == 0) { - return_val = RIGHT_KEY; - } else if (strcmp(default_value, "UpKey") == 0) { - return_val = UP_KEY; - } else if (strcmp(default_value, "DownKey") == 0) { - return_val = DOWN_KEY; - } + switch (key) + { + case LCDM001_KEYS_LEFT_KEY: + return LEFT_KEY; + case LCDM001_KEYS_RIGHT_KEY: + return RIGHT_KEY; + case LCDM001_KEYS_UP_KEY: + return UP_KEY; + case LCDM001_KEYS_DOWN_KEY: + return DOWN_KEY; } - return return_val; + + return 0; // unreachable } /** @@ -137,7 +126,7 @@ lcdm001_cursorblink(Driver *drvthis, int on) * API: Set up any device-specific stuff. */ MODULE_EXPORT int -lcdm001_init (Driver *drvthis) +lcdm001_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; @@ -171,30 +160,30 @@ lcdm001_init (Driver *drvthis) memset(p->framebuf, ' ', p->width * p->height); /* READ CONFIG FILE: */ + Lcdm001DriverConfig config; + elektraFillStructV(elektra, &config, CONF_LCDM001, drvthis->index); /* which serial device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, "/dev/lcd"), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* keypad settings */ - p->pause_key = lcdm001_parse_keypad_setting(drvthis, "PauseKey", "DownKey"); - p->back_key = lcdm001_parse_keypad_setting(drvthis, "BackKey", "LeftKey"); - p->forward_key = lcdm001_parse_keypad_setting(drvthis, "ForwardKey", "RightKey"); - p->main_menu_key = lcdm001_parse_keypad_setting(drvthis, "MainMenuKey", "UpKey"); + p->pause_key = map_key(config.pausekey); + p->back_key = map_key(config.backkey); + p->forward_key = map_key(config.forwardkey); + p->main_menu_key = map_key(config.mainmenukey); /* Set up io port correctly, and open it... */ - debug(RPT_DEBUG, "%s: opening serial device: %s", __FUNCTION__, p->device); - p->fd = open(p->device, O_RDWR | O_NOCTTY | O_NDELAY); + debug(RPT_DEBUG, "%s: opening serial device: %s", __FUNCTION__, config.device); + p->fd = open(config.device, O_RDWR | O_NOCTTY | O_NDELAY); if (p->fd == -1) { report(RPT_ERR, "%s: open(%d) failed (%s)", - drvthis->name, p->device, strerror(errno)); + drvthis->name, config.device, strerror(errno)); if (errno == EACCES) report(RPT_ERR, "%s: make sure you have rw access to %s!", - drvthis->name, p->device); + drvthis->name, config.device); return -1; } - report(RPT_INFO, "%s: opened display on %s", drvthis->name, p->device); + report(RPT_INFO, "%s: opened display on %s", drvthis->name, config.device); tcgetattr(p->fd, &portset); #ifdef HAVE_CFMAKERAW diff --git a/server/drivers/lcdm001.h b/server/drivers/lcdm001.h index e30be399..02edf057 100644 --- a/server/drivers/lcdm001.h +++ b/server/drivers/lcdm001.h @@ -24,7 +24,9 @@ #ifndef LCDM001_H #define LCDM001_H -MODULE_EXPORT int lcdm001_init (Driver *drvthis); +#include + +MODULE_EXPORT int lcdm001_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void lcdm001_close (Driver *drvthis); MODULE_EXPORT int lcdm001_width (Driver *drvthis); MODULE_EXPORT int lcdm001_height (Driver *drvthis); diff --git a/server/drivers/lcterm.c b/server/drivers/lcterm.c index d000bcc6..5fd92e07 100644 --- a/server/drivers/lcterm.c +++ b/server/drivers/lcterm.c @@ -73,7 +73,7 @@ MODULE_EXPORT char *symbol_prefix = "lcterm_"; * \retval <0 Error. */ MODULE_EXPORT int -lcterm_init (Driver *drvthis) +lcterm_init (Driver *drvthis, Elektra * elektra) { char device[200]; int speed=B9600; diff --git a/server/drivers/lcterm.h b/server/drivers/lcterm.h index ef9dd3ca..675b921b 100644 --- a/server/drivers/lcterm.h +++ b/server/drivers/lcterm.h @@ -26,7 +26,9 @@ #ifndef LCTERM_H #define LCTERM_H -MODULE_EXPORT int lcterm_init (Driver *drvthis); +#include + +MODULE_EXPORT int lcterm_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void lcterm_close (Driver *drvthis); MODULE_EXPORT int lcterm_width (Driver *drvthis); MODULE_EXPORT int lcterm_height (Driver *drvthis); diff --git a/server/drivers/linux_input.c b/server/drivers/linux_input.c index 5b914d4c..f52e5d25 100644 --- a/server/drivers/linux_input.c +++ b/server/drivers/linux_input.c @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef HAVE_CONFIG_H # include "config.h" @@ -25,6 +24,10 @@ #include "shared/report.h" #include "shared/LL.h" +#include "../elektragen.h" + +#include + #define LINUXINPUT_DEFAULT_DEVICE "/dev/input/event0" /** describe the button of a keycode */ @@ -33,39 +36,6 @@ struct keycode { char *button; }; -/** - * Parse key definition from config file - * \param configvalue value part of the config file entry - * \retval NULL Error. - * \retval else Pointer to newly allocated struct keycode. - */ -static struct keycode * -keycode_create(const char *configvalue) -{ - long code; - char *button; - struct keycode *ret; - - code = strtol(configvalue, NULL, 0); - if (code < 0 || code > UINT16_MAX) - return NULL; - - button = strchr(configvalue,','); - if (!button) - return NULL; - button = strdup(&button[1]); - if (!button) - return NULL; - - ret = malloc(sizeof(*ret)); - if (ret) { - ret->code = code; - ret->button = button; - } - - return ret; -} - /** private data for the linux event device driver */ typedef struct linuxInput_private_data { int fd; @@ -143,15 +113,10 @@ static int linuxInput_search_by_name(const char *name) * \retval <0 Error. */ MODULE_EXPORT int -linuxInput_init (Driver *drvthis) +linuxInput_init (Driver *drvthis, Elektra * elektra) { - PrivateData *p; - const char *s; - struct keycode *key; - int i; - - /* Allocate and store private data */ - p = (PrivateData *) calloc(1, sizeof(PrivateData)); + /* Allocate and store private data */ + PrivateData *p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) return -1; if (drvthis->store_private_ptr(drvthis, p)) @@ -164,36 +129,36 @@ linuxInput_init (Driver *drvthis) return -1; } - /* Read config file */ + /* Read config */ + /* not using struct, since it is inconvenient for keymap */ /* What device should be used */ - s = drvthis->config_get_string(drvthis->name, "Device", 0, - LINUXINPUT_DEFAULT_DEVICE); - report(RPT_INFO, "%s: using Device %s", drvthis->name, s); + const char * device = elektraGetV(elektra, CONF_LINUX_INPUT_DEVICE, drvthis->index); + report(RPT_INFO, "%s: using Device %s", drvthis->name, device); /* Open the device, eiher by path or by name */ - if (s[0] == '/') { - if ((p->fd = open(s, O_RDONLY | O_NONBLOCK)) == -1) { + if (device[0] == '/') { + if ((p->fd = open(device, O_RDONLY | O_NONBLOCK)) == -1) { report(RPT_ERR, "%s: open(%s) failed (%s)", - drvthis->name, s, strerror(errno)); + drvthis->name, device, strerror(errno)); return -1; } } else { - if ((p->fd = linuxInput_search_by_name(s)) == -1) { + if ((p->fd = linuxInput_search_by_name(device)) == -1) { report(RPT_ERR, "%s: could not find '%s' input-device", - drvthis->name, s); + drvthis->name, device); return -1; } - p->name = s; + p->name = device; } - for (i = 0; (s = drvthis->config_get_string(drvthis->name, "key", i, NULL)) != NULL; i++) { - if ((key = keycode_create(s)) == NULL) { - report(RPT_ERR, "%s: parsing configvalue '%s' failed", - drvthis->name, s); - continue; - } + kdb_long_long_t size = elektraSizeV(elektra, CONF_LINUX_INPUT_KEYS, drvthis->index); + + for (kdb_long_long_t i = 0; i < size; ++i) { + struct keycode * key = malloc(sizeof(struct keycode)); + key->code = elektraGetV(elektra, CONF_LINUX_INPUT_KEYS_CODE, drvthis->index, i); + key->button = strdup(elektraGetV(elektra, CONF_LINUX_INPUT_KEYS_BUTTON, drvthis->index, i)); LL_AddNode(p->buttonmap, key); } diff --git a/server/drivers/linux_input.h b/server/drivers/linux_input.h index 8477f58d..4cf800f8 100644 --- a/server/drivers/linux_input.h +++ b/server/drivers/linux_input.h @@ -3,7 +3,9 @@ #include "lcd.h" -MODULE_EXPORT int linuxInput_init (Driver *drvthis); +#include + +MODULE_EXPORT int linuxInput_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void linuxInput_close (Driver *drvthis); MODULE_EXPORT const char *linuxInput_get_key (Driver *drvthis); diff --git a/server/drivers/lircin.c b/server/drivers/lircin.c index 9a55f3d4..c5ee81ff 100644 --- a/server/drivers/lircin.c +++ b/server/drivers/lircin.c @@ -71,7 +71,7 @@ MODULE_EXPORT char *symbol_prefix = "lircin_"; * \retval <0 Error. */ MODULE_EXPORT int -lircin_init (Driver *drvthis) +lircin_init (Driver *drvthis, Elektra * elektra) { char s[256] = ""; diff --git a/server/drivers/lircin.h b/server/drivers/lircin.h index 3299c3b1..34783294 100644 --- a/server/drivers/lircin.h +++ b/server/drivers/lircin.h @@ -21,7 +21,9 @@ #ifndef LCD_LIRCIN_H #define LCD_LIRCIN_H -MODULE_EXPORT int lircin_init (Driver *drvthis); +#include + +MODULE_EXPORT int lircin_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void lircin_close (Driver *drvthis); MODULE_EXPORT const char * lircin_get_key (Driver *drvthis); diff --git a/server/drivers/lis.c b/server/drivers/lis.c index 4478bdba..60dd36d4 100644 --- a/server/drivers/lis.c +++ b/server/drivers/lis.c @@ -336,7 +336,7 @@ lis_get_brightness(Driver *drvthis, int state) * API: Init the driver and display */ MODULE_EXPORT int -lis_init(Driver *drvthis) +lis_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int err; diff --git a/server/drivers/lis.h b/server/drivers/lis.h index 6638d7d1..b948a79a 100644 --- a/server/drivers/lis.h +++ b/server/drivers/lis.h @@ -11,6 +11,8 @@ #ifndef LIS_H #define LIS_H +#include + /*----------------------------- Constants ---------------------------------*/ #define DISPLAY_VENDOR_ID 0x0403 @@ -76,7 +78,7 @@ typedef struct lis_private_data { } PrivateData; -MODULE_EXPORT int lis_init(Driver *drvthis); +MODULE_EXPORT int lis_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void lis_close(Driver *drvthis); MODULE_EXPORT int lis_width(Driver *drvthis); MODULE_EXPORT int lis_height(Driver *drvthis); diff --git a/server/drivers/mdm166a.c b/server/drivers/mdm166a.c index 0cd0f6e1..b4732a2a 100644 --- a/server/drivers/mdm166a.c +++ b/server/drivers/mdm166a.c @@ -130,7 +130,7 @@ drawchar2fb(Driver *drvthis, int x, int y, unsigned char z) * \retval <0 Error. */ MODULE_EXPORT int -mdm166a_init(Driver *drvthis) +mdm166a_init(Driver *drvthis, Elektra * elektra) { char clock[256] = DEFAULT_CLOCK; PrivateData *p; diff --git a/server/drivers/mdm166a.h b/server/drivers/mdm166a.h index 9cd856ad..7fe79e91 100644 --- a/server/drivers/mdm166a.h +++ b/server/drivers/mdm166a.h @@ -1,7 +1,9 @@ #ifndef MDM166A_H #define MDM166A_H -MODULE_EXPORT int mdm166a_init (Driver *drvthis); +#include + +MODULE_EXPORT int mdm166a_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void mdm166a_close (Driver *drvthis); MODULE_EXPORT int mdm166a_width (Driver *drvthis); MODULE_EXPORT int mdm166a_height (Driver *drvthis); diff --git a/server/drivers/ms6931.c b/server/drivers/ms6931.c index a96a31c2..f7902e7d 100644 --- a/server/drivers/ms6931.c +++ b/server/drivers/ms6931.c @@ -154,7 +154,7 @@ ms6931_draw_frame (Driver *drvthis, unsigned char *dat) // Opens com port and sets baud correctly... // MODULE_EXPORT int -ms6931_init (Driver *drvthis) +ms6931_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; diff --git a/server/drivers/mtc_s16209x.c b/server/drivers/mtc_s16209x.c index d972cd48..d8ac4298 100644 --- a/server/drivers/mtc_s16209x.c +++ b/server/drivers/mtc_s16209x.c @@ -113,7 +113,7 @@ MODULE_EXPORT char *symbol_prefix = "MTC_S16209X_"; // Opens com port and sets baud correctly... // MODULE_EXPORT int -MTC_S16209X_init (Driver *drvthis) +MTC_S16209X_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; diff --git a/server/drivers/mtc_s16209x.h b/server/drivers/mtc_s16209x.h index 7f4ddee7..b2196233 100644 --- a/server/drivers/mtc_s16209x.h +++ b/server/drivers/mtc_s16209x.h @@ -38,7 +38,9 @@ #ifndef MTC_S16209X_H #define MTC_S16209X_H -MODULE_EXPORT int MTC_S16209X_init(Driver *drvthis); +#include + +MODULE_EXPORT int MTC_S16209X_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void MTC_S16209X_close(Driver *drvthis); MODULE_EXPORT int MTC_S16209X_width (Driver *drvthis); MODULE_EXPORT int MTC_S16209X_height (Driver *drvthis); diff --git a/server/drivers/picolcd.c b/server/drivers/picolcd.c index 401f5935..163cef74 100644 --- a/server/drivers/picolcd.c +++ b/server/drivers/picolcd.c @@ -242,7 +242,7 @@ MODULE_EXPORT char *symbol_prefix = "picoLCD_"; * \retval <0 Error. */ MODULE_EXPORT int -picoLCD_init(Driver *drvthis) +picoLCD_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; #ifdef HAVE_LIBUSB_1_0 diff --git a/server/drivers/picolcd.h b/server/drivers/picolcd.h index 2d7293e5..f5ac9b72 100644 --- a/server/drivers/picolcd.h +++ b/server/drivers/picolcd.h @@ -21,6 +21,7 @@ # include # define USB_DEVICE_HANDLE usb_dev_handle #endif +#include /* 12 keys plus a 0 placeholder */ #define KEYPAD_MAX 13 @@ -74,7 +75,7 @@ typedef struct _picolcd_device { } picolcd_device; -MODULE_EXPORT int picoLCD_init(Driver *drvthis); +MODULE_EXPORT int picoLCD_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void picoLCD_close(Driver *drvthis); MODULE_EXPORT int picoLCD_width(Driver *drvthis); MODULE_EXPORT int picoLCD_height(Driver *drvthis); diff --git a/server/drivers/pylcd.c b/server/drivers/pylcd.c index faed66b2..e894b3e6 100644 --- a/server/drivers/pylcd.c +++ b/server/drivers/pylcd.c @@ -58,6 +58,8 @@ #include "shared/report.h" #include "adv_bignum.h" +#include "../elektragen.h" + #define True 1 #define False 0 @@ -290,7 +292,7 @@ initTTY(Driver *drvthis, int FD) * \retval <0 Error. */ MODULE_EXPORT int -pyramid_init(Driver *drvthis) +pyramid_init(Driver *drvthis, Elektra * elektra) { char buffer[MAXCOUNT]; int i; @@ -320,22 +322,23 @@ pyramid_init(Driver *drvthis) p->timeout.tv_usec = MICROTIMEOUT; /* - * read config file, fill configuration dependent elements of private + * read config, fill configuration dependent elements of private * data */ + PyramidDriverConfig config; + elektraFillStructV(elektra, &config, CONF_PYRAMID, drvthis->index); + /* Which serial device should be used? */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, "/dev/lcd"), sizeof(p->device)); - p->device[sizeof(p->device) - 1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + report(RPT_INFO, "%s/#"ELEKTRA_LONG_LONG_F": using Device %s", drvthis->name, drvthis->index, config.device); /* Initialize connection to the LCD */ /* open and initialize serial device */ - p->FD = open(p->device, O_RDWR); + p->FD = open(config.device, O_RDWR); if (p->FD == -1) { - report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, p->device, strerror(errno)); + report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, config.device, strerror(errno)); return -1; } @@ -469,22 +472,22 @@ pyramid_flush(Driver *drvthis) */ for (i = 1; i < 33; i++) { switch ((unsigned char)mesg[i]) { - case 0xe4: /* ä */ + case 0xe4: /* ä */ mesg[i] = 0xe1; break; - case 0xf6: /* ö */ + case 0xf6: /* ö */ mesg[i] = 0xef; break; - case 0xfc: /* ü */ + case 0xfc: /* ü */ mesg[i] = 0xf5; break; - case 0xdf: /* ß */ + case 0xdf: /* ß */ mesg[i] = 0xe2; break; - case 0xb7: /* · */ + case 0xb7: /* · */ mesg[i] = 0xa5; break; - case 0xb0: /* ° */ + case 0xb0: /* ° */ mesg[i] = 0xdf; break; } diff --git a/server/drivers/pylcd.h b/server/drivers/pylcd.h index 05725d61..78e675a0 100644 --- a/server/drivers/pylcd.h +++ b/server/drivers/pylcd.h @@ -25,6 +25,8 @@ #ifndef PYLCD_H #define PYLCD_H +#include + #define MAXCOUNT 10 /* Size of read buffer including NUL */ /* Display properties */ @@ -39,7 +41,6 @@ typedef struct pyramid_private_data { /* device io */ int FD; - char device[255]; fd_set rdfs; struct timeval timeout; @@ -70,7 +71,7 @@ typedef struct pyramid_private_data { } PrivateData; -MODULE_EXPORT int pyramid_init(Driver *drvthis); +MODULE_EXPORT int pyramid_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void pyramid_close(Driver *drvthis); MODULE_EXPORT int pyramid_width(Driver *drvthis); MODULE_EXPORT int pyramid_height(Driver *drvthis); diff --git a/server/drivers/rawserial.c b/server/drivers/rawserial.c index 7f8e1fdd..0e930aff 100644 --- a/server/drivers/rawserial.c +++ b/server/drivers/rawserial.c @@ -83,7 +83,7 @@ MODULE_EXPORT char *symbol_prefix = "rawserial_"; * \retval <0 Error. */ MODULE_EXPORT int -rawserial_init(Driver *drvthis) +rawserial_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; char buf[256]; diff --git a/server/drivers/rawserial.h b/server/drivers/rawserial.h index 66fd27c1..5ff48c7e 100644 --- a/server/drivers/rawserial.h +++ b/server/drivers/rawserial.h @@ -1,6 +1,8 @@ #ifndef LCD_rawserial_H #define LCD_rawserial_H +#include + #define DEFAULT_DEVICE "/dev/cuaU0" #define DISPLAY_DEFAULT_SIZE "40x4" @@ -9,7 +11,7 @@ #define DEFAULT_UPDATE_RATE 1.0 #define SECOND_GRANULARITY 1000 -MODULE_EXPORT int rawserial_init(Driver *drvthis); +MODULE_EXPORT int rawserial_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void rawserial_close(Driver *drvthis); MODULE_EXPORT int rawserial_width(Driver *drvthis); MODULE_EXPORT int rawserial_height(Driver *drvthis); diff --git a/server/drivers/sdeclcd.c b/server/drivers/sdeclcd.c index 93e1ce2a..b69b61bd 100644 --- a/server/drivers/sdeclcd.c +++ b/server/drivers/sdeclcd.c @@ -220,7 +220,7 @@ sdec_init() * API: Initialize the driver. */ MODULE_EXPORT int -sdeclcd_init(Driver *drvthis) +sdeclcd_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int i, j; diff --git a/server/drivers/sed1330.h b/server/drivers/sed1330.h index 47e83530..6598994b 100644 --- a/server/drivers/sed1330.h +++ b/server/drivers/sed1330.h @@ -5,7 +5,9 @@ #ifndef SED1330_H #define SED1330_H -MODULE_EXPORT int sed1330_init(Driver *drvthis); +#include + +MODULE_EXPORT int sed1330_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void sed1330_close(Driver *drvthis); MODULE_EXPORT int sed1330_width(Driver *drvthis); MODULE_EXPORT int sed1330_height(Driver *drvthis); diff --git a/server/drivers/sed1520.h b/server/drivers/sed1520.h index c791b3c7..2fd9bdf6 100644 --- a/server/drivers/sed1520.h +++ b/server/drivers/sed1520.h @@ -1,6 +1,8 @@ #ifndef SED1520_H #define SED1520_H +#include + /* Commands for SED1520 */ #define DISP_OFF 0xAE #define DISP_ON 0xAF @@ -15,7 +17,7 @@ #define DUTY_1_32 0xA9 #define SOFT_RESET 0xE2 -MODULE_EXPORT int sed1520_init (Driver *drvthis); +MODULE_EXPORT int sed1520_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void sed1520_close (Driver *drvthis); MODULE_EXPORT int sed1520_width (Driver *drvthis); MODULE_EXPORT int sed1520_height (Driver *drvthis); diff --git a/server/drivers/serialVFD.c b/server/drivers/serialVFD.c index 44ade9b4..4c019d1b 100644 --- a/server/drivers/serialVFD.c +++ b/server/drivers/serialVFD.c @@ -89,7 +89,7 @@ static void serialVFD_hw_write (Driver *drvthis, int i); * \retval <0 Error. */ MODULE_EXPORT int -serialVFD_init (Driver *drvthis) +serialVFD_init (Driver *drvthis, Elektra * elektra) { int tmp, w, h; char size[200] = DEFAULT_SIZE; diff --git a/server/drivers/serialVFD.h b/server/drivers/serialVFD.h index d8713909..71b2ecf8 100644 --- a/server/drivers/serialVFD.h +++ b/server/drivers/serialVFD.h @@ -26,6 +26,8 @@ #ifndef SERIALVFD_H #define SERIALVFD_H +#include + #define DEFAULT_CELL_WIDTH 5 #define DEFAULT_CELL_HEIGHT 7 #define DEFAULT_DEVICE "/dev/lcd" @@ -39,7 +41,7 @@ #define DEFAULT_LPTPORT 0x378 -MODULE_EXPORT int serialVFD_init (Driver *drvthis); +MODULE_EXPORT int serialVFD_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void serialVFD_close (Driver *drvthis); MODULE_EXPORT int serialVFD_width (Driver *drvthis); MODULE_EXPORT int serialVFD_height (Driver *drvthis); diff --git a/server/drivers/shuttleVFD.c b/server/drivers/shuttleVFD.c index 2498cc3e..1134338f 100644 --- a/server/drivers/shuttleVFD.c +++ b/server/drivers/shuttleVFD.c @@ -94,7 +94,7 @@ static void send_packet(Driver *drvthis, char* packet) * \retval 0 Success. * \retval <0 Error. */ -MODULE_EXPORT int shuttleVFD_init(Driver *drvthis) +MODULE_EXPORT int shuttleVFD_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; struct usb_bus *bus; diff --git a/server/drivers/shuttleVFD.h b/server/drivers/shuttleVFD.h index 45fd9726..702210af 100644 --- a/server/drivers/shuttleVFD.h +++ b/server/drivers/shuttleVFD.h @@ -26,8 +26,10 @@ #ifndef SHUTTLE_VFD_H #define SHUTTLE_VFD_H +#include + // mandatory functions (necessary for all drivers) -MODULE_EXPORT int shuttleVFD_init(Driver *drvthis); +MODULE_EXPORT int shuttleVFD_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void shuttleVFD_close(Driver *drvthis); // essential output functions (necessary for output drivers) diff --git a/server/drivers/stv5730.c b/server/drivers/stv5730.c index e3163abe..1eeb1c72 100644 --- a/server/drivers/stv5730.c +++ b/server/drivers/stv5730.c @@ -282,7 +282,7 @@ stv5730_drawchar2fb (Driver *drvthis, int x, int y, unsigned char z) // a command line argument. // MODULE_EXPORT int -stv5730_init (Driver *drvthis) +stv5730_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; int i; diff --git a/server/drivers/stv5730.h b/server/drivers/stv5730.h index 743a5fed..daa54cdc 100644 --- a/server/drivers/stv5730.h +++ b/server/drivers/stv5730.h @@ -1,7 +1,9 @@ #ifndef STV5730_H #define STV5730_H -MODULE_EXPORT int stv5730_init (Driver *drvthis); +#include + +MODULE_EXPORT int stv5730_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void stv5730_close (Driver *drvthis); MODULE_EXPORT int stv5730_width (Driver *drvthis); MODULE_EXPORT int stv5730_height (Driver *drvthis); diff --git a/server/drivers/svgalib_drv.c b/server/drivers/svgalib_drv.c index d2166fcd..045ed3d5 100644 --- a/server/drivers/svgalib_drv.c +++ b/server/drivers/svgalib_drv.c @@ -219,7 +219,7 @@ MODULE_EXPORT char *symbol_prefix = "svga_"; * Init driver */ MODULE_EXPORT int -svga_init (Driver *drvthis) +svga_init (Driver *drvthis, Elektra * elektra) { char modestr[LCD_MAX_WIDTH+1] = DEFAULT_MODESTR; char size[LCD_MAX_WIDTH+1] = DEFAULT_SIZE; diff --git a/server/drivers/svgalib_drv.h b/server/drivers/svgalib_drv.h index ab11f18d..d47e2941 100644 --- a/server/drivers/svgalib_drv.h +++ b/server/drivers/svgalib_drv.h @@ -1,6 +1,8 @@ #ifndef LCD_SVGALIB_H #define LCD_SVGALIB_H +#include + #define DEFAULT_MODESTR "G320x200x256" #define DEFAULT_SIZE "20x4" #define DEFAULT_CONTRAST 500 @@ -27,7 +29,7 @@ typedef struct svga_private_data { } PrivateData; -MODULE_EXPORT int svga_init (Driver *drvthis); +MODULE_EXPORT int svga_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void svga_close (Driver *drvthis); MODULE_EXPORT int svga_width (Driver *drvthis); MODULE_EXPORT int svga_height (Driver *drvthis); diff --git a/server/drivers/t6963.c b/server/drivers/t6963.c index 1ceaf20f..22d8635f 100644 --- a/server/drivers/t6963.c +++ b/server/drivers/t6963.c @@ -62,7 +62,7 @@ MODULE_EXPORT char *symbol_prefix = "t6963_"; * API: Initialize the driver. */ MODULE_EXPORT int -t6963_init(Driver *drvthis) +t6963_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int w, h; diff --git a/server/drivers/t6963.h b/server/drivers/t6963.h index 885cdd85..a6758a2f 100644 --- a/server/drivers/t6963.h +++ b/server/drivers/t6963.h @@ -11,8 +11,10 @@ #ifndef T6963_H #define T6963_H +#include + /* API functions */ -MODULE_EXPORT int t6963_init (Driver *drvthis); +MODULE_EXPORT int t6963_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void t6963_close (Driver *drvthis); MODULE_EXPORT int t6963_width (Driver *drvthis); MODULE_EXPORT int t6963_height (Driver *drvthis); diff --git a/server/drivers/text.c b/server/drivers/text.c index 2b6a8698..3fe3b98d 100644 --- a/server/drivers/text.c +++ b/server/drivers/text.c @@ -33,6 +33,7 @@ #include "text.h" #include "shared/report.h" +#include "../elektragen.h" /** private data for the \c text driver */ typedef struct text_private_data { @@ -56,10 +57,9 @@ MODULE_EXPORT char *symbol_prefix = "text_"; * \retval <0 Error. */ MODULE_EXPORT int -text_init (Driver *drvthis) +text_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; - char buf[256]; /* Allocate and store private data */ p = (PrivateData *) calloc(1, sizeof(PrivateData)); @@ -70,6 +70,9 @@ text_init (Driver *drvthis) /* initialize private data */ + TextDriverConfig config; + elektraFillStructV(elektra, &config, CONF_TEXT, drvthis->index); + // Set display sizes if ((drvthis->request_display_width() > 0) && (drvthis->request_display_height() > 0)) { @@ -79,13 +82,11 @@ text_init (Driver *drvthis) } else { /* Use our own size from config file */ - strncpy(buf, drvthis->config_get_string(drvthis->name, "Size", 0, TEXTDRV_DEFAULT_SIZE), sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - if ((sscanf(buf , "%dx%d", &p->width, &p->height) != 2) + if ((sscanf(config.size , "%dx%d", &p->width, &p->height) != 2) || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", - drvthis->name, buf, TEXTDRV_DEFAULT_SIZE); + drvthis->name, config.size, TEXTDRV_DEFAULT_SIZE); sscanf(TEXTDRV_DEFAULT_SIZE, "%dx%d", &p->width, &p->height); } } diff --git a/server/drivers/text.h b/server/drivers/text.h index 01a3fe46..88ddf071 100644 --- a/server/drivers/text.h +++ b/server/drivers/text.h @@ -1,7 +1,9 @@ #ifndef LCD_TEXT_H #define LCD_TEXT_H -MODULE_EXPORT int text_init (Driver *drvthis); +#include + +MODULE_EXPORT int text_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void text_close (Driver *drvthis); MODULE_EXPORT int text_width (Driver *drvthis); MODULE_EXPORT int text_height (Driver *drvthis); diff --git a/server/drivers/ula200.c b/server/drivers/ula200.c index a9483ea7..53a8566a 100644 --- a/server/drivers/ula200.c +++ b/server/drivers/ula200.c @@ -544,7 +544,7 @@ ula200_load_custom_chars(Driver *drvthis) * \retval <0 Error. */ MODULE_EXPORT int -ula200_init(Driver *drvthis) +ula200_init(Driver *drvthis, Elektra * elektra) { PrivateData *p; int err, i; diff --git a/server/drivers/ula200.h b/server/drivers/ula200.h index 47639708..d8ea92b7 100644 --- a/server/drivers/ula200.h +++ b/server/drivers/ula200.h @@ -23,7 +23,9 @@ #ifndef ULA200_H #define ULA200_H -MODULE_EXPORT int ula200_init(Driver *drvthis); +#include + +MODULE_EXPORT int ula200_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void ula200_close (Driver *drvthis); MODULE_EXPORT int ula200_width (Driver *drvthis); MODULE_EXPORT int ula200_height (Driver *drvthis); diff --git a/server/drivers/vlsys_m428.c b/server/drivers/vlsys_m428.c index f57a385f..a2eff31e 100644 --- a/server/drivers/vlsys_m428.c +++ b/server/drivers/vlsys_m428.c @@ -261,7 +261,7 @@ initialise_display(PrivateData *p) * \retval <0 Error. */ MODULE_EXPORT int -vlsys_m428_init(Driver *drvthis) +vlsys_m428_init(Driver *drvthis, Elektra * elektra) { PrivateData *p = NULL; char path[PATH_SIZE]; /* device path (serial port) */ diff --git a/server/drivers/vlsys_m428.h b/server/drivers/vlsys_m428.h index 5c0c1c57..b3fa9892 100644 --- a/server/drivers/vlsys_m428.h +++ b/server/drivers/vlsys_m428.h @@ -13,7 +13,9 @@ #ifndef VLSYS_M428_H #define VLSYS_M428_H -MODULE_EXPORT int vlsys_m428_init(Driver *drvthis); +#include + +MODULE_EXPORT int vlsys_m428_init(Driver *drvthis, Elektra * elektra); MODULE_EXPORT void vlsys_m428_close(Driver *drvthis); MODULE_EXPORT int vlsys_m428_width(Driver *drvthis); diff --git a/server/drivers/wirz-sli.c b/server/drivers/wirz-sli.c index be688891..e12edd2d 100644 --- a/server/drivers/wirz-sli.c +++ b/server/drivers/wirz-sli.c @@ -52,7 +52,7 @@ MODULE_EXPORT char *symbol_prefix = "sli_"; // Opens com port and sets baud correctly... // MODULE_EXPORT int -sli_init (Driver *drvthis) +sli_init (Driver *drvthis, Elektra * elektra) { PrivateData *p; struct termios portset; diff --git a/server/drivers/wirz-sli.h b/server/drivers/wirz-sli.h index 559e1a37..fa63f727 100644 --- a/server/drivers/wirz-sli.h +++ b/server/drivers/wirz-sli.h @@ -7,7 +7,9 @@ #ifndef SLI_H #define SLI_H -MODULE_EXPORT int sli_init (Driver *drvthis); +#include + +MODULE_EXPORT int sli_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void sli_close (Driver *drvthis); MODULE_EXPORT int sli_width (Driver *drvthis); MODULE_EXPORT int sli_height (Driver *drvthis); diff --git a/server/drivers/xosdlib_drv.c b/server/drivers/xosdlib_drv.c index edd0fe3a..771c9cde 100644 --- a/server/drivers/xosdlib_drv.c +++ b/server/drivers/xosdlib_drv.c @@ -44,6 +44,8 @@ #include "xosdlib_drv.h" #include "adv_bignum.h" +#include "../elektragen.h" + static char icon_char = '@'; @@ -61,17 +63,10 @@ MODULE_EXPORT char *symbol_prefix = "xosdlib_drv_"; * \retval <0 Error. */ MODULE_EXPORT int -xosdlib_drv_init (Driver *drvthis) +xosdlib_drv_init (Driver *drvthis, Elektra * elektra) { - const char *size; - const char *offset; - int x, y; - int tmp; - - PrivateData *p; - /* Allocate and store private data */ - p = (PrivateData *) calloc(1, sizeof(PrivateData)); + PrivateData *p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) return -1; if (drvthis->store_private_ptr(drvthis, p)) @@ -85,74 +80,53 @@ xosdlib_drv_init (Driver *drvthis) debug(RPT_DEBUG, "%s(%p)", __FUNCTION__, drvthis); - /* Read config file */ + /* Read config */ + XosdDriverConfig config; + elektraFillStructV(elektra, &config, CONF_XOSD, drvthis->index); /* Which size */ - if (drvthis->config_has_key(drvthis->name, "Size")) { - int w; - int h; - - size = drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE); - debug(RPT_INFO, "%s: Size (in config) is '%s'", __FUNCTION__, size); - if ((sscanf(size, "%dx%d", &w, &h) != 2) || - (w <= 0) || (w > LCD_MAX_WIDTH) || - (h <= 0) || (h > LCD_MAX_HEIGHT)) { - report(RPT_WARNING, "%s: cannot read Size: %s. using default %s", - drvthis->name, size, DEFAULT_SIZE); - sscanf(DEFAULT_SIZE, "%dx%d", &w, &h); - } - p->width = w; - p->height = h; - } - else { - /* Determine the size of the screen */ + if ((drvthis->request_display_width() > 0) + && (drvthis->request_display_height() > 0)) { + /* If this driver is secondary driver, use size from primary driver */ p->width = drvthis->request_display_width(); p->height = drvthis->request_display_height(); - if ((p->width <= 0) || (p->width >= LCD_MAX_WIDTH) || - (p->height <= 0) || (p->height >= LCD_MAX_HEIGHT)) { - p->width = LCD_DEFAULT_WIDTH; - p->height = LCD_DEFAULT_HEIGHT; + } + else { + /* Use our own size from config file */ + if ((sscanf(config.size , "%dx%d", &p->width, &p->height) != 2) + || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) + || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { + report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", + drvthis->name, config.size, DEFAULT_SIZE); + sscanf(DEFAULT_SIZE, "%dx%d", &p->width, &p->height); } } report(RPT_INFO, "%s: using size %dx%d", drvthis->name, p->width, p->height); /* Which x/y offsets */ - offset = drvthis->config_get_string(drvthis->name, "Offset", 0, DEFAULT_OFFSET); - debug(RPT_INFO, "%s: Offset (in config) is '%s'", __FUNCTION__, offset); - if (sscanf(offset, "%dx%d", &x, &y) != 2) { + debug(RPT_INFO, "%s: Offset (in config) is '%s'", __FUNCTION__, config.offset); + if (sscanf(config.offset, "%dx%d", &p->xoffs, &p->yoffs) != 2) { report(RPT_WARNING, "%s: cannot read Offset: %s. using default %s", - drvthis->name, offset, DEFAULT_OFFSET); - sscanf(DEFAULT_OFFSET, "%dx%d", &x, &y); + drvthis->name, config.offset, DEFAULT_OFFSET); + sscanf(DEFAULT_OFFSET, "%dx%d", &p->xoffs, &p->yoffs); } - p->xoffs= x; - p->yoffs = y; - report(RPT_INFO, "%s: using offset %dx%d", drvthis->name, p->xoffs, p->yoffs); /* Which backlight brightness */ - tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); - debug(RPT_INFO, "%s: Brightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: Brightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_BRIGHTNESS); - tmp = DEFAULT_BRIGHTNESS; - } - p->brightness = tmp; + debug(RPT_INFO, "%s: Brightness (in config) is '%d'", __FUNCTION__, config.brightness); + p->brightness = config.brightness; /* Which backlight-off "brightness" */ - tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS); - debug(RPT_INFO, "%s: OffBrightness (in config) is '%d'", __FUNCTION__, tmp); - if ((tmp < 0) || (tmp > 1000)) { - report(RPT_WARNING, "%s: OffBrightness must be between 0 and 1000; using default %d", - drvthis->name, DEFAULT_OFFBRIGHTNESS); - tmp = DEFAULT_OFFBRIGHTNESS; - } - p->offbrightness = tmp; + debug(RPT_INFO, "%s: OffBrightness (in config) is '%d'", __FUNCTION__, config.offbrightness); + p->offbrightness = config.offbrightness; + + /* Which contrast */ + debug(RPT_INFO, "%s: Contrast (in config) is '%d'", __FUNCTION__, config.contrast); + p->contrast = config.contrast; /* which font */ - strncpy(p->font, drvthis->config_get_string(drvthis->name, "Font", - 0, DEFAULT_FONT), sizeof(p->font)); + strncpy(p->font, config.font, sizeof(p->font)); p->font[sizeof(p->font) - 1] = '\0'; debug(RPT_INFO, "%s: Font (in config) is '%s'", __FUNCTION__, p->font); @@ -470,7 +444,6 @@ MODULE_EXPORT void xosdlib_drv_set_contrast (Driver *drvthis, int promille) { PrivateData *p = drvthis->private_data; - int contrast; /* Check it */ if (promille < 0 || promille > 1000) @@ -480,7 +453,7 @@ xosdlib_drv_set_contrast (Driver *drvthis, int promille) p->contrast = promille; /* map range [0, 1000] to [0, 255] */ - contrast = (p->contrast * 255) / 1000; + /* int contrast = (p->contrast * 255) / 1000; */ /* What to do with it ? */ } diff --git a/server/drivers/xosdlib_drv.h b/server/drivers/xosdlib_drv.h index 16bf9033..3a088213 100644 --- a/server/drivers/xosdlib_drv.h +++ b/server/drivers/xosdlib_drv.h @@ -2,6 +2,7 @@ #define LCD_XOSDLIB_H #include +#include #define DEFAULT_FONT "fixed" #define DEFAULT_SIZE "20x4" @@ -34,7 +35,7 @@ typedef struct xosd_private_data { } PrivateData; -MODULE_EXPORT int xosdlib_drv_init (Driver *drvthis); +MODULE_EXPORT int xosdlib_drv_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void xosdlib_drv_close (Driver *drvthis); MODULE_EXPORT int xosdlib_drv_width (Driver *drvthis); MODULE_EXPORT int xosdlib_drv_height (Driver *drvthis); diff --git a/server/drivers/yard2LCD.c b/server/drivers/yard2LCD.c index c95fc453..f93b0a69 100644 --- a/server/drivers/yard2LCD.c +++ b/server/drivers/yard2LCD.c @@ -257,7 +257,7 @@ yard_hwWriteCGRam(Driver *drvthis, unsigned char numChar, unsigned char *data) * Inits settings and connection */ MODULE_EXPORT int -yard_init(Driver *drvthis) +yard_init(Driver *drvthis, Elektra * elektra) { debug(RPT_DEBUG, "%s: Event 08 - Enter yard_init",drvthis->name); struct sockaddr_un srvAddr; diff --git a/server/drivers/yard2LCD.h b/server/drivers/yard2LCD.h index b10a3032..4eb7f41a 100644 --- a/server/drivers/yard2LCD.h +++ b/server/drivers/yard2LCD.h @@ -20,6 +20,8 @@ #ifndef yard2LCD_H #define yard2LCD_H +#include + #define MAX_YARDDATA_SIZE 40 #define DEFAULT_SOCK_PATH "/tmp/lcdserver" #define DEFAULT_OFF_BRIGHTNESS 100 @@ -37,7 +39,7 @@ #define NUM_CUSTOMCHARS 8 -MODULE_EXPORT int yard_init (Driver *drvthis); +MODULE_EXPORT int yard_init (Driver *drvthis, Elektra * elektra); MODULE_EXPORT void yard_close (Driver *drvthis); MODULE_EXPORT int yard_width (Driver *drvthis); MODULE_EXPORT int yard_height (Driver *drvthis); diff --git a/server/input.c b/server/input.c index 09f3dd8c..846e3e3b 100644 --- a/server/input.c +++ b/server/input.c @@ -17,7 +17,6 @@ #include "shared/sockets.h" #include "shared/report.h" -#include "shared/configfile.h" #include "shared/LL.h" #include "drivers.h" @@ -31,6 +30,7 @@ #include "input.h" #include "render.h" /* For server_msg* */ +#include "elektragen.h" LinkedList *keylist; char *toggle_rotate_key; @@ -44,18 +44,18 @@ int server_input(int key); void input_internal_key(const char *key); -int input_init(void) +int input_init(Elektra * elektra) { debug(RPT_DEBUG, "%s()", __FUNCTION__); keylist = LL_new(); /* Get rotate/scroll keys from config file */ - toggle_rotate_key = strdup(config_get_string("server", "ToggleRotateKey", 0, "Enter")); - prev_screen_key = strdup(config_get_string("server", "PrevScreenKey", 0, "Left")); - next_screen_key = strdup(config_get_string("server", "NextScreenKey", 0, "Right")); - scroll_up_key = strdup(config_get_string("server", "ScrollUpKey", 0, "Up")); - scroll_down_key = strdup(config_get_string("server", "ScrollDownKey", 0, "Down")); + toggle_rotate_key = strdup(elektraGet(elektra, CONF_SERVER_TOGGLEROTATEKEY)); + prev_screen_key = strdup(elektraGet(elektra, CONF_SERVER_PREVSCREENKEY)); + next_screen_key = strdup(elektraGet(elektra, CONF_SERVER_NEXTSCREENKEY)); + scroll_up_key = strdup(elektraGet(elektra, CONF_SERVER_SCROLLUPKEY)); + scroll_down_key = strdup(elektraGet(elektra, CONF_SERVER_SCROLLDOWNKEY)); return 0; } diff --git a/server/input.h b/server/input.h index 03d2c076..fe4b1aa7 100644 --- a/server/input.h +++ b/server/input.h @@ -21,6 +21,8 @@ #endif #include "shared/defines.h" +#include + /* Accepts and uses keypad input while displaying screens... */ void handle_input(void); @@ -31,7 +33,7 @@ typedef struct KeyReservation { } KeyReservation; -int input_init(void); +int input_init(Elektra * elektra); /* Init the input handling system */ void input_shutdown(void); diff --git a/server/main.c b/server/main.c index 35a08569..780e43c3 100644 --- a/server/main.c +++ b/server/main.c @@ -51,8 +51,8 @@ #endif /* TODO: fill in what to include otherwise */ -#include "shared/report.h" -#include "shared/defines.h" +#include +#include #include "drivers.h" #include "sock.h" @@ -64,10 +64,11 @@ #include "serverscreens.h" #include "menuscreens.h" #include "input.h" -#include "shared/configfile.h" #include "drivers.h" #include "main.h" +#include "elektragen.h" + #if !defined(SYSCONFDIR) # define SYSCONFDIR "/etc" #endif @@ -125,7 +126,6 @@ char user[64]; /* The values will be overwritten anyway... */ int frame_interval = DEFAULT_FRAME_INTERVAL; /* The drivers and their driver parameters */ -char *drivernames[MAX_DRIVERS]; int num_drivers = 0; /* End of configuration variables */ @@ -136,17 +136,17 @@ static int report_dest = UNSET_INT; static int report_level = UNSET_INT; static int stored_argc; -static char **stored_argv; +static const char **stored_argv; static volatile short got_reload_signal = 0; +static Elektra * elektra; + /* Local exported variables */ long timer = 0; /**** Local functions ****/ static void clear_settings(void); -static int process_command_line(int argc, char **argv); -static int process_configfile(char *cfgfile); -static void set_default_settings(void); +static int process_config(); static void install_signal_handlers(int allow_reload); static void child_ok_func(int signal); static pid_t daemonize(void); @@ -157,16 +157,20 @@ static void do_reload(void); static void do_mainloop(void); static void exit_program(int val); static void catch_reload_signal(int val); -static int interpret_boolean_arg(char *s); static void output_help_screen(void); static void output_GPL_notice(void); #define CHAIN(e,f) { if (e>=0) { e=(f); }} #define CHAIN_END(e,msg) { if (e<0) { report(RPT_CRIT,(msg)); exit(EXIT_FAILURE); }} +static const char * help_prefix = + "LCDd - LCDproc Server Daemon, "VERSION"\n\n" + "Copyright (c) 1998-2017 Selene Scriven, William Ferrell, and misc. contributors.\n" + "This program is released under the terms of the GNU General Public License.\n\n"; + int -main(int argc, char **argv) +main(int argc, const char **argv) { int e = 0; pid_t parent_pid = 0; @@ -201,17 +205,8 @@ main(int argc, char **argv) clear_settings(); - /* Read command line*/ - CHAIN(e, process_command_line(argc, argv)); - - /* Read config file - * If config file was not given on command line use default */ - if (strcmp(configfile, UNSET_STR) == 0) - strncpy(configfile, DEFAULT_CONFIGFILE, sizeof(configfile)); - CHAIN(e, process_configfile(configfile)); - - /* Set default values*/ - set_default_settings(); + /* Read config */ + CHAIN(e, process_config()); /* Set reporting settings (will also flush delayed reports) */ set_reporting("LCDd", report_level, report_dest); @@ -238,9 +233,9 @@ main(int argc, char **argv) CHAIN(e, screenlist_init()); CHAIN(e, init_drivers()); CHAIN(e, clients_init()); - CHAIN(e, input_init()); - CHAIN(e, menuscreens_init()); - CHAIN(e, server_screen_init()); + CHAIN(e, input_init(elektra)); + CHAIN(e, menuscreens_init(elektra)); + CHAIN(e, server_screen_init(elektra)); CHAIN_END(e, "Critical error while initializing, abort."); if (!foreground_mode) { /* Tell to parent that startup went OK. */ @@ -259,8 +254,6 @@ main(int argc, char **argv) static void clear_settings(void) { - int i; - debug(RPT_DEBUG, "%s()", __FUNCTION__); bind_port = UNSET_INT; @@ -276,271 +269,68 @@ clear_settings(void) default_duration = UNSET_INT; report_dest = UNSET_INT; report_level = UNSET_INT; - - for (i = 0; i < num_drivers; i++) { - free(drivernames[i]); - drivernames[i] = NULL; - } num_drivers = 0; } - -/* parses arguments given on command line */ -static int -process_command_line(int argc, char **argv) +static void on_fatal_error(ElektraError * error) // TODO: finalize method { - int c, b; - int e = 0, help = 0; - - debug(RPT_DEBUG, "%s(argc=%d, argv=...)", __FUNCTION__, argc); - - /* Reset getopt */ - opterr = 0; /* Prevent some messages to stderr */ - - /* Analyze options here.. (please try to keep list of options the - * same everywhere) */ - while ((c = getopt(argc, argv, "hc:d:fa:p:u:w:s:r:i:")) > 0) { - switch(c) { - case 'h': - help = 1; /* Continue to process the other - * options */ - break; - case 'c': - strncpy(configfile, optarg, sizeof(configfile)); - configfile[sizeof(configfile)-1] = '\0'; /* Terminate string */ - break; - case 'd': - /* Add to a list of drivers to be initialized later...*/ - if (num_drivers < MAX_DRIVERS) { - drivernames[num_drivers] = strdup(optarg); - if (drivernames[num_drivers] != NULL) { - num_drivers++; - } - else { - report(RPT_ERR, "alloc error storing driver name: %s", optarg); - e = -1; - } - } else { - report(RPT_ERR, "Too many drivers!"); - e = -1; - } - break; - case 'f': - foreground_mode = 1; - break; - case 'a': - strncpy(bind_addr, optarg, sizeof(bind_addr)); - bind_addr[sizeof(bind_addr)-1] = '\0'; /* Terminate string */ - break; - case 'p': - bind_port = atoi(optarg); - break; - case 'u': - strncpy(user, optarg, sizeof(user)); - user[sizeof(user)-1] = '\0'; /* Terminate string */ - break; - case 'w': - default_duration = (int) (atof(optarg) * 1e6 / frame_interval); - if (default_duration * frame_interval < 2e6) { - report(RPT_ERR, "Waittime should be at least 2 (seconds), not %.8s", optarg); - e = -1; - } - break; - case 's': - b = interpret_boolean_arg(optarg); - if (b == -1) { - report(RPT_ERR, "Not a boolean value: '%s'", optarg); - e = -1; - } else { - report_dest = (b) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; - } - break; - case 'r': - report_level = atoi(optarg); - break; - case 'i': - b = interpret_boolean_arg(optarg); - if (b == -1) { - report(RPT_ERR, "Not a boolean value: '%s'", optarg); - e = -1; - } else { - rotate_server_screen = b; - } - break; - case '?': - /* For some reason getopt also returns an '?' - * when an option argument is mission... */ - report(RPT_ERR, "Unknown option: '%c'", optopt); - e = -1; - break; - case ':': - report(RPT_ERR, "Missing option argument!"); - e = -1; - break; - } - } - - if (optind < argc) { - report(RPT_ERR, "Non-option arguments on the command line !"); - e = -1; - } - if (help) { - output_help_screen(); - e = -1; - } - return e; + fprintf(stderr, "ERROR: %s\n", elektraErrorDescription(error)); + exit(EXIT_FAILURE); } -/* reads and parses configuration file */ +/* reads and parses configuration */ static int -process_configfile(char *configfile) +process_config() { debug(RPT_DEBUG, "%s()", __FUNCTION__); - /* Read server settings*/ + ElektraError * error = NULL; + elektra = NULL; + int rc = loadConfiguration(&elektra, &error); - if (config_read_file(configfile) != 0) { - report(RPT_CRIT, "Could not read config file: %s", configfile); + if (rc == -1) + { + fprintf(stderr, "An error occurred while initializing elektra: %s\n", elektraErrorDescription(error)); + elektraErrorReset(&error); return -1; } - if (bind_port == UNSET_INT) - bind_port = config_get_int("Server", "Port", 0, UNSET_INT); - - if (strcmp(bind_addr, UNSET_STR) == 0) - strncpy(bind_addr, config_get_string("Server", "Bind", 0, UNSET_STR), sizeof(bind_addr)); - - if (strcmp(user, UNSET_STR) == 0) - strncpy(user, config_get_string("Server", "User", 0, UNSET_STR), sizeof(user)); - - if (default_duration == UNSET_INT) { - default_duration = (config_get_float("Server", "WaitTime", 0, 0) * 1e6 / frame_interval); - if (default_duration == 0) - default_duration = UNSET_INT; - else if (default_duration * frame_interval < 2e6) { - report(RPT_WARNING, "Waittime should be at least 2 (seconds). Set to 2 seconds."); - default_duration = 2e6 / frame_interval; - } + if (rc == 1) + { + // help mode + printHelpMessage(elektra, NULL, help_prefix); + elektraClose (elektra); + exit (EXIT_SUCCESS); } - if (foreground_mode == UNSET_INT) { - int fg = config_get_bool("Server", "Foreground", 0, UNSET_INT); + elektraFatalErrorHandler(elektra, on_fatal_error); - if (fg != UNSET_INT) - foreground_mode = fg; - } + bind_port = elektraGet(elektra, CONF_SERVER_PORT); + strncpy(bind_addr, elektraGet(elektra, CONF_SERVER_BIND), sizeof(bind_addr)); + strncpy(user, elektraGet(elektra, CONF_SERVER_USER), sizeof(user)); - if (rotate_server_screen == UNSET_INT) { - rotate_server_screen = config_get_tristate("Server", "ServerScreen", 0, "blank", UNSET_INT); + frame_interval = elektraGet(elektra, CONF_SERVER_FRAMEINTERVAL); + default_duration = elektraGet(elektra, CONF_SERVER_WAITTIME) * 1e6 / frame_interval; + if (default_duration * frame_interval < 2e6) { + report(RPT_WARNING, "Waittime should be at least 2 (seconds). Set to 2 seconds."); + default_duration = 2e6 / frame_interval; } - if (backlight == UNSET_INT) { - backlight = config_get_tristate("Server", "Backlight", 0, "open", UNSET_INT); - } - - if (heartbeat == UNSET_INT) { - heartbeat = config_get_tristate("Server", "Heartbeat", 0, "open", UNSET_INT); - } - - if (autorotate == UNSET_INT) { - autorotate = config_get_bool("Server", "AutoRotate", 0, DEFAULT_AUTOROTATE); - } - - if (titlespeed == UNSET_INT) { - int speed = config_get_int("Server", "TitleSpeed", 0, DEFAULT_TITLESPEED); - - /* set titlespeed */ - titlespeed = (speed <= TITLESPEED_NO) - ? TITLESPEED_NO - : min(speed, TITLESPEED_MAX); - } - - frame_interval = config_get_int("Server", "FrameInterval", 0, DEFAULT_FRAME_INTERVAL); - - if (report_dest == UNSET_INT) { - int rs = config_get_bool("Server", "ReportToSyslog", 0, UNSET_INT); + foreground_mode = elektraGet(elektra, CONF_SERVER_FOREGROUND); + rotate_server_screen = elektraGet(elektra, CONF_SERVER_SERVERSCREEN); + backlight = elektraGet(elektra, CONF_SERVER_BACKLIGHT); + heartbeat = elektraGet(elektra, CONF_SERVER_HEARTBEAT); + autorotate = elektraGet(elektra, CONF_SERVER_AUTOROTATE); - if (rs != UNSET_INT) - report_dest = (rs) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; - } - if (report_level == UNSET_INT) { - report_level = config_get_int("Server", "ReportLevel", 0, UNSET_INT); - } - - - /* Read drivers */ + titlespeed = elektraGet(elektra, CONF_SERVER_TITLESPEED); + report_dest = (elektraGet(elektra, CONF_SERVER_REPORTTOSYSLOG)) ? RPT_DEST_SYSLOG : RPT_DEST_STDERR; - /* If drivers have been specified on the command line, then do not - * use the driver list from the config file. - */ - if (num_drivers == 0) { - /* loop over all the Driver= directives to read the driver names */ - while (1) { - const char *s = config_get_string("Server", "Driver", num_drivers, NULL); - if (s == NULL) - break; - if (s[0] != '\0') { - drivernames[num_drivers] = strdup(s); - if (drivernames[num_drivers] == NULL) { - report(RPT_ERR, "alloc error storing driver name: %s", s); - exit(EXIT_FAILURE); - } - num_drivers++; - } - } - } + report_level = elektraGet(elektra, CONF_SERVER_REPORTLEVEL); return 0; } - -static void -set_default_settings(void) -{ - debug(RPT_DEBUG, "%s()", __FUNCTION__); - - /* Set defaults into unfilled variables... */ - - if (bind_port == UNSET_INT) - bind_port = DEFAULT_BIND_PORT; - if (strcmp(bind_addr, UNSET_STR) == 0) - strncpy(bind_addr, DEFAULT_BIND_ADDR, sizeof(bind_addr)); - if (strcmp(user, UNSET_STR) == 0) - strncpy(user, DEFAULT_USER, sizeof(user)); - - if (foreground_mode == UNSET_INT) - foreground_mode = DEFAULT_FOREGROUND_MODE; - if (rotate_server_screen == UNSET_INT) - rotate_server_screen = DEFAULT_ROTATE_SERVER_SCREEN; - - if (default_duration == UNSET_INT) - default_duration = DEFAULT_SCREEN_DURATION; - if (backlight == UNSET_INT) - backlight = DEFAULT_BACKLIGHT; - if (heartbeat == UNSET_INT) - heartbeat = DEFAULT_HEARTBEAT; - if (titlespeed == UNSET_INT) - titlespeed = DEFAULT_TITLESPEED; - - if (report_dest == UNSET_INT) - report_dest = DEFAULT_REPORTDEST; - if (report_level == UNSET_INT) - report_level = DEFAULT_REPORTLEVEL; - - - /* Use default driver */ - if (num_drivers == 0) { - drivernames[0] = strdup(DEFAULT_DRIVER); - if (drivernames[0] == NULL) { - report(RPT_ERR, "alloc error storing driver name: %s", DEFAULT_DRIVER); - exit(EXIT_FAILURE); - } - num_drivers = 1; - } -} - - static void install_signal_handlers(int allow_reload) { @@ -663,20 +453,27 @@ wave_to_parent(pid_t parent_pid) static int init_drivers(void) { - int i, res; + int res; debug(RPT_DEBUG, "%s()", __FUNCTION__); - for (i = 0; i < num_drivers; i++) { + /* Read drivers */ + num_drivers = elektraSize(elektra, CONF_SERVER_DRIVERS); + for (kdb_long_long_t i = 0; i < num_drivers; ++i) { + if(i > MAX_DRIVERS) + { + report(RPT_ERR, "too many driver; max = %d", MAX_DRIVERS); + exit(EXIT_FAILURE); + } - res = drivers_load_driver(drivernames[i]); + res = drivers_load_driver(elektra, i); if (res >= 0) { /* Load went OK */ if (res == 2) foreground_mode = 1; } else { - report(RPT_ERR, "Could not load driver %.40s", drivernames[i]); + report(RPT_ERR, "Could not load driver #"ELEKTRA_LONG_LONG_F, i); } } @@ -719,19 +516,11 @@ do_reload(void) drivers_unload_all(); /* Close all drivers */ - config_clear(); clear_settings(); - /* Reread command line*/ - CHAIN(e, process_command_line(stored_argc, stored_argv)); - - /* Reread config file */ - if (strcmp(configfile, UNSET_STR)==0) - strncpy(configfile, DEFAULT_CONFIGFILE, sizeof(configfile)); - CHAIN(e, process_configfile(configfile)); - - /* Set default values */ - CHAIN(e, (set_default_settings(), 0)); + elektraClose(elektra); + /* Reread config */ + CHAIN(e, process_config()); /* Set reporting values */ CHAIN(e, set_reporting("LCDd", report_level, report_dest)); @@ -857,7 +646,7 @@ exit_program(int val) report_dest = DEFAULT_REPORTDEST; set_reporting("LCDd", report_level, report_dest); - goodbye_screen(); /* display goodbye screen on LCD display */ + goodbye_screen(elektra); /* display goodbye screen on LCD display */ drivers_unload_all(); /* release driver memory and file descriptors */ /* Shutdown things if server start was complete */ @@ -867,6 +656,8 @@ exit_program(int val) input_shutdown(); /* shutdown key input part */ sock_shutdown(); /* shutdown the sockets server */ + elektraClose(elektra); + report(RPT_INFO, "Exiting."); _exit(EXIT_SUCCESS); } @@ -881,25 +672,6 @@ catch_reload_signal(int val) } -static int -interpret_boolean_arg(char *s) -{ - /* keep these checks consistent with config_get_boolean() */ - if (strcasecmp(s, "0") == 0 || strcasecmp(s, "false") == 0 - || strcasecmp(s, "n") == 0 || strcasecmp(s, "no") == 0 - || strcasecmp(s, "off") == 0) { - return 0; - } - if (strcasecmp(s, "1") == 0 || strcasecmp(s, "true") == 0 - || strcasecmp(s, "y") == 0 || strcasecmp(s, "yes") == 0 - || strcasecmp(s, "on") == 0) { - return 1; - } - /* no legal boolean string given */ - return -1; -} - - static void output_GPL_notice(void) { @@ -926,40 +698,3 @@ output_GPL_notice(void) "Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n"); } - -static void -output_help_screen(void) -{ - /* Help screen is printed to stdout on purpose. No reason to have - * this in syslog... - */ - debug(RPT_DEBUG, "%s()", __FUNCTION__); - - fprintf(stdout, "LCDd - LCDproc Server Daemon, %s\n\n", version); - fprintf(stdout, "Copyright (c) 1998-2017 Selene Scriven, William Ferrell, and misc. contributors.\n"); - fprintf(stdout, "This program is released under the terms of the GNU General Public License.\n\n"); - fprintf(stdout, "Usage: LCDd []\n"); - fprintf(stdout, " where are:\n"); - fprintf(stdout, " -h Display this help screen\n"); - fprintf(stdout, " -c Use a configuration file other than %s\n", - DEFAULT_CONFIGFILE); - fprintf(stdout, " -d Add a driver to use (overrides drivers in config file) [%s]\n", - DEFAULT_DRIVER); - fprintf(stdout, " -f Run in the foreground\n"); - fprintf(stdout, " -a Network (IP) address to bind to [%s]\n", - DEFAULT_BIND_ADDR); - fprintf(stdout, " -p Network port to listen for connections on [%i]\n", - DEFAULT_BIND_PORT); - fprintf(stdout, " -u User to run as [%s]\n", - DEFAULT_USER); - fprintf(stdout, " -w Time to pause at each screen (in seconds) [%d]\n", - (int) ((DEFAULT_SCREEN_DURATION * frame_interval) / 1e6)); - fprintf(stdout, " -s If set, reporting will be done using syslog\n"); - fprintf(stdout, " -r Report level [%d]\n", - DEFAULT_REPORTLEVEL); - fprintf(stdout, " -i Whether to rotate the server info screen\n"); - - /* Error messages will be flushed to the configured output after this - * help message. - */ -} diff --git a/server/main.h b/server/main.h index e2491bb0..622f9dcd 100644 --- a/server/main.h +++ b/server/main.h @@ -51,7 +51,6 @@ extern char user[]; /* The values will be overwritten anyway... */ extern int frame_interval; /* Not a command line option, but could be */ /* The drivers and their driver parameters */ -extern char *drivernames[]; extern int num_drivers; /* End of configuration variables */ diff --git a/server/menu.c b/server/menu.c index 56f27a9b..50d32adc 100644 --- a/server/menu.c +++ b/server/menu.c @@ -393,7 +393,7 @@ void menu_build_screen(MenuItem *menu, Screen *s) subitem != NULL; subitem = LL_GetNext(menu->data.menu.contents), itemnr ++) { - char buf[10]; + char buf[20]; if (subitem->is_hidden) continue; diff --git a/server/menuscreens.c b/server/menuscreens.c index b5cae936..ec217547 100644 --- a/server/menuscreens.c +++ b/server/menuscreens.c @@ -29,7 +29,6 @@ #include "screen.h" #include "screenlist.h" #include "menuscreens.h" -#include "shared/configfile.h" #include "shared/report.h" #include "input.h" #include "driver.h" @@ -42,6 +41,8 @@ /* Next include files are needed for settings that we can modify */ #include "render.h" +#include "elektragen.h" + char *menu_key; char *enter_key; @@ -78,13 +79,13 @@ MenuEventFunc(contrast_handler); MenuEventFunc(brightness_handler); int -menuscreens_init(void) +menuscreens_init(Elektra * elektra) { const char *tmp; debug(RPT_DEBUG, "%s()", __FUNCTION__); - menu_permissive_goto = config_get_bool("menu", "PermissiveGoto", 0, 0); + menu_permissive_goto = elektraGet(elektra, CONF_MENU_PERMISSIVEGOTO); /* * Get keys from config file: MenuKey, EnterKey, UpKey, DownKey, @@ -93,53 +94,53 @@ menuscreens_init(void) */ keymask = 0; menu_key = enter_key = NULL; - tmp = config_get_string("menu", "MenuKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_MENUKEY); + if (strlen(tmp) > 0) { menu_key = strdup(tmp); keymask |= MENUTOKEN_MENU; } - tmp = config_get_string("menu", "EnterKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_ENTERKEY); + if (strlen(tmp) > 0) { enter_key = strdup(tmp); keymask |= MENUTOKEN_ENTER; } up_key = down_key = NULL; - tmp = config_get_string("menu", "UpKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_UPKEY); + if (strlen(tmp) > 0) { up_key = strdup(tmp); keymask |= MENUTOKEN_UP; } - tmp = config_get_string("menu", "DownKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_DOWNKEY); + if (strlen(tmp) > 0) { down_key = strdup(tmp); keymask |= MENUTOKEN_DOWN; } left_key = right_key = NULL; - tmp = config_get_string("menu", "LeftKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_LEFTKEY); + if (strlen(tmp) > 0) { left_key = strdup(tmp); keymask |= MENUTOKEN_LEFT; } - tmp = config_get_string("menu", "RightKey", 0, NULL); - if (tmp != NULL) { + tmp = elektraGet(elektra, CONF_MENU_RIGHTKEY); + if (strlen(tmp) > 0) { right_key = strdup(tmp); keymask |= MENUTOKEN_RIGHT; } /* Now reserve the keys that were defined */ - if (menu_key != NULL) + if (keymask & MENUTOKEN_MENU) input_reserve_key(menu_key, true, NULL); - if (enter_key != NULL) + if (keymask & MENUTOKEN_ENTER) input_reserve_key(enter_key, false, NULL); - if (up_key != NULL) + if (keymask & MENUTOKEN_UP) input_reserve_key(up_key, false, NULL); - if (down_key != NULL) + if (keymask & MENUTOKEN_DOWN) input_reserve_key(down_key, false, NULL); - if (left_key != NULL) + if (keymask & MENUTOKEN_LEFT) input_reserve_key(left_key, false, NULL); - if (right_key != NULL) + if (keymask & MENUTOKEN_RIGHT) input_reserve_key(right_key, false, NULL); /* Create screen */ diff --git a/server/menuscreens.h b/server/menuscreens.h index 1984585a..0ca6f6ac 100644 --- a/server/menuscreens.h +++ b/server/menuscreens.h @@ -18,10 +18,12 @@ #include "menu.h" #include "screen.h" +#include + extern Screen *menuscreen; extern Menu *main_menu; -int menuscreens_init(void); +int menuscreens_init(Elektra * elektra); int menuscreens_shutdown(void); diff --git a/server/serverscreens.c b/server/serverscreens.c index 0e31ab4f..91b56028 100644 --- a/server/serverscreens.c +++ b/server/serverscreens.c @@ -29,7 +29,6 @@ #endif #include "shared/report.h" -#include "shared/configfile.h" #include "drivers.h" #include "clients.h" @@ -40,6 +39,8 @@ #include "main.h" #include "serverscreens.h" +#include "elektragen.h" + /* global variables */ Screen *server_screen = NULL; @@ -58,12 +59,13 @@ static int reset_server_screen(int rotate, int heartbeat, int title); * 0 otherwise. */ int -server_screen_init(void) +server_screen_init(Elektra * elektra) { Widget *w; int i; - has_hello_msg = config_has_key("Server", "Hello"); + kdb_long_long_t helloArraySize = elektraSize(elektra, CONF_SERVER_GOODBYE); + has_hello_msg = helloArraySize > 0; debug(RPT_DEBUG, "%s()", __FUNCTION__); @@ -78,7 +80,7 @@ server_screen_init(void) /* Create all the widgets...*/ for (i = 0; i < display_props->height; i++) { - char id[8]; + char id[20]; sprintf(id, "line%d", i+1); w = widget_create(id, WID_STRING, server_screen); @@ -97,13 +99,11 @@ server_screen_init(void) /* set the widgets depending on the Hello option in LCDd.conf */ if (has_hello_msg) { /* show whole Hello message */ - int i; - - for (i = 0; i < display_props->height; i++) { - const char *line = config_get_string("Server", "Hello", i, ""); - char id[8]; + for (kdb_long_long_t i = 0; i < display_props->height && i < helloArraySize; i++) { + const char *line = elektraGetV(elektra, CONF_SERVER_HELLO, i); + char id[30]; - sprintf(id, "line%d", i+1); + sprintf(id, "line"ELEKTRA_LONG_LONG_F, i+1); w = screen_find_widget(server_screen, id); if ((w != NULL) && (w->text != NULL)) { strncpy(w->text, line, LCD_MAX_WIDTH); @@ -211,19 +211,18 @@ update_server_screen(void) * \return Always 0. */ int -goodbye_screen(void) +goodbye_screen(Elektra * elektra) { if (!display_props) return 0; drivers_clear(); - if (config_has_key("Server", "GoodBye")) { /* custom GoodBye */ - int i; - + kdb_long_long_t arraySize = elektraSize(elektra, CONF_SERVER_GOODBYE); + if (arraySize > 0) { /* custom GoodBye */ /* loop over all display lines to read config & display message */ - for (i = 0; i < display_props->height; i++) { - const char *line = config_get_string("Server", "GoodBye", i, ""); + for (kdb_long_long_t i = 0; i < display_props->height && i < arraySize; i++) { + const char *line = elektraGetV(elektra, CONF_SERVER_GOODBYE, i); drivers_string(1, 1+i, line); } @@ -276,7 +275,7 @@ reset_server_screen(int rotate, int heartbeat, int title) ? PRI_INFO : PRI_BACKGROUND; for (i = 0; i < display_props->height; i++) { - char id[8]; + char id[20]; Widget *w; sprintf(id, "line%d", i+1); diff --git a/server/serverscreens.h b/server/serverscreens.h index 756394aa..ed7030a3 100644 --- a/server/serverscreens.h +++ b/server/serverscreens.h @@ -15,6 +15,8 @@ #include "screen.h" +#include + /* server screen rotation states */ #define SERVERSCREEN_OFF 0 /**< Show server screen in rotation. */ #define SERVERSCREEN_ON 1 /**< Show server sreen only when there is no other screen. */ @@ -24,9 +26,9 @@ extern Screen *server_screen; extern int rotate_server_screen; -int server_screen_init(void); +int server_screen_init(Elektra * elektra); int server_screen_shutdown(void); int update_server_screen(void); -int goodbye_screen(void); +int goodbye_screen(Elektra * elektra); #endif diff --git a/server/specification/LCDd-spec.ini b/server/specification/LCDd-spec.ini new file mode 100644 index 00000000..ade30d2c --- /dev/null +++ b/server/specification/LCDd-spec.ini @@ -0,0 +1,1744 @@ +[] +mountpoint = LCDd.conf +infos/plugins = ni type reference range ; hexnumber network path + +; TODO (elektra): Until the max plugin error is not fixed, some specifications will be left commented out + +;============================================================================= +;============================================================================= + +;Server +;---------------------------------------- +[server/driverpath] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = $ORIGIN/drivers/ +description = Select the LCD size + +[server/drivers] +default = "" +array = #0 ; TODO (kodebach): max drivers ?? +check/reference = single +check/reference/restrict = #_14 +check/reference/restrict/#0 = @/bayrad/# +check/reference/restrict/#1 = @/cfontz/# +check/reference/restrict/#2 = @/cfontzpacket/# +check/reference/restrict/#3 = @/curses/# +check/reference/restrict/#4 = @/cwlnx/# +check/reference/restrict/#5 = @/glcd/# +check/reference/restrict/#6 = @/glk/# +check/reference/restrict/#7 = @/hd44780/# +check/reference/restrict/#8 = @/lb216/# +check/reference/restrict/#9 = @/lcdm001/# +check/reference/restrict/#_10 = @/linux_input/# +check/reference/restrict/#_11 = @/mtxorb/# +check/reference/restrict/#_12 = @/pyramid/# +check/reference/restrict/#_13 = @/text/# +check/reference/restrict/#_14 = @/xosd/# +description = "Tells the server to load a driver. +The given value is a reference the configuration of the driver, e.g. @/curses/#0" + +[server/drivers/#] +type = string +check/type = string +require = + +[server/bind] +type = string +; check/ipaddr = ; TODO (elektra): too many plugins +check/type = string +default = 127.0.0.1 +description = Tells the driver to bind to the given interface +opt = a +opt/long = address + +[server/port] +type = unsigned_short +; check/port = ; TODO (elektra): too many plugins +; check/port/listen = ; TODO (elektra): too many plugins +check/type = unsigned_short +default = 13666 +description = Listen on this specified port. [default: 13666] +opt = p +opt/long = port + +[server/reportlevel] +type = unsigned_short +check/type = unsigned_short +check/range = 0-5 +default = 2 +description = Sets the reporting level, defaults to warnings and errors only. +opt = r +opt/long = report-level + +[server/reporttosyslog] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Should we report to syslog instead of stderr? +opt = s +opt/long = report-to-syslog +opt/arg = none + +[server/user] +type = string +check/type = string +default = nobody +description = "set to run as. LCDd will drop its root privileges and run as this user instead. [default: nobody]" +opt = u +opt/long = user + +[server/foreground] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = The server will stay in the foreground if set to yes +opt = f +opt/long = foreground +opt/arg = none + +[server/hello/#] +type = string +check/type = string +default = "" +description = "Hello message: each entry represents a display line" + +[server/goodbye/#] +type = string +check/type = string +default = "" +description = "GoodBye message: each entry represents a display line" + +[server/frameinterval] +type = unsigned_long +check/type = unsigned_long +; check/range = 1- ; TODO (kodebach): open ranges +default = 125000 +description = "Sets the interval in microseconds for updating the display [default: 125000 meaning 8Hz]" + +[server/waittime] +type = float +check/type = float +; TODO (kodebach): bigger than 2 +default = 4 +description = Sets the default time in seconds to displays a screen +opt = w +opt/long = wait-time + +[server/autorotate] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = If set to no, LCDd will start with screen rotation disabled. This has the\ +same effect as if the ToggleRotateKey had been pressed. Rotation will start\ +if the ToggleRotateKey is pressed. Note that this setting does not turn off\ +priority sorting of screens + +[server/serverscreen] +type = enum +check/enum = #2 +check/enum/#0 = off +check/enum/#1 = on +check/enum/#2 = blank +default = on +description = If yes, the the serverscreen will be rotated as a usual info screen. If no,\ +it will be a background screen, only visible when no other screens are\ +active. The special value 'blank' is similar to no, but only a blank screen\ +is displayed. +opt = i +opt/long = rotate-server-screen + +[server/backlight] +type = enum +check/enum = #2 +check/enum/#0 = off +check/enum/#1 = on +check/enum/#2 = open +default = open +description = Set master backlight setting. If set to 'open' a client may control the\ +backlight for its own screens (only) + +[server/heartbeat] +type = enum +check/enum = #2 +check/enum/#0 = off +check/enum/#1 = on +check/enum/#2 = open +default = open +description = Set master heartbeat setting. If set to 'open' a client may control the +heartbeat for its own screens (only) + +[server/titlespeed] +type = unsigned_short +check/range = 0-10 +default = 10 +description = title scrolling speed + +[server/togglerotatekey] +type = string +check/type = string +default = Enter +description = "The '...Key=' lines define what the server does with keypresses that +don't go to any client. The ToggleRotateKey stops rotation of screens, while +the PrevScreenKey and NextScreenKey go back / forward one screen (even if +rotation is disabled. +Assign the key string returned by the driver to the ...Key setting." + +[server/prevscreenkey] +type = string +check/type = string +default = Left +description = "The '...Key=' lines define what the server does with keypresses that +don't go to any client. The ToggleRotateKey stops rotation of screens, while +the PrevScreenKey and NextScreenKey go back / forward one screen (even if +rotation is disabled. +Assign the key string returned by the driver to the ...Key setting." + +[server/nextscreenkey] +type = string +check/type = string +default = Right +description = "The '...Key=' lines define what the server does with keypresses that +don't go to any client. The ToggleRotateKey stops rotation of screens, while +the PrevScreenKey and NextScreenKey go back / forward one screen (even if +rotation is disabled. +Assign the key string returned by the driver to the ...Key setting." + +[server/scrollupkey] +type = string +check/type = string +default = Up +description = "The '...Key=' lines define what the server does with keypresses that +don't go to any client. The ToggleRotateKey stops rotation of screens, while +the PrevScreenKey and NextScreenKey go back / forward one screen (even if +rotation is disabled. +Assign the key string returned by the driver to the ...Key setting." + +[server/scrolldownkey] +type = string +check/type = string +default = Down +description = "The '...Key=' lines define what the server does with keypresses that +don't go to any client. The ToggleRotateKey stops rotation of screens, while +the PrevScreenKey and NextScreenKey go back / forward one screen (even if +rotation is disabled. +Assign the key string returned by the driver to the ...Key setting." + + +;Menu +;================================================== +[menu/permissivegoto] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = If true the server allows transitions between different client`s menus + +[menu/menukey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + +[menu/enterkey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + +[menu/upkey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + +[menu/downkey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + +[menu/leftkey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + +[menu/rightkey] +type = string +check/type = any +default = "" +description = "Up to six keys are supported. The MenuKey (to enter and exit the menu), the +EnterKey (to select values) and at least one movement keys are required." + + + +;bayrad +;================================================== +[bayrad] +default = "" +array = #0 + +[bayrad/#] +type = struct +check/type = any +default = "" +gen/struct/type = BayradDriverConfig +gen/struct/alloc = 0 +description = Configuration for a bayrad driver. + +[bayrad/#/file] +type = string +default = "bayrad" +description = name of the shared library to load (without prefix and extension) + +[bayrad/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = Select the output device to use + +[bayrad/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200 +default = 9600 +description = Set the communication speed + +;CFontz +;================================================== +[cfontz] +default = "" +array = #0 + +[cfontz/#] +type = struct +check/type = any +default = "" +gen/struct/type = CFontzDriverConfig +gen/struct/alloc = 0 +description = Configuration for a CFontz driver. + +[cfontz/#/file] +type = string +default = "CFontz" +description = name of the shared library to load (without prefix and extension) + +[cfontz/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 350 +check/range = 0-1000 +description = Set the initial contrast + +[cfontz/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial brightness + +[cfontz/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = Set the initial off-brightness.\ +This value is used when the display is normally\ +switched off in case LCDd is inactive + +[cfontz/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[cfontz/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = Select the output device to use + +[cfontz/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = Select the LCD size + +[cfontz/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200, 115200 +default = 9600 +description = Set the communication speed + +[cfontz/#/newfirmware] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Set the firmware version (New means >= 2.0)" + +[cfontz/#/usb] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Is this driver using USB?" + +;CFontzPacket +;================================================== +[cfontzpacket] +default = "" +array = #0 + +[cfontzpacket/#] +type = struct +check/type = any +default = "" +gen/struct/type = CFontzPacketDriverConfig +gen/struct/alloc = 0 +description = Configuration for a CFontzPacket driver. + +[cfontzpacket/#/file] +type = string +default = "CFontzPacket" +description = name of the shared library to load (without prefix and extension) + +[cfontzpacket/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 350 +check/range = 0-1000 +description = Set the initial contrast + +[cfontzpacket/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial brightness + +[cfontzpacket/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = Set the initial off-brightness.\ +This value is used when the display is normally\ +switched off in case LCDd is inactive + +[cfontzpacket/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[cfontzpacket/#/model] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = 533 +check/enum/#1 = 631 +check/enum/#2 = 633 +check/enum/#3 = 635 +gen/enum/type = CFontzPacketModel +default = 633 +description = Select the LCD model + +[cfontzpacket/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +;description = Select the output device to use + +[cfontzpacket/#/usb] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Enable the USB flag if the device is connected to an USB port. For serial ports leave it disabled. + +[cfontzpacket/#/oldfirmware] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Very old 633 firmware versions do not support partial screen updates using\ +'Send Data to LCD' command (31). For those devices it may be necessary to\ +enable this flag + +[cfontzpacket/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = Override the LCD size known for the selected model. Usually setting this value should not be necessary. + +[cfontzpacket/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 19200, 115200 +default = 115200 +description = Override the default communication speed known for the selected model. Default value depends on model. + +;curses +;================================================== +[curses] +default = "" +array = #0 + +[curses/#] +type = struct +check/type = any +default = "" +gen/struct/type = CursesDriverConfig +gen/struct/alloc = 0 +description = Configuration for a curses driver. + +[curses/#/file] +type = string +default = "curses" +description = name of the shared library to load (without prefix and extension) + +[curses/#/foreground] +type = enum +check/type = enum +check/enum = #7 +check/enum/#0 = red +check/enum/#1 = black +check/enum/#2 = green +check/enum/#3 = yellow +check/enum/#4 = blue +check/enum/#5 = magenta +check/enum/#6 = cyan +check/enum/#7 = white +gen/enum/type = CursesColor +default = blue +description = Color settings + +[curses/#/background] +type = enum +check/type = enum +check/enum = #7 +check/enum/#0 = red +check/enum/#1 = black +check/enum/#2 = green +check/enum/#3 = yellow +check/enum/#4 = blue +check/enum/#5 = magenta +check/enum/#6 = cyan +check/enum/#7 = white +gen/enum/type = CursesColor +default = cyan +description = background color when "backlight" is off + +[curses/#/backlight] +type = enum +check/type = enum +check/enum = #7 +check/enum/#0 = red +check/enum/#1 = black +check/enum/#2 = green +check/enum/#3 = yellow +check/enum/#4 = blue +check/enum/#5 = magenta +check/enum/#6 = cyan +check/enum/#7 = white +gen/enum/type = CursesColor +default = red +description = background color when "backlight" is on + +[curses/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = display size + +[curses/#/topleftx] +type = unsigned_short +check/type = unsigned_short +default = 7 +description = What position (X,Y) to start the left top corner at... + +[curses/#/toplefty] +type = unsigned_short +check/type = unsigned_short +default = 7 +description = What position (X,Y) to start the left top corner at... + +[curses/#/useacs] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = use ASC symbols for icons & bars + +[curses/#/drawborder] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = draw Border + +;CwLnx +;================================================== +[cwlnx] +default = "" +array = #0 + +[cwlnx/#] +type = struct +check/type = any +default = "" +gen/struct/type = CwLnxDriverConfig +gen/struct/alloc = 0 +description = Configuration for a CwLnx driver. + +[cwlnx/#/file] +type = string +default = "CwLnx" +description = name of the shared library to load (without prefix and extension) + +[cwlnx/#/model] +type = enum +check/type = enum +check/enum = #2 +check/enum/#0 = 12232 +check/enum/#1 = 12832 +check/enum/#2 = 1602 +gen/enum/type = CwLnxModel +default = 12232 +description = Select the LCD model + +[cwlnx/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = Select the output device to use + +[cwlnx/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "Select the LCD size. Default depends on model: \n12232: 20x4 \n12832: 21x4 \n1602: 16x2" + +[cwlnx/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 9600, 19200 +default = 19200 +description = Set the communication speed + +[cwlnx/#/keypad] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = If you have a keypad connected. Keypad layout is currently not configureable from the config file. + +[cwlnx/#/keymap_a] +type = string +check/type = string +default = Up +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[cwlnx/#/keymap_b] +type = string +check/type = string +default = Down +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[cwlnx/#/keymap_c] +type = string +check/type = string +default = Left +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[cwlnx/#/keymap_d] +type = string +check/type = string +default = Right +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[cwlnx/#/keymap_e] +type = string +check/type = string +default = Enter +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[cwlnx/#/keymap_f] +type = string +check/type = string +default = Escape +description = "If you have a non-standard keypad you can associate any keystrings to keys. +There are 6 input keys in the CwLnx hardware that generate characters +from 'A' to 'F'.\n +The built-in default mapping hardcoded in the driver. +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + + +[cwlnx/#/keypad_test_mode] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = permits one to test keypad assignment + +;glk +;================================================== +[glk] +default = "" +array = #0 + +[glk/#] +type = struct +check/type = any +default = "" +gen/struct/type = GlkDriverConfig +gen/struct/alloc = 0 +description = Configuration for a glk driver. + +[glk/#/file] +type = string +default = "glk" +description = name of the shared library to load (without prefix and extension) + +[glk/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 500 +check/range = 0-1000 +description = Set the initial contrast + +[glk/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "select the serial device to use" + +[glk/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 9600, 19200, 38400, 57600, 115200 +default = 19200 +description = set the serial port speed + +;hd44780 +;================================================== +[hd44780] +default = "" +array = #0 + +[hd44780/#] +type = struct +check/type = any +default = "" +gen/struct/type = Hd44780DriverConfig +gen/struct/alloc = 0 +gen/struct/depth = 2 +description = Configuration for a hd44780 driver. + +[hd44780/#/file] +type = string +default = "hd44780" +description = name of the shared library to load (without prefix and extension) + +[hd44780/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 800 +check/range = 0-1000 +description = Set the initial contrast + +[hd44780/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 800 +check/range = 0-1000 + +[hd44780/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 300 +check/range = 0-1000 + +[hd44780/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[hd44780/#/connectiontype] +type = enum +check/type = enum +check/enum = #_27 +check/enum/#0 = 4bit +check/enum/#1 = 8bit +check/enum/#2 = winamp +check/enum/#3 = lcm162 +check/enum/#4 = serialLpt +check/enum/#5 = picanlcd +check/enum/#6 = lcdserializer +check/enum/#7 = los-panel +check/enum/#8 = vdr-lcd +check/enum/#9 = vdr-wakeup +check/enum/#_10 = ezio +check/enum/#_11 = pertelian +check/enum/#_12 = lis2 +check/enum/#_13 = mplay +check/enum/#_14 = usblcd +check/enum/#_15 = bwctusb +check/enum/#_16 = lcd2usb +check/enum/#_17 = usbtiny +check/enum/#_18 = uss720 +check/enum/#_19 = USB-4-all +check/enum/#_20 = ftdi +check/enum/#_21 = i2c +check/enum/#_22 = piplate +check/enum/#_23 = spi +check/enum/#_24 = pifacecad +check/enum/#_25 = ethlcd +check/enum/#_26 = raspberrypi +check/enum/#_27 = gpio +gen/enum/type = Hd44780ConnectionType +default = 4bit +description = "Select what type of connection. See documentation for available types: + https://github.com/lcdproc/lcdproc/blob/master/docs/lcdproc-user/drivers/hd44780.docbook" + +[hd44780/#/model] +type = enum +check/type = enum +check/enum = #7 +check/enum/#0 = default +check/enum/#1 = standard +check/enum/#2 = extended +check/enum/#3 = ks0073 +check/enum/#4 = hd66710 +check/enum/#5 = winstar_oled +check/enum/#6 = weh00xxyya +check/enum/#7 = pt6314_vfd +default = standard +description = "Select model if have non-standard one which require extra initialization or handling or + just want extra features it offers. + Available: standard (default), extended, winstar_oled, pt6314_vfd + - standard is default, use for LCDs not mentioned below. + - extended, hd66712, ks0073: allows use 4-line 'extended' mode, + same as deprecated now option ExtendedMode=yes + - winstar_oled, weh00xxyya: changes initialization for WINSTAR's WEH00xxyyA displays + and allows handling brightness + - pt6314_vfd: allows handling brightness on PTC's PT6314 VFDs + This option should be independent of connection type." + +[hd44780/#/port] +type = string +check/type = string +check/validation = 0x[0-9A-F]{3} +check/validation/match = LINE +check/validation/message = Port must begin with "0x", followed by 3 Hexadezimal values, eg. 0x3BC +default = 0x378 +description = I/O address of the LPT port. Usual values are: 0x278, 0x378 and 0x3BC.\ + For I2C connections this sets the slave address (usually 0x20). + +[hd44780/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = "" +description = "Device of the serial, I2C, or SPI interface (default is connectiontype dependent)" + +[hd44780/#/speed] +type = unsigned_long +check/type = unsigned_long +default = 0 +description = "Bitrate of the serial port (0 for interface default)" + +[hd44780/#/keypad] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "If you have a keypad connected. +You may also need to configure the keypad layout further on in this file." + +[hd44780/#/backlight] +type = enum +check/type = enum +check/enum = #2 +check/enum/#0 = default +check/enum/#1 = enabled +check/enum/#2 = disabled +default = default +description = "Whether or not a switchable backlight is be used. If 'default' is chosen, +the value is model dependent. On Winstar OLED and PT6314 VFD, it is 'enabled' on other models +it is 'disabled'." + +[hd44780/#/backlightmode] +array = +default = "" + +[hd44780/#/backlightmode/#] +type = enum +check/type = enum +check/enum = #2 +check/enum/#0 = external +check/enum/#1 = internal +check/enum/#2 = internalCmds +require = +description = "If the switchable backlight is enabled (see hd44780/#/backlight), this value +determines which method for turning it on/off will be used. +# +The supported methods are: +- external - use external pin or any other method defined with ConnectionType backlight + handling. +- internal - means that backlight is handled using internal commands according + to selected display model (with Model option). Depending on model, + Brightness and OffBrightness options can be taken into account. +- internalCmds - means that commands for turning on and off backlight are given + with extra options BacklightOnCmd and BacklightOffCmd, which would be treated + as catch up (last resort) for other types of displays which have similar features. +# +This array will only be taken into account, if hd44780/#/backlight is set to enabled. If it is +set to default and Winstar OLED or PT6314 VFD are used, we will always use 'internal'. +# +Multiple elements can be given, to use multiple methods." +gen/struct/field/ignore = 1 + +[hd44780/#/backlightcmdon] +type = string +check/type = string +check/validation = 0x[0-9A-F]{4} +check/validation/match = LINE +check/validation/message = 4 bytes can be encoded, as integer number in big-endian order (0x0000-0xFFFF) +default = 0x1223 +description = "Commands for enabling internal backlight for use with Backlight=internalCmds. +Up to 4 bytes can be encoded, as integer number in big-endian order. +# +NOTE: this is advanced option, if command contains bits other than only brighness handling, +they must be set accordingly to not disrupt display state. If for example 'FUNCTION SET' command +is used for this purpose, bits of interface length (4-bit / 8-bit) must be set according to +selected ConnectionType." + +[hd44780/#/backlightcmdoff] +type = string +check/type = string +check/validation = 0x[0-9A-F]{4} +check/validation/match = LINE +check/validation/message = 4 bytes can be encoded, as integer number in big-endian order (0x0000-0xFFFF) +default = 0x1234 +description = "Commands for disabling internal backlight for use with Backlight=internalCmds. +Up to 4 bytes can be encoded, as integer number in big-endian order." + +[hd44780/#/outputport] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = If you have the additional output port ("bargraph") and you want to\ +be able to control it with the lcdproc OUTPUT command + +[hd44780/#/lastline] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Specifies if the last line is pixel addressable (yes) or it controls an +underline effect (no)." + +[hd44780/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = Specifies the size of the LCD.\ +In case of multiple combined displays, this should be the total size. + +[hd44780/#/vspan] +type = string +check/type = string +default = "" +check/validation = ^([1-9][0-9]*(,[1-9][0-9]*)*)?$ +check/validation/match = LINE +check/validation/message = Declarations must look like this: 2,2 or 2,2,1 +description = "For multiple combined displays: how many lines does each display have. +Vspan=2,2 means both displays have 2 lines." + +[hd44780/#/extendedmode] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "If you have an HD66712, a KS0073 or another controller with 'extended mode', +set this flag to get into 4-line mode. On displays with just two lines, do +not set this flag. +As an additional restriction, controllers with and without extended mode +AND 4 lines cannot be mixed for those connection types that support more +than one display! +NOTE: This option is deprecated in favour of choosing Model=extended option." + +[hd44780/#/lineaddress] +type = string +check/type = string +check/validation = 0x([1-9A-F]+[0-9A-F]*) +check/validation/match = LINE +check/validation/message = Not a line Address. eg. 0x20, 0x10 +default = 0x20 +description = In extended mode, on some controllers like the ST7036 (in 3 line mode)\ +the next line in DDRAM won`t start 0x20 higher. + +[hd44780/#/charmap] +type = enum +check/type = enum +check/enum = #8 +check/enum/#0 = hd44780_default +check/enum/#1 = hd44780_euro +check/enum/#2 = ea_ks0073 +check/enum/#3 = sed1278f_0b +check/enum/#4 = hd44780_koi8_r +check/enum/#5 = hd44780_cp1251 +check/enum/#6 = hd44780_8859_5 +check/enum/#7 = upd16314 +check/enum/#8 = weh001602a_1 +default = hd44780_default +description = "Character map to to map ISO-8859-1 to the LCD's character set. (hd44780_koi8_r, hd44780_cp1251, hd44780_8859_5, upd16314 and weh001602a_1 +are possible if compiled with additional charmaps)" + +[hd44780/#/fontbank] +type = unsigned_short +check/type = unsigned_short +check/range = 0-3 +default = 0 +description = "Font bank to be used for some displays such as the WINSTAR WEH001602A +0: English/Japanese (default) +1: Western Europe I +2: English/Rusian +3: Western Europe II" + +[hd44780/#/delaymult] +type = unsigned_short +check/type = unsigned_short +check/range = 1, 2, 4, 8, 16 +default = 1 +description = "If your display is slow and cannot keep up with the flow of data from +LCDd, garbage can appear on the LCDd. Set this delay factor to 2 or 4 +to increase the delays." + +[hd44780/#/keepalivedisplay] +type = unsigned_short +check/type = unsigned_short +check/range = 0-10 +default = 0 +description = "Some displays (e.g. vdr-wakeup) need a message from the driver to that it +is still alive. When set to a value bigger then null the character in the +upper left corner is updated every seconds." + +[hd44780/#/refreshdisplay] +type = unsigned_short +check/type = unsigned_short +check/range = 0-20 +default = 0 +description = "If you experience occasional garbage on your display you can use this +option as workaround. If set to a value bigger than null it forces a +full screen refresh seconds." + +[hd44780/#/delaybus] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "You can reduce the inserted delays by setting this to false. +On fast PCs it is possible your LCD does not respond correctly." + +[hd44780/#/keydirect] +array = #5 +default = "" + +[hd44780/#/keydirect/#] +type = string +check/type = string +default = "" +description = "If you have a keypad, you can assign keystrings to the keys. +If you have 2d keypad (like on a phone), use hd44780/#/keymatrix/#/# instead." +gen/struct/field/ignore = 1 + +[hd44780/#/keymatrix] +array = #4 +default = "Don't change the max element. We will always use the KEYPAD_MAXX value from hd44780-low.h" + +[hd44780/#/keymatrix/#] +array = #_10 +default = "Don't change the max element. We will always use the KEYPAD_MAXY value from hd44780-low.h" +gen/struct/field/ignore = 1 + +[hd44780/#/keymatrix/#/#] +type = string +check/type = string +default = "" +description = "If you have a keypad, you can assign keystrings to the keys. +The first index is the X-coordinate, the second one the Y-cooordinate. +e.g. keymatrix/4/9 is the 5th key in the 10th row (indicies). +If you only have a 1d keypad, use hd44780/#/keydirect/#/# instead." +gen/struct/field/ignore = 1 + +[hd44780/#/i2c/backlightinvert] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "default is meant for the data port of PCF8574" ; TODO +gen/struct/field = i2cBacklightInvert + +[hd44780/#/i2c/line_rs] +type = long +check/type = long +default = 16 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_rw] +type = long +check/type = long +default = 32 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_en] +type = long +check/type = long +default = 64 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_bl] +type = long +check/type = long +default = 128 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_d4] +type = long +check/type = long +default = 1 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_d5] +type = long +check/type = long +default = 2 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_d6] +type = long +check/type = long +default = 4 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/i2c/line_d7] +type = long +check/type = long +default = 8 ; TODO (elektra): default values conversion hex? +description = "default is meant for the data port of PCF8574" ; TODO + +[hd44780/#/spi/backlightdevice] +type = string +check/type = string +default = "" +description = "" ; TODO +gen/struct/field = spiBacklightDevice + +[hd44780/#/usb/serialnumber] +type = string +check/type = string +default = "" +description = "used by bwctusb and ftdi" + +[hd44780/#/usb/description] +type = string +check/type = string +default = "" +description = "used by ftdi" + +[hd44780/#/usb/vendorid] +type = unsigned_long +check/type = unsigned_long +default = 0 ; TODO (elektra): default values conversion hex? +description = "used by uss720 and ftdi; set to 0 to use connectiontype dependent default" + +[hd44780/#/usb/productid] +type = unsigned_long +check/type = unsigned_long +default = 0 ; TODO (elektra): default values conversion hex? +description = "used by uss720 and ftdi; set to 0 to use connectiontype dependent default" + +[hd44780/#/ftdi/mode] +type = long +check/type = long +default = 8 +check/range = 4, 8 +description = "" ; TODO + +[hd44780/#/ftdi/line_rs] +type = long +check/type = long +default = 1 ; TODO (elektra): default values conversion hex? +description = "" ; TODO + +[hd44780/#/ftdi/line_rw] +type = long +check/type = long +default = 2 ; TODO (elektra): default values conversion hex? +description = "" ; TODO + +[hd44780/#/ftdi/line_en] +type = long +check/type = long +default = 4 ; TODO (elektra): default values conversion hex? +description = "" ; TODO + +[hd44780/#/ftdi/line_backlight] +type = long +check/type = long +default = 8 ; TODO (elektra): default values conversion hex? +description = "" ; TODO + +[hd44780/#/gpio/pin_en] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (8), with gpio it causes an error" + +[hd44780/#/gpio/pin_rs] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (7), with gpio it causes an error" + +[hd44780/#/gpio/pin_rw] +type = long +check/type = long +default = -1 +description = "required if gpio is used" + +[hd44780/#/gpio/pin_d7] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (18), with gpio it causes an error" + +[hd44780/#/gpio/pin_d6] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (23), with gpio it causes an error" + +[hd44780/#/gpio/pin_d5] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (24), with gpio it causes an error" + +[hd44780/#/gpio/pin_d4] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used; +with raspberrypi -1 triggers the default (25), with gpio it causes an error" + +[hd44780/#/gpio/pin_en2] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used and 2 controllers are connected; +with raspberrypi -1 triggers the default (22), with gpio it causes an error" + +[hd44780/#/gpio/pin_bl] +type = long +check/type = long +default = -1 +description = "required if raspberrypi or gpio is used and backlight (external) is enabled; +with raspberrypi -1 triggers the default (17), with gpio it causes an error" + +;lb216 +;================================================== +[lb216] +default = "" +array = #0 + +[lb216/#] +type = struct +check/type = any +default = "" +gen/struct/type = Lb216DriverConfig +gen/struct/alloc = 0 +description = Configuration for a lb216 driver. + +[lb216/#/file] +type = string +default = "lb216" +description = name of the shared library to load (without prefix and extension) + +[lb216/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 200 +check/range = 0-255 + +[lb216/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[lb216/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "Select the input device to use" + +[lb216/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 2400, 9600 +default = 9600 +description = Set the communication speed + +;lcdm001 +;================================================== +[lcdm001] +default = "" +array = #0 + +[lcdm001/#] +type = struct +check/type = any +default = "" +gen/struct/type = Lcdm001DriverConfig +gen/struct/alloc = 0 +description = Configuration for a lcdm001 driver. + +[lcdm001/#/file] +type = string +default = "lcdm001" +description = name of the shared library to load (without prefix and extension) + +[lcdm001/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = "select the device to use" + +[lcdm001/#/pausekey] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = LeftKey +check/enum/#1 = RightKey +check/enum/#2 = UpKey +check/enum/#3 = DownKey +gen/enum/type = Lcdm001Keys +default = LeftKey +description = "Normal Context: Pause/Continue +Menu Context: Enter/select" + +[lcdm001/#/backkey] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = LeftKey +check/enum/#1 = RightKey +check/enum/#2 = UpKey +check/enum/#3 = DownKey +gen/enum/type = Lcdm001Keys +default = UpKey +description = "Normal Context: Back(Go to previous screen) +Menu Context: Up/Left" + +[lcdm001/#/forwardkey] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = LeftKey +check/enum/#1 = RightKey +check/enum/#2 = UpKey +check/enum/#3 = DownKey +gen/enum/type = Lcdm001Keys +default = DownKey +description = "Normal Context: Forward(Go to next screen) +Menu Context: Down/Right" + +[lcdm001/#/mainmenukey] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = LeftKey +check/enum/#1 = RightKey +check/enum/#2 = UpKey +check/enum/#3 = DownKey +gen/enum/type = Lcdm001Keys +default = RightKey +description = "Normal Context: Open main menu +Menu Context: Exit/Cancel" + +;linux_input +;================================================== +[linux_input] +default = "" +array = #0 + +[linux_input/#] +type = struct +check/type = any +default = "" +gen/struct/type = Linux_inputDriverConfig +gen/struct/alloc = 0 +description = Configuration for a linux_input driver. + +[linux_input/#/file] +type = string +default = "linux_input" +description = name of the shared library to load (without prefix and extension) + +[linux_input/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/input/event0 +description = "select the device to use" + +[linux_input/#/keys] +default = "" +array = #0 +description = "specify a non-default key map, eg.: + /linux_input/key/#0/code = 1 + /linux_input/key/#0/button = Enter + sets the keycode 1 to be the Enter key" + +[linux_input/#/keys/#] +type = string +default = "" +gen/struct/field/ignore = 1 +description = "INGORE: only here to generate tag" + +[linux_input/#/keys/#/code] +type = unsigned_short +check/type = unsigned_short +default = 0 ; should be required + +[linux_input/#/keys/#/button] +type = string +check/type = string +default = "" ; should be required + +;MtxOrb +;================================================== +[mtxorb] +default = "" +array = #0 + +[mtxorb/#] +type = struct +check/type = any +default = "" +gen/struct/type = MtxOrbDriverConfig +gen/struct/alloc = 0 +description = Configuration for a MtxOrb driver. + +[mtxorb/#/file] +type = string +default = "MtxOrb" +description = name of the shared library to load (without prefix and extension) + +[mtxorb/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 480 +check/range = 0-1000 +description = "Set the initial contrast +NOTE: The driver will ignore this if the display +is a vfd or vkd as they don't have this feature" + +[mtxorb/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[mtxorb/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = "Set the initial off-brightness +This value is used when the display is normally +switched off in case LCDd is inactive" + +[mtxorb/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS0 +description = "Select the output device to use" + +[mtxorb/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = display size + +[mtxorb/#/type] +type = enum +check/type = enum +check/enum = #3 +check/enum/#0 = lcd +check/enum/#1 = lkd +check/enum/#2 = vfd +check/enum/#3 = vkd +default = lcd +description = "Set the display type" + +[mtxorb/#/hasadjustablebacklight] +type = boolean +check/type = boolean +gen/struct/field = hasAdjustableBacklight +default = 0 ; TODO (elektra): default values conversion +description = "Some old displays do not have an adjustable backlight but only can +switch the backlight on/off. If you experience randomly appearing block +characters, try setting this to false." + +[mtxorb/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200 +default = 19200 +description = Set the communication + +[mtxorb/#/keypad_test_mode] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = permits one to test keypad assignment + +[mtxorb/#/keymap_a] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +[mtxorb/#/keymap_b] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +[mtxorb/#/keymap_c] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +[mtxorb/#/keymap_d] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +[mtxorb/#/keymap_e] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +[mtxorb/#/keymap_f] +type = string +check/type = string +default = "" +description = "By default no keys are mapped, meaning the keypad is not used at all." + +;pyramid +;================================================== +[pyramid] +default = "" +array = #0 + +[pyramid/#] +type = struct +check/type = any +default = "" +gen/struct/type = PyramidDriverConfig +gen/struct/alloc = 0 +description = Configuration for a pyramid driver. + +[pyramid/#/file] +type = string +default = "pyramid" +description = name of the shared library to load (without prefix and extension) + +[pyramid/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "device to connect to" + +;text +;================================================== +[text] +default = "" +array = #0 + +[text/#] +type = struct +check/type = any +default = "" +gen/struct/type = TextDriverConfig +gen/struct/alloc = 0 +description = Configuration for a text driver. + +[text/#/file] +type = string +default = "text" +description = name of the shared library to load (without prefix and extension) + +[text/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[text/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[text/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[text/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[text/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "set display size" + +;xosd +;================================================== +[xosd] +default = "" +array = #0 + +[xosd/#] +type = struct +check/type = any +default = "" +gen/struct/type = XosdDriverConfig +gen/struct/alloc = 0 +description = Configuration for a xosd driver. + +[xosd/#/file] +type = string +default = "xosd" +description = name of the shared library to load (without prefix and extension) + +[xosd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[xosd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[xosd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[xosd/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "set display size" + +[xosd/#/offset] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid offset declaration. Examples: 200x200 +default = 0x0 +description = "Offset in pixels from the top-left corner of the monitor [default: 0x0]" + +[xosd/#/font] +type = string +check/type = string +default = "-*-terminus-*-r-*-*-*-320-*-*-*-*-*" +description = "X font to use, in XLFD format, as given by 'xfontsel'" diff --git a/server/specification/LCDd-spec_notupdated.ini b/server/specification/LCDd-spec_notupdated.ini new file mode 100644 index 00000000..476f10e0 --- /dev/null +++ b/server/specification/LCDd-spec_notupdated.ini @@ -0,0 +1,3106 @@ +; This file contains the specifications for drivers that haven't been updated yet. + +;ea65 +;================================================== +[ea65] +default = "" +array = #0 + +[ea65/#] +type = struct +check/type = any +default = "" +gen/struct/type = Ea65DriverConfig +gen/struct/alloc = 0 +description = Configuration for a ea65 driver. + +[ea65/#/file] +type = string +default = "ea65" +description = name of the shared library to load (without prefix and extension) + +[ea65/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[ea65/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 500 +check/range = 0-1000 +description = "As the VFD is self luminescent we don't have a backlight +But we can use the backlight functions to control the front LEDs +Brightness 0 to 299 -> LEDs off +Brightness 300 to 699 -> LEDs half bright +Brightness 700 to 1000 -> LEDs full bright" + +[ea65/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = OffBrightness is the the value used for the 'backlight off' state + +[ea65/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +;EyeboxOne +;================================================== +[eyeboxone] +default = "" +array = #0 + +[eyeboxone/#] +type = struct +check/type = any +default = "" +gen/struct/type = EyeboxOneDriverConfig +gen/struct/alloc = 0 +description = Configuration for a EyeboxOne driver. + +[eyeboxone/#/file] +type = string +default = "EyeboxOne" +description = name of the shared library to load (without prefix and extension) + +[eyeboxone/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[eyeboxone/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[eyeboxone/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[eyeboxone/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[eyeboxone/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = Select the output device to use + +[eyeboxone/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = Set the display size + +[eyeboxone/#/backlight] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Switch on the backlight? + +[eyeboxone/#/cursor] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Switch on the cursor? + +[eyeboxone/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200 +default = 19200 +description = Set the communication speed + +[eyeboxone/#/leftkey] +type = string +check/type = string +default = D +description = "Enter Key is a \r character, so it's hardcoded in the driver" + +[eyeboxone/#/rightkey] +type = string +check/type = string +default = C +description = "Enter Key is a \r character, so it's hardcoded in the driver" + +[eyeboxone/#/upkey] +type = string +check/type = string +default = A +description = "Enter Key is a \r character, so it's hardcoded in the driver" + +[eyeboxone/#/downkey] +type = string +check/type = string +default = B +description = "Enter Key is a \r character, so it's hardcoded in the driver" + +[eyeboxone/#/escapekey] +type = string +check/type = string +default = P +description = "Enter Key is a \r character, so it's hardcoded in the driver" + + +[eyeboxone/#/keypad_test_mode] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "You can find out which key of your display sends which +character by setting keypad_test_mode to yes and running +LCDd. LCDd will output all characters it receives. +Afterwards you can modify the settings above and set +keypad_set_mode to no again." + +;futaba +;================================================== +[futaba] +default = "" +array = #0 + +[futaba/#] +type = struct +check/type = any +default = "" +gen/struct/type = FutabaDriverConfig +gen/struct/alloc = 0 +description = Configuration for a futaba driver. + +[futaba/#/file] +type = string +default = "futaba" +description = name of the shared library to load (without prefix and extension) + +;g15 +;================================================== +[g15] +default = "" +array = #0 + +[g15/#] +type = struct +check/type = any +default = "" +gen/struct/type = G15DriverConfig +gen/struct/alloc = 0 +description = Configuration for a g15 driver. + +[g15/#/file] +type = string +default = "g15" +description = name of the shared library to load (without prefix and extension) + +[g15/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[g15/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[g15/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[g15/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[g15/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x5 +description = Display size (currently unused) + +;glcd +;================================================== +[glcd] +default = "" +array = #0 + +[glcd/#] +type = struct +check/type = any +default = "" +gen/struct/type = GlcdDriverConfig +gen/struct/alloc = 0 +description = Configuration for a glcd driver. + +[glcd/#/file] +type = string +default = "glcd" +description = name of the shared library to load (without prefix and extension) + +[glcd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 600 +check/range = 0-1000 +description = Set the initial contrast + +[glcd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 800 +check/range = 0-1000 + +[glcd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 100 +check/range = 0-1000 + +[glcd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[glcd/#/connectiontype] +type = enum +check/type = enum +check/enum = #6 +check/enum/#0 = t6963 +check/enum/#1 = png +check/enum/#2 = serdisplib +check/enum/#3 = glcd2usb +check/enum/#4 = x11 +check/enum/#5 = picolcdgfx +check/enum/#6 = xyz +gen/enum/type = GlcdConnectionType +default = t6963 +description = Select what type of connection. See documentation for types. + +[glcd/#/size] +type = string +check/type = string +check/validation = (640|[1-9]|[1-9][0-9]|[1-5][0-9][0-9]|6[0-3][0-9])x(480|[1-9]|[1-9][0-9]|[1-3][0-9][0-9]|4[0-7][0-9]) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. legal: 1x1 - 640x480 +default = 128x64 +description = Width and height of the display in pixel. The supported sizes may depend on the ConnectionType + +[glcd/#/cellsize] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 6x8 +description = Width and height of a character cell in pixels. This value is only used \ +the driver has been compiled with FreeType and it is enabled. Otherwise the\ +default 6x8 cell is used. + +[glcd/#/useft2] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = If LCDproc has been compiled with FreeType 2 support this option can be used\ +to turn if off intentionally. + +[glcd/#/normal_font] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /usr/local/lib/X11/fonts/TTF/andalemo.ttf +description = Path to font file to use for FreeType rendering. This font must be monospace\ +and should contain some special Unicode characters like arrows (Andale Mono\ +is recommended and can be fetched at http://corefonts.sf.net). + +[glcd/#/fonthasicons] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Some fonts miss the Unicode characters used to represent icons. In this case\ +the built-in 5x8 font can used if this option is turned off. + +[glcd/#/keyrepeatdelay] +type = unsigned_short +check/type = unsigned_short +check/range = 0-3000 +default = 500 +description = Time (ms) from first key report to first repeat. Set to 0 to disable repeated key reports. + +[glcd/#/keymap_a] +type = string +check/type = string +default = Up +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keymap_b] +type = string +check/type = string +default = Down +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keymap_c] +type = string +check/type = string +default = Left +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keymap_d] +type = string +check/type = string +default = Right +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keymap_e] +type = string +check/type = string +default = Enter +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keymap_f] +type = string +check/type = string +default = Escape +description = "Assign key strings to keys. There may be up to 16 keys numbered 'A' to 'Z'. +By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape." + +[glcd/#/keyrepeatinterval] +type = unsigned_short +check/type = unsigned_short +check/range = 0-3000 +default = 500 +description = Time (ms) between repeated key reports. Ignored if KeyRepeatDelay is disabled (set to zero). + +[glcd/#/port] +type = string +check/type = string +check/validation = 0x([2-3][0-9A-F]{2}|400) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. legal: 0x200 - 0x400 +default = 0x378 +description = Parallel port to use + +[glcd/#/bidirectional] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Use LPT port in bi-directional mode. This should work on most LPT port\ +and is required for proper timing! + +[glcd/#/delaybus] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Insert additional delays into reads / writes. + +[glcd/#/serdisp_name] +type = string +check/type = string +default = t6963 +description = Name of the underlying serdisplib driver, e.g. ctinclud. See +serdisplib documentation for details. + +[glcd/#/serdisp_device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ppi0 +description = The display device to use, e.g. serraw:/dev/ttyS0,\ +parport:/dev/parport0 or USB:07c0/1501 + +[glcd/#/serdisp_options] +type = string +check/type = string +default = "INVERT=1" +description = "Options string to pass to serdisplib during initialization. Use +this to set any display related options (e.g. wiring). The display size is +always set based on the Size configured above! By default, no options are +set. +Important: The value must be quoted as it contains equal signs!" + +[glcd/#/x11_pixelsize] +type = string +check/type = string +check/validation = \d+\+\d+ +check/validation/match = LINE +default = 3+1 +check/validation/message = [number]+[number] has to be provided, eg: 3+1 or 5+2 +description = "Each LCD dot is drawn in the X window as a filled rectangle of this size + plus a gap between each filled rectangle. A PixelSize of 3+1 + would draw a 3x3 filled rectangle with a gap of 1 pixel to the right and + bottom, effectively using a 4x4 area of the window. Default is 3+1." + +[glcd/#/x11_pixelcolor] +type = string +check/type = string +check/validation = 0x[0-9A-F]{6} +check/validation/match = LINE +check/validation/message = Colors are in RRGGBB format prefixed with "0x" +default = 0x000000 +description = The color of each dot at full contrast. + +[glcd/#/x11_backlightcolor] +type = string +check/type = string +check/validation = 0x[0-9A-F]{6} +check/validation/match = LINE +check/validation/message = Colors are in RRGGBB format prefixed with "0x" +default = 0x80FF80 +description = The color of the backlight as full brightness. + +[glcd/#/x11_border] +type = unsigned_long +check/type = unsigned_long +default = 20 +description = Adds a border (empty space) around the LCD portion of X11 window. + +[glcd/#/x11_inverted] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Inverts the pixels. + +[glcd/#/picolcdgfx_keytimeout] +type = unsigned_long +check/type = unsigned_long +; check/range = 1- ; TODO (elektra): open ranges +default = 125 +description = Time in ms for usb_read to wait on a key press. + +[glcd/#/picolcdgfx_inverted] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Inverts the pixels. + +;glcdlib +;================================================== +[glcdlib] +default = "" +array = #0 + +[glcdlib/#] +type = struct +check/type = any +default = "" +gen/struct/type = GlcdlibDriverConfig +gen/struct/alloc = 0 +description = Configuration for a glcdlib driver. + +[glcdlib/#/file] +type = string +default = "glcdlib" +description = name of the shared library to load (without prefix and extension) + +[glcdlib/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 50 +check/range = 0-100 +description = Set the initial contrast + +[glcdlib/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 50 +check/range = 0-100 + +[glcdlib/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[glcdlib/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[glcdlib/#/driver] +type = string +check/type = string +default = image +description = " +Specify which graphical display supported by graphlcd-base to use. + Legal values for GRAPHLCD-DRIVER are + specified in graphlcd's configuration file /etc/graphlcd.conf. + For graphlcd 0.13 they comprise avrctl, framebuffer, gu140x32f, gu256x64-372, + gu256x64C-3xx0, hd61830, image, ks0108, noritake800, sed1330, sed1520, serdisp, simlcd, t6963c +" + +[glcdlib/#/CharEncoding] +type = string +check/type = string +default = iso8859-2 +description = "character encoding to use" + +[glcdlib/#/useft2] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "no=use graphlcd bitmap fonts (they have only one size / font file) +yes=use fonts supported by FreeType2 (needs Freetype2 support in +libglcdprocdriver and its dependants)" + +[glcdlib/#/textresolution] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x4 +description = "Text resolution in fixed width characters. +(if it won't fit according to available physical pixel resolution +and the minimum available font face size in pixels, then +'DebugBorder' will automatically be turned on)" + +[glcdlib/#/fontfile] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /usr/share/fonts/corefonts/courbd.ttf +description = "path to font file to use" + +[glcdlib/#/minfontfacesize] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 7x12 +description = "path to font file to use" + +[glcdlib/#/backlight] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion + +[glcdlib/#/upsidedown] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion + +[glcdlib/#/invert] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion + +[glcdlib/#/showdebugframe] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion + +[glcdlib/#/showbigborder] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion + +[glcdlib/#/showthinborder] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion + +[glcdlib/#/pixelshiftx] +type = unsigned_short +check/type = unsigned_short +default = 0 + +[glcdlib/#/pixelshifty] +type = unsigned_short +check/type = unsigned_short +default = 2 + +;icp_a106 +;================================================== +[icp_a106] +default = "" +array = #0 + +[icp_a106/#] +type = struct +check/type = any +default = "" +gen/struct/type = Icp_a106DriverConfig +gen/struct/alloc = 0 +description = Configuration for a icp_a106 driver. + +[icp_a106/#/file] +type = string +default = "icp_a106" +description = name of the shared library to load (without prefix and extension) + +[icp_a106/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[icp_a106/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[icp_a106/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[icp_a106/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[icp_a106/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "Device of the serial, I2C, or SPI interface" + +[icp_a106/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x2 +description = Display dimensions + +;IOWarrior +;================================================== +[iowarrior] +default = "" +array = #0 + +[iowarrior/#] +type = struct +check/type = any +default = "" +gen/struct/type = IOWarriorDriverConfig +gen/struct/alloc = 0 +description = Configuration for a IOWarrior driver. + +[iowarrior/#/file] +type = string +default = "IOWarrior" +description = name of the shared library to load (without prefix and extension) + +[iowarrior/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[iowarrior/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[iowarrior/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[iowarrior/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[iowarrior/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = Display dimensions + +[iowarrior/#/serialnumber] +type = string +check/type = any +default = 00000674 +description = serial number. Must be exactly as listed by usbview\ +(if not given, the 1st IOWarrior found gets used) + +[iowarrior/#/extendedmode] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "If you have an HD66712, a KS0073 or another 'almost HD44780-compatible', +set this flag to get into extended mode (4-line linear)." + +[iowarrior/#/lastline] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Specifies if the last line is pixel addressable (yes) or it controls an +underline effect (no)." + +;imon +;================================================== +[imon] +default = "" +array = #0 + +[imon/#] +type = struct +check/type = any +default = "" +gen/struct/type = ImonDriverConfig +gen/struct/alloc = 0 +description = Configuration for a imon driver. + +[imon/#/file] +type = string +default = "imon" +description = name of the shared library to load (without prefix and extension) + +[imon/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[imon/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[imon/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[imon/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[imon/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd0 +description = "select the device to use" + +[imon/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = Display dimensions + +[imon/#/charmap] +type = enum +check/type = enum +check/enum = #5 +check/enum/#0 = hd44780_euro +check/enum/#1 = upd16314 +check/enum/#2 = hd44780_koi8_r +check/enum/#3 = hd44780_cp1251 +check/enum/#4 = hd44780_8859_5 +check/enum/#5 = none +gen/enum/type = IMonCharmap +default = none +description = "Character map to to map ISO-8859-1 to the displays character set. (upd16314, hd44780_koi8_r, +hd44780_cp1251, hd44780_8859_5 are possible if compiled with additional +charmaps)" + +;imonlcd +;================================================== +[imonlcd] +default = "" +array = #0 + +[imonlcd/#] +type = struct +check/type = any +default = "" +gen/struct/type = ImonlcdDriverConfig +gen/struct/alloc = 0 +description = Configuration for a imonlcd driver. + +[imonlcd/#/file] +type = string +default = "imonlcd" +description = name of the shared library to load (without prefix and extension) + +[imonlcd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 200 +check/range = 0-1000 +description = Set the initial contrast + +[imonlcd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[imonlcd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[imonlcd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[imonlcd/#/protocol] +type = string +check/type = string +check/enum = #3 +check/enum/#0 = 15c2:ffdc +check/enum/#1 = 15c2:0038 +check/enum/#2 = 0 +gen/enum/#2/value = 0 +check/enum/#3 = 1 +gen/enum/#3/value = 1 +gen/enum/type = IMonLCDProtocol +default = 0 +description = "Specify which iMon protocol should be used +Choose 0 for 15c2:ffdc device, +Choose 1 for 15c2:0038 device" + +[imonlcd/#/onexit] +type = unsigned_short +check/type = unsigned_short +check/range = 0-2 +default = 1 +description = "Set the exit behavior +0 means leave shutdown message, +1 means show the big clock, +2 means blank device" + +[imonlcd/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd0 +description = "select the output device to use" + +[imonlcd/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 96x16 +description = Specify the size of the display in pixels + +[imonlcd/#/backlight] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Set the backlight state" + +[imonlcd/#/discmode] +type = enum +check/type = enum +check/enum = #1 +check/enum/#0 = 0 +check/enum/#1 = 1 +gen/enum/type = IMonLCDDiscMode +default = 0 +description = "Set the disc mode +0 => spin the 'slim' disc - two disc segments, +1 => their complement spinning;" + +;IrMan +;================================================== +[irman] +default = "" +array = #0 + +[irman/#] +type = struct +check/type = any +default = "" +gen/struct/type = IrManDriverConfig +gen/struct/alloc = 0 +description = Configuration for a IrMan driver. + +[irman/#/file] +type = string +default = "IrMan" +description = name of the shared library to load (without prefix and extension) + +[irman/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[irman/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[irman/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[irman/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[irman/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/irman +description = "select the device to use" + +[irman/#/config] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /etc/irman.cfg +description = "Select the configuration file to use" + +;irtrans +;================================================== +[irtrans] +default = "" +array = #0 + +[irtrans/#] +type = struct +check/type = any +default = "" +gen/struct/type = IrtransDriverConfig +gen/struct/alloc = 0 +description = Configuration for a irtrans driver. + +[irtrans/#/file] +type = string +default = "irtrans" +description = name of the shared library to load (without prefix and extension) + +[irtrans/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[irtrans/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[irtrans/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[irtrans/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[irtrans/#/backlight] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Does the device have a backlight?" + +[irtrans/#/hostname] +type = string +check/type = string +default = localhost +description = "IRTrans device to connect to" + +[irtrans/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = Specify the size of the display in pixels + +;joy +;================================================== +[joy] +default = "" +array = #0 + +[joy/#] +type = struct +check/type = any +default = "" +gen/struct/type = JoyDriverConfig +gen/struct/alloc = 0 +description = Configuration for a joy driver. + +[joy/#/file] +type = string +default = "joy" +description = name of the shared library to load (without prefix and extension) + +[joy/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[joy/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[joy/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[joy/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[joy/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/js0 +description = "Select the input device to use" + +[joy/#/map_axis1neg] +type = string +check/type = string +default = Left +description = "set the axis map" + +[joy/#/map_axis1pos] +type = string +check/type = string +default = Right +description = "set the axis map" + +[joy/#/map_axis2neg] +type = string +check/type = string +default = Up +description = "set the axis map" + +[joy/#/map_axis2pos] +type = string +check/type = string +default = Down +description = "set the axis map" + +[joy/#/map_button1] +type = string +check/type = string +default = Enter +description = "set the button map" + +[joy/#/map_button2] +type = string +check/type = string +default = Escape +description = "set the button map" + +;lcterm +;================================================== +[lcterm] +default = "" +array = #0 + +[lcterm/#] +type = struct +check/type = any +default = "" +gen/struct/type = LctermDriverConfig +gen/struct/alloc = 0 +description = Configuration for a lcterm driver. + +[lcterm/#/file] +type = string +default = "lcterm" +description = name of the shared library to load (without prefix and extension) + +[lcterm/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[lcterm/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[lcterm/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[lcterm/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[lcterm/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = "select the device to use" + +[lcterm/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = Specify the size of the display in pixels + +;lirc +;================================================== +[lirc] +default = "" +array = #0 + +[lirc/#] +type = struct +check/type = any +default = "" +gen/struct/type = LircDriverConfig +gen/struct/alloc = 0 +description = Configuration for a lirc driver. + +[lirc/#/file] +type = string +default = "lirc" +description = name of the shared library to load (without prefix and extension) + +[lirc/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[lirc/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[lirc/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[lirc/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[lirc/#/lircrc] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = ~/.lircrc +description = "select the device to use" + +[lirc/#/prog] +type = string +check/type = string +default = lcdd +description = "Must be the same as in your lircrc" + +;lis +;================================================== +[lis] +default = "" +array = #0 + +[lis/#] +type = struct +check/type = any +default = "" +gen/struct/type = LisDriverConfig +gen/struct/alloc = 0 +description = Configuration for a lis driver. + +[lis/#/file] +type = string +default = "lis" +description = name of the shared library to load (without prefix and extension) + +[lis/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[lis/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = "Set the initial brightness +0-250 = 25%, 251-500 = 50%, 501-750 = 75%, 751-1000 = 100%" + +[lis/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[lis/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[lis/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = Columns by lines + +[lis/#/vendorid] +type = string +check/type = string +check/validation = 0x([0-9A-F]{4}) +check/validation/match = LINE +check/validation/message = Not a valid size VendorID: 0x0000-0xFFFF is allowed +default = 0x0403 +description = USB Vendor ID. Change only if testing a compatible device. + +[lis/#/productid] +type = string +check/type = string +check/validation = 0x([0-9A-F]{4}) +check/validation/match = LINE +check/validation/message = Not a valid size ProductID: 0x0000-0xFFFF is allowed +default = 0x6001 +description = USB Product ID. Change only if testing a compatible device. + +[lis/#/lastline] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Specifies if the last line is pixel addressable (yes) or it only controls an +underline effect (no)" + +;MD8800 +;================================================== +[md8800] +default = "" +array = #0 + +[md8800/#] +type = struct +check/type = any +default = "" +gen/struct/type = MD8800DriverConfig +gen/struct/alloc = 0 +description = Configuration for a MD8800 driver. + +[md8800/#/file] +type = string +default = "MD8800" +description = name of the shared library to load (without prefix and extension) + +[md8800/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[md8800/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[md8800/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = "Set the initial off-brightness +This value is used when the display is normally +switched off in case LCDd is inactive" + +[md8800/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[md8800/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = "select the device to use" + +[md8800/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = display size + +;mdm166a +;================================================== +[mdm166a] +default = "" +array = #0 + +[mdm166a/#] +type = struct +check/type = any +default = "" +gen/struct/type = Mdm166aDriverConfig +gen/struct/alloc = 0 +description = Configuration for a mdm166a driver. + +[mdm166a/#/file] +type = string +default = "mdm166a" +description = name of the shared library to load (without prefix and extension) + +[mdm166a/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[mdm166a/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[mdm166a/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[mdm166a/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[mdm166a/#/clock] +type = enum +check/type = enum +check/enum = #2 +check/enum/#0 = no +check/enum/#1 = small +check/enum/#2 = big +default = no +description = "Show self-running clock after LCDd shutdown" + +[mdm166a/#/dimming] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Dim display, no dimming gives full brightness" + +[mdm166a/#/offdimming] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Dim display in case LCDd is inactive" + +;ms6931 +;================================================== +[ms6931] +default = "" +array = #0 + +[ms6931/#] +type = struct +check/type = any +default = "" +gen/struct/type = Ms6931DriverConfig +gen/struct/alloc = 0 +description = Configuration for a ms6931 driver. + +[ms6931/#/file] +type = string +default = "ms6931" +description = name of the shared library to load (without prefix and extension) + +[ms6931/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[ms6931/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[ms6931/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[ms6931/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[ms6931/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = "select the device to use" + +[ms6931/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = display size + +;mtc_s16209x +;================================================== +[mtc_s16209x] +default = "" +array = #0 + +[mtc_s16209x/#] +type = struct +check/type = any +default = "" +gen/struct/type = Mtc_s16209xDriverConfig +gen/struct/alloc = 0 +description = Configuration for a mtc_s16209x driver. + +[mtc_s16209x/#/file] +type = string +default = "mtc_s16209x" +description = name of the shared library to load (without prefix and extension) + +[mtc_s16209x/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[mtc_s16209x/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 200 +check/range = 0-255 + +[mtc_s16209x/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[mtc_s16209x/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[mtc_s16209x/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "Select the output device to use" + +;mx5000 +;================================================== +[mx5000] +default = "" +array = #0 + +[mx5000/#] +type = struct +check/type = any +default = "" +gen/struct/type = Mx5000DriverConfig +gen/struct/alloc = 0 +description = Configuration for a mx5000 driver. + +[mx5000/#/file] +type = string +default = "mx5000" +description = name of the shared library to load (without prefix and extension) + +[mx5000/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[mx5000/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[mx5000/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[mx5000/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[mx5000/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/hiddev0 +description = "Select the output device to use" + +[mx5000/#/waitafterrefresh] +type = unsigned_long +check/type = unsigned_long +; check/range = 1- ; TODO (elektra): open ranges +default = 1000 +description = Time to wait in ms after the refresh screen has been sent + +;NoritakeVFD +;================================================== +[noritakevfd] +default = "" +array = #0 + +[noritakevfd/#] +type = struct +check/type = any +default = "" +gen/struct/type = NoritakeVFDDriverConfig +gen/struct/alloc = 0 +description = Configuration for a NoritakeVFD driver. + +[noritakevfd/#/file] +type = string +default = "NoritakeVFD" +description = name of the shared library to load (without prefix and extension) + +[noritakevfd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[noritakevfd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[noritakevfd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = "Set the initial off-brightness +This value is used when the display is normally +switched off in case LCDd is inactive" + +[noritakevfd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[noritakevfd/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "device where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1" + +[noritakevfd/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = display size + +[noritakevfd/#/speed] +type = unsigned_long +check/type = unsigned_long +check/range = 1200, 2400, 9600, 19200, 115200 +default = 19200 +description = set the serial port speed + +[noritakevfd/#/parity] +type = unsigned_long +check/type = unsigned_long +check/range = 0-2 +default = 0 +description = "Set serial data parity +Meaning: 0(=none), 1(=odd), 2(=even)" + +;Olimex_MOD_LCD1x9 +;================================================== +[olimex_mod_lcd1x9] +default = "" +array = #0 + +[olimex_mod_lcd1x9/#] +type = struct +check/type = any +default = "" +gen/struct/type = Olimex_MOD_LCD1x9DriverConfig +gen/struct/alloc = 0 +description = Configuration for a Olimex_MOD_LCD1x9 driver. + +[olimex_mod_lcd1x9/#/file] +type = string +default = "Olimex_MOD_LCD1x9" +description = name of the shared library to load (without prefix and extension) + +[olimex_mod_lcd1x9/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[olimex_mod_lcd1x9/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[olimex_mod_lcd1x9/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[olimex_mod_lcd1x9/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[olimex_mod_lcd1x9/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/i2c-0 +description = "device file of the i2c controller" + +;picolcd +;================================================== +[picolcd] +default = "" +array = #0 + +[picolcd/#] +type = struct +check/type = any +default = "" +gen/struct/type = PicolcdDriverConfig +gen/struct/alloc = 0 +description = Configuration for a picolcd driver. + +[picolcd/#/file] +type = string +default = "picolcd" +description = name of the shared library to load (without prefix and extension) + +[picolcd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[picolcd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = "Set the initial brightness [default: 1000; legal: 0 - 1000]. Works only +with the 20x4 device" + +[picolcd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = "Set the brightness while the backlight is 'off'. +Works only with the 20x4 device." + +[picolcd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[picolcd/#/keytimeout] +type = unsigned_short +check/type = unsigned_short +check/range = 0-1000 +default = 500 +description = "KeyTimeout is only used if the picoLCD driver is built with libusb-0.1. When +built with libusb-1.0 key and IR data is input asynchronously so there is no +need to wait for the USB data. +KeyTimeout is the time in ms that LCDd spends waiting for a key press before +cycling through other duties. Higher values make LCDd use less CPU time and +make key presses more detectable. Lower values make LCDd more responsive +but a little prone to missing key presses. 500 (.5 second) is the default +and a balanced value." + +[picolcd/#/keyrepeatdelay] +type = unsigned_short +check/type = unsigned_short +check/range = 0-3000 +default = 300 +description = "Key auto repeat is only available if the picoLCD driver is built with +libusb-1.0. Use KeyRepeatDelay and KeyRepeatInterval to configure key auto +repeat. +# +Key auto repeat delay (time in ms from first key report to first repeat). Use +zero to disable auto repeat." + +[picolcd/#/keyrepeatinterval] +type = unsigned_short +check/type = unsigned_short +check/range = 0-3000 +default = 200 +description = "Key auto repeat interval (time in ms between repeat reports). Only used if +KeyRepeatDelay is not zero." + +[picolcd/#/backlight] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Sets the initial state of the backlight upon start-up. + +[picolcd/#/linklights] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Link the key lights to the backlight? + +[picolcd/#/keylights] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = Light the keys? + +[picolcd/#/key0light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/key1light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/key2light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/key3light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/key4light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/key5light] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "If Keylights is on, the you can unlight specific keys below: +Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys. +There is no LED for the +/- keys. This is a handy way to indicate to users +which keys are disabled." + +[picolcd/#/lirchost] +; check/ipaddr = ; TODO (elektra): too many plugins +type = string +check/type = string +default = 127.0.0.1 +description = Host name or IP address of the LIRC instance that is to receive IR codes\ +If not set, or set to an empty value, IR support is disabled. + +[picolcd/#/lircport] +; check/port = ; TODO (elektra): too many plugins +type = unsigned_short +default = 8765 +description = UDP port on which LIRC is listening + +[picolcd/#/lirctime_us] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "UDP data time unit for LIRC +On: times sent in microseconds (requires LIRC UDP driver that accepts this). +Off: times sent in 'jiffies' (1/16384s) (supported by standard LIRC UDP driver)." + +[picolcd/#/lircflushthreshold] +type = unsigned_long +check/type = unsigned_long +check/validation = [1-9]\d{3,} +check/validation/match = LINE +check/validation/message = LircFlushThreshold must be a positive number >1000 +default = 1000 +description = "Threshold in microseconds of the gap that triggers flushing the IR data +to lirc [default: 8000; legal: 1000 - ] +If LircTime_us is on values greater than 32.767ms will disable the flush +If LircTime_us is off values greater than 1.999938s will disable the flush" + +;rawserial +;================================================== +[rawserial] +default = "" +array = #0 + +[rawserial/#] +type = struct +check/type = any +default = "" +gen/struct/type = RawserialDriverConfig +gen/struct/alloc = 0 +description = Configuration for a rawserial driver. + +[rawserial/#/file] +type = string +default = "rawserial" +description = name of the shared library to load (without prefix and extension) + +[rawserial/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[rawserial/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[rawserial/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[rawserial/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[rawserial/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/cuaU0 +description = "Select the output device to use" + +[rawserial/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 40x4 +description = "Specifies the size of the LCD. If this driver is loaded as a secondary driver +it always adopts to the size of the primary driver. If loaded as the only +(or primary) driver, the size can be set." + +[rawserial/#/updaterate] +type = float +check/type = float +default = 1 +description = "How often to dump the LCD contents out the port, in Hertz (times per second) +1 = once per second, 4 is 4 times per second, 0.1 is once every 10 seconds. +[default: 1; legal: 0.0005 - 10]" + +[rawserial/#/speed] +type = unsigned_long +check/type = unsigned_long +default = 9600 +description = "Serial port baudrate [default: 9600]" + +;sed1330 +;================================================== +[sed1330] +default = "" +array = #0 + +[sed1330/#] +type = struct +check/type = any +default = "" +gen/struct/type = Sed1330DriverConfig +gen/struct/alloc = 0 +description = Configuration for a sed1330 driver. + +[sed1330/#/file] +type = string +default = "sed1330" +description = name of the shared library to load (without prefix and extension) + +[sed1330/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[sed1330/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[sed1330/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[sed1330/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[sed1330/#/port] +type = string +check/type = string +check/validation = 0x([0-9A-F]{3}) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. It should start with 0x, followed by 3 HEX values. eg. 0x3BC +default = 0x378 +description = Port where the LPT is. Common values are 0x278, 0x378 and 0x3BC + +[sed1330/#/type] +type = enum +check/type = enum +check/enum = #5 +check/enum/#0 = G321D +check/enum/#1 = G121C +check/enum/#2 = G242C +check/enum/#3 = G191D +check/enum/#4 = G2446 +check/enum/#5 = SP14Q002 +default = G321D +description = "Type of LCD module. +Note: Currently only tested with G321D & SP14Q002." + +[sed1330/#/cellsize] +type = string +check/type = string +check/validation =[6-8]x([1-9][0-6]|[1-9]) +check/validation/match = LINE +check/validation/message = Width x Height of a character cell in pixels [legal: 6x7 - 8x16] +default = 6x10 +description = Width x Height of a character cell in pixels + +[sed1330/#/connectiontype] +type = enum +check/type = enum +check/enum = #1 +check/enum/#0 = classic +check/enum/#1 = bitshaker +default = classic +description = "Select what type of connection" + +;sed1520 +;================================================== +[sed1520] +default = "" +array = #0 + +[sed1520/#] +type = struct +check/type = any +default = "" +gen/struct/type = Sed1520DriverConfig +gen/struct/alloc = 0 +description = Configuration for a sed1520 driver. + +[sed1520/#/file] +type = string +default = "sed1520" +description = name of the shared library to load (without prefix and extension) + +[sed1520/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[sed1520/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[sed1520/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[sed1520/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[sed1520/#/port] +type = string +check/type = string +check/validation = 0x([0-9A-F]{3}) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. It should start with 0x, followed by 3 HEX values. eg. 0x3BC +default = 0x378 +description = Port where the LPT is. Usual values are 0x278, 0x378 and 0x3BC + +[sed1520/#/interfacetype] +type = unsigned_short +check/type = unsigned_short +check/range = 68, 80 +default = 80 +description = "Select the interface type (wiring) for the display. Supported values are +68 for 68-style connection (RESET level high) and 80 for 80-style connection +(RESET level low)" + +[sed1520/#/delaymult] +type = unsigned_short +check/type = unsigned_short +check/range = 0-1000 +default = 1 +description = "On fast machines it may be necessary to slow down transfer to the display. +If this value is set to zero, delay is disabled. Any value greater than +zero slows down each write by one microsecond." + +[sed1520/#/haveinverter] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "The original wiring used an inverter to drive the control lines. If you do +not use an inverter set haveInverter to no." + +[sed1520/#/invertedmapping] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "On some displays column data in memory is mapped to segment lines from right +to left. This is called inverted mapping (not to be confused with +'haveInverter' from above)." + +[sed1520/#/usehardreset] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "At least one display is reported (Everbouquet MG1203D) that requires sending +three times 0xFF before a reset during initialization." + +;serialPOS +;================================================== +[serialpos] +default = "" +array = #0 + +[serialpos/#] +type = struct +check/type = any +default = "" +gen/struct/type = SerialPOSDriverConfig +gen/struct/alloc = 0 +description = Configuration for a serialPOS driver. + +[serialpos/#/file] +type = string +default = "serialPOS" +description = name of the shared library to load (without prefix and extension) + +[serialpos/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[serialpos/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[serialpos/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[serialpos/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[serialpos/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS0 +description = "Device to use in serial mode" + +[serialpos/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = "Specifies the size of the display in characters." + +[serialpos/#/cellsize] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 5x8 +description = "Specifies the cell size of each character cell on the display in characters." + +[serialpos/#/custom_chars] +type = unsigned_long +check/type = unsigned_long +check/validation = ^([1-9]\d*|0)$ +check/validation/match = LINE +check/validation/message = Must be any positive number including 0 +default = 0 +description = "Specifies the number of custom characters supported by the display. +Custom characters are only used for the rendering of horizontal bars +and vertical bars. For displays whose cell character cell widths are +lower than the number of custom characters supported, +then custom characters will be used to render the horizontal bars. +For more information look at: https://github.com/lcdproc/lcdproc/blob/master/docs/lcdproc-user/drivers/serialPOS.docbook" + +[serialpos/#/type] +type = enum +check/type = enum +check/enum = #5 +check/enum/#0 = AEDEX +check/enum/#1 = CD5220 +check/enum/#2 = Epson +check/enum/#3 = Emax +check/enum/#4 = LogicControls +check/enum/#5 = Ultimate +default = AEDEX +description = "Set the communication protocol to use with the POS display." + +[serialpos/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 4800, 9600, 19200, 115200 +default = 9600 +description = communication baud rate with the display + +;serialVFD +;================================================== +[serialvfd] +default = "" +array = #0 + +[serialvfd/#] +type = struct +check/type = any +default = "" +gen/struct/type = SerialVFDDriverConfig +gen/struct/alloc = 0 +description = Configuration for a serialVFD driver. + +[serialvfd/#/file] +type = string +default = "serialVFD" +description = name of the shared library to load (without prefix and extension) + +[serialvfd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[serialvfd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial brightness. (4 steps 0-250, 251-500, 501-750, 751-1000) + +[serialvfd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 +description = "Set the initial off-brightness +This value is used when the display is normally +switched off in case LCDd is inactive +(4 steps 0-250, 251-500, 501-750, 751-1000)" + +[serialvfd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[serialvfd/#/type] +type = unsigned_short +check/type = unsigned_short +check/enum = #_17 +check/enum/#0 = nec_fipc8367 +check/enum/#1 = kd_rev_2_1 +check/enum/#2 = noritake_vfd +check/enum/#3 = futaba_vfd +check/enum/#4 = iee_s03601-95b +check/enum/#5 = iee_s03601-96-080 +check/enum/#6 = futaba_na202sd08fa +check/enum/#7 = samsung_20s207da4/20s207da6 +check/enum/#8 = nixdorf_ba6x/vt100 +check/enum/#_9 = 0 +gen/enum/value = 0 +check/enum/#_10 = 1 +gen/enum/value = 1 +check/enum/#_11 = 2 +gen/enum/value = 2 +check/enum/#_12 = 3 +gen/enum/value = 3 +check/enum/#_13 = 4 +gen/enum/value = 4 +check/enum/#_14 = 5 +gen/enum/value = 5 +check/enum/#_15 = 6 +gen/enum/value = 6 +check/enum/#_16 = 7 +gen/enum/value = 7 +check/enum/#_17 = 8 +gen/enum/value = 8 +gen/enum/type = SerialVFDType +default = 0 +description = "Specifies the displaytype.[default: 0] +0 NEC (FIPC8367 based) VFDs. +1 KD Rev 2.1. +2 Noritake VFDs (*). +3 Futaba VFDs +4 IEE S03601-95B +5 IEE S03601-96-080 (*) +6 Futaba NA202SD08FA (allmost IEE compatible) +7 Samsung 20S207DA4 and 20S207DA6 +8 Nixdorf BA6x / VT100 +(* most should work, not tested yet.)" + +[serialvfd/#/use_parallel] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "'no' if display connected serial, 'yes' if connected parallel. +I.e. serial by default" + +[serialvfd/#/custom-characters] +type = unsigned_long +check/type = unsigned_long +default = 0 +description = "Number of Custom-Characters. default is display type dependent" + +[serialvfd/#/port] +type = string +check/type = string +check/validation = 0x([0-9A-F]{3}) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. It should start with 0x, followed by 3 HEX values. eg. 0x3BC +default = 0x378 +description = Portaddress where the LPT is. Used in parallel mode only. Usual values are 0x278, 0x378 and 0x3BC. + +[serialvfd/#/portwait] +type = unsigned_short +check/type = unsigned_short +check/range = 0-255 +default = 2 +description = Set parallel port timing delay (us). Used in parallel mode only. + +[serialvfd/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyS1 +description = "Device to use in serial mode. Usual values are /dev/ttyS0 and /dev/ttyS1" + +[serialvfd/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x2 +description = "Specifies the size of the VFD." + +[serialvfd/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200, 115200 +default = 9600 +description = set the serial port speed + +[serialvfd/#/iso_8859_1] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "enable ISO 8859 1 compatibility" + +;sli +;================================================== +[sli] +default = "" +array = #0 + +[sli/#] +type = struct +check/type = any +default = "" +gen/struct/type = SliDriverConfig +gen/struct/alloc = 0 +description = Configuration for a sli driver. + +[sli/#/file] +type = string +default = "sli" +description = name of the shared library to load (without prefix and extension) + +[sli/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[sli/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[sli/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[sli/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[sli/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "Select the output device to use" + +[sli/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 1200, 2400, 9600, 19200, 38400, 57600, 115200 +default = 19200 +description = Set the communication speed + +;stv5730 +;================================================== +[stv5730] +default = "" +array = #0 + +[stv5730/#] +type = struct +check/type = any +default = "" +gen/struct/type = Stv5730DriverConfig +gen/struct/alloc = 0 +description = Configuration for a stv5730 driver. + +[stv5730/#/file] +type = string +default = "stv5730" +description = name of the shared library to load (without prefix and extension) + +[stv5730/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[stv5730/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[stv5730/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[stv5730/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[stv5730/#/port] +type = string +check/type = string +check/validation = 0x([0-9A-F]{3}) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. It should start with 0x, followed by 3 HEX values. eg. 0x3BC +default = 0x378 +description = Port the device is connected to + +;SureElec +;================================================== +[sureelec] +default = "" +array = #0 + +[sureelec/#] +type = struct +check/type = any +default = "" +gen/struct/type = SureElecDriverConfig +gen/struct/alloc = 0 +description = Configuration for a SureElec driver. + +[sureelec/#/file] +type = string +default = "SureElec" +description = name of the shared library to load (without prefix and extension) + +[sureelec/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 480 +check/range = 0-1000 +description = Set the initial contrast + +[sureelec/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 480 +check/range = 0-1000 + +[sureelec/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 480 +check/range = 0-1000 +description = "Set the initial off-brightness +This value is used when the display is normally +switched off in case LCDd is inactive" + +[sureelec/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[sureelec/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyUSB0 +description = "Port the device is connected to (by default first USB serial port)" + +[sureelec/#/edition] +type = unsigned_short +check/type = unsigned_short +check/range = 1-3 +default = 2 +description = Edition level of the device (can be 1, 2 or 3) + +[sureelec/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = "set display size +Note: The size can be obtained directly from device for edition 2 & 3." + +;svga +;================================================== +[svga] +default = "" +array = #0 + +[svga/#] +type = struct +check/type = any +default = "" +gen/struct/type = SvgaDriverConfig +gen/struct/alloc = 0 +description = Configuration for a svga driver. + +[svga/#/file] +type = string +default = "svga" +description = name of the shared library to load (without prefix and extension) + +[svga/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 500 +check/range = 0-1000 +description = Set the initial contrast + +[svga/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 1-1000 + +[svga/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 500 +check/range = 1-1000 + +[svga/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[svga/#/mode] +type = string +check/type = string +default = G320x240x256 +description = "svgalib mode to use [default: G320x240x256 ] +legal values are supported svgalib modes. See man7 pages for allowed values" + +[svga/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "set display size" + +;t6963 +;================================================== +[t6963] +default = "" +array = #0 + +[t6963/#] +type = struct +check/type = any +default = "" +gen/struct/type = T6963DriverConfig +gen/struct/alloc = 0 +description = Configuration for a t6963 driver. + +[t6963/#/file] +type = string +default = "t6963" +description = name of the shared library to load (without prefix and extension) + +[t6963/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[t6963/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[t6963/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[t6963/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[t6963/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 128x64 +description = "set display size in pixels" + +[t6963/#/port] +type = string +check/type = string +check/validation = 0x([2-3][0-9A-F]{2}|400) +check/validation/match = LINE +check/validation/message = Not a valid port declaration. legal: 0x200 - 0x400 +default = 0x378 +description = Parallel port to use + +[t6963/#/bidirectional] +type = boolean +check/type = boolean +default = 1 ; TODO (elektra): default values conversion +description = "Use LPT port in bi-directional mode. This should work on most LPT port and +is required for proper timing!" + +[t6963/#/delaybus] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Insert additional delays into reads / writes." + +[t6963/#/cleargraphic] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = "Clear graphic memory on start-up." + +;tyan +;================================================== +[tyan] +default = "" +array = #0 + +[tyan/#] +type = struct +check/type = any +default = "" +gen/struct/type = TyanDriverConfig +gen/struct/alloc = 0 +description = Configuration for a tyan driver. + +[tyan/#/file] +type = string +default = "tyan" +description = name of the shared library to load (without prefix and extension) + +[tyan/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[tyan/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[tyan/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[tyan/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[tyan/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/lcd +description = "Select the output device to use" + +[tyan/#/speed] +type = unsigned_short +check/type = unsigned_short +check/range = 4800, 9600 +default = 9600 +description = Set the communication speed + +[tyan/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 16x2 +description = "set display size" + + +;ula200 +;================================================== +[ula200] +default = "" +array = #0 + +[ula200/#] +type = struct +check/type = any +default = "" +gen/struct/type = Ula200DriverConfig +gen/struct/alloc = 0 +description = Configuration for a ula200 driver. + +[ula200/#/file] +type = string +default = "ula200" +description = name of the shared library to load (without prefix and extension) + +[ula200/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[ula200/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[ula200/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[ula200/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[ula200/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "Select the LCD size" + +[ula200/#/keymap_a] +type = string +check/type = string +default = Up +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[ula200/#/keymap_b] +type = string +check/type = string +default = Down +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[ula200/#/keymap_c] +type = string +check/type = string +default = Left +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[ula200/#/keymap_d] +type = string +check/type = string +default = Right +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[ula200/#/keymap_e] +type = string +check/type = string +default = Enter +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +[ula200/#/keymap_f] +type = string +check/type = string +default = Escape +description = "If you have a non standard keypad you can associate any keystrings to keys. +There are 6 input key in the CwLnx hardware that generate characters +from 'A' to 'F'. +# +You can leave those unchanged if you have a standard keypad. +You can change it if you want to report other keystrings or have a non +standard keypad." + +;vlsys_m428 +;================================================== +[vlsys_m428] +default = "" +array = #0 + +[vlsys_m428/#] +type = struct +check/type = any +default = "" +gen/struct/type = Vlsys_m428DriverConfig +gen/struct/alloc = 0 +description = Configuration for a vlsys_m428 driver. + +[vlsys_m428/#/file] +type = string +default = "vlsys_m428" +description = name of the shared library to load (without prefix and extension) + +[vlsys_m428/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[vlsys_m428/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[vlsys_m428/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[vlsys_m428/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[vlsys_m428/#/device] +type = string +check/type = string +; check/path = ; TODO (elektra): too many plugins +default = /dev/ttyUSB0 +description = "Select the output device to use" + +;yard2LCD +;================================================== +[yard2lcd] +default = "" +array = #0 + +[yard2lcd/#] +type = struct +check/type = any +default = "" +gen/struct/type = Yard2LCDDriverConfig +gen/struct/alloc = 0 +description = Configuration for a yard2LCD driver. + +[yard2lcd/#/file] +type = string +default = "yard2LCD" +description = name of the shared library to load (without prefix and extension) + +[yard2lcd/#/contrast] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 +description = Set the initial contrast + +[yard2lcd/#/brightness] +type = unsigned_short +check/type = unsigned_short +default = 1000 +check/range = 0-1000 + +[yard2lcd/#/offbrightness] +type = unsigned_short +check/type = unsigned_short +default = 0 +check/range = 0-1000 + +[yard2lcd/#/reboot] +type = boolean +check/type = boolean +default = 0 ; TODO (elektra): default values conversion +description = Reinitialize the LCD`s BIOS normally you shouldn`t need this + +[yard2lcd/#/size] +type = string +check/type = string +check/validation = ([1-9]+[0-9]*)x([1-9]+[0-9]*) +check/validation/match = LINE +check/validation/message = Not a valid size declaration. Examples: 20x4, 19x3, 40x150 +default = 20x4 +description = "set display size" diff --git a/shared/Makefile.am b/shared/Makefile.am index 1356cf07..be982a23 100644 --- a/shared/Makefile.am +++ b/shared/Makefile.am @@ -2,12 +2,12 @@ noinst_LIBRARIES = libLCDstuff.a -libLCDstuff_a_SOURCES = LL.c LL.h sockets.c sockets.h str.c str.h configfile.c configfile.h report.c report.h snprintf.c snprintf.h sring.c sring.h +libLCDstuff_a_SOURCES = LL.c LL.h sockets.c sockets.h str.c str.h report.c report.h sring.c sring.h libLCDstuff_a_LIBADD = @LIBOBJS@ AM_CPPFLAGS = -I$(top_srcdir) -EXTRA_DIST = getopt.c getopt1.c getopt.h defines.h +EXTRA_DIST = defines.h ## EOF diff --git a/shared/configfile.c b/shared/configfile.c deleted file mode 100644 index 303cc186..00000000 --- a/shared/configfile.c +++ /dev/null @@ -1,833 +0,0 @@ -/** \file configfile.c - * Define routines to read INI-file like files. - */ - -/* This file is part of LCDd, the lcdproc server. - * - * This file is released under the GNU General Public License. Refer to the - * COPYING file distributed with this package. - * - * Copyright(c) 2001, Joris Robijn - * (c) 2003, Rene Wagner - * (c) 2006,2007 Peter Marschall - * - */ - -#include -#include -#include -#include -#include - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "shared/report.h" - - -/** configuration key */ -typedef struct _config_key { - char *name; /**< name of the config key */ - char *value; /**< value of the config key */ - struct _config_key *next_key; /**< pointer to next config key */ -} ConfigKey; - -/** configuration section */ -typedef struct _config_section { - char *name; /**< name of the config section */ - ConfigKey *first_key; /**< config keys in the config section */ - struct _config_section *next_section; /**< pointer to next config section */ -} ConfigSection; - - -static ConfigSection *first_section = NULL; -/* Yes there is a static. It's C after all :)*/ - - -static ConfigSection *find_section(const char *sectionname); -static ConfigSection *add_section(const char *sectionname); -static ConfigKey *find_key(ConfigSection *s, const char *keyname, int skip); -static ConfigKey *add_key(ConfigSection *s, const char *keyname, const char *value); -#if defined(LCDPROC_CONFIG_READ_STRING) -static char get_next_char_f(FILE *f); -static int process_config(ConfigSection **current_section, char(*get_next_char)(), const char *source_descr, FILE *f); -#else -static int process_config(ConfigSection **current_section, const char *source_descr, FILE *f); -#endif - - -/**** PUBLIC FUNCTIONS ****/ - -/** Parse configuration from INI-file style config file into memory. - * \param filename Name of the config file. - * \retval 0 config successfully parsed - * \retval <0 error occurred - */ -int config_read_file(const char *filename) -{ - FILE *f; - ConfigSection *curr_section = NULL; - int result = 0; - - report(RPT_NOTICE, "Using Configuration File: %s", filename); - - f = fopen(filename, "r"); - if (f == NULL) { - return -1; - } - -#if defined(LCDPROC_CONFIG_READ_STRING) - result = process_config(&curr_section, get_next_char_f, filename, f); -#else - result = process_config(&curr_section, filename, f); -#endif - - fclose(f); - - return result; -} - - -#if defined(LCDPROC_CONFIG_READ_STRING) -int config_read_string(const char *sectionname, const char *str) -/* All the config parameters are placed in the given section in memory.*/ -{ - int pos = 0; - ConfigSection *s; - - /* We use a nested function to transfer the characters from buffer to parser*/ - char get_next_char() { - return str[pos++]; - } - - if ((s = find_section(sectionname)) == NULL) - s = add_section(sectionname); - - return process_config(&s, get_next_char, "command line", NULL); -} -#endif - - -/** Get string from configuration in memory. - * - * The strings returned are always NUL-terminated. - * They should never be modified, and used only short-term. - * In successive calls this function can re-use the data space ! - * - * You can do some things with the returned string: - * \li Scan or parse it: - * \code - * s = config_get_string(...); - * sscanf(s, "%dx%d", &w, &h); // scan format like: 20x4 - * \endcode - * ...and check the w and h values... - * \li Copy it to a pre-allocated buffer like \c device[256]: - * \code - * s = config_get_string(...); - * strncpy(device, s, sizeof(device)); - * device[sizeof(device)-1] = '\0'; // make sure it is terminated - * \endcode - * \li Copy it to a newly allocated space in \c char \c *device: - * \code - * s = config_get_string(...); - * device = malloc(strlen(s)+1); - * if (device == NULL) return -5; // or whatever < 0 - * strcpy( device, s ); - * \endcode - * - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \param skip Number of values to skip/ignore before returning the value. - * This is used to iterate through the values of a multi-valued key: - * \c 0 for the first value, \c 1 for the 2nd, ... and \c -1 for the last. - * \param default_value Default value if section/key is not found - * or \c skip exceeds the number of values of the key. - * \return Value found / \c default_value - */ -const char *config_get_string(const char *sectionname, const char *keyname, - int skip, const char *default_value) -{ - ConfigKey *k = find_key(find_section(sectionname), keyname, skip); - - if (k == NULL) - return default_value; - - return k->value; - -/* This is the safer way:*/ - - /* Reallocate memory space for the return value*/ - /* - string_storage = realloc(string_storage,(strlen(k->value) / 256 + 1) * 256); - strcpy(string_storage, k->value); - - But then you also need a global static string_storage = NULL; -*/ -} - - -/** Get boolean value from configuration in memory. - * - * Legal boolean values are: - * \li \c 0 , \c false , \c off , \c no or \c n for FALSE. - * \li \c 1 , \c true , \c on , \c yes or \c y for TRUE - * - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \param skip Number of values to skip/ignore before returning the value. - * This is used to iterate through the values of a multi-valued key: - * \c 0 for the first value, \c 1 for the 2nd, ... and \c -1 for the last. - * \param default_value Default value if section/key is not found, value is no legal boolean, - * or \c skip exceeds the number of values of the key. - * \return Value found / \c default_value - */ -short config_get_bool(const char *sectionname, const char *keyname, - int skip, short default_value) -{ - ConfigKey *k = find_key(find_section(sectionname), keyname, skip); - - if (k == NULL) - return default_value; - - if ((strcasecmp(k->value, "0") == 0) || (strcasecmp(k->value, "false") == 0) || - (strcasecmp(k->value, "n") == 0) || (strcasecmp(k->value, "no") == 0) || - (strcasecmp(k->value, "off") == 0)) { - return 0; - } - if ((strcasecmp(k->value, "1") == 0) || (strcasecmp(k->value, "true") == 0) || - (strcasecmp(k->value, "y") == 0) || (strcasecmp(k->value, "yes") == 0) || - (strcasecmp(k->value, "on") == 0)) { - return 1; - } - return default_value; -} - - -/** Get tristate value from configuration in memory. - * - * Legal tristate values are: - * \li \c 0 , \c false , \c off , \c no or \c n for 0. - * \li \c 1 , \c true , \c on , \c yes or \c y for 1 - * \li \c 2 or the given name of the third state for 2 - * - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \param skip Number of values to skip/ignore before returning the value. - * This is used to iterate through the values of a multi-valued key: - * \c 0 for the first value, \c 1 for the 2nd, ... and \c -1 for the last. - * \param name3rd Name of the 3rd state - * \param default_value Default value if section/key is not found, value is no legal boolean, - * or \c skip exceeds the number of values of the key. - * \return Value found / \c default_value - */ -short config_get_tristate(const char *sectionname, const char *keyname, - int skip, const char *name3rd, short default_value) -{ - ConfigKey *k = find_key(find_section(sectionname), keyname, skip); - - if (k == NULL) - return default_value; - - if ((strcasecmp(k->value, "0") == 0) || (strcasecmp(k->value, "false") == 0) || - (strcasecmp(k->value, "n") == 0) || (strcasecmp(k->value, "no") == 0) || - (strcasecmp(k->value, "off") == 0)) { - return 0; - } - if ((strcasecmp(k->value, "1") == 0) || (strcasecmp(k->value, "true") == 0) || - (strcasecmp(k->value, "y") == 0) || (strcasecmp(k->value, "yes") == 0) || - (strcasecmp(k->value, "on") == 0)) { - return 1; - } - if ((strcasecmp(k->value, "2") == 0) || - ((name3rd != NULL) && (strcasecmp(k->value, name3rd) == 0))) { - return 2; - } - return default_value; -} - - -/** Get integer from configuration in memory. - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \param skip Number of values to skip/ignore before returning the value. - * This is used to iterate through the values of a multi-valued key: - * \c 0 for the first value, \c 1 for the 2nd, ... and \c -1 for the last. - * \param default_value Default value if section/key is not found, value is no integer, - * or \c skip exceeds the number of values of the key. - * \return Value found / \c default_value - */ -long int config_get_int(const char *sectionname, const char *keyname, - int skip, long int default_value) -{ - ConfigKey *k = find_key(find_section(sectionname), keyname, skip); - - if (k != NULL) { - char *end; - long int v = strtol(k->value, &end, 0); - - if ((end != NULL) && (end != k->value) && (*end == '\0')) - /* Conversion successful */ - return v; - } - return default_value; -} - - -/** Get floating point number from configuration in memory. - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \param skip Number of values to skip/ignore before returning the value. - * This is used to iterate through the values of a multi-valued key: - * \c 0 for the first value, \c 1 for the 2nd, ... and \c -1 for the last. - * \param default_value Default value if section/key is not found, value is no floating point number - * or \c skip exceeds the number of values of the key. - * \return Value found / \c default_value - */ -double config_get_float(const char *sectionname, const char *keyname, - int skip, double default_value) -{ - ConfigKey *k = find_key(find_section(sectionname), keyname, skip); - - if (k != NULL) { - char *end; - double v = strtod(k->value, &end); - - if ((end != NULL) && (end != k->value) && (*end == '\0')) - /* Conversion successful*/ - return v; - } - return default_value; -} - - -/** Test whether the configuration contains a specific section. - * \param sectionname Name of the section to look for. - * \retval 0 section not in config - * \retval 1 section in config - */ -int config_has_section(const char *sectionname) -{ - return (find_section(sectionname) != NULL) ? 1 : 0; -} - - -/** Test whether the configuration contains a specific key in a specific section. - * \param sectionname Name of the section where the key is sought. - * \param keyname Name of the key to look for. - * \retval 0 key or section not found - * \retval n key found with \c n values (\c n > 0) - */ -int config_has_key(const char *sectionname, const char *keyname) -{ - ConfigSection *s = find_section(sectionname); - int count = 0; - - if (s != NULL) { - ConfigKey *k; - - for (k = s->first_key; k != NULL; k = k->next_key) { - /* Did we find the right key ?*/ - if (strcasecmp(k->name, keyname) == 0) - count++; - } - } - return count; -} - - -/** Clear configuration. */ -void config_clear(void) -{ - ConfigSection *s; - ConfigSection *next_s; - - for (s = first_section; s != NULL; s = next_s) { - ConfigKey *k; - ConfigKey *next_k; - - for (k = s->first_key; k != NULL; k = next_k) { - /* Advance before we destroy the current key */ - next_k = k->next_key; - - free(k->name); - free(k->value); - free(k); - } - /* Advance before we destroy the current section */ - next_s = s->next_section; - - /* And destroy it */ - free(s->name); - free(s); - } - /* Finally make everything inaccessible */ - first_section = NULL; -} - - -/**** INTERNAL FUNCTIONS ****/ - -static ConfigSection *find_section(const char *sectionname) -{ - ConfigSection *s; - - for (s = first_section; s != NULL; s = s->next_section) { - if (strcasecmp(s->name, sectionname) == 0) { - return s; - } - } - return NULL; /* not found */ -} - - -static ConfigSection *add_section(const char *sectionname) -{ - ConfigSection *s; - ConfigSection **place = &first_section; - - for (s = first_section; s != NULL; s = s->next_section) - place = &(s->next_section); - - *place = (ConfigSection *) malloc(sizeof(ConfigSection)); - if (*place != NULL) { - (*place)->name = strdup(sectionname); - (*place)->first_key = NULL; - (*place)->next_section = NULL; - } - - return(*place); -} - - -static ConfigKey *find_key(ConfigSection *s, const char *keyname, int skip) -{ - ConfigKey *k; - int count = 0; - ConfigKey *last_key = NULL; - - /* Check for NULL section*/ - if (s == NULL) - return NULL; - - for (k = s->first_key; k != NULL; k = k->next_key) { - - /* Did we find the right key ?*/ - if (strcasecmp(k->name, keyname) == 0) { - if (count == skip) - return k; - - count++; - last_key = k; - } - } - if (skip == -1) - return last_key; - - return NULL; /* not found*/ -} - - -static ConfigKey *add_key(ConfigSection *s, const char *keyname, const char *value) -{ - if (s != NULL) { - ConfigKey *k; - ConfigKey **place = &(s->first_key); - - for (k = s->first_key; k != NULL; k = k->next_key) - place = &(k->next_key); - - *place = (ConfigKey *) malloc(sizeof(ConfigKey)); - if (*place != NULL) { - (*place)->name = strdup(keyname); - (*place)->value = strdup(value); - (*place)->next_key = NULL; - } - - return(*place); - } - return NULL; -} - - -#if defined(LCDPROC_CONFIG_READ_STRING) -static char get_next_char_f(FILE *f) -{ - int c = fgetc(f); - - return((c == EOF) ? '\0' : c); -} -#endif - - -/* Parser states */ -#define ST_INITIAL 0 -#define ST_COMMENT 257 -#define ST_SECTIONLABEL 258 -#define ST_KEYNAME 259 -#define ST_ASSIGNMENT 260 -#define ST_VALUE 261 -#define ST_QUOTEDVALUE 262 -#define ST_SECTIONLABEL_DONE 263 -#define ST_VALUE_DONE 264 -#define ST_INVALID_SECTIONLABEL 265 -#define ST_INVALID_KEYNAME 266 -#define ST_INVALID_ASSIGNMENT 267 -#define ST_INVALID_VALUE 268 -#define ST_END 999 - -/* Limits */ -#define MAXSECTIONLABELLENGTH 40 -#define MAXKEYNAMELENGTH 40 -#define MAXVALUELENGTH 200 - - -#if defined(LCDPROC_CONFIG_READ_STRING) -static int process_config(ConfigSection **current_section, char(*get_next_char)(), const char *source_descr, FILE *f) -#else -static int process_config(ConfigSection **current_section, const char *source_descr, FILE *f) -#endif -{ - int state = ST_INITIAL; - int ch; - char sectionname[MAXSECTIONLABELLENGTH+1]; - int sectionname_pos = 0; - char keyname[MAXKEYNAMELENGTH+1]; - int keyname_pos = 0; - char value[MAXVALUELENGTH+1]; - int value_pos = 0; - int escape = 0; - int line_nr = 1; - int error = 0; - -#if !defined(LCDPROC_CONFIG_READ_STRING) - if (f == NULL) - return(0); -#endif - - while (state != ST_END) { - -#if defined(LCDPROC_CONFIG_READ_STRING) - ch = (f != NULL) - ? get_next_char(f) - : get_next_char(); -#else - ch = fgetc(f); - if (ch == EOF) - ch = '\0'; -#endif - - /* Secretly keep count of the line numbers */ - if (ch == '\n') - line_nr++; - - switch (state) { - case ST_INITIAL: - switch (ch) { - case '#': - case ';': - /* comment start */ - state = ST_COMMENT; - /* fall through */ - case '\0': - case '\n': - case '\r': - case '\t': - case ' ': - /* ignore spaces */ - break; - case '[': - /* section name */ - state = ST_SECTIONLABEL; - sectionname_pos = 0; - sectionname[sectionname_pos] = '\0'; - break; - default: - /* key word */ - state = ST_KEYNAME; - keyname_pos = 0; - keyname[keyname_pos++] = ch; - keyname[keyname_pos] = '\0'; - } - break; - case ST_SECTIONLABEL: - /* section label: "["{non-space chars}+"]" */ - switch (ch) { - case '\0': - case '\n': - /* premature end of label */ - report(RPT_WARNING, "Unterminated section label on line %d of %s: %s", - line_nr, source_descr, sectionname); - error = 1; - state = ST_INITIAL; /* already at the end, no resync required */ - break; - case ']': - /* label terminated: find/create section */ - if (!(*current_section = find_section(sectionname))) { - *current_section = add_section(sectionname); - } - state = ST_SECTIONLABEL_DONE; - break; - // case '\r': - // case '\t': - // case ' ': - // /* no spaces allowed in section labels WHY? */ - // report(RPT_WARNING, "Invalid character in section label on line %d of %s: %s", - // line_nr, source_descr, sectionname); - // error = 1; - // state = ST_INVALID_SECTIONLABEL; /* resync required */ - // break; - default: - /* append char to section label */ - if (sectionname_pos < MAXSECTIONLABELLENGTH) { - sectionname[sectionname_pos++] = ch; - sectionname[sectionname_pos] = '\0'; - break; - } - report(RPT_WARNING, "Section name too long on line %d of %s: %s", - line_nr, source_descr, sectionname); - error = 1; - state = ST_INVALID_SECTIONLABEL; /* resync required */ - } - break; - case ST_KEYNAME: - /* key name: {non-space chars}+ */ - switch (ch) { - case '\r': - case '\t': - case ' ': - /* ignore trailing spaces */ - if (keyname_pos != 0) - state = ST_ASSIGNMENT; - break; - case '\0': - case '\n': - /* premature end of line */ - report(RPT_WARNING, "Loose word found on line %d of %s: %s", - line_nr, source_descr, keyname); - error = 1; - state = ST_INITIAL; /* already at the end; no resync required */ - break; - case '=': - /* end of key reached, "=" found, now we need a value */ - state = ST_VALUE; - value[0] = '\0'; - value_pos = 0; - break; - // case '"': - // case '[': - // case ']': - // /* character invalid in key names WHY ? */ - // report(RPT_WARNING, "Invalid character in key name on line %d of %s: %s", - // line_nr, source_descr, keyname); - // error = 1; - // state = ST_INVALID_KEYNAME; /* resync required */ - // break; - default: - /* append char to key name */ - if (keyname_pos < MAXKEYNAMELENGTH) { - keyname[keyname_pos++] = ch; - keyname[keyname_pos] = '\0'; - break; - } - report(RPT_WARNING, "Key name too long on line %d of %s: %s", - line_nr, source_descr, keyname); - error = 1; - state = ST_INVALID_KEYNAME; /* resync required */ - } - break; - case ST_ASSIGNMENT: - /* assignment: "=" */ - switch (ch) { - case '\t': - case ' ': - /* ignore leading spaces */ - break; - case '=': - /* "=" found, now we need a value */ - state = ST_VALUE; - value[0] = '\0'; - value_pos = 0; - break; - default: - report(RPT_WARNING, "Assignment expected on line %d of %s: %s", - line_nr, source_descr, keyname); - error = 1; - state = ST_INVALID_ASSIGNMENT; - } - break; - case ST_VALUE: - /* value: {non-space char}+ | "\""{any potentially-quoted char}+"\"" */ - switch (ch) { - case '#': - case ';': - /* allow comment if we already had a value */ - /* WHY ONLY THEN ? 'xx=' can be seen as equivalent to 'xx=""' */ - if (value_pos > 0) { - state = ST_COMMENT; - break; - } - /* fall through */ - case '[': - case ']': - case '=': - /* illegal characters WHY? */ - report(RPT_WARNING, "Invalid character '%c' in value on line %d of %s, at key: %s", - ch, line_nr, source_descr, keyname); - error = 1; - state = ST_INVALID_VALUE; - break; - case '\t': - case ' ': - /* ignore leading spaces */ - if (value_pos == 0) - break; - /* fall through */ - case '\0': - case '\n': - case '\r': - /* value complete */ - if (!*current_section) { - report(RPT_WARNING, "Data outside sections on line %d of %s with key: %s", - line_nr, source_descr, keyname); - error = 1; - } - else { - /* Store the value*/ - (void) add_key(*current_section, keyname, value); - } - /* And be ready for next thing...*/ - state = ((ch == ' ') || (ch == '\t')) ? ST_VALUE_DONE : ST_INITIAL; - break; - case '"': - /* quoted string */ - state = ST_QUOTEDVALUE; - break; - default: - /* append char to value */ - if (value_pos < MAXVALUELENGTH) { - value[value_pos++] = ch; - value[value_pos] = '\0'; - break; - } - report(RPT_WARNING, "Value too long on line %d of %s, at key: %s", - line_nr, source_descr, keyname); - error = 1; - state = ST_INVALID_VALUE; - } - break; - case ST_QUOTEDVALUE: - /* a quoted part of a string */ - switch (ch) { - case '\0': - case '\n': - report(RPT_WARNING, "Premature end of quoted string on line %d of %s: %s", - line_nr, source_descr, keyname); - error = 1; - state = ST_INITIAL; - break; - case '\\': - if (!escape) { - escape = 1; - break; - } - /* fall through */ - case '"': - if (!escape) { - state = ST_VALUE; - break; - } - /* fall through */ - default: - if (escape) { - switch (ch) { - case 'a': ch = '\a'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - /* default: literal char (i.e. ignore '\') */ - } - escape = 0; - } - value[value_pos++] = ch; - value[value_pos] = '\0'; - } - break; - case ST_SECTIONLABEL_DONE: - case ST_VALUE_DONE: - switch (ch) { - case ';': - case '#': - state = ST_COMMENT; - break; - case '\0': - case '\n': - state = ST_INITIAL; - break; - case '\t': - case ' ': - break; - default: - /* illegal characters */ - report(RPT_WARNING, "Invalid character '%c' on line %d of %s", - ch, line_nr, source_descr); - error = 1; - state = ST_INVALID_VALUE; - } - case ST_INVALID_SECTIONLABEL: - /* invalid section label: resync up to end of label/next line */ - if (ch == ']') - state = ST_INITIAL; - /* fall through */ - case ST_INVALID_ASSIGNMENT: - case ST_INVALID_KEYNAME: - case ST_INVALID_VALUE: - case ST_COMMENT: - /* comment or error: ignore anything up to the next line */ - if (ch == '\n') - state = ST_INITIAL; - } - if (ch == '\0') { - if ((!error) && (state != ST_INITIAL) && (state != ST_COMMENT) && - (state != ST_SECTIONLABEL_DONE) && (state != ST_VALUE_DONE)) { - report(RPT_WARNING, "Premature end of configuration on line %d of %s: %d", - line_nr, source_descr, state); - - error = 1; - } - state = ST_END; - } - - } - return (error) ? -1 : 0; -} - - -#if CONFIGFILE_DEBUGTEST -void config_dump(void) -{ -ConfigSection *s; - - for (s = first_section; s != NULL; s = s->next_section) { - ConfigKey *k; - - fprintf(stderr, "[%s]\n", s->name); - - for (k = s->first_key; k != NULL; k = k->next_key) - fprintf(stderr, "%s = \"%s\"\n", k->name, k->value); - - fprintf(stderr, "\n"); - } -} - - -int main(int argc, char *argv[]) -{ - if (argc > 0) - config_read_file(argv[1]); - config_dump(); -} -#endif diff --git a/shared/configfile.h b/shared/configfile.h deleted file mode 100644 index 0164b639..00000000 --- a/shared/configfile.h +++ /dev/null @@ -1,107 +0,0 @@ -/** \file configfile.h - * Declare routines to read INI-file like files. - */ - -/* This file is part of LCDd, the lcdproc server. - * - * This file is released under the GNU General Public License. Refer to the - * COPYING file distributed with this package. - * - * Copyright (c) 2001, Joris Robijn - * (c) 2006,2007 Peter Marschall - * - */ - -#ifndef CONFIGFILE_H -#define CONFIGFILE_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Opens the specified file and reads everything into memory. - * Returns 0 when config file was successfully parsed - * Returns <0 on errors - */ -int config_read_file(const char *filename); - -#if defined(LCDPROC_CONFIG_READ_STRING) -/* Reads everything in the string into memory. - * Returns 0 when config file was successfully parsed - * Returns <0 on errors - */ -int config_read_string(const char *sectionname, const char *str); -#endif - -/* Tries to interpret a value in the config file as a boolean. - * 0, false, off, no, n = false - * 1, true, on, yes, y = true - * If the key is not found or cannot be interpreted, the given default value is - * returned. - * The skip value can be used to iterate over multiple values with the same - * key. Should be 0 to get the first one, 1 for the second etc. and -1 for the - * last. - */ -short config_get_bool(const char *sectionname, const char *keyname, - int skip, short default_value); - -/* Tries to interpret a value in the config file as a boolean. - * 0, false, off, no, n = 0 - * 1, true, on, yes, y = 1 - * 2, or the given 3rd name = 2 - * If the key is not found or cannot be interpreted, the given default value is - * returned. - * The skip value can be used to iterate over multiple values with the same - * key. Should be 0 to get the first one, 1 for the second etc. and -1 for the - * last. - */ -short config_get_tristate(const char *sectionname, const char *keyname, - int skip, const char *name3rd, short default_value); - -/* Tries to interpret a value in the config file as an integer.*/ -long int config_get_int(const char *sectionname, const char *keyname, - int skip, long int default_value); - -/* Tries to interpret a value in the config file as a float.*/ -double config_get_float(const char *sectionname, const char *keyname, - int skip, double default_value); - -/* Returns a pointer to the string associated with the specified key. - * The strings returned are always NUL-terminated. - * The string should never be modified, and used only short-term. - * In successive calls this function can * re-use the data space ! - * - * You can do some things with the returned string: - * 1. Scan or parse it: - * s = config_get_string(...); - * sscanf( s, "%dx%d", &w, &h ); // scan format like: 20x4 - * ...and check the w and h values... - * 2. Copy it to a preallocated buffer like device[256]: - * s = config_get_string(...); - * strncpy( device, s, sizeof(device)); - * device[sizeof(device)-1] = 0; - * 3. Copy it to a newly allocated space in char *device: - * s = config_get_string(...); - * device = malloc(strlen(s)+1); - * if( device == NULL ) return -5; // or whatever < 0 - * strcpy( device, s ); - */ -const char *config_get_string(const char *sectionname, const char *keyname, - int skip, const char *default_value); - -/* Checks if a specified section exists. - * Returns whether it exists. - */ -int config_has_section(const char *sectionname); - -/* Checks if a specified key within the specified section exists. - * Returns the number of times the key exists. - */ -int config_has_key(const char *sectionname, const char *keyname); - -/* Clears all data stored by the config_read_* functions. - * Should be called if the config should be reread. - */ -void config_clear(void); - -#endif diff --git a/shared/getopt.c b/shared/getopt.c deleted file mode 100644 index 5b6fe98e..00000000 --- a/shared/getopt.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* Getopt for GNU. - NOTE: The canonical source of this file is maintained with the GNU - C Library. Bugs can be reported to bug-glibc@gnu.org. - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 - Free Software Foundation, Inc. - - 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, 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. - - 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -# ifndef const -# define const -# endif -# endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -# include -# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ - -#ifdef VMS -# include -# if HAVE_STRING_H - 0 -# include -# endif -#endif - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. - When compiling libc, the _ macro is predefined. */ -# ifdef HAVE_LIBINTL_H -# include -# define _(msgid) gettext (msgid) -# else -# define _(msgid) (msgid) -# endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -int __getopt_initialized; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -# include -# define my_index strchr -#else - -# if HAVE_STRING_H -# include -# else -# include -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); -#endif - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -# if (!defined __STDC__ || !__STDC__) && !defined strlen -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -# endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -#ifdef _LIBC -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; - -static int nonoption_flags_max_len; -static int nonoption_flags_len; - -static int original_argc; -static char *const *original_argv; - -/* Make sure the environment variable bash 2.0 puts in the environment - is valid for the getopt call we must make sure that the ARGV passed - to getopt is that one passed to the process. */ -static void -__attribute__ ((unused)) -store_args_and_env (int argc, char *const *argv) -{ - /* XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; -} -# ifdef text_set_element -text_set_element (__libc_subinit, store_args_and_env); -# endif /* text_set_element */ - -# define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -#if defined __STDC__ && __STDC__ -static void exchange (char **); -#endif - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -#if defined __STDC__ && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); -#endif -static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - -#ifdef _LIBC - if (posixly_correct == NULL - && argc == original_argc && argv == original_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } - } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#ifdef _LIBC -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) -#else -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') -#endif - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); - else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/shared/getopt.h b/shared/getopt.h deleted file mode 100644 index c60d1999..00000000 --- a/shared/getopt.h +++ /dev/null @@ -1,169 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@gnu.org. - 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, 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. - - 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 Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -# if defined __STDC__ && __STDC__ - const char *name; -# else - char *name; -# endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `getopt'. */ - -#if (defined __STDC__ && __STDC__) || defined PROTOTYPES -# ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int __argc, char *const *__argv, const char *__shortopts); -# else /* not __GNU_LIBRARY__ */ -extern int getopt (); -# endif /* __GNU_LIBRARY__ */ - -# ifndef __need_getopt -extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, - const struct option *__longopts, int *__longind); -extern int getopt_long_only (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only); -# endif -#else /* not ((defined __STDC__ && __STDC__) || defined PROTOTYPES) */ -extern int getopt (); -# ifndef __need_getopt -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -# endif -#endif /* (defined __STDC__ && __STDC__) || defined PROTOTYPES */ - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/shared/getopt1.c b/shared/getopt1.c deleted file mode 100644 index fb13992a..00000000 --- a/shared/getopt1.c +++ /dev/null @@ -1,188 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 - Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@gnu.org. - - 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, 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. - - 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#else -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif -#endif - -#include "getopt.h" - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -#include -#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/shared/report.h b/shared/report.h index 0a412d98..8217f9c0 100644 --- a/shared/report.h +++ b/shared/report.h @@ -61,6 +61,10 @@ * Ex: What function has been called, what subpart of a function is being * executed, what was received and sent over the socket, etc. */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #define RPT_CRIT 0 #define RPT_ERR 1 #define RPT_WARNING 2 diff --git a/shared/snprintf.c b/shared/snprintf.c deleted file mode 100644 index 642110b4..00000000 --- a/shared/snprintf.c +++ /dev/null @@ -1,1134 +0,0 @@ -/* - * snprintf.c - a portable implementation of snprintf - * - * AUTHOR - * Mark Martinec , April 1999. - * - * Copyright 1999-2002 Mark Martinec. All rights reserved. - * - * TERMS AND CONDITIONS - * This program is free software; it is dual licensed, the terms of the - * "Frontier Artistic License" or the "GNU General Public License" - * can be chosen at your discretion. The chosen license then applies - * solely and in its entirety. Both licenses come with this Kit. - * - * 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 license for more details. - * - * You should have received a copy of the "Frontier Artistic License" - * with this Kit in the file named LICENSE.txt, and the copy of - * the "GNU General Public License" in the file named LICENSE-GPL.txt. - * If not, I'll be glad to provide one. - * - * FEATURES - * - careful adherence to specs regarding flags, field width and precision; - * - good performance for large string handling (large format, large - * argument or large paddings). Performance is similar to system's sprintf - * and in several cases significantly better (make sure you compile with - * optimizations turned on, tell the compiler the code is strict ANSI - * if necessary to give it more freedom for optimizations); - * - return value semantics per ISO/IEC 9899:1999 ("ISO C99"); - * - written in standard ISO/ANSI C - requires an ANSI C compiler; - * - works also with non-ASCII 8-bit character sets (e.g. EBCDIC) - * provided strings are '\0'-terminated. - * - * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES - * - * This snprintf only supports the following conversion specifiers: - * s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below) - * with flags: '-', '+', ' ', '0' and '#'. - * An asterisk is supported for field width and for the precision. - * - * Length modifiers 'h' (short int), 'l' (long int), - * and 'll' (long long int) are supported. - * NOTE: - * If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the - * length modifier 'll' is recognized but treated the same as 'l', - * which may cause argument value truncation! Defining - * SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also - * handles length modifier 'll'. long long int is a language extension - * which may not be portable. - * - * Conversion of numeric data (conversion specifiers d, u, o, x, X, p) - * with length modifiers (none or h, l, ll) is left to the system routine - * sprintf, but all handling of flags, field width and precision as well as - * c and s conversions is done very carefully by this portable routine. - * If a string precision (truncation) is specified (e.g. %.8s) it is - * guaranteed the string beyond the specified precision will not be referenced. - * - * Length modifiers h, l and ll are ignored for c and s conversions (data - * types wint_t and wchar_t are not supported). - * - * The following common synonyms for conversion characters are supported: - * - i is a synonym for d - * - D is a synonym for ld, explicit length modifiers are ignored - * - U is a synonym for lu, explicit length modifiers are ignored - * - O is a synonym for lo, explicit length modifiers are ignored - * The D, O and U conversion characters are nonstandard, they are supported - * for backward compatibility only, and should not be used for new code. - * - * The following is specifically NOT supported: - * - flag ' (thousands' grouping character) is recognized but ignored - * - numeric conversion specifiers: f, e, E, g, G and synonym F, - * as well as the new a and A conversion specifiers - * - length modifier 'L' (long double) and 'q' (quad - use 'll' instead) - * - wide character/string conversions: lc, ls, and nonstandard - * synonyms C and S - * - writeback of converted string length: conversion character n - * - the n$ specification for direct reference to n-th argument - * - locales - * - * It is permitted for str_m to be zero, and it is permitted to specify NULL - * pointer for resulting string argument if str_m is zero (as per ISO C99). - * - * The return value is the number of characters which would be generated - * for the given input, excluding the trailing null. If this value - * is greater or equal to str_m, not all characters from the result - * have been stored in str, output bytes beyond the (str_m-1) -th character - * are discarded. If str_m is greater than zero it is guaranteed - * the resulting string will be null-terminated. - * - * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1, - * but is different from some older and vendor implementations, - * and is also different from XPG, XSH5, SUSv2 specifications. - * For historical discussion on changes in the semantics and standards - * of snprintf see printf(3) man page in the Linux programmers manual. - * - * Routines asprintf and vasprintf return a pointer (in the ptr argument) - * to a buffer sufficiently large to hold the resulting string. This pointer - * should be passed to free(3) to release the allocated storage when it is - * no longer needed. If sufficient space cannot be allocated, these functions - * will return -1 and set ptr to be a NULL pointer. These two routines are a - * GNU C library extensions (glibc). - * - * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf, - * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1 - * characters into the allocated output string, the last character in the - * allocated buffer then gets the terminating null. If the formatted string - * length (the return value) is greater than or equal to the str_m argument, - * the resulting string was truncated and some of the formatted characters - * were discarded. These routines present a handy way to limit the amount - * of allocated memory to some sane value. - * - * AVAILABILITY - * http://www.ijs.si/software/snprintf/ - * - * REVISION HISTORY - * 1999-04 V0.9 Mark Martinec - * - initial version, some modifications after comparing printf - * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, - * and checking how Perl handles sprintf (differently!); - * 1999-04-09 V1.0 Mark Martinec - * - added main test program, fixed remaining inconsistencies, - * added optional (long long int) support; - * 1999-04-12 V1.1 Mark Martinec - * - support the 'p' conversion (pointer to void); - * - if a string precision is specified - * make sure the string beyond the specified precision - * will not be referenced (e.g. by strlen); - * 1999-04-13 V1.2 Mark Martinec - * - support synonyms %D=%ld, %U=%lu, %O=%lo; - * - speed up the case of long format string with few conversions; - * 1999-06-30 V1.3 Mark Martinec - * - fixed runaway loop (eventually crashing when str_l wraps - * beyond 2^31) while copying format string without - * conversion specifiers to a buffer that is too short - * (thanks to Edwin Young for - * spotting the problem); - * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) - * to snprintf.h - * 2000-02-14 V2.0 (never released) Mark Martinec - * - relaxed license terms: The Artistic License now applies. - * You may still apply the GNU GENERAL PUBLIC LICENSE - * as was distributed with previous versions, if you prefer; - * - changed REVISION HISTORY dates to use ISO 8601 date format; - * - added vsnprintf (patch also independently proposed by - * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) - * 2000-06-27 V2.1 Mark Martinec - * - removed POSIX check for str_m<1; value 0 for str_m is - * allowed by ISO C99 (and GNU C library 2.1) - (pointed out - * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). - * Besides relaxed license this change in standards adherence - * is the main reason to bump up the major version number; - * - added nonstandard routines asnprintf, vasnprintf, asprintf, - * vasprintf that dynamically allocate storage for the - * resulting string; these routines are not compiled by default, - * see comments where NEED_V?ASN?PRINTF macros are defined; - * - autoconf contributed by Caolan McNamara - * 2000-10-06 V2.2 Mark Martinec - * - BUG FIX: the %c conversion used a temporary variable - * that was no longer in scope when referenced, - * possibly causing incorrect resulting character; - * - BUG FIX: make precision and minimal field width unsigned - * to handle huge values (2^31 <= n < 2^32) correctly; - * also be more careful in the use of signed/unsigned/size_t - * internal variables - probably more careful than many - * vendor implementations, but there may still be a case - * where huge values of str_m, precision or minimal field - * could cause incorrect behaviour; - * - use separate variables for signed/unsigned arguments, - * and for short/int, long, and long long argument lengths - * to avoid possible incompatibilities on certain - * computer architectures. Also use separate variable - * arg_sign to hold sign of a numeric argument, - * to make code more transparent; - * - some fiddling with zero padding and "0x" to make it - * Linux compatible; - * - systematically use macros fast_memcpy and fast_memset - * instead of case-by-case hand optimization; determine some - * breakeven string lengths for different architectures; - * - terminology change: 'format' -> 'conversion specifier', - * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', - * 'alternative form' -> 'alternate form', - * 'data type modifier' -> 'length modifier'; - * - several comments rephrased and new ones added; - * - make compiler not complain about 'credits' defined but - * not used; - * 2001-08 V2.3 Mark Martinec - * .. 2002-02 - writeback conversion specifier 'n' is now supported; - * - bump the size of a temporary buffer for simple - * numeric->string conversion from 32 to 48 characters - * in anticipation of 128-bit machines; - * - added #include and to snprintf.h; - * - fixed one assert in test.c - * (thanks to Tuomo A Turunen for reporting this problem); - * - portability fix: use isdigit() provided with - * and do not assume character set is ASCII - call strtoul() - * if needed to convert field width and precision; - * - check for broken or non-ANSI native sprintf (e.g. SunOS) - * which does not return string lenth, and work around it; - * - shouldn't happen, but just in case (applies to numeric - * conversions only): added assertion after a call to - * system's sprintf to make sure we detect a problem - * as it happens (or very shortly - but still - after a - * buffer overflow occured for some strange reason - * in system's sprintf); - * - cleanup: avoid comparing signed and unsigned values - * (ANSI c++ complaint); added a couple of 'const' qualifiers; - * - changed few comments, new references to some other - * implementations added to the README file; - * - it appears the Artistic License and its variant the Frontier - * Artistic License are incompatible with GPL and precludes - * this work to be included with GPL-licensed work. This was - * not my intention. The fact that this package is dual licensed - * comes to the rescue. Changed the credits[] string, and - * TERMS AND CONDITIONS to explicitly say so, stressing - * the fact that this work is dual licensed. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -/* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf. - * - * If HAVE_SNPRINTF is defined this module will not produce code for - * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, - * causing this portable version of snprintf to be called portable_snprintf - * (and portable_vsnprintf). - */ -/* #define HAVE_SNPRINTF */ - -/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and - * vsnprintf but you would prefer to use the portable routine(s) instead. - * In this case the portable routine is declared as portable_snprintf - * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') - * is defined to expand to 'portable_v?snprintf' - see file snprintf.h . - * Defining this macro is only useful if HAVE_SNPRINTF is also defined, - * but does no harm if defined nevertheless. - */ -/* #define PREFER_PORTABLE_SNPRINTF */ - -/* Define SNPRINTF_LONGLONG_SUPPORT if you want to support - * data type (long long int) and length modifier 'll' (e.g. %lld). - * If undefined, 'll' is recognized but treated as a single 'l'. - * - * If the system's sprintf does not handle 'll' - * the SNPRINTF_LONGLONG_SUPPORT must not be defined! - * - * This is off by default as (long long int) is a language extension. - */ -/* #define SNPRINTF_LONGLONG_SUPPORT */ - -/* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf. - * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly, - * otherwise both snprintf and vsnprintf routines will be defined - * and snprintf will be a simple wrapper around vsnprintf, at the expense - * of an extra procedure call. - */ -/* #define NEED_SNPRINTF_ONLY */ - -/* Define NEED_V?ASN?PRINTF macros if you need library extension - * routines asprintf, vasprintf, asnprintf, vasnprintf respectively, - * and your system library does not provide them. They are all small - * wrapper routines around portable_vsnprintf. Defining any of the four - * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY - * and turns on PREFER_PORTABLE_SNPRINTF. - * - * Watch for name conflicts with the system library if these routines - * are already present there. - * - * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as - * specified by C99, to be able to traverse the same list of arguments twice. - * I don't know of any other standard and portable way of achieving the same. - * With some versions of gcc you may use __va_copy(). You might even get away - * with "ap2 = ap", in this case you must not call va_end(ap2) ! - * #define va_copy(ap2,ap) __va_copy((ap2),(ap)) - * #define va_copy(ap2,ap) (ap2) = (ap) - */ -/* #define NEED_ASPRINTF */ -/* #define NEED_ASNPRINTF */ -/* #define NEED_VASPRINTF */ -/* #define NEED_VASNPRINTF */ - -/* Define the following macros if desired: - * SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE, - * HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE, - * DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE, - * PERL_COMPATIBLE, PERL_BUG_COMPATIBLE, - * - * - For portable applications it is best not to rely on peculiarities - * of a given implementation so it may be best not to define any - * of the macros that select compatibility and to avoid features - * that vary among the systems. - * - * - Selecting compatibility with more than one operating system - * is not strictly forbidden but is not recommended. - * - * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE . - * - * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is - * documented in a sprintf man page on a given operating system - * and actually adhered to by the system's sprintf (but not on - * most other operating systems). It may also refer to and enable - * a behaviour that is declared 'undefined' or 'implementation specific' - * in the man page but a given implementation behaves predictably - * in a certain way. - * - * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf - * that contradicts the sprintf man page on the same operating system. - * - * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE - * conditionals take into account all idiosyncrasies of a particular - * implementation, there may be other incompatibilities. - */ - - - -/* ============================================= */ -/* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */ -/* ============================================= */ - -#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 -#define PORTABLE_SNPRINTF_VERSION_MINOR 3 - -#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) -# if defined(NEED_SNPRINTF_ONLY) -# undef NEED_SNPRINTF_ONLY -# endif -# if !defined(PREFER_PORTABLE_SNPRINTF) -# define PREFER_PORTABLE_SNPRINTF -# endif -#endif - -#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) -#define SOLARIS_COMPATIBLE -#endif - -#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) -#define HPUX_COMPATIBLE -#endif - -#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) -#define DIGITAL_UNIX_COMPATIBLE -#endif - -#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) -#define PERL_COMPATIBLE -#endif - -#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) -#define LINUX_COMPATIBLE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -/* For copying strings longer or equal to 'breakeven_point' - * it is more efficient to call memcpy() than to do it inline. - * The value depends mostly on the processor architecture, - * but also on the compiler and its optimization capabilities. - * The value is not critical, some small value greater than zero - * will be just fine if you don't care to squeeze every drop - * of performance out of the code. - * - * Small values favour memcpy & memset (extra procedure call, less code), - * large values favour inline code (saves procedure call, more code). - */ -#if defined(__alpha__) || defined(__alpha) -# define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc */ -#endif -#if defined(__i386__) || defined(__i386) -# define breakeven_point 15 /* Intel Pentium/Linux - gcc 2.96 (12..30) */ -#endif -#if defined(__hppa) -# define breakeven_point 10 /* HP-PA - gcc */ -#endif -#if defined(__sparc__) || defined(__sparc) -# define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ -#endif - -/* some other values of possible interest: */ -/* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ -/* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ - -#ifndef breakeven_point -# define breakeven_point 6 /* some reasonable one-size-fits-all value */ -#endif - -#define fast_memcpy(d,s,n) \ - { register size_t nn = (size_t)(n); \ - if (nn >= breakeven_point) memcpy((d), (s), nn); \ - else if (nn > 0) { /* call overhead is worth only for large strings*/ \ - register char *dd; register const char *ss; \ - for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } - -#define fast_memset(d,c,n) \ - { register size_t nn = (size_t)(n); \ - if (nn >= breakeven_point) memset((d), (int)(c), nn); \ - else if (nn > 0) { /* call overhead is worth only for large strings*/ \ - register char *dd; register const int cc=(int)(c); \ - for (dd=(d); nn>0; nn--) *dd++ = cc; } } - -/* The following isdigit() is not portable (e.g. may not work - * with non-ASCII character sets). Use the system-provided isdigit() - * if available, otherwise uncomment: - * #define isdigit(c) ((c) >= '0' && (c) <= '9') - */ - -/* atosizet converts a span of decimal digits to a number of type size_t. - * It is a macro, similar to: (but not quite, p will be modified!) - * void atosizet(const char *p, const char **endp, size_t *result); - * endp will point to just beyond the digits substring. - * This is _not_ a general-purpose macro: - * - the first argument will be modified; - * - the first character must already be checked to be a digit! - * NOTE: size_t could be wider than unsigned int; - * but we treat numeric string like common implementations do! - * If character set is ASCII (checking with a quick and simple-minded test) - * we convert string to a number inline for speed, otherwise we call strtoul. - */ -#define atosizet(p, endp, result) \ - if ((int)'0' == 48) { /* a compile-time constant expression, */ \ - /* hoping the code from one branch */ \ - /* will be optimized away */ \ - /* looks like ASCII character set, let's hope it really is */ \ - register unsigned int uj = (unsigned int)(*(p)++ - '0'); \ - while (isdigit((int)(*(p)))) \ - uj = 10*uj + (unsigned int)(*(p)++ - '0'); \ - if ((endp) != NULL) *(endp) = (p); \ - *(result) = (size_t) uj; \ - } else { \ - /* non-ASCII character set, play by the rules */ \ - char *ep; /* NOTE: no 'const' to make strtoul happy! */ \ - /* NOTE: clip (unsigned long) to (unsigned int) as is common !!! */ \ - const unsigned int uj = (unsigned int) strtoul((p), &ep, 10); \ - /* The following assignment is legal: the address of a non-const */ \ - /* object can be assigned to a pointer to a const object, but */ \ - /* that pointer cannot be used to alter the value of the object. */ \ - if ((endp) != NULL) *(endp) = ep; \ - /* if num too large the result will be ULONG_MAX and errno=ERANGE */ \ - *(result) = (size_t) uj; \ - } \ - -/* prototypes */ - -#if defined(NEED_ASPRINTF) -int asprintf (char **ptr, const char *fmt, /*args*/ ...); -#endif -#if defined(NEED_VASPRINTF) -int vasprintf (char **ptr, const char *fmt, va_list ap); -#endif -#if defined(NEED_ASNPRINTF) -int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); -#endif -#if defined(NEED_VASNPRINTF) -int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); -#endif - -#if defined(HAVE_SNPRINTF) -/* declare our portable snprintf routine under name portable_snprintf */ -/* declare our portable vsnprintf routine under name portable_vsnprintf */ -#else -/* declare our portable routines under names snprintf and vsnprintf */ -#define portable_snprintf snprintf -#if !defined(NEED_SNPRINTF_ONLY) -#define portable_vsnprintf vsnprintf -#endif -#endif - -#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); -#if !defined(NEED_SNPRINTF_ONLY) -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); -#endif -#endif - -/* declarations */ - -static const char credits[] = "\n\ -@(#)snprintf.c, v2.3: Mark Martinec, \n\ -@(#)snprintf.c, v2.3: Copyright 1999-2002 Mark Martinec. Dual licensed: Frontier Artistic License or GNU General Public License applies.\n\ -@(#)snprintf.c, v2.3: http://www.ijs.si/software/snprintf/\n"; - -#if defined(NEED_ASPRINTF) -int asprintf(char **ptr, const char *fmt, /*args*/ ...) { - va_list ap; - size_t str_m; - int str_l; - - *ptr = NULL; - va_start(ap, fmt); /* measure the required size */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); - va_end(ap); - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t)str_l + 1); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2; - va_start(ap, fmt); - str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - va_end(ap); - assert(str_l2 == str_l); - } - return str_l; -} -#endif - -#if defined(NEED_VASPRINTF) -int vasprintf(char **ptr, const char *fmt, va_list ap) { - size_t str_m; - int str_l; - - *ptr = NULL; - { va_list ap2; - va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ - va_end(ap2); - } - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t)str_l + 1); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - const int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - assert(str_l2 == str_l); - } - return str_l; -} -#endif - -#if defined(NEED_ASNPRINTF) -int asnprintf(char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { - va_list ap; - int str_l; - - *ptr = NULL; - va_start(ap, fmt); /* measure the required size */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); - va_end(ap); - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ - /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ - if (str_m == 0) { /* not interested in resulting string, just return size */ - } else { - *ptr = (char *) malloc(str_m); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2; - va_start(ap, fmt); - str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - va_end(ap); - assert(str_l2 == str_l); - } - } - return str_l; -} -#endif - -#if defined(NEED_VASNPRINTF) -int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap) { - int str_l; - - *ptr = NULL; - { va_list ap2; - va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ - va_end(ap2); - } - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ - /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ - if (str_m == 0) { /* not interested in resulting string, just return size */ - } else { - *ptr = (char *) malloc(str_m); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - const int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - assert(str_l2 == str_l); - } - } - return str_l; -} -#endif - -/* - * If the system does have snprintf and the portable routine is not - * specifically required, this module produces no code for snprintf/vsnprintf. - */ -#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) - -#if !defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { - va_list ap; - int str_l; - - va_start(ap, fmt); - str_l = portable_vsnprintf(str, str_m, fmt, ap); - va_end(ap); - return str_l; -} -#endif - -#if defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { -#else -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { -#endif - -#if defined(NEED_SNPRINTF_ONLY) - va_list ap; -#endif - size_t str_l = 0; - const char *p = fmt; - -/* In contrast to POSIX, the ISO C99 now says - * that str can be NULL and str_m can be 0. - * This is more useful than the old: if (str_m < 1) return -1; */ - -#if defined(NEED_SNPRINTF_ONLY) - va_start(ap, fmt); -#endif - if (!p) p = ""; - while (*p) { - if (*p != '%') { - if (0) { /* compile time decision between two equivalent alternatives */ - /* this is simple but slow */ - if (str_l < str_m) str[str_l] = *p; - p++; str_l++; - } else { - /* this usually achieves much better performance for cases - * where format string is long and contains few conversions */ - const char *const q = strchr(p+1,'%'); - const size_t n = !q ? strlen(p) : (q-p); - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memcpy(str+str_l, p, (n>avail?avail:n)); - } - p += n; str_l += n; - } - } else { - const char *starting_p; - size_t min_field_width = 0, precision = 0; - int zero_padding = 0, precision_specified = 0, justify_left = 0; - int alternate_form = 0, force_sign = 0; - int space_for_positive = 1; /* If both the ' ' and '+' flags appear, - the ' ' flag should be ignored. */ - char length_modifier = '\0'; /* allowed values: \0, h, l, L */ - char tmp[48];/* temporary buffer for simple numeric->string conversion */ - - const char *str_arg; /* string address in case of string argument */ - size_t str_arg_l; /* natural field width of arg without padding - and sign */ - unsigned char uchar_arg; - /* unsigned char argument value - only defined for c conversion. - N.B. standard explicitly states the char argument for - the c conversion is unsigned */ - - size_t number_of_zeros_to_pad = 0; - /* number of zeros to be inserted for numeric conversions - as required by the precision or minimal field width */ - - size_t zero_padding_insertion_ind = 0; - /* index into tmp where zero padding is to be inserted */ - - char fmt_spec = '\0'; - /* current conversion specifier character */ - - str_arg = credits;/* just to make compiler happy (defined but not used)*/ - str_arg = NULL; - starting_p = p; p++; /* skip '%' */ - /* parse flags */ - while (*p == '0' || *p == '-' || *p == '+' || - *p == ' ' || *p == '#' || *p == '\'') { - switch (*p) { - case '0': zero_padding = 1; break; - case '-': justify_left = 1; break; - case '+': force_sign = 1; space_for_positive = 0; break; - case ' ': force_sign = 1; - /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ -#ifdef PERL_COMPATIBLE - /* ... but in Perl the last of ' ' and '+' applies */ - space_for_positive = 1; -#endif - break; - case '#': alternate_form = 1; break; - case '\'': break; - } - p++; - } - /* If flags '0' and '-' both appear, the '0' flag should be ignored. */ - - /* parse field width */ - if (*p == '*') { - const int j = va_arg(ap, int); - p++; - if (j >= 0) min_field_width = j; - else { min_field_width = -j; justify_left = 1; } - } else if (isdigit((int)(*p))) { - atosizet(p, &p, &min_field_width); - } - /* parse precision */ - if (*p == '.') { - p++; precision_specified = 1; - if (*p == '*') { - const int j = va_arg(ap, int); - p++; - if (j >= 0) precision = j; - else { - precision_specified = 0; precision = 0; - /* NOTE: - * Solaris 2.6 man page claims that in this case the precision - * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page - * claim that this case should be treated as unspecified precision, - * which is what we do here. - */ - } - } else if (isdigit((int)(*p))) { - atosizet(p, &p, &precision); - } - } - /* parse 'h', 'l' and 'll' length modifiers */ - if (*p == 'h' || *p == 'l') { - length_modifier = *p; p++; - if (length_modifier == 'l' && *p == 'l') { /* double el = long long */ -#ifdef SNPRINTF_LONGLONG_SUPPORT - length_modifier = '2'; /* double letter el encoded as '2' */ -#else - length_modifier = 'l'; /* treat it as a single 'l' (letter el) */ -#endif - p++; - } - } - fmt_spec = *p; - /* common synonyms: */ - switch (fmt_spec) { - case 'i': fmt_spec = 'd'; break; - case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; - case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; - case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; - default: break; - } - /* get parameter value, do initial processing */ - switch (fmt_spec) { - case '%': /* % behaves similar to 's' regarding flags and field widths */ - case 'c': /* c behaves similar to 's' regarding flags and field widths */ - case 's': - length_modifier = '\0'; /* wint_t and wchar_t not supported */ - /* the result of zero padding flag with non-numeric conversion specifier*/ - /* is undefined. Solaris and HPUX 10 does zero padding in this case, */ - /* Digital Unix and Linux does not. */ -#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) - zero_padding = 0; /* turn zero padding off for string conversions */ -#endif - str_arg_l = 1; - switch (fmt_spec) { - case '%': - str_arg = p; break; - case 'c': { - const int j = va_arg(ap, int); - uchar_arg = (unsigned char) j; /* standard demands unsigned char */ - str_arg = (const char *) &uchar_arg; - break; - } - case 's': - str_arg = va_arg(ap, const char *); - if (!str_arg) str_arg_l = 0; - /* make sure not to address string beyond the specified precision !!! */ - else if (!precision_specified) str_arg_l = strlen(str_arg); - /* truncate string if necessary as requested by precision */ - else if (precision == 0) str_arg_l = 0; - else { - /* memchr on HP does not like n > 2^31 !!! */ - const char *const q = (const char *) memchr(str_arg, '\0', - precision <= 0x7fffffff ? precision : 0x7fffffff); - str_arg_l = !q ? precision : (q-str_arg); - } - break; - default: break; - } - break; - case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { - /* NOTE: the u, o, x, X and p conversion specifiers imply - the value is unsigned; d implies a signed value */ - - int arg_sign = 0; - /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), - +1 if greater than zero (or nonzero for unsigned arguments), - -1 if negative (unsigned argument is never negative) */ - - int int_arg = 0; unsigned int uint_arg = 0; - /* only defined for length modifier h, or for no length modifiers */ - - long int long_arg = 0; unsigned long int ulong_arg = 0; - /* only defined for length modifier l (letter el) */ - - void *ptr_arg = NULL; - /* pointer argument value - only defined for p conversion */ - -#ifdef SNPRINTF_LONGLONG_SUPPORT - long long int long_long_arg = 0; - unsigned long long int ulong_long_arg = 0; - /* only defined for length modifier ll (double letter el) */ -#endif - if (fmt_spec == 'p') { - /* HPUX 10: An l, h, ll or L before any other conversion character - * (other than d, i, u, o, x, or X) is ignored. - * Digital Unix: - * not specified, but seems to behave as HPUX does. - * Solaris: If an h, l, or L appears before any other conversion - * specifier (other than d, i, u, o, x, or X), the behavior - * is undefined. (Actually %hp converts only 16-bits of address - * and %llp treats address as 64-bit data which is incompatible - * with (void *) argument on a 32-bit system). - */ -#ifdef SOLARIS_COMPATIBLE -# ifdef SOLARIS_BUG_COMPATIBLE - /* keep length modifiers even if it represents 'll' */ -# else - if (length_modifier == '2') length_modifier = '\0'; -# endif -#else - length_modifier = '\0'; -#endif - ptr_arg = va_arg(ap, void *); - if (ptr_arg != NULL) arg_sign = 1; - } else if (fmt_spec == 'd') { /* signed */ - switch (length_modifier) { - case '\0': - case 'h': - /* It is non-portable to specify char or short as the second argument - * to va_arg, because arguments seen by the called function - * are not char or short. C converts char and short arguments - * to int before passing them to a function. - */ - int_arg = va_arg(ap, int); - if (int_arg > 0) arg_sign = 1; - else if (int_arg < 0) arg_sign = -1; - break; - case 'l': /* letter el */ - long_arg = va_arg(ap, long int); - if (long_arg > 0) arg_sign = 1; - else if (long_arg < 0) arg_sign = -1; - break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': - long_long_arg = va_arg(ap, long long int); - if (long_long_arg > 0) arg_sign = 1; - else if (long_long_arg < 0) arg_sign = -1; - break; -#endif - } - } else { /* unsigned */ - switch (length_modifier) { - case '\0': - case 'h': - uint_arg = va_arg(ap, unsigned int); - if (uint_arg) arg_sign = 1; - break; - case 'l': /* letter el */ - ulong_arg = va_arg(ap, unsigned long int); - if (ulong_arg) arg_sign = 1; - break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': - ulong_long_arg = va_arg(ap, unsigned long long int); - if (ulong_long_arg) arg_sign = 1; - break; -#endif - } - } - str_arg = tmp; str_arg_l = 0; - /* NOTE: - * For d, i, u, o, x, and X conversions, if precision is specified, - * the '0' flag should be ignored. This is so with Solaris 2.6, - * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. - */ -#ifndef PERL_COMPATIBLE - if (precision_specified) zero_padding = 0; -#endif - if (fmt_spec == 'd') { - if (force_sign && arg_sign >= 0) - tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; - /* leave negative numbers for sprintf to handle, - to avoid handling tricky cases like (short int)(-32768) */ -#ifdef LINUX_COMPATIBLE - } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { - tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; -#endif - } else if (alternate_form) { - if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) - { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } - /* alternate form should have no effect for p conversion, but ... */ -#ifdef HPUX_COMPATIBLE - else if (fmt_spec == 'p' - /* HPUX 10: for an alternate form of p conversion, - * a nonzero result is prefixed by 0x. */ -#ifndef HPUX_BUG_COMPATIBLE - /* Actually it uses 0x prefix even for a zero value. */ - && arg_sign != 0 -#endif - ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } -#endif - } - zero_padding_insertion_ind = str_arg_l; - if (!precision_specified) precision = 1; /* default precision is 1 */ - if (precision == 0 && arg_sign == 0 -#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) - && fmt_spec != 'p' - /* HPUX 10 man page claims: With conversion character p the result of - * converting a zero value with a precision of zero is a null string. - * Actually HP returns all zeroes, and Linux returns "(nil)". */ -#endif - ) { - /* converted to null string */ - /* When zero value is formatted with an explicit precision 0, - the resulting formatted string is empty (d, i, u, o, x, X, p). */ - } else { - static int sprintf_return_value_is_ansi_compliant = -1; /* unknown */ - char f[5]; int f_l = 0, sprintf_l = 0; - f[f_l++] = '%'; /* construct a simple format string for sprintf */ - if (!length_modifier) { } - else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } - else f[f_l++] = length_modifier; - f[f_l++] = fmt_spec; f[f_l++] = '\0'; - if (sprintf_return_value_is_ansi_compliant < 0) { /* not yet known */ - /* let's do a little run-time experiment (only once) to see if the - * native sprintf returns a string length as required by ANSI, or has - * some other ideas like the old SunOS which returns buffer address */ - sprintf_return_value_is_ansi_compliant = - (sprintf(tmp+str_arg_l, "%d", 19) == 2); - } - if (fmt_spec == 'p') sprintf_l=sprintf(tmp+str_arg_l, f, ptr_arg); - else if (fmt_spec == 'd') { /* signed */ - switch (length_modifier) { - case '\0': - case 'h': sprintf_l=sprintf(tmp+str_arg_l, f, int_arg); break; - case 'l': sprintf_l=sprintf(tmp+str_arg_l, f, long_arg); break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': sprintf_l=sprintf(tmp+str_arg_l,f,long_long_arg); break; -#endif - } - } else { /* unsigned */ - switch (length_modifier) { - case '\0': - case 'h': sprintf_l=sprintf(tmp+str_arg_l, f, uint_arg); break; - case 'l': sprintf_l=sprintf(tmp+str_arg_l, f, ulong_arg); break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': sprintf_l=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; -#endif - } - } - if (!sprintf_return_value_is_ansi_compliant) { /* broken sprintf? */ - tmp[sizeof(tmp)-1] = '\0'; sprintf_l = strlen(tmp+str_arg_l); - } - assert(sprintf_l >= 0); /* should not happen; problem in sprintf? */ - assert(sprintf_l+str_arg_l < sizeof(tmp)); /*better late then never*/ - str_arg_l += sprintf_l; - /* include the optional minus sign and possible "0x" - in the region before the zero padding insertion point */ - if (zero_padding_insertion_ind < str_arg_l && - tmp[zero_padding_insertion_ind] == '-') { - zero_padding_insertion_ind++; - } - if (zero_padding_insertion_ind+1 < str_arg_l && - tmp[zero_padding_insertion_ind] == '0' && - (tmp[zero_padding_insertion_ind+1] == 'x' || - tmp[zero_padding_insertion_ind+1] == 'X') ) { - zero_padding_insertion_ind += 2; - } - } - { const size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; - if (alternate_form && fmt_spec == 'o' -#ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ - && (str_arg_l > 0) -#endif -#ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ -#else - /* unless zero is already the first character */ - && !(zero_padding_insertion_ind < str_arg_l - && tmp[zero_padding_insertion_ind] == '0') -#endif - ) { /* assure leading zero for alternate-form octal numbers */ - if (!precision_specified || precision < num_of_digits+1) { - /* precision is increased to force the first character to be zero, - except if a zero value is formatted with an explicit precision - of zero */ - precision = num_of_digits+1; precision_specified = 1; - } - } - /* zero padding to specified precision? */ - if (num_of_digits < precision) - number_of_zeros_to_pad = precision - num_of_digits; - } - /* zero padding to specified minimal field width? */ - if (!justify_left && zero_padding) { - const int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) number_of_zeros_to_pad += n; - } - break; - } - case 'n': { - void *const ptr = va_arg(ap, void *); - if (ptr != NULL) { - /* same problem of size_t -> int type conversion as with the - * snprintf return value - see comment at the end of this procedure */ - switch (length_modifier) { - case '\0': *( int *const)ptr = str_l; break; - case 'h': *(short int *const)ptr = str_l; break; - case 'l': *(long int *const)ptr = str_l; break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': *(long long int *const)ptr = str_l; break; -#endif - } - } - /* no argument converted */ - min_field_width = number_of_zeros_to_pad = str_arg_l = 0; - break; - } - default: /* unrecognized conversion specifier, keep format string as-is*/ - zero_padding = 0; /* turn zero padding off for non-numeric convers. */ -#ifndef DIGITAL_UNIX_COMPATIBLE - justify_left = 1; min_field_width = 0; /* reset flags */ -#endif -#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) - /* keep the entire format string unchanged */ - str_arg = starting_p; str_arg_l = p - starting_p; - /* well, not exactly so for Linux, which does something inbetween, - * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ -#else - /* discard the unrecognized conversion, just keep * - * the unrecognized conversion character */ - str_arg = p; str_arg_l = 0; -#endif - if (*p) str_arg_l++; /* include invalid conversion specifier unchanged - if not at end-of-string */ - break; - } - if (*p) p++; /* step over the just processed conversion specifier */ - /* insert padding to the left as requested by min_field_width; - this does not include the zero padding in case of numerical conversions*/ - if (!justify_left) { /* left padding with blank or zero */ - const int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) { - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memset(str+str_l, (zero_padding?'0':' '), - ((unsigned int)n > avail ? avail : (unsigned int)n)); - } - str_l += n; - } - } - /* is zero padding as requested by the precision or by the - * minimal field width for numeric conversions required? */ - if (number_of_zeros_to_pad <= 0) { - /* will not copy the first part of numeric right now, * - * force it to be copied later in its entirety */ - zero_padding_insertion_ind = 0; - } else { - /* insert first part of numerics (sign or '0x') before zero padding */ - { const int n = zero_padding_insertion_ind; - if (n > 0) { - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memcpy(str+str_l, str_arg, - ((unsigned int)n > avail ? avail : (unsigned int)n)); - } - str_l += n; - } - } - /* insert zero padding as requested by the precision or min field width */ - { const int n = number_of_zeros_to_pad; - if (n > 0) { - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memset(str+str_l, '0', - ((unsigned int)n > avail ? avail : (unsigned int)n)); - } - str_l += n; - } - } - } - /* insert formatted string - * (or as-is conversion specifier for unknown conversions) */ - { const int n = str_arg_l - zero_padding_insertion_ind; - if (n > 0) { - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, - ((unsigned int)n > avail ? avail : (unsigned int)n)); - } - str_l += n; - } - } - /* insert right padding */ - if (justify_left) { /* right blank padding to the field width */ - const int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) { - if (str_l < str_m) { - const size_t avail = str_m-str_l; - fast_memset(str+str_l, ' ', - ((unsigned int)n > avail ? avail : (unsigned int)n)); - } - str_l += n; - } - } - } - } -#if defined(NEED_SNPRINTF_ONLY) - va_end(ap); -#endif - if (str_m > 0) { /* make sure the string is null-terminated, possibly - at the expense of overwriting the last character */ - str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; - } - /* Return the number of characters formatted (excluding trailing null - * character), that is, the number of characters that would have been - * written to the buffer if it were large enough. - * - * The value of str_l should be returned, but str_l is of unsigned type - * size_t, and snprintf is int, possibly leading to an undetected - * integer overflow, resulting in a negative return value, which is invalid. - * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. - * Should errno be set to EOVERFLOW and EOF returned in this case??? - */ - return (int) str_l; -} -#endif diff --git a/shared/snprintf.h b/shared/snprintf.h deleted file mode 100644 index f567ba68..00000000 --- a/shared/snprintf.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _PORTABLE_SNPRINTF_H_ -#define _PORTABLE_SNPRINTF_H_ - -#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 -#define PORTABLE_SNPRINTF_VERSION_MINOR 2 - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_SNPRINTF -#include -#else -extern int snprintf(char *, size_t, const char *, /*args*/ ...); -extern int vsnprintf(char *, size_t, const char *, va_list); -#endif - -#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF) -extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); -extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); -#define snprintf portable_snprintf -#define vsnprintf portable_vsnprintf -#endif - -extern int asprintf (char **ptr, const char *fmt, /*args*/ ...); -extern int vasprintf (char **ptr, const char *fmt, va_list ap); -extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); -extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); - -#endif diff --git a/shared/sockets.c b/shared/sockets.c index 7539fa27..a42a4d9e 100644 --- a/shared/sockets.c +++ b/shared/sockets.c @@ -67,7 +67,7 @@ sock_init_sockaddr (sockaddr_in *name, const char *hostname, unsigned short int * \return socket file descriptor on success, -1 on error */ int -sock_connect (char *host, unsigned short int port) +sock_connect (const char *host, unsigned short int port) { struct sockaddr_in servername; int sock; @@ -312,7 +312,7 @@ sock_printf_error(int fd, const char *format, .../*args*/ ) va_list ap; int size = 0; - strncpy(buf, huh, sizeof(huh)); // note: sizeof(huh) < MAXMSG + strcpy(buf, huh); // note: sizeof(huh) < MAXMSG va_start(ap, format); size = vsnprintf(buf + (sizeof(huh)-1), sizeof(buf) - (sizeof(huh)-1), format, ap); diff --git a/shared/sockets.h b/shared/sockets.h index a85481d0..1ecb88e7 100644 --- a/shared/sockets.h +++ b/shared/sockets.h @@ -18,7 +18,7 @@ #endif /** Connect to server on host, port */ -int sock_connect (char *host, unsigned short int port); +int sock_connect (const char *host, unsigned short int port); /** Disconnect from server */ int sock_close (int fd); /** Send printf-like formatted output */