From: Hauke Mehrtens Date: Sun, 12 Jul 2015 22:59:20 +0000 (+0000) Subject: lcd4linux: moved to github X-Git-Url: http://git.openwrt.org/openwrt/docs.git?a=commitdiff_plain;h=b770592f7a5145b7ce1fce891b37a350a3273a35;p=openwrt%2Fsvn-archive%2Fpackages.git lcd4linux: moved to github Signed-off-by: Hauke Mehrtens SVN-Revision: 46316 --- diff --git a/utils/lcd4linux/Config.in b/utils/lcd4linux/Config.in deleted file mode 100644 index 617521c1f..000000000 --- a/utils/lcd4linux/Config.in +++ /dev/null @@ -1,501 +0,0 @@ -if PACKAGE_lcd4linux-custom - -config LCD4LINUX_CUSTOM_NEEDS_libdbus - bool - -config LCD4LINUX_CUSTOM_NEEDS_libdpf - bool - -#config LCD4LINUX_CUSTOM_NEEDS_libftdi -# bool - -config LCD4LINUX_CUSTOM_NEEDS_libgd - bool - -config LCD4LINUX_CUSTOM_NEEDS_libiconv - bool - -config LCD4LINUX_CUSTOM_NEEDS_libjpeg - bool - -config LCD4LINUX_CUSTOM_NEEDS_libmpdclient - bool - -config LCD4LINUX_CUSTOM_NEEDS_libmysqlclient - bool - -config LCD4LINUX_CUSTOM_NEEDS_libncurses - bool - -config LCD4LINUX_CUSTOM_NEEDS_libnmeap - bool - -config LCD4LINUX_CUSTOM_NEEDS_libsqlite3 - bool - -config LCD4LINUX_CUSTOM_NEEDS_libusb - bool - -config LCD4LINUX_CUSTOM_NEEDS_libvncserver - bool - -#config LCD4LINUX_CUSTOM_NEEDS_libX11 -# bool - -config LCD4LINUX_CUSTOM_NEEDS_ppp - bool - -config LCD4LINUX_CUSTOM_NEEDS_python - bool - -config LCD4LINUX_CUSTOM_NEEDS_serdisplib - bool - -config LCD4LINUX_CUSTOM_NEEDS_st2205tool - bool - - -comment "Drivers ---" - -config LCD4LINUX_CUSTOM_DRIVER_ASTUSB - bool - prompt "ASTUSB" - -config LCD4LINUX_CUSTOM_DRIVER_BeckmannEgle - bool - prompt "BeckmannEgle" - -config LCD4LINUX_CUSTOM_DRIVER_BWCT - bool - prompt "BWCT" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_CrystalFontz - bool - prompt "CrystalFontz" - -config LCD4LINUX_CUSTOM_DRIVER_Curses - bool - prompt "Curses" - select LCD4LINUX_CUSTOM_NEEDS_libncurses - -config LCD4LINUX_CUSTOM_DRIVER_Cwlinux - bool - prompt "Cwlinux" - -config LCD4LINUX_CUSTOM_DRIVER_D4D - bool - prompt "D4D" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_dpf - bool - prompt "dpf" - select LCD4LINUX_CUSTOM_NEEDS_libdpf - -config LCD4LINUX_CUSTOM_DRIVER_EA232graphic - bool - prompt "EA232graphic" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_EFN - bool - prompt "EFN" - -config LCD4LINUX_CUSTOM_DRIVER_FutabaVFD - bool - prompt "FutabaVFD" - -config LCD4LINUX_CUSTOM_DRIVER_FW8888 - bool - prompt "FW8888" - -config LCD4LINUX_CUSTOM_DRIVER_G15 - bool - prompt "G15" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_GLCD2USB - bool - prompt "GLCD2USB" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_HD44780 - bool - prompt "HD44780" - depends on BROKEN - -config LCD4LINUX_CUSTOM_DRIVER_HD44780-I2C - bool - prompt "HD44780-I2C" - depends on BROKEN - -config LCD4LINUX_CUSTOM_DRIVER_IRLCD - bool - prompt "IRLCD" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_LCD2USB - bool - prompt "LCD2USB" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_LCDLinux - bool - prompt "LCDLinux" - depends on BROKEN - -config LCD4LINUX_CUSTOM_DRIVER_LCDTerm - bool - prompt "LCDTerm" - -config LCD4LINUX_CUSTOM_DRIVER_LEDMatrix - bool - prompt "LEDMatrix" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_LPH7508 - bool - prompt "LPH7508" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_LUIse - bool - prompt "LUIse" - select LCD4LINUX_CUSTOM_NEEDS_libgd - #select LCD4LINUX_CUSTOM_NEEDS_libluise - depends on BROKEN - -config LCD4LINUX_CUSTOM_DRIVER_LW_ABP - bool - prompt "LW_ABP" - -config LCD4LINUX_CUSTOM_DRIVER_M50530 - bool - prompt "M50530" - -config LCD4LINUX_CUSTOM_DRIVER_MatrixOrbital - bool - prompt "MatrixOrbital" - -config LCD4LINUX_CUSTOM_DRIVER_MatrixOrbitalGX - bool - prompt "MatrixOrbitalGX" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_mdm166a - bool - prompt "mdm166a" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_MilfordInstruments - bool - prompt "MilfordInstruments" - -config LCD4LINUX_CUSTOM_DRIVER_Newhaven - bool - prompt "Newhaven" - -config LCD4LINUX_CUSTOM_DRIVER_Noritake - bool - prompt "Noritake" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_NULL - bool - prompt "NULL" - default y - -config LCD4LINUX_CUSTOM_DRIVER_Pertelian - bool - prompt "Pertelian" - -config LCD4LINUX_CUSTOM_DRIVER_PHAnderson - bool - prompt "PHAnderson" - -config LCD4LINUX_CUSTOM_DRIVER_PICGraphic - bool - prompt "PICGraphic" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_picoLCD - bool - prompt "picoLCD" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_picoLCDGraphic - bool - prompt "picoLCDGraphic" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_PNG - bool - prompt "PNG" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_PPM - bool - prompt "PPM" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_RouterBoard - bool - prompt "RouterBoard" - depends on TARGET_rb532 - -config LCD4LINUX_CUSTOM_DRIVER_SamsungSPF - bool - prompt "SamsungSPF" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libjpeg - -config LCD4LINUX_CUSTOM_DRIVER_serdisplib - bool - prompt "serdisplib" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_serdisplib - -config LCD4LINUX_CUSTOM_DRIVER_ShuttleVFD - bool - prompt "ShuttleVFD" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_SimpleLCD - bool - prompt "SimpleLCD" - -config LCD4LINUX_CUSTOM_DRIVER_st2205 - bool - prompt "st2205" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_st2205tool - -config LCD4LINUX_CUSTOM_DRIVER_T6963 - bool - prompt "T6963" - select LCD4LINUX_CUSTOM_NEEDS_libgd - -config LCD4LINUX_CUSTOM_DRIVER_TeakLCM - bool - prompt "TeakLCM" - -config LCD4LINUX_CUSTOM_DRIVER_TEW673GRU - bool - select LCD4LINUX_CUSTOM_NEEDS_libgd - depends on TARGET_ar71xx - default TARGET_ar71xx - -config LCD4LINUX_CUSTOM_DRIVER_Trefon - bool - prompt "Trefon" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -#config LCD4LINUX_CUSTOM_DRIVER_ULA200 -# bool -# prompt "ULA200" -# select LCD4LINUX_CUSTOM_NEEDS_libftdi -# select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_USBHUB - bool - prompt "USBHUB" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_USBLCD - bool - prompt "USBLCD" - select LCD4LINUX_CUSTOM_NEEDS_libusb - -config LCD4LINUX_CUSTOM_DRIVER_VNC - bool - prompt "VNC" - select LCD4LINUX_CUSTOM_NEEDS_libgd - select LCD4LINUX_CUSTOM_NEEDS_libvncserver - -config LCD4LINUX_CUSTOM_DRIVER_WincorNixdorf - bool - prompt "WincorNixdorf" - -#config LCD4LINUX_CUSTOM_DRIVER_X11 -# bool -# prompt "X11" -# select LCD4LINUX_CUSTOM_NEEDS_libgd -# select LCD4LINUX_CUSTOM_NEEDS_libX11 - - -comment "Plugins ---" - -config LCD4LINUX_CUSTOM_PLUGIN_apm - bool - prompt "apm" - -config LCD4LINUX_CUSTOM_PLUGIN_asterisk - bool - prompt "asterisk" - -config LCD4LINUX_CUSTOM_PLUGIN_button_exec - bool - prompt "button_exec" - -config LCD4LINUX_CUSTOM_PLUGIN_cpuinfo - bool - prompt "cpuinfo" - default y - -config LCD4LINUX_CUSTOM_PLUGIN_dbus - bool - prompt "dbus" - select LCD4LINUX_CUSTOM_NEEDS_libdbus - -config LCD4LINUX_CUSTOM_PLUGIN_diskstats - bool - prompt "diskstats" - -config LCD4LINUX_CUSTOM_PLUGIN_dvb - bool - prompt "dvb" - -config LCD4LINUX_CUSTOM_PLUGIN_event - bool - prompt "event" - -config LCD4LINUX_CUSTOM_PLUGIN_exec - bool - prompt "exec" - -config LCD4LINUX_CUSTOM_PLUGIN_fifo - bool - prompt "fifo" - -config LCD4LINUX_CUSTOM_PLUGIN_file - bool - prompt "file" - -config LCD4LINUX_CUSTOM_PLUGIN_gps - bool - prompt "gps" - select LCD4LINUX_CUSTOM_NEEDS_libnmeap - -config LCD4LINUX_CUSTOM_PLUGIN_hddtemp - bool - prompt "hddtemp" - -config LCD4LINUX_CUSTOM_PLUGIN_huawei - bool - prompt "huawei" - -config LCD4LINUX_CUSTOM_PLUGIN_i2c_sensors - bool - prompt "i2c_sensors" - -config LCD4LINUX_CUSTOM_PLUGIN_iconv - bool - prompt "iconv" - select LCD4LINUX_CUSTOM_NEEDS_libiconv - -config LCD4LINUX_CUSTOM_PLUGIN_imon - bool - prompt "imon" - -config LCD4LINUX_CUSTOM_PLUGIN_isdn - bool - prompt "isdn" - -config LCD4LINUX_CUSTOM_PLUGIN_kvv - bool - prompt "kvv" - -config LCD4LINUX_CUSTOM_PLUGIN_loadavg - bool - prompt "loadavg" - default y - -config LCD4LINUX_CUSTOM_PLUGIN_meminfo - bool - prompt "meminfo" - default y - -config LCD4LINUX_CUSTOM_PLUGIN_mpd - bool - prompt "mpd" - select LCD4LINUX_CUSTOM_NEEDS_libmpdclient - -config LCD4LINUX_CUSTOM_PLUGIN_mpris_dbus - bool - prompt "mpris_dbus" - select LCD4LINUX_CUSTOM_NEEDS_libdbus - -config LCD4LINUX_CUSTOM_PLUGIN_mysql - bool - prompt "mysql" - select LCD4LINUX_CUSTOM_NEEDS_libmysqlclient - -config LCD4LINUX_CUSTOM_PLUGIN_netdev - bool - prompt "netdev" - -config LCD4LINUX_CUSTOM_PLUGIN_netinfo - bool - prompt "netinfo" - -config LCD4LINUX_CUSTOM_PLUGIN_pop3 - bool - prompt "pop3" - -config LCD4LINUX_CUSTOM_PLUGIN_ppp - bool - prompt "ppp" - select LCD4LINUX_CUSTOM_NEEDS_ppp - -config LCD4LINUX_CUSTOM_PLUGIN_proc_stat - bool - prompt "proc_stat" - default y - -#config LCD4LINUX_CUSTOM_PLUGIN_python -# bool -# prompt "python" -# select LCD4LINUX_CUSTOM_NEEDS_python - -config LCD4LINUX_CUSTOM_PLUGIN_qnaplog - bool - prompt "qnaplog" - select LCD4LINUX_CUSTOM_NEEDS_libsqlite3 - -config LCD4LINUX_CUSTOM_PLUGIN_seti - bool - prompt "seti" - -config LCD4LINUX_CUSTOM_PLUGIN_statfs - bool - prompt "statfs" - -config LCD4LINUX_CUSTOM_PLUGIN_uname - bool - prompt "uname" - -config LCD4LINUX_CUSTOM_PLUGIN_uptime - bool - prompt "uptime" - default y - -config LCD4LINUX_CUSTOM_PLUGIN_w1retap - bool - prompt "w1retap" - -config LCD4LINUX_CUSTOM_PLUGIN_wireless - bool - prompt "wireless" - depends on BROKEN - -config LCD4LINUX_CUSTOM_PLUGIN_xmms - bool - prompt "xmms" - -endif diff --git a/utils/lcd4linux/Makefile b/utils/lcd4linux/Makefile deleted file mode 100644 index 452ffebef..000000000 --- a/utils/lcd4linux/Makefile +++ /dev/null @@ -1,321 +0,0 @@ -# -# Copyright (C) 2007-2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=lcd4linux -PKG_REV:=1187 -PKG_VERSION:=r$(PKG_REV) -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=https://ssl.bulix.org/svn/lcd4linux/trunk/ -PKG_SOURCE_SUBDIR:=lcd4linux-$(PKG_VERSION) -PKG_SOURCE_VERSION:=$(PKG_REV) -PKG_SOURCE_PROTO:=svn - -LCD4LINUX_DRIVERS:= \ - ASTUSB \ - BeckmannEgle \ - BWCT \ - CrystalFontz \ - Curses \ - Cwlinux \ - D4D \ - DPF \ - EA232graphic \ - EFN \ - FutabaVFD \ - FW8888 \ - G15 \ - GLCD2USB \ - IRLCD \ - $(if $(CONFIG_BROKEN),HD44780) \ - $(if $(CONFIG_BROKEN),HD44780-I2C) \ - LCD2USB \ - $(if $(CONFIG_BROKEN),LCDLinux) \ - LCDTerm \ - LEDMatrix \ - LPH7508 \ - $(if $(CONFIG_BROKEN),LUIse) \ - LW_ABP \ - M50530 \ - MatrixOrbital \ - MatrixOrbitalGX \ - MilfordInstruments \ - Newhaven \ - Noritake \ - NULL \ - Pertelian \ - PHAnderson \ - PICGraphic \ - picoLCD \ - picoLCDGraphic \ - PNG \ - PPM \ - $(if $(CONFIG_TARGET_rb532),RouterBoard) \ - $(if $(CONFIG_BROKEN),SamsungSPF) \ - serdisplib \ - ShuttleVFD \ - SimpleLCD \ - st2205 \ - T6963 \ - TeakLCM \ - $(if $(CONFIG_TARGET_ar71xx),TEW673GRU) \ - Trefon \ - USBHUB \ - USBLCD \ - VNC \ - WincorNixdorf \ -# ULA200 \ -# X11 \ - -LCD4LINUX_PLUGINS:= \ - apm \ - asterisk \ - button_exec \ - cpuinfo \ - dbus \ - diskstats \ - dvb \ - event \ - exec \ - fifo \ - file \ - gps \ - hddtemp \ - huawei \ - i2c_sensors \ - iconv \ - imon \ - isdn \ - kvv \ - loadavg \ - netdev \ - netinfo \ - meminfo \ - mpd \ - mpris_dbus \ - mysql \ - netdev \ - pop3 \ - ppp \ - proc_stat \ - qnaplog \ - seti \ - statfs \ - uname \ - uptime \ - w1retap \ - $(if $(CONFIG_BROKEN),wireless) \ - xmms \ -# python \ - -PKG_FIXUP:=autoreconf -PKG_INSTALL:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) - -PKG_BUILD_DEPENDS:= \ - libdbus \ - libgd \ - libmpdclient \ - libmysqlclient \ - libncurses \ - libnmeap \ - libsqlite3 \ - libvncserver \ - ppp \ - serdisplib \ - st2205tool \ -# libftdi \ -# libX11 \ -# python \ - -PKG_CONFIG_DEPENDS:= \ - $(patsubst %,CONFIG_LCD4LINUX_CUSTOM_DRIVER_%,$(LCD4LINUX_DRIVERS)) \ - $(patsubst %,CONFIG_LCD4LINUX_CUSTOM_PLUGIN_%,$(LCD4LINUX_PLUGINS)) \ - -include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/nls.mk - -define Package/lcd4linux/Default - SECTION:=utils - CATEGORY:=Utilities - MAINTAINER:=Jonathan McCrohan - TITLE:=LCD display utility - URL:=http://lcd4linux.bulix.org/ -endef - -define Package/lcd4linux/Default/description - LCD4Linux is a small program that grabs information from the kernel and - some subsystems and displays it on an external liquid crystal display. -endef - - -define Package/lcd4linux-custom -$(call Package/lcd4linux/Default) - DEPENDS:= \ - +LCD4LINUX_CUSTOM_NEEDS_libdbus:libdbus \ - +LCD4LINUX_CUSTOM_NEEDS_libdpf:libdpf \ - +LCD4LINUX_CUSTOM_NEEDS_libgd:libgd \ - $(if $(ICONV_FULL),+LCD4LINUX_CUSTOM_NEEDS_libiconv:libiconv-full) \ - +LCD4LINUX_CUSTOM_NEEDS_libjpeg:libjpeg \ - +LCD4LINUX_CUSTOM_NEEDS_libmpdclient:libmpdclient \ - +LCD4LINUX_CUSTOM_NEEDS_libmysqlclient:libmysqlclient \ - +LCD4LINUX_CUSTOM_NEEDS_libncurses:libncurses \ - +LCD4LINUX_CUSTOM_NEEDS_libsqlite3:libsqlite3 \ - +LCD4LINUX_CUSTOM_NEEDS_libusb:libusb-compat \ - +LCD4LINUX_CUSTOM_NEEDS_libvncserver:libvncserver \ - +LCD4LINUX_CUSTOM_NEEDS_serdisplib:serdisplib \ - +LCD4LINUX_CUSTOM_NEEDS_st2205tool:st2205tool \ -# +LCD4LINUX_CUSTOM_NEEDS_libftdi:libftdi \ -# +LCD4LINUX_CUSTOM_NEEDS_libX11:libX11 \ -# +LCD4LINUX_CUSTOM_NEEDS_python:python - MENU:=1 - PROVIDES:=lcd4linux - VARIANT=custom -endef - -define Package/lcd4linux-custom/config - source "$(SOURCE)/Config.in" -endef - -define Package/lcd4linux-custom/description -$(call Package/lcd4linux/Default/description) - . - This package contains a customized version of LCD4Linux. -endef - - -define Package/lcd4linux-full -$(call Package/lcd4linux/Default) - DEPENDS:= @DEVEL \ - +libdbus \ - +libdpf \ - +libgd \ - $(if $(ICONV_FULL),+libiconv-full) \ - +libmpdclient \ - +libmysqlclient \ - +libncurses \ - +libsqlite3 \ - +libusb-compat \ - +libvncserver \ - +serdisplib \ - +st2205tool \ -# +libftdi \ -# +libX11 \ -# +python - PROVIDES:=lcd4linux - VARIANT=full -endef - -define Package/lcd4linux-full/description -$(call Package/lcd4linux/Default/description) - . - This package contains a version of LCD4Linux built with all supported - drivers and plugins. -endef - - -CONFIGURE_ARGS+= \ - --disable-rpath \ - -EXTRA_LDFLAGS+= -Wl,-rpath-link,$(STAGING_DIR)/usr/lib - -ifeq ($(BUILD_VARIANT),custom) - - LCD4LINUX_CUSTOM_DRIVERS:= $(strip $(foreach c, $(LCD4LINUX_DRIVERS), \ - $(if $(CONFIG_LCD4LINUX_CUSTOM_DRIVER_$(c)),$(c),) \ - )) - ifeq ($(LCD4LINUX_CUSTOM_DRIVERS),) - LCD4LINUX_CUSTOM_DRIVERS:=Sample - endif - - LCD4LINUX_CUSTOM_PLUGINS:= $(strip $(foreach c, $(LCD4LINUX_PLUGINS), \ - $(if $(CONFIG_LCD4LINUX_CUSTOM_PLUGIN_$(c)),$(c)) \ - )) - ifeq ($(LCD4LINUX_CUSTOM_PLUGINS),) - LCD4LINUX_CUSTOM_PLUGINS:=sample - endif - - CONFIGURE_ARGS+= \ - --with-drivers="$(LCD4LINUX_CUSTOM_DRIVERS)" \ - --with-plugins="$(LCD4LINUX_CUSTOM_PLUGINS)" \ - - ifneq ($(CONFIG_LCD4LINUX_CUSTOM_NEEDS_libiconv),) - CONFIGURE_ARGS+= --with-libiconv-prefix="$(ICONV_PREFIX)" - else - CONFIGURE_ARGS+= --without-libiconv-prefix - endif - - ifneq ($(CONFIG_LCD4LINUX_CUSTOM_NEEDS_libmysqlclient),) - EXTRA_LDFLAGS+= -L$(STAGING_DIR)/usr/lib/mysql - endif - -# ifneq ($(CONFIG_LCD4LINUX_CUSTOM_NEEDS_python),) -# CONFIGURE_ARGS+= --with-python -# else - CONFIGURE_ARGS+= --without-python -# endif - -# ifneq ($(CONFIG_LCD4LINUX_CUSTOM_NEEDS_libX11),) -# CONFIGURE_ARGS+= --with-x -# else - CONFIGURE_ARGS+= --without-x -# endif - -endif - -ifeq ($(BUILD_VARIANT),full) - - LCD4LINUX_FULL_DRIVERS:= $(strip $(foreach c, $(LCD4LINUX_DRIVERS), \ - $(c) \ - )) - - LCD4LINUX_FULL_PLUGINS:= $(strip $(foreach c, $(LCD4LINUX_PLUGINS), \ - $(c) \ - )) - - CONFIGURE_ARGS+= \ - --with-drivers="$(LCD4LINUX_FULL_DRIVERS)" \ - --with-plugins="$(LCD4LINUX_FULL_PLUGINS)" \ - --with-libiconv-prefix="$(ICONV_PREFIX)" \ - --without-python \ - --without-x \ - - EXTRA_LDFLAGS+= -L$(STAGING_DIR)/usr/lib/mysql - -endif - - -define Package/lcd4linux/conffiles -/etc/lcd4linux.conf -endef - -define Package/lcd4linux/install - $(INSTALL_DIR) $(1)/usr/bin - $(CP) $(PKG_INSTALL_DIR)/usr/bin/lcd4linux $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_CONF) $(PKG_BUILD_DIR)/lcd4linux.conf.sample $(1)/etc/lcd4linux.conf - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/lcd4linux.init $(1)/etc/init.d/lcd4linux - $(SED) "s|^\(Display 'GLCD2USB'\)|#\1|g" \ - -e "s|^\(Layout 'TestLayer'\)|#\1|g" \ - -e "s|^#\(Display 'Image'\)|\1|g" \ - -e "s|^#\(Layout 'Default'\)|\1|g" \ - $(1)/etc/lcd4linux.conf -endef - -Package/lcd4linux-custom/conffiles = $(Package/lcd4linux/conffiles) -Package/lcd4linux-custom/install = $(Package/lcd4linux/install) - -Package/lcd4linux-full/conffiles = $(Package/lcd4linux/conffiles) -Package/lcd4linux-full/install = $(Package/lcd4linux/install) - -$(eval $(call BuildPackage,lcd4linux-custom)) -$(eval $(call BuildPackage,lcd4linux-full)) diff --git a/utils/lcd4linux/files/lcd4linux.init b/utils/lcd4linux/files/lcd4linux.init deleted file mode 100644 index ec56a0922..000000000 --- a/utils/lcd4linux/files/lcd4linux.init +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2007-2011 OpenWrt.org - -START=98 - -SERVICE_USE_PID=1 - -start() { - service_start /usr/bin/lcd4linux -o /tmp/lcd4linux.png -q -} - -stop() { - service_stop /usr/bin/lcd4linux -} - diff --git a/utils/lcd4linux/patches/100-drv_RouterBoard.patch b/utils/lcd4linux/patches/100-drv_RouterBoard.patch deleted file mode 100644 index 9780f5a6b..000000000 --- a/utils/lcd4linux/patches/100-drv_RouterBoard.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drv_RouterBoard.c -+++ b/drv_RouterBoard.c -@@ -106,7 +106,7 @@ - #include - #include - #include --#include -+#include - - #include "debug.h" - #include "cfg.h" diff --git a/utils/lcd4linux/patches/110-uclibc-logarithm-fix.patch b/utils/lcd4linux/patches/110-uclibc-logarithm-fix.patch deleted file mode 100644 index 8f6d8619d..000000000 --- a/utils/lcd4linux/patches/110-uclibc-logarithm-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/plugin_netinfo.c -+++ b/plugin_netinfo.c -@@ -264,7 +264,7 @@ static void my_netmask_short(RESULT * re - sin = get_netmask(arg1); - if (NULL != sin) { - logval = (long double) (get_netmask(arg1)->sin_addr.s_addr); -- netlen = (int) rint(log2l(logval) / log2l(2.0)); -+ netlen = (int) rint(log2f(logval) / log2f(2.0)); - qprintf(value, sizeof(value), "/%d", netlen); - } else { - qprintf(value, sizeof(value), "/?"); diff --git a/utils/lcd4linux/patches/120-remove-as-needed-linker-option.patch b/utils/lcd4linux/patches/120-remove-as-needed-linker-option.patch deleted file mode 100644 index b5e56fe7b..000000000 --- a/utils/lcd4linux/patches/120-remove-as-needed-linker-option.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Makefile.am -+++ b/Makefile.am -@@ -18,7 +18,7 @@ ACLOCAL_AMFLAGS=-I m4 - # use this for lots of warnings - #AM_CFLAGS = -D_GNU_SOURCE -std=c99 -m64 -Wall -W -pedantic -Wno-variadic-macros -fno-strict-aliasing - --lcd4linux_LDFLAGS ="-Wl,--as-needed" -+lcd4linux_LDFLAGS = - lcd4linux_LDADD = @DRIVERS@ @PLUGINS@ @DRVLIBS@ @PLUGINLIBS@ - lcd4linux_DEPENDENCIES = @DRIVERS@ @PLUGINS@ - diff --git a/utils/lcd4linux/patches/140-no_repnop_T6963.patch b/utils/lcd4linux/patches/140-no_repnop_T6963.patch deleted file mode 100644 index 85be2c376..000000000 --- a/utils/lcd4linux/patches/140-no_repnop_T6963.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/drv_T6963.c -+++ b/drv_T6963.c -@@ -114,7 +114,9 @@ static void drv_T6_status1(void) - /* wait for STA0=1 and STA1=1 */ - n = 0; - do { -+#if 0 - rep_nop(); -+#endif - if (++n > 1000) { - debug("hang in status1"); - bug = 1; -@@ -150,7 +152,9 @@ static void drv_T6_status2(void) - /* wait for STA3=1 */ - n = 0; - do { -+#if 0 - rep_nop(); -+#endif - if (++n > 1000) { - debug("hang in status2"); - bug = 1; diff --git a/utils/lcd4linux/patches/150-addlibmpdclient.patch b/utils/lcd4linux/patches/150-addlibmpdclient.patch deleted file mode 100644 index 0e51f6760..000000000 --- a/utils/lcd4linux/patches/150-addlibmpdclient.patch +++ /dev/null @@ -1,2624 +0,0 @@ ---- /dev/null -+++ b/libmpdclient.c -@@ -0,0 +1,1957 @@ -+/* libmpdclient -+ (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) -+ This project's homepage is: http://www.musicpd.org -+ -+ Redistribution and use in source and binary forms, with or without -+ modification, are permitted provided that the following conditions -+ are met: -+ -+ - Redistributions of source code must retain the above copyright -+ notice, this list of conditions and the following disclaimer. -+ -+ - Redistributions in binary form must reproduce the above copyright -+ notice, this list of conditions and the following disclaimer in the -+ documentation and/or other materials provided with the distribution. -+ -+ - Neither the name of the Music Player Daemon nor the names of its -+ contributors may be used to endorse or promote products derived from -+ this software without specific prior written permission. -+ -+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR -+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+#include "libmpdclient.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef WIN32 -+# include -+# include -+#else -+# include -+# include -+# include -+# include -+#endif -+ -+/* (bits+1)/3 (plus the sign character) */ -+#define INTLEN ((sizeof(int) * CHAR_BIT + 1) / 3 + 1) -+#define LONGLONGLEN ((sizeof(long long) * CHAR_BIT + 1) / 3 + 1) -+ -+#define COMMAND_LIST 1 -+#define COMMAND_LIST_OK 2 -+ -+#ifndef MPD_NO_GAI -+# ifdef AI_ADDRCONFIG -+# define MPD_HAVE_GAI -+# endif -+#endif -+ -+#ifndef MSG_DONTWAIT -+# define MSG_DONTWAIT 0 -+#endif -+ -+#ifdef WIN32 -+# define SELECT_ERRNO_IGNORE (errno == WSAEINTR || errno == WSAEINPROGRESS) -+# define SENDRECV_ERRNO_IGNORE SELECT_ERRNO_IGNORE -+#else -+# define SELECT_ERRNO_IGNORE (errno == EINTR) -+# define SENDRECV_ERRNO_IGNORE (errno == EINTR || errno == EAGAIN) -+# define winsock_dll_error(c) 0 -+# define closesocket(s) close(s) -+# define WSACleanup() do { /* nothing */ } while (0) -+#endif -+ -+#ifdef WIN32 -+static int winsock_dll_error(mpd_Connection * connection) -+{ -+ WSADATA wsaData; -+ if ((WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 || LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { -+ strcpy(connection->errorStr, "Could not find usable WinSock DLL."); -+ connection->error = MPD_ERROR_SYSTEM; -+ return 1; -+ } -+ return 0; -+} -+ -+static int do_connect_fail(mpd_Connection * connection, const struct sockaddr *serv_addr, int addrlen) -+{ -+ int iMode = 1; /* 0 = blocking, else non-blocking */ -+ ioctlsocket(connection->sock, FIONBIO, (u_long FAR *) & iMode); -+ return (connect(connection->sock, serv_addr, addrlen) == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK); -+} -+#else /* !WIN32 (sane operating systems) */ -+static int do_connect_fail(mpd_Connection * connection, const struct sockaddr *serv_addr, int addrlen) -+{ -+ int flags = fcntl(connection->sock, F_GETFL, 0); -+ fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); -+ return (connect(connection->sock, serv_addr, addrlen) < 0 && errno != EINPROGRESS); -+} -+#endif /* !WIN32 */ -+ -+#ifdef MPD_HAVE_GAI -+static int mpd_connect(mpd_Connection * connection, const char *host, int port, float timeout) -+{ -+ int error; -+ char service[INTLEN + 1]; -+ struct addrinfo hints; -+ struct addrinfo *res = NULL; -+ struct addrinfo *addrinfo = NULL; -+ -+ /** -+ * Setup hints -+ */ -+ hints.ai_flags = AI_ADDRCONFIG; -+ hints.ai_family = PF_UNSPEC; -+ hints.ai_socktype = SOCK_STREAM; -+ hints.ai_protocol = IPPROTO_TCP; -+ hints.ai_addrlen = 0; -+ hints.ai_addr = NULL; -+ hints.ai_canonname = NULL; -+ hints.ai_next = NULL; -+ -+ snprintf(service, sizeof(service), "%i", port); -+ -+ error = getaddrinfo(host, service, &hints, &addrinfo); -+ -+ if (error) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "host \"%s\" not found: %s", host, gai_strerror(error)); -+ connection->error = MPD_ERROR_UNKHOST; -+ return -1; -+ } -+ -+ for (res = addrinfo; res; res = res->ai_next) { -+ /* create socket */ -+ connection->sock = socket(res->ai_family, SOCK_STREAM, res->ai_protocol); -+ if (connection->sock < 0) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "problems creating socket: %s", strerror(errno)); -+ connection->error = MPD_ERROR_SYSTEM; -+ freeaddrinfo(addrinfo); -+ return -1; -+ } -+ -+ mpd_setConnectionTimeout(connection, timeout); -+ -+ /* connect stuff */ -+ if (do_connect_fail(connection, res->ai_addr, res->ai_addrlen)) { -+ /* try the next address family */ -+ closesocket(connection->sock); -+ connection->sock = -1; -+ continue; -+ } -+ } -+ -+ freeaddrinfo(addrinfo); -+ -+ if (connection->sock < 0) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, -+ "problems connecting to \"%s\" on port %i: %s", host, port, strerror(errno)); -+ connection->error = MPD_ERROR_CONNPORT; -+ -+ return -1; -+ } -+ -+ return 0; -+} -+#else /* !MPD_HAVE_GAI */ -+static int mpd_connect(mpd_Connection * connection, const char *host, int port, float timeout) -+{ -+ struct hostent *he; -+ struct sockaddr *dest; -+ int destlen; -+ struct sockaddr_in sin; -+ -+ if (!(he = gethostbyname(host))) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "host \"%s\" not found", host); -+ connection->error = MPD_ERROR_UNKHOST; -+ return -1; -+ } -+ -+ memset(&sin, 0, sizeof(struct sockaddr_in)); -+ /*dest.sin_family = he->h_addrtype; */ -+ sin.sin_family = AF_INET; -+ sin.sin_port = htons(port); -+ -+ switch (he->h_addrtype) { -+ case AF_INET: -+ memcpy((char *) &sin.sin_addr.s_addr, (char *) he->h_addr, he->h_length); -+ dest = (struct sockaddr *) &sin; -+ destlen = sizeof(struct sockaddr_in); -+ break; -+ default: -+ strcpy(connection->errorStr, "address type is not IPv4"); -+ connection->error = MPD_ERROR_SYSTEM; -+ return -1; -+ break; -+ } -+ -+ if ((connection->sock = socket(dest->sa_family, SOCK_STREAM, 0)) < 0) { -+ strcpy(connection->errorStr, "problems creating socket"); -+ connection->error = MPD_ERROR_SYSTEM; -+ return -1; -+ } -+ -+ mpd_setConnectionTimeout(connection, timeout); -+ -+ /* connect stuff */ -+ if (do_connect_fail(connection, dest, destlen)) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, -+ "problems connecting to \"%s\" on port" " %i", host, port); -+ connection->error = MPD_ERROR_CONNPORT; -+ return -1; -+ } -+ -+ return 0; -+} -+#endif /* !MPD_HAVE_GAI */ -+ -+char *mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES] = { -+ "Artist", -+ "Album", -+ "Title", -+ "Track", -+ "Name", -+ "Genre", -+ "Date", -+ "Composer", -+ "Performer", -+ "Comment", -+ "Disc", -+ "Filename", -+ "Any" -+}; -+ -+static char *mpd_sanitizeArg(const char *arg) -+{ -+ size_t i; -+ char *ret; -+ register const char *c; -+ register char *rc; -+ -+ /* instead of counting in that loop above, just -+ * use a bit more memory and half running time -+ */ -+ ret = malloc(strlen(arg) * 2 + 1); -+ -+ c = arg; -+ rc = ret; -+ for (i = strlen(arg) + 1; i != 0; --i) { -+ if (*c == '"' || *c == '\\') -+ *rc++ = '\\'; -+ *(rc++) = *(c++); -+ } -+ -+ return ret; -+} -+ -+static mpd_ReturnElement *mpd_newReturnElement(const char *name, const char *value) -+{ -+ mpd_ReturnElement *ret = malloc(sizeof(mpd_ReturnElement)); -+ -+ ret->name = strdup(name); -+ ret->value = strdup(value); -+ -+ return ret; -+} -+ -+static void mpd_freeReturnElement(mpd_ReturnElement * re) -+{ -+ free(re->name); -+ free(re->value); -+ free(re); -+} -+ -+void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout) -+{ -+ connection->timeout.tv_sec = (int) timeout; -+ connection->timeout.tv_usec = (int) (timeout * 1e6 - connection->timeout.tv_sec * 1000000 + 0.5); -+} -+ -+static int mpd_parseWelcome(mpd_Connection * connection, const char *host, int port, char *rt, char *output) -+{ -+ char *tmp; -+ char *test; -+ int i; -+ -+ if (strncmp(output, MPD_WELCOME_MESSAGE, strlen(MPD_WELCOME_MESSAGE))) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, -+ "mpd not running on port %i on host \"%s\"", port, host); -+ connection->error = MPD_ERROR_NOTMPD; -+ return 1; -+ } -+ -+ tmp = &output[strlen(MPD_WELCOME_MESSAGE)]; -+ -+ for (i = 0; i < 3; i++) { -+ if (tmp) -+ connection->version[i] = strtol(tmp, &test, 10); -+ -+ if (!tmp || (test[0] != '.' && test[0] != '\0')) { -+ snprintf(connection->errorStr, -+ MPD_ERRORSTR_MAX_LENGTH, -+ "error parsing version number at " "\"%s\"", &output[strlen(MPD_WELCOME_MESSAGE)]); -+ connection->error = MPD_ERROR_NOTMPD; -+ return 1; -+ } -+ tmp = ++test; -+ } -+ -+ return 0; -+} -+ -+mpd_Connection *mpd_newConnection(const char *host, int port, float timeout) -+{ -+ int err; -+ char *rt; -+ char *output = NULL; -+ mpd_Connection *connection = malloc(sizeof(mpd_Connection)); -+ struct timeval tv; -+ fd_set fds; -+ strcpy(connection->buffer, ""); -+ connection->buflen = 0; -+ connection->bufstart = 0; -+ strcpy(connection->errorStr, ""); -+ connection->error = 0; -+ connection->doneProcessing = 0; -+ connection->commandList = 0; -+ connection->listOks = 0; -+ connection->doneListOk = 0; -+ connection->returnElement = NULL; -+ connection->request = NULL; -+ -+ if (winsock_dll_error(connection)) -+ return connection; -+ -+ if (mpd_connect(connection, host, port, timeout) < 0) -+ return connection; -+ -+ while (!(rt = strstr(connection->buffer, "\n"))) { -+ tv.tv_sec = connection->timeout.tv_sec; -+ tv.tv_usec = connection->timeout.tv_usec; -+ FD_ZERO(&fds); -+ FD_SET(connection->sock, &fds); -+ if ((err = select(connection->sock + 1, &fds, NULL, NULL, &tv)) == 1) { -+ int readed; -+ readed = recv(connection->sock, -+ &(connection->buffer[connection->buflen]), MPD_BUFFER_MAX_LENGTH - connection->buflen, 0); -+ if (readed <= 0) { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, -+ "problems getting a response from" " \"%s\" on port %i : %s", host, port, strerror(errno)); -+ connection->error = MPD_ERROR_NORESPONSE; -+ return connection; -+ } -+ connection->buflen += readed; -+ connection->buffer[connection->buflen] = '\0'; -+ } else if (err < 0) { -+ if (SELECT_ERRNO_IGNORE) -+ continue; -+ snprintf(connection->errorStr, -+ MPD_ERRORSTR_MAX_LENGTH, "problems connecting to \"%s\" on port" " %i", host, port); -+ connection->error = MPD_ERROR_CONNPORT; -+ return connection; -+ } else { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, -+ "timeout in attempting to get a response from" " \"%s\" on port %i", host, port); -+ connection->error = MPD_ERROR_NORESPONSE; -+ return connection; -+ } -+ } -+ -+ *rt = '\0'; -+ output = strdup(connection->buffer); -+ strcpy(connection->buffer, rt + 1); -+ connection->buflen = strlen(connection->buffer); -+ -+ if (mpd_parseWelcome(connection, host, port, rt, output) == 0) -+ connection->doneProcessing = 1; -+ -+ free(output); -+ -+ return connection; -+} -+ -+void mpd_clearError(mpd_Connection * connection) -+{ -+ connection->error = 0; -+ connection->errorStr[0] = '\0'; -+} -+ -+void mpd_closeConnection(mpd_Connection * connection) -+{ -+ closesocket(connection->sock); -+ if (connection->returnElement) -+ free(connection->returnElement); -+ if (connection->request) -+ free(connection->request); -+ free(connection); -+ WSACleanup(); -+} -+ -+static void mpd_executeCommand(mpd_Connection * connection, char *command) -+{ -+ int ret; -+ struct timeval tv; -+ fd_set fds; -+ char *commandPtr = command; -+ int commandLen = strlen(command); -+ -+ if (!connection->doneProcessing && !connection->commandList) { -+ strcpy(connection->errorStr, "not done processing current command"); -+ connection->error = 1; -+ return; -+ } -+ -+ mpd_clearError(connection); -+ -+ FD_ZERO(&fds); -+ FD_SET(connection->sock, &fds); -+ tv.tv_sec = connection->timeout.tv_sec; -+ tv.tv_usec = connection->timeout.tv_usec; -+ -+ while ((ret = select(connection->sock + 1, NULL, &fds, NULL, &tv) == 1) || (ret == -1 && SELECT_ERRNO_IGNORE)) { -+ ret = send(connection->sock, commandPtr, commandLen, MSG_DONTWAIT); -+ if (ret <= 0) { -+ if (SENDRECV_ERRNO_IGNORE) -+ continue; -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "problems giving command \"%s\"", command); -+ connection->error = MPD_ERROR_SENDING; -+ return; -+ } else { -+ commandPtr += ret; -+ commandLen -= ret; -+ } -+ -+ if (commandLen <= 0) -+ break; -+ } -+ -+ if (commandLen > 0) { -+ perror(""); -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "timeout sending command \"%s\"", command); -+ connection->error = MPD_ERROR_TIMEOUT; -+ return; -+ } -+ -+ if (!connection->commandList) -+ connection->doneProcessing = 0; -+ else if (connection->commandList == COMMAND_LIST_OK) { -+ connection->listOks++; -+ } -+} -+ -+static void mpd_getNextReturnElement(mpd_Connection * connection) -+{ -+ char *output = NULL; -+ char *rt = NULL; -+ char *name = NULL; -+ char *value = NULL; -+ fd_set fds; -+ struct timeval tv; -+ char *tok = NULL; -+ int readed; -+ char *bufferCheck = NULL; -+ int err; -+ int pos; -+ -+ if (connection->returnElement) -+ mpd_freeReturnElement(connection->returnElement); -+ connection->returnElement = NULL; -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ strcpy(connection->errorStr, "already done processing current command"); -+ connection->error = 1; -+ return; -+ } -+ -+ bufferCheck = connection->buffer + connection->bufstart; -+ while (connection->bufstart >= connection->buflen || !(rt = strchr(bufferCheck, '\n'))) { -+ if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) { -+ memmove(connection->buffer, -+ connection->buffer + connection->bufstart, connection->buflen - connection->bufstart + 1); -+ connection->buflen -= connection->bufstart; -+ connection->bufstart = 0; -+ } -+ if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) { -+ strcpy(connection->errorStr, "buffer overrun"); -+ connection->error = MPD_ERROR_BUFFEROVERRUN; -+ connection->doneProcessing = 1; -+ connection->doneListOk = 0; -+ return; -+ } -+ bufferCheck = connection->buffer + connection->buflen; -+ tv.tv_sec = connection->timeout.tv_sec; -+ tv.tv_usec = connection->timeout.tv_usec; -+ FD_ZERO(&fds); -+ FD_SET(connection->sock, &fds); -+ if ((err = select(connection->sock + 1, &fds, NULL, NULL, &tv) == 1)) { -+ readed = recv(connection->sock, -+ connection->buffer + connection->buflen, -+ MPD_BUFFER_MAX_LENGTH - connection->buflen, MSG_DONTWAIT); -+ if (readed < 0 && SENDRECV_ERRNO_IGNORE) { -+ continue; -+ } -+ if (readed <= 0) { -+ strcpy(connection->errorStr, "connection" " closed"); -+ connection->error = MPD_ERROR_CONNCLOSED; -+ connection->doneProcessing = 1; -+ connection->doneListOk = 0; -+ return; -+ } -+ connection->buflen += readed; -+ connection->buffer[connection->buflen] = '\0'; -+ } else if (err < 0 && SELECT_ERRNO_IGNORE) -+ continue; -+ else { -+ strcpy(connection->errorStr, "connection timeout"); -+ connection->error = MPD_ERROR_TIMEOUT; -+ connection->doneProcessing = 1; -+ connection->doneListOk = 0; -+ return; -+ } -+ } -+ -+ *rt = '\0'; -+ output = connection->buffer + connection->bufstart; -+ connection->bufstart = rt - connection->buffer + 1; -+ -+ if (strcmp(output, "OK") == 0) { -+ if (connection->listOks > 0) { -+ strcpy(connection->errorStr, "expected more list_OK's"); -+ connection->error = 1; -+ } -+ connection->listOks = 0; -+ connection->doneProcessing = 1; -+ connection->doneListOk = 0; -+ return; -+ } -+ -+ if (strcmp(output, "list_OK") == 0) { -+ if (!connection->listOks) { -+ strcpy(connection->errorStr, "got an unexpected list_OK"); -+ connection->error = 1; -+ } else { -+ connection->doneListOk = 1; -+ connection->listOks--; -+ } -+ return; -+ } -+ -+ if (strncmp(output, "ACK", strlen("ACK")) == 0) { -+ char *test; -+ char *needle; -+ int val; -+ -+ strcpy(connection->errorStr, output); -+ connection->error = MPD_ERROR_ACK; -+ connection->errorCode = MPD_ACK_ERROR_UNK; -+ connection->errorAt = MPD_ERROR_AT_UNK; -+ connection->doneProcessing = 1; -+ connection->doneListOk = 0; -+ -+ needle = strchr(output, '['); -+ if (!needle) -+ return; -+ val = strtol(needle + 1, &test, 10); -+ if (*test != '@') -+ return; -+ connection->errorCode = val; -+ val = strtol(test + 1, &test, 10); -+ if (*test != ']') -+ return; -+ connection->errorAt = val; -+ return; -+ } -+ -+ tok = strchr(output, ':'); -+ if (!tok) -+ return; -+ pos = tok - output; -+ value = ++tok; -+ name = output; -+ name[pos] = '\0'; -+ -+ if (value[0] == ' ') { -+ connection->returnElement = mpd_newReturnElement(name, &(value[1])); -+ } else { -+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "error parsing: %s:%s", name, value); -+ connection->error = 1; -+ } -+} -+ -+void mpd_finishCommand(mpd_Connection * connection) -+{ -+ while (!connection->doneProcessing) { -+ if (connection->doneListOk) -+ connection->doneListOk = 0; -+ mpd_getNextReturnElement(connection); -+ } -+} -+ -+static void mpd_finishListOkCommand(mpd_Connection * connection) -+{ -+ while (!connection->doneProcessing && connection->listOks && !connection->doneListOk) { -+ mpd_getNextReturnElement(connection); -+ } -+} -+ -+int mpd_nextListOkCommand(mpd_Connection * connection) -+{ -+ mpd_finishListOkCommand(connection); -+ if (!connection->doneProcessing) -+ connection->doneListOk = 0; -+ if (connection->listOks == 0 || connection->doneProcessing) -+ return -1; -+ return 0; -+} -+ -+void mpd_sendStatusCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "status\n"); -+} -+ -+mpd_Status *mpd_getStatus(mpd_Connection * connection) -+{ -+ mpd_Status *status; -+ -+ /*mpd_executeCommand(connection,"status\n"); -+ -+ if(connection->error) return NULL; */ -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ if (!connection->returnElement) -+ mpd_getNextReturnElement(connection); -+ -+ status = malloc(sizeof(mpd_Status)); -+ status->volume = -1; -+ status->repeat = 0; -+ status->random = 0; -+ status->playlist = -1; -+ status->playlistLength = -1; -+ status->state = -1; -+ status->song = 0; -+ status->songid = 0; -+ status->elapsedTime = 0; -+ status->totalTime = 0; -+ status->bitRate = 0; -+ status->sampleRate = 0; -+ status->bits = 0; -+ status->channels = 0; -+ status->crossfade = -1; -+ status->error = NULL; -+ status->updatingDb = 0; -+ -+ if (connection->error) { -+ free(status); -+ return NULL; -+ } -+ while (connection->returnElement) { -+ mpd_ReturnElement *re = connection->returnElement; -+ if (strcmp(re->name, "volume") == 0) { -+ status->volume = atoi(re->value); -+ } else if (strcmp(re->name, "repeat") == 0) { -+ status->repeat = atoi(re->value); -+ } else if (strcmp(re->name, "random") == 0) { -+ status->random = atoi(re->value); -+ } else if (strcmp(re->name, "playlist") == 0) { -+ status->playlist = strtol(re->value, NULL, 10); -+ } else if (strcmp(re->name, "playlistlength") == 0) { -+ status->playlistLength = atoi(re->value); -+ } else if (strcmp(re->name, "bitrate") == 0) { -+ status->bitRate = atoi(re->value); -+ } else if (strcmp(re->name, "state") == 0) { -+ if (strcmp(re->value, "play") == 0) { -+ status->state = MPD_STATUS_STATE_PLAY; -+ } else if (strcmp(re->value, "stop") == 0) { -+ status->state = MPD_STATUS_STATE_STOP; -+ } else if (strcmp(re->value, "pause") == 0) { -+ status->state = MPD_STATUS_STATE_PAUSE; -+ } else { -+ status->state = MPD_STATUS_STATE_UNKNOWN; -+ } -+ } else if (strcmp(re->name, "song") == 0) { -+ status->song = atoi(re->value); -+ } else if (strcmp(re->name, "songid") == 0) { -+ status->songid = atoi(re->value); -+ } else if (strcmp(re->name, "time") == 0) { -+ char *tok = strchr(re->value, ':'); -+ /* the second strchr below is a safety check */ -+ if (tok && (strchr(tok, 0) > (tok + 1))) { -+ /* atoi stops at the first non-[0-9] char: */ -+ status->elapsedTime = atoi(re->value); -+ status->totalTime = atoi(tok + 1); -+ } -+ } else if (strcmp(re->name, "error") == 0) { -+ status->error = strdup(re->value); -+ } else if (strcmp(re->name, "xfade") == 0) { -+ status->crossfade = atoi(re->value); -+ } else if (strcmp(re->name, "updating_db") == 0) { -+ status->updatingDb = atoi(re->value); -+ } else if (strcmp(re->name, "audio") == 0) { -+ char *tok = strchr(re->value, ':'); -+ if (tok && (strchr(tok, 0) > (tok + 1))) { -+ status->sampleRate = atoi(re->value); -+ status->bits = atoi(++tok); -+ tok = strchr(tok, ':'); -+ if (tok && (strchr(tok, 0) > (tok + 1))) -+ status->channels = atoi(tok + 1); -+ } -+ } -+ -+ mpd_getNextReturnElement(connection); -+ if (connection->error) { -+ free(status); -+ return NULL; -+ } -+ } -+ -+ if (connection->error) { -+ free(status); -+ return NULL; -+ } else if (status->state < 0) { -+ strcpy(connection->errorStr, "state not found"); -+ connection->error = 1; -+ free(status); -+ return NULL; -+ } -+ -+ return status; -+} -+ -+void mpd_freeStatus(mpd_Status * status) -+{ -+ if (status->error) -+ free(status->error); -+ free(status); -+} -+ -+void mpd_sendStatsCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "stats\n"); -+} -+ -+mpd_Stats *mpd_getStats(mpd_Connection * connection) -+{ -+ mpd_Stats *stats; -+ -+ /*mpd_executeCommand(connection,"stats\n"); -+ -+ if(connection->error) return NULL; */ -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ if (!connection->returnElement) -+ mpd_getNextReturnElement(connection); -+ -+ stats = malloc(sizeof(mpd_Stats)); -+ stats->numberOfArtists = 0; -+ stats->numberOfAlbums = 0; -+ stats->numberOfSongs = 0; -+ stats->uptime = 0; -+ stats->dbUpdateTime = 0; -+ stats->playTime = 0; -+ stats->dbPlayTime = 0; -+ -+ if (connection->error) { -+ free(stats); -+ return NULL; -+ } -+ while (connection->returnElement) { -+ mpd_ReturnElement *re = connection->returnElement; -+ if (strcmp(re->name, "artists") == 0) { -+ stats->numberOfArtists = atoi(re->value); -+ } else if (strcmp(re->name, "albums") == 0) { -+ stats->numberOfAlbums = atoi(re->value); -+ } else if (strcmp(re->name, "songs") == 0) { -+ stats->numberOfSongs = atoi(re->value); -+ } else if (strcmp(re->name, "uptime") == 0) { -+ stats->uptime = strtol(re->value, NULL, 10); -+ } else if (strcmp(re->name, "db_update") == 0) { -+ stats->dbUpdateTime = strtol(re->value, NULL, 10); -+ } else if (strcmp(re->name, "playtime") == 0) { -+ stats->playTime = strtol(re->value, NULL, 10); -+ } else if (strcmp(re->name, "db_playtime") == 0) { -+ stats->dbPlayTime = strtol(re->value, NULL, 10); -+ } -+ -+ mpd_getNextReturnElement(connection); -+ if (connection->error) { -+ free(stats); -+ return NULL; -+ } -+ } -+ -+ if (connection->error) { -+ free(stats); -+ return NULL; -+ } -+ -+ return stats; -+} -+ -+void mpd_freeStats(mpd_Stats * stats) -+{ -+ free(stats); -+} -+ -+mpd_SearchStats *mpd_getSearchStats(mpd_Connection * connection) -+{ -+ mpd_SearchStats *stats; -+ mpd_ReturnElement *re; -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ if (!connection->returnElement) -+ mpd_getNextReturnElement(connection); -+ -+ if (connection->error) -+ return NULL; -+ -+ stats = malloc(sizeof(mpd_SearchStats)); -+ stats->numberOfSongs = 0; -+ stats->playTime = 0; -+ -+ while (connection->returnElement) { -+ re = connection->returnElement; -+ -+ if (strcmp(re->name, "songs") == 0) { -+ stats->numberOfSongs = atoi(re->value); -+ } else if (strcmp(re->name, "playtime") == 0) { -+ stats->playTime = strtol(re->value, NULL, 10); -+ } -+ -+ mpd_getNextReturnElement(connection); -+ if (connection->error) { -+ free(stats); -+ return NULL; -+ } -+ } -+ -+ if (connection->error) { -+ free(stats); -+ return NULL; -+ } -+ -+ return stats; -+} -+ -+void mpd_freeSearchStats(mpd_SearchStats * stats) -+{ -+ free(stats); -+} -+ -+static void mpd_initSong(mpd_Song * song) -+{ -+ song->file = NULL; -+ song->artist = NULL; -+ song->album = NULL; -+ song->track = NULL; -+ song->title = NULL; -+ song->name = NULL; -+ song->date = NULL; -+ /* added by Qball */ -+ song->genre = NULL; -+ song->composer = NULL; -+ song->performer = NULL; -+ song->disc = NULL; -+ song->comment = NULL; -+ -+ song->time = MPD_SONG_NO_TIME; -+ song->pos = MPD_SONG_NO_NUM; -+ song->id = MPD_SONG_NO_ID; -+} -+ -+static void mpd_finishSong(mpd_Song * song) -+{ -+ if (song->file) -+ free(song->file); -+ if (song->artist) -+ free(song->artist); -+ if (song->album) -+ free(song->album); -+ if (song->title) -+ free(song->title); -+ if (song->track) -+ free(song->track); -+ if (song->name) -+ free(song->name); -+ if (song->date) -+ free(song->date); -+ if (song->genre) -+ free(song->genre); -+ if (song->composer) -+ free(song->composer); -+ if (song->disc) -+ free(song->disc); -+ if (song->comment) -+ free(song->comment); -+} -+ -+mpd_Song *mpd_newSong(void) -+{ -+ mpd_Song *ret = malloc(sizeof(mpd_Song)); -+ -+ mpd_initSong(ret); -+ -+ return ret; -+} -+ -+void mpd_freeSong(mpd_Song * song) -+{ -+ mpd_finishSong(song); -+ free(song); -+} -+ -+mpd_Song *mpd_songDup(mpd_Song * song) -+{ -+ mpd_Song *ret = mpd_newSong(); -+ -+ if (song->file) -+ ret->file = strdup(song->file); -+ if (song->artist) -+ ret->artist = strdup(song->artist); -+ if (song->album) -+ ret->album = strdup(song->album); -+ if (song->title) -+ ret->title = strdup(song->title); -+ if (song->track) -+ ret->track = strdup(song->track); -+ if (song->name) -+ ret->name = strdup(song->name); -+ if (song->date) -+ ret->date = strdup(song->date); -+ if (song->genre) -+ ret->genre = strdup(song->genre); -+ if (song->composer) -+ ret->composer = strdup(song->composer); -+ if (song->disc) -+ ret->disc = strdup(song->disc); -+ if (song->comment) -+ ret->comment = strdup(song->comment); -+ ret->time = song->time; -+ ret->pos = song->pos; -+ ret->id = song->id; -+ -+ return ret; -+} -+ -+static void mpd_initDirectory(mpd_Directory * directory) -+{ -+ directory->path = NULL; -+} -+ -+static void mpd_finishDirectory(mpd_Directory * directory) -+{ -+ if (directory->path) -+ free(directory->path); -+} -+ -+mpd_Directory *mpd_newDirectory(void) -+{ -+ mpd_Directory *directory = malloc(sizeof(mpd_Directory));; -+ -+ mpd_initDirectory(directory); -+ -+ return directory; -+} -+ -+void mpd_freeDirectory(mpd_Directory * directory) -+{ -+ mpd_finishDirectory(directory); -+ -+ free(directory); -+} -+ -+mpd_Directory *mpd_directoryDup(mpd_Directory * directory) -+{ -+ mpd_Directory *ret = mpd_newDirectory(); -+ -+ if (directory->path) -+ ret->path = strdup(directory->path); -+ -+ return ret; -+} -+ -+static void mpd_initPlaylistFile(mpd_PlaylistFile * playlist) -+{ -+ playlist->path = NULL; -+} -+ -+static void mpd_finishPlaylistFile(mpd_PlaylistFile * playlist) -+{ -+ if (playlist->path) -+ free(playlist->path); -+} -+ -+mpd_PlaylistFile *mpd_newPlaylistFile(void) -+{ -+ mpd_PlaylistFile *playlist = malloc(sizeof(mpd_PlaylistFile)); -+ -+ mpd_initPlaylistFile(playlist); -+ -+ return playlist; -+} -+ -+void mpd_freePlaylistFile(mpd_PlaylistFile * playlist) -+{ -+ mpd_finishPlaylistFile(playlist); -+ free(playlist); -+} -+ -+mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist) -+{ -+ mpd_PlaylistFile *ret = mpd_newPlaylistFile(); -+ -+ if (playlist->path) -+ ret->path = strdup(playlist->path); -+ -+ return ret; -+} -+ -+static void mpd_initInfoEntity(mpd_InfoEntity * entity) -+{ -+ entity->info.directory = NULL; -+} -+ -+static void mpd_finishInfoEntity(mpd_InfoEntity * entity) -+{ -+ if (entity->info.directory) { -+ if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { -+ mpd_freeDirectory(entity->info.directory); -+ } else if (entity->type == MPD_INFO_ENTITY_TYPE_SONG) { -+ mpd_freeSong(entity->info.song); -+ } else if (entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { -+ mpd_freePlaylistFile(entity->info.playlistFile); -+ } -+ } -+} -+ -+mpd_InfoEntity *mpd_newInfoEntity(void) -+{ -+ mpd_InfoEntity *entity = malloc(sizeof(mpd_InfoEntity)); -+ -+ mpd_initInfoEntity(entity); -+ -+ return entity; -+} -+ -+void mpd_freeInfoEntity(mpd_InfoEntity * entity) -+{ -+ mpd_finishInfoEntity(entity); -+ free(entity); -+} -+ -+static void mpd_sendInfoCommand(mpd_Connection * connection, char *command) -+{ -+ mpd_executeCommand(connection, command); -+} -+ -+mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection) -+{ -+ mpd_InfoEntity *entity = NULL; -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ if (!connection->returnElement) -+ mpd_getNextReturnElement(connection); -+ -+ if (connection->returnElement) { -+ if (strcmp(connection->returnElement->name, "file") == 0) { -+ entity = mpd_newInfoEntity(); -+ entity->type = MPD_INFO_ENTITY_TYPE_SONG; -+ entity->info.song = mpd_newSong(); -+ entity->info.song->file = strdup(connection->returnElement->value); -+ } else if (strcmp(connection->returnElement->name, "directory") == 0) { -+ entity = mpd_newInfoEntity(); -+ entity->type = MPD_INFO_ENTITY_TYPE_DIRECTORY; -+ entity->info.directory = mpd_newDirectory(); -+ entity->info.directory->path = strdup(connection->returnElement->value); -+ } else if (strcmp(connection->returnElement->name, "playlist") == 0) { -+ entity = mpd_newInfoEntity(); -+ entity->type = MPD_INFO_ENTITY_TYPE_PLAYLISTFILE; -+ entity->info.playlistFile = mpd_newPlaylistFile(); -+ entity->info.playlistFile->path = strdup(connection->returnElement->value); -+ } else if (strcmp(connection->returnElement->name, "cpos") == 0) { -+ entity = mpd_newInfoEntity(); -+ entity->type = MPD_INFO_ENTITY_TYPE_SONG; -+ entity->info.song = mpd_newSong(); -+ entity->info.song->pos = atoi(connection->returnElement->value); -+ } else { -+ connection->error = 1; -+ strcpy(connection->errorStr, "problem parsing song info"); -+ return NULL; -+ } -+ } else -+ return NULL; -+ -+ mpd_getNextReturnElement(connection); -+ while (connection->returnElement) { -+ mpd_ReturnElement *re = connection->returnElement; -+ -+ if (strcmp(re->name, "file") == 0) -+ return entity; -+ else if (strcmp(re->name, "directory") == 0) -+ return entity; -+ else if (strcmp(re->name, "playlist") == 0) -+ return entity; -+ else if (strcmp(re->name, "cpos") == 0) -+ return entity; -+ -+ if (entity->type == MPD_INFO_ENTITY_TYPE_SONG && strlen(re->value)) { -+ if (!entity->info.song->artist && strcmp(re->name, "Artist") == 0) { -+ entity->info.song->artist = strdup(re->value); -+ } else if (!entity->info.song->album && strcmp(re->name, "Album") == 0) { -+ entity->info.song->album = strdup(re->value); -+ } else if (!entity->info.song->title && strcmp(re->name, "Title") == 0) { -+ entity->info.song->title = strdup(re->value); -+ } else if (!entity->info.song->track && strcmp(re->name, "Track") == 0) { -+ entity->info.song->track = strdup(re->value); -+ } else if (!entity->info.song->name && strcmp(re->name, "Name") == 0) { -+ entity->info.song->name = strdup(re->value); -+ } else if (entity->info.song->time == MPD_SONG_NO_TIME && strcmp(re->name, "Time") == 0) { -+ entity->info.song->time = atoi(re->value); -+ } else if (entity->info.song->pos == MPD_SONG_NO_NUM && strcmp(re->name, "Pos") == 0) { -+ entity->info.song->pos = atoi(re->value); -+ } else if (entity->info.song->id == MPD_SONG_NO_ID && strcmp(re->name, "Id") == 0) { -+ entity->info.song->id = atoi(re->value); -+ } else if (!entity->info.song->date && strcmp(re->name, "Date") == 0) { -+ entity->info.song->date = strdup(re->value); -+ } else if (!entity->info.song->genre && strcmp(re->name, "Genre") == 0) { -+ entity->info.song->genre = strdup(re->value); -+ } else if (!entity->info.song->composer && strcmp(re->name, "Composer") == 0) { -+ entity->info.song->composer = strdup(re->value); -+ } else if (!entity->info.song->performer && strcmp(re->name, "Performer") == 0) { -+ entity->info.song->performer = strdup(re->value); -+ } else if (!entity->info.song->disc && strcmp(re->name, "Disc") == 0) { -+ entity->info.song->disc = strdup(re->value); -+ } else if (!entity->info.song->comment && strcmp(re->name, "Comment") == 0) { -+ entity->info.song->comment = strdup(re->value); -+ } -+ } else if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { -+ } else if (entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { -+ } -+ -+ mpd_getNextReturnElement(connection); -+ } -+ -+ return entity; -+} -+ -+static char *mpd_getNextReturnElementNamed(mpd_Connection * connection, const char *name) -+{ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ mpd_getNextReturnElement(connection); -+ while (connection->returnElement) { -+ mpd_ReturnElement *re = connection->returnElement; -+ -+ if (strcmp(re->name, name) == 0) -+ return strdup(re->value); -+ mpd_getNextReturnElement(connection); -+ } -+ -+ return NULL; -+} -+ -+char *mpd_getNextTag(mpd_Connection * connection, int type) -+{ -+ if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES || type == MPD_TAG_ITEM_ANY) -+ return NULL; -+ if (type == MPD_TAG_ITEM_FILENAME) -+ return mpd_getNextReturnElementNamed(connection, "file"); -+ return mpd_getNextReturnElementNamed(connection, mpdTagItemKeys[type]); -+} -+ -+char *mpd_getNextArtist(mpd_Connection * connection) -+{ -+ return mpd_getNextReturnElementNamed(connection, "Artist"); -+} -+ -+char *mpd_getNextAlbum(mpd_Connection * connection) -+{ -+ return mpd_getNextReturnElementNamed(connection, "Album"); -+} -+ -+void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songPos) -+{ -+ int len = strlen("playlistinfo") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistinfo \"%i\"\n", songPos); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id) -+{ -+ int len = strlen("playlistid") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistid \"%i\"\n", id); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist) -+{ -+ int len = strlen("plchanges") + 2 + LONGLONGLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "plchanges \"%lld\"\n", playlist); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist) -+{ -+ int len = strlen("plchangesposid") + 2 + LONGLONGLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "plchangesposid \"%lld\"\n", playlist); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendListallCommand(mpd_Connection * connection, const char *dir) -+{ -+ char *sDir = mpd_sanitizeArg(dir); -+ int len = strlen("listall") + 2 + strlen(sDir) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "listall \"%s\"\n", sDir); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+ free(sDir); -+} -+ -+void mpd_sendListallInfoCommand(mpd_Connection * connection, const char *dir) -+{ -+ char *sDir = mpd_sanitizeArg(dir); -+ int len = strlen("listallinfo") + 2 + strlen(sDir) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "listallinfo \"%s\"\n", sDir); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+ free(sDir); -+} -+ -+void mpd_sendLsInfoCommand(mpd_Connection * connection, const char *dir) -+{ -+ char *sDir = mpd_sanitizeArg(dir); -+ int len = strlen("lsinfo") + 2 + strlen(sDir) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "lsinfo \"%s\"\n", sDir); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+ free(sDir); -+} -+ -+void mpd_sendCurrentSongCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "currentsong\n"); -+} -+ -+void mpd_sendSearchCommand(mpd_Connection * connection, int table, const char *str) -+{ -+ mpd_startSearch(connection, 0); -+ mpd_addConstraintSearch(connection, table, str); -+ mpd_commitSearch(connection); -+} -+ -+void mpd_sendFindCommand(mpd_Connection * connection, int table, const char *str) -+{ -+ mpd_startSearch(connection, 1); -+ mpd_addConstraintSearch(connection, table, str); -+ mpd_commitSearch(connection); -+} -+ -+void mpd_sendListCommand(mpd_Connection * connection, int table, const char *arg1) -+{ -+ char st[10]; -+ int len; -+ char *string; -+ if (table == MPD_TABLE_ARTIST) -+ strcpy(st, "artist"); -+ else if (table == MPD_TABLE_ALBUM) -+ strcpy(st, "album"); -+ else { -+ connection->error = 1; -+ strcpy(connection->errorStr, "unknown table for list"); -+ return; -+ } -+ if (arg1) { -+ char *sanitArg1 = mpd_sanitizeArg(arg1); -+ len = strlen("list") + 1 + strlen(sanitArg1) + 2 + strlen(st) + 3; -+ string = malloc(len); -+ snprintf(string, len, "list %s \"%s\"\n", st, sanitArg1); -+ free(sanitArg1); -+ } else { -+ len = strlen("list") + 1 + strlen(st) + 2; -+ string = malloc(len); -+ snprintf(string, len, "list %s\n", st); -+ } -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendAddCommand(mpd_Connection * connection, const char *file) -+{ -+ char *sFile = mpd_sanitizeArg(file); -+ int len = strlen("add") + 2 + strlen(sFile) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "add \"%s\"\n", sFile); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sFile); -+} -+ -+int mpd_sendAddIdCommand(mpd_Connection * connection, const char *file) -+{ -+ int retval = -1; -+ char *sFile = mpd_sanitizeArg(file); -+ int len = strlen("addid") + 2 + strlen(sFile) + 3; -+ char *string = malloc(len); -+ -+ snprintf(string, len, "addid \"%s\"\n", sFile); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+ free(sFile); -+ -+ string = mpd_getNextReturnElementNamed(connection, "Id"); -+ if (string) { -+ retval = atoi(string); -+ free(string); -+ } -+ -+ return retval; -+} -+ -+void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos) -+{ -+ int len = strlen("delete") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "delete \"%i\"\n", songPos); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id) -+{ -+ int len = strlen("deleteid") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "deleteid \"%i\"\n", id); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSaveCommand(mpd_Connection * connection, const char *name) -+{ -+ char *sName = mpd_sanitizeArg(name); -+ int len = strlen("save") + 2 + strlen(sName) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "save \"%s\"\n", sName); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sName); -+} -+ -+void mpd_sendLoadCommand(mpd_Connection * connection, const char *name) -+{ -+ char *sName = mpd_sanitizeArg(name); -+ int len = strlen("load") + 2 + strlen(sName) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "load \"%s\"\n", sName); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sName); -+} -+ -+void mpd_sendRmCommand(mpd_Connection * connection, const char *name) -+{ -+ char *sName = mpd_sanitizeArg(name); -+ int len = strlen("rm") + 2 + strlen(sName) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "rm \"%s\"\n", sName); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sName); -+} -+ -+void mpd_sendRenameCommand(mpd_Connection * connection, const char *from, const char *to) -+{ -+ char *sFrom = mpd_sanitizeArg(from); -+ char *sTo = mpd_sanitizeArg(to); -+ int len = strlen("rename") + 2 + strlen(sFrom) + 3 + strlen(sTo) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "rename \"%s\" \"%s\"\n", sFrom, sTo); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sFrom); -+ free(sTo); -+} -+ -+void mpd_sendShuffleCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "shuffle\n"); -+} -+ -+void mpd_sendClearCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "clear\n"); -+} -+ -+void mpd_sendPlayCommand(mpd_Connection * connection, int songPos) -+{ -+ int len = strlen("play") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "play \"%i\"\n", songPos); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendPlayIdCommand(mpd_Connection * connection, int id) -+{ -+ int len = strlen("playid") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playid \"%i\"\n", id); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendStopCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "stop\n"); -+} -+ -+void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode) -+{ -+ int len = strlen("pause") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "pause \"%i\"\n", pauseMode); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendNextCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "next\n"); -+} -+ -+void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to) -+{ -+ int len = strlen("move") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "move \"%i\" \"%i\"\n", from, to); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to) -+{ -+ int len = strlen("moveid") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "moveid \"%i\" \"%i\"\n", id, to); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2) -+{ -+ int len = strlen("swap") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "swap \"%i\" \"%i\"\n", song1, song2); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2) -+{ -+ int len = strlen("swapid") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "swapid \"%i\" \"%i\"\n", id1, id2); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time) -+{ -+ int len = strlen("seek") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "seek \"%i\" \"%i\"\n", song, time); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int time) -+{ -+ int len = strlen("seekid") + 2 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "seekid \"%i\" \"%i\"\n", id, time); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendUpdateCommand(mpd_Connection * connection, char *path) -+{ -+ char *sPath = mpd_sanitizeArg(path); -+ int len = strlen("update") + 2 + strlen(sPath) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "update \"%s\"\n", sPath); -+ mpd_sendInfoCommand(connection, string); -+ free(string); -+ free(sPath); -+} -+ -+int mpd_getUpdateId(mpd_Connection * connection) -+{ -+ char *jobid; -+ int ret = 0; -+ -+ jobid = mpd_getNextReturnElementNamed(connection, "updating_db"); -+ if (jobid) { -+ ret = atoi(jobid); -+ free(jobid); -+ } -+ -+ return ret; -+} -+ -+void mpd_sendPrevCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "previous\n"); -+} -+ -+void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode) -+{ -+ int len = strlen("repeat") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "repeat \"%i\"\n", repeatMode); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode) -+{ -+ int len = strlen("random") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "random \"%i\"\n", randomMode); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange) -+{ -+ int len = strlen("setvol") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "setvol \"%i\"\n", volumeChange); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange) -+{ -+ int len = strlen("volume") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "volume \"%i\"\n", volumeChange); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds) -+{ -+ int len = strlen("crossfade") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "crossfade \"%i\"\n", seconds); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendPasswordCommand(mpd_Connection * connection, const char *pass) -+{ -+ char *sPass = mpd_sanitizeArg(pass); -+ int len = strlen("password") + 2 + strlen(sPass) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "password \"%s\"\n", sPass); -+ mpd_executeCommand(connection, string); -+ free(string); -+ free(sPass); -+} -+ -+void mpd_sendCommandListBegin(mpd_Connection * connection) -+{ -+ if (connection->commandList) { -+ strcpy(connection->errorStr, "already in command list mode"); -+ connection->error = 1; -+ return; -+ } -+ connection->commandList = COMMAND_LIST; -+ mpd_executeCommand(connection, "command_list_begin\n"); -+} -+ -+void mpd_sendCommandListOkBegin(mpd_Connection * connection) -+{ -+ if (connection->commandList) { -+ strcpy(connection->errorStr, "already in command list mode"); -+ connection->error = 1; -+ return; -+ } -+ connection->commandList = COMMAND_LIST_OK; -+ mpd_executeCommand(connection, "command_list_ok_begin\n"); -+ connection->listOks = 0; -+} -+ -+void mpd_sendCommandListEnd(mpd_Connection * connection) -+{ -+ if (!connection->commandList) { -+ strcpy(connection->errorStr, "not in command list mode"); -+ connection->error = 1; -+ return; -+ } -+ connection->commandList = 0; -+ mpd_executeCommand(connection, "command_list_end\n"); -+} -+ -+void mpd_sendOutputsCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "outputs\n"); -+} -+ -+mpd_OutputEntity *mpd_getNextOutput(mpd_Connection * connection) -+{ -+ mpd_OutputEntity *output = NULL; -+ -+ if (connection->doneProcessing || (connection->listOks && connection->doneListOk)) { -+ return NULL; -+ } -+ -+ if (connection->error) -+ return NULL; -+ -+ output = malloc(sizeof(mpd_OutputEntity)); -+ output->id = -10; -+ output->name = NULL; -+ output->enabled = 0; -+ -+ if (!connection->returnElement) -+ mpd_getNextReturnElement(connection); -+ -+ while (connection->returnElement) { -+ mpd_ReturnElement *re = connection->returnElement; -+ if (strcmp(re->name, "outputid") == 0) { -+ if (output != NULL && output->id >= 0) -+ return output; -+ output->id = atoi(re->value); -+ } else if (strcmp(re->name, "outputname") == 0) { -+ output->name = strdup(re->value); -+ } else if (strcmp(re->name, "outputenabled") == 0) { -+ output->enabled = atoi(re->value); -+ } -+ -+ mpd_getNextReturnElement(connection); -+ if (connection->error) { -+ free(output); -+ return NULL; -+ } -+ -+ } -+ -+ return output; -+} -+ -+void mpd_sendEnableOutputCommand(mpd_Connection * connection, int outputId) -+{ -+ int len = strlen("enableoutput") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "enableoutput \"%i\"\n", outputId); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId) -+{ -+ int len = strlen("disableoutput") + 2 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "disableoutput \"%i\"\n", outputId); -+ mpd_executeCommand(connection, string); -+ free(string); -+} -+ -+void mpd_freeOutputElement(mpd_OutputEntity * output) -+{ -+ free(output->name); -+ free(output); -+} -+ -+/** -+ * mpd_sendNotCommandsCommand -+ * odd naming, but it gets the not allowed commands -+ */ -+ -+void mpd_sendNotCommandsCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "notcommands\n"); -+} -+ -+/** -+ * mpd_sendCommandsCommand -+ * odd naming, but it gets the allowed commands -+ */ -+void mpd_sendCommandsCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "commands\n"); -+} -+ -+/** -+ * Get the next returned command -+ */ -+char *mpd_getNextCommand(mpd_Connection * connection) -+{ -+ return mpd_getNextReturnElementNamed(connection, "command"); -+} -+ -+void mpd_sendUrlHandlersCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "urlhandlers\n"); -+} -+ -+char *mpd_getNextHandler(mpd_Connection * connection) -+{ -+ return mpd_getNextReturnElementNamed(connection, "handler"); -+} -+ -+void mpd_sendTagTypesCommand(mpd_Connection * connection) -+{ -+ mpd_executeCommand(connection, "tagtypes\n"); -+} -+ -+char *mpd_getNextTagType(mpd_Connection * connection) -+{ -+ return mpd_getNextReturnElementNamed(connection, "tagtype"); -+} -+ -+void mpd_startSearch(mpd_Connection * connection, int exact) -+{ -+ if (connection->request) { -+ strcpy(connection->errorStr, "search already in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ if (exact) -+ connection->request = strdup("find"); -+ else -+ connection->request = strdup("search"); -+} -+ -+void mpd_startStatsSearch(mpd_Connection * connection) -+{ -+ if (connection->request) { -+ strcpy(connection->errorStr, "search already in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ connection->request = strdup("count"); -+} -+ -+void mpd_startPlaylistSearch(mpd_Connection * connection, int exact) -+{ -+ if (connection->request) { -+ strcpy(connection->errorStr, "search already in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ if (exact) -+ connection->request = strdup("playlistfind"); -+ else -+ connection->request = strdup("playlistsearch"); -+} -+ -+void mpd_startFieldSearch(mpd_Connection * connection, int type) -+{ -+ char *strtype; -+ int len; -+ -+ if (connection->request) { -+ strcpy(connection->errorStr, "search already in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES) { -+ strcpy(connection->errorStr, "invalid type specified"); -+ connection->error = 1; -+ return; -+ } -+ -+ strtype = mpdTagItemKeys[type]; -+ -+ len = 5 + strlen(strtype) + 1; -+ connection->request = malloc(len); -+ -+ snprintf(connection->request, len, "list %c%s", tolower(strtype[0]), strtype + 1); -+} -+ -+void mpd_addConstraintSearch(mpd_Connection * connection, int type, const char *name) -+{ -+ char *strtype; -+ char *arg; -+ int len; -+ char *string; -+ -+ if (!connection->request) { -+ strcpy(connection->errorStr, "no search in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES) { -+ strcpy(connection->errorStr, "invalid type specified"); -+ connection->error = 1; -+ return; -+ } -+ -+ if (name == NULL) { -+ strcpy(connection->errorStr, "no name specified"); -+ connection->error = 1; -+ return; -+ } -+ -+ string = strdup(connection->request); -+ strtype = mpdTagItemKeys[type]; -+ arg = mpd_sanitizeArg(name); -+ -+ len = strlen(string) + 1 + strlen(strtype) + 2 + strlen(arg) + 2; -+ connection->request = realloc(connection->request, len); -+ snprintf(connection->request, len, "%s %c%s \"%s\"", string, tolower(strtype[0]), strtype + 1, arg); -+ -+ free(string); -+ free(arg); -+} -+ -+void mpd_commitSearch(mpd_Connection * connection) -+{ -+ int len; -+ -+ if (!connection->request) { -+ strcpy(connection->errorStr, "no search in progress"); -+ connection->error = 1; -+ return; -+ } -+ -+ len = strlen(connection->request) + 2; -+ connection->request = realloc(connection->request, len); -+ connection->request[len - 2] = '\n'; -+ connection->request[len - 1] = '\0'; -+ mpd_sendInfoCommand(connection, connection->request); -+ -+ free(connection->request); -+ connection->request = NULL; -+} -+ -+/** -+ * @param connection a MpdConnection -+ * @param path the path to the playlist. -+ * -+ * List the content, with full metadata, of a stored playlist. -+ * -+ */ -+void mpd_sendListPlaylistInfoCommand(mpd_Connection * connection, char *path) -+{ -+ char *arg = mpd_sanitizeArg(path); -+ int len = strlen("listplaylistinfo") + 2 + strlen(arg) + 3; -+ char *query = malloc(len); -+ snprintf(query, len, "listplaylistinfo \"%s\"\n", arg); -+ mpd_sendInfoCommand(connection, query); -+ free(arg); -+ free(query); -+} -+ -+/** -+ * @param connection a MpdConnection -+ * @param path the path to the playlist. -+ * -+ * List the content of a stored playlist. -+ * -+ */ -+void mpd_sendListPlaylistCommand(mpd_Connection * connection, char *path) -+{ -+ char *arg = mpd_sanitizeArg(path); -+ int len = strlen("listplaylist") + 2 + strlen(arg) + 3; -+ char *query = malloc(len); -+ snprintf(query, len, "listplaylist \"%s\"\n", arg); -+ mpd_sendInfoCommand(connection, query); -+ free(arg); -+ free(query); -+} -+ -+void mpd_sendPlaylistClearCommand(mpd_Connection * connection, char *path) -+{ -+ char *sPath = mpd_sanitizeArg(path); -+ int len = strlen("playlistclear") + 2 + strlen(sPath) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistclear \"%s\"\n", sPath); -+ mpd_executeCommand(connection, string); -+ free(sPath); -+ free(string); -+} -+ -+void mpd_sendPlaylistAddCommand(mpd_Connection * connection, char *playlist, char *path) -+{ -+ char *sPlaylist = mpd_sanitizeArg(playlist); -+ char *sPath = mpd_sanitizeArg(path); -+ int len = strlen("playlistadd") + 2 + strlen(sPlaylist) + 3 + strlen(sPath) + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistadd \"%s\" \"%s\"\n", sPlaylist, sPath); -+ mpd_executeCommand(connection, string); -+ free(sPlaylist); -+ free(sPath); -+ free(string); -+} -+ -+void mpd_sendPlaylistMoveCommand(mpd_Connection * connection, char *playlist, int from, int to) -+{ -+ char *sPlaylist = mpd_sanitizeArg(playlist); -+ int len = strlen("playlistmove") + 2 + strlen(sPlaylist) + 3 + INTLEN + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistmove \"%s\" \"%i\" \"%i\"\n", sPlaylist, from, to); -+ mpd_executeCommand(connection, string); -+ free(sPlaylist); -+ free(string); -+} -+ -+void mpd_sendPlaylistDeleteCommand(mpd_Connection * connection, char *playlist, int pos) -+{ -+ char *sPlaylist = mpd_sanitizeArg(playlist); -+ int len = strlen("playlistdelete") + 2 + strlen(sPlaylist) + 3 + INTLEN + 3; -+ char *string = malloc(len); -+ snprintf(string, len, "playlistdelete \"%s\" \"%i\"\n", sPlaylist, pos); -+ mpd_executeCommand(connection, string); -+ free(sPlaylist); -+ free(string); -+} ---- /dev/null -+++ b/libmpdclient.h -@@ -0,0 +1,661 @@ -+/* libmpdclient -+ (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) -+ This project's homepage is: http://www.musicpd.org -+ -+ Redistribution and use in source and binary forms, with or without -+ modification, are permitted provided that the following conditions -+ are met: -+ -+ - Redistributions of source code must retain the above copyright -+ notice, this list of conditions and the following disclaimer. -+ -+ - Redistributions in binary form must reproduce the above copyright -+ notice, this list of conditions and the following disclaimer in the -+ documentation and/or other materials provided with the distribution. -+ -+ - Neither the name of the Music Player Daemon nor the names of its -+ contributors may be used to endorse or promote products derived from -+ this software without specific prior written permission. -+ -+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR -+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+#ifndef LIBMPDCLIENT_H -+#define LIBMPDCLIENT_H -+ -+#ifdef WIN32 -+# define __W32API_USE_DLLIMPORT__ 1 -+#endif -+ -+#include -+#include -+#define MPD_BUFFER_MAX_LENGTH 50000 -+#define MPD_ERRORSTR_MAX_LENGTH 1000 -+#define MPD_WELCOME_MESSAGE "OK MPD " -+ -+#define MPD_ERROR_TIMEOUT 10 /* timeout trying to talk to mpd */ -+#define MPD_ERROR_SYSTEM 11 /* system error */ -+#define MPD_ERROR_UNKHOST 12 /* unknown host */ -+#define MPD_ERROR_CONNPORT 13 /* problems connecting to port on host */ -+#define MPD_ERROR_NOTMPD 14 /* mpd not running on port at host */ -+#define MPD_ERROR_NORESPONSE 15 /* no response on attempting to connect */ -+#define MPD_ERROR_SENDING 16 /* error sending command */ -+#define MPD_ERROR_CONNCLOSED 17 /* connection closed by mpd */ -+#define MPD_ERROR_ACK 18 /* ACK returned! */ -+#define MPD_ERROR_BUFFEROVERRUN 19 /* Buffer was overrun! */ -+ -+#define MPD_ACK_ERROR_UNK -1 -+#define MPD_ERROR_AT_UNK -1 -+ -+#define MPD_ACK_ERROR_NOT_LIST 1 -+#define MPD_ACK_ERROR_ARG 2 -+#define MPD_ACK_ERROR_PASSWORD 3 -+#define MPD_ACK_ERROR_PERMISSION 4 -+#define MPD_ACK_ERROR_UNKNOWN_CMD 5 -+ -+#define MPD_ACK_ERROR_NO_EXIST 50 -+#define MPD_ACK_ERROR_PLAYLIST_MAX 51 -+#define MPD_ACK_ERROR_SYSTEM 52 -+#define MPD_ACK_ERROR_PLAYLIST_LOAD 53 -+#define MPD_ACK_ERROR_UPDATE_ALREADY 54 -+#define MPD_ACK_ERROR_PLAYER_SYNC 55 -+#define MPD_ACK_ERROR_EXIST 56 -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ typedef enum mpd_TagItems { -+ MPD_TAG_ITEM_ARTIST, -+ MPD_TAG_ITEM_ALBUM, -+ MPD_TAG_ITEM_TITLE, -+ MPD_TAG_ITEM_TRACK, -+ MPD_TAG_ITEM_NAME, -+ MPD_TAG_ITEM_GENRE, -+ MPD_TAG_ITEM_DATE, -+ MPD_TAG_ITEM_COMPOSER, -+ MPD_TAG_ITEM_PERFORMER, -+ MPD_TAG_ITEM_COMMENT, -+ MPD_TAG_ITEM_DISC, -+ MPD_TAG_ITEM_FILENAME, -+ MPD_TAG_ITEM_ANY, -+ MPD_TAG_NUM_OF_ITEM_TYPES -+ } mpd_TagItems; -+ -+ extern char *mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES]; -+ -+/* internal stuff don't touch this struct */ -+ typedef struct _mpd_ReturnElement { -+ char *name; -+ char *value; -+ } mpd_ReturnElement; -+ -+/* mpd_Connection -+ * holds info about connection to mpd -+ * use error, and errorStr to detect errors -+ */ -+ typedef struct _mpd_Connection { -+ /* use this to check the version of mpd */ -+ int version[3]; -+ /* IMPORTANT, you want to get the error messages from here */ -+ char errorStr[MPD_ERRORSTR_MAX_LENGTH + 1]; -+ int errorCode; -+ int errorAt; -+ /* this will be set to MPD_ERROR_* if there is an error, 0 if not */ -+ int error; -+ /* DON'T TOUCH any of the rest of this stuff */ -+ int sock; -+ char buffer[MPD_BUFFER_MAX_LENGTH + 1]; -+ int buflen; -+ int bufstart; -+ int doneProcessing; -+ int listOks; -+ int doneListOk; -+ int commandList; -+ mpd_ReturnElement *returnElement; -+ struct timeval timeout; -+ char *request; -+ } mpd_Connection; -+ -+/* mpd_newConnection -+ * use this to open a new connection -+ * you should use mpd_closeConnection, when your done with the connection, -+ * even if an error has occurred -+ * _timeout_ is the connection timeout period in seconds -+ */ -+ mpd_Connection *mpd_newConnection(const char *host, int port, float timeout); -+ -+ void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout); -+ -+/* mpd_closeConnection -+ * use this to close a connection and free'ing subsequent memory -+ */ -+ void mpd_closeConnection(mpd_Connection * connection); -+ -+/* mpd_clearError -+ * clears error -+ */ -+ void mpd_clearError(mpd_Connection * connection); -+ -+/* STATUS STUFF */ -+ -+/* use these with status.state to determine what state the player is in */ -+#define MPD_STATUS_STATE_UNKNOWN 0 -+#define MPD_STATUS_STATE_STOP 1 -+#define MPD_STATUS_STATE_PLAY 2 -+#define MPD_STATUS_STATE_PAUSE 3 -+ -+/* us this with status.volume to determine if mpd has volume support */ -+#define MPD_STATUS_NO_VOLUME -1 -+ -+/* mpd_Status -+ * holds info return from status command -+ */ -+ typedef struct mpd_Status { -+ /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */ -+ int volume; -+ /* 1 if repeat is on, 0 otherwise */ -+ int repeat; -+ /* 1 if random is on, 0 otherwise */ -+ int random; -+ /* playlist length */ -+ int playlistLength; -+ /* playlist, use this to determine when the playlist has changed */ -+ long long playlist; -+ /* use with MPD_STATUS_STATE_* to determine state of player */ -+ int state; -+ /* crossfade setting in seconds */ -+ int crossfade; -+ /* if a song is currently selected (always the case when state is -+ * PLAY or PAUSE), this is the position of the currently -+ * playing song in the playlist, beginning with 0 -+ */ -+ int song; -+ /* Song ID of the currently selected song */ -+ int songid; -+ /* time in seconds that have elapsed in the currently playing/paused -+ * song -+ */ -+ int elapsedTime; -+ /* length in seconds of the currently playing/paused song */ -+ int totalTime; -+ /* current bit rate in kbs */ -+ int bitRate; -+ /* audio sample rate */ -+ unsigned int sampleRate; -+ /* audio bits */ -+ int bits; -+ /* audio channels */ -+ int channels; -+ /* 1 if mpd is updating, 0 otherwise */ -+ int updatingDb; -+ /* error */ -+ char *error; -+ } mpd_Status; -+ -+ void mpd_sendStatusCommand(mpd_Connection * connection); -+ -+/* mpd_getStatus -+ * returns status info, be sure to free it with mpd_freeStatus() -+ * call this after mpd_sendStatusCommand() -+ */ -+ mpd_Status *mpd_getStatus(mpd_Connection * connection); -+ -+/* mpd_freeStatus -+ * free's status info malloc'd and returned by mpd_getStatus -+ */ -+ void mpd_freeStatus(mpd_Status * status); -+ -+ typedef struct _mpd_Stats { -+ int numberOfArtists; -+ int numberOfAlbums; -+ int numberOfSongs; -+ unsigned long uptime; -+ unsigned long dbUpdateTime; -+ unsigned long playTime; -+ unsigned long dbPlayTime; -+ } mpd_Stats; -+ -+ typedef struct _mpd_SearchStats { -+ int numberOfSongs; -+ unsigned long playTime; -+ } mpd_SearchStats; -+ -+ void mpd_sendStatsCommand(mpd_Connection * connection); -+ -+ mpd_Stats *mpd_getStats(mpd_Connection * connection); -+ -+ void mpd_freeStats(mpd_Stats * stats); -+ -+ mpd_SearchStats *mpd_getSearchStats(mpd_Connection * connection); -+ -+ void mpd_freeSearchStats(mpd_SearchStats * stats); -+ -+/* SONG STUFF */ -+ -+#define MPD_SONG_NO_TIME -1 -+#define MPD_SONG_NO_NUM -1 -+#define MPD_SONG_NO_ID -1 -+ -+/* mpd_Song -+ * for storing song info returned by mpd -+ */ -+ typedef struct _mpd_Song { -+ /* filename of song */ -+ char *file; -+ /* artist, maybe NULL if there is no tag */ -+ char *artist; -+ /* title, maybe NULL if there is no tag */ -+ char *title; -+ /* album, maybe NULL if there is no tag */ -+ char *album; -+ /* track, maybe NULL if there is no tag */ -+ char *track; -+ /* name, maybe NULL if there is no tag; it's the name of the current -+ * song, f.e. the icyName of the stream */ -+ char *name; -+ /* date */ -+ char *date; -+ -+ /* added by qball */ -+ /* Genre */ -+ char *genre; -+ /* Composer */ -+ char *composer; -+ /* Performer */ -+ char *performer; -+ /* Disc */ -+ char *disc; -+ /* Comment */ -+ char *comment; -+ -+ /* length of song in seconds, check that it is not MPD_SONG_NO_TIME */ -+ int time; -+ /* if plchanges/playlistinfo/playlistid used, is the position of the -+ * song in the playlist */ -+ int pos; -+ /* song id for a song in the playlist */ -+ int id; -+ } mpd_Song; -+ -+/* mpd_newSong -+ * use to allocate memory for a new mpd_Song -+ * file, artist, etc all initialized to NULL -+ * if your going to assign values to file, artist, etc -+ * be sure to malloc or strdup the memory -+ * use mpd_freeSong to free the memory for the mpd_Song, it will also -+ * free memory for file, artist, etc, so don't do it yourself -+ */ -+ mpd_Song *mpd_newSong(void); -+ -+/* mpd_freeSong -+ * use to free memory allocated by mpd_newSong -+ * also it will free memory pointed to by file, artist, etc, so be careful -+ */ -+ void mpd_freeSong(mpd_Song * song); -+ -+/* mpd_songDup -+ * works like strDup, but for a mpd_Song -+ */ -+ mpd_Song *mpd_songDup(mpd_Song * song); -+ -+/* DIRECTORY STUFF */ -+ -+/* mpd_Directory -+ * used to store info fro directory (right now that just the path) -+ */ -+ typedef struct _mpd_Directory { -+ char *path; -+ } mpd_Directory; -+ -+/* mpd_newDirectory -+ * allocates memory for a new directory -+ * use mpd_freeDirectory to free this memory -+ */ -+ mpd_Directory *mpd_newDirectory(void); -+ -+/* mpd_freeDirectory -+ * used to free memory allocated with mpd_newDirectory, and it frees -+ * path of mpd_Directory, so be careful -+ */ -+ void mpd_freeDirectory(mpd_Directory * directory); -+ -+/* mpd_directoryDup -+ * works like strdup, but for mpd_Directory -+ */ -+ mpd_Directory *mpd_directoryDup(mpd_Directory * directory); -+ -+/* PLAYLISTFILE STUFF */ -+ -+/* mpd_PlaylistFile -+ * stores info about playlist file returned by lsinfo -+ */ -+ typedef struct _mpd_PlaylistFile { -+ char *path; -+ } mpd_PlaylistFile; -+ -+/* mpd_newPlaylistFile -+ * allocates memory for new mpd_PlaylistFile, path is set to NULL -+ * free this memory with mpd_freePlaylistFile -+ */ -+ mpd_PlaylistFile *mpd_newPlaylistFile(void); -+ -+/* mpd_freePlaylist -+ * free memory allocated for freePlaylistFile, will also free -+ * path, so be careful -+ */ -+ void mpd_freePlaylistFile(mpd_PlaylistFile * playlist); -+ -+/* mpd_playlistFileDup -+ * works like strdup, but for mpd_PlaylistFile -+ */ -+ mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist); -+ -+/* INFO ENTITY STUFF */ -+ -+/* the type of entity returned from one of the commands that generates info -+ * use in conjunction with mpd_InfoEntity.type -+ */ -+#define MPD_INFO_ENTITY_TYPE_DIRECTORY 0 -+#define MPD_INFO_ENTITY_TYPE_SONG 1 -+#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2 -+ -+/* mpd_InfoEntity -+ * stores info on stuff returned info commands -+ */ -+ typedef struct mpd_InfoEntity { -+ /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine -+ * what this entity is (song, directory, etc...) -+ */ -+ int type; -+ /* the actual data you want, mpd_Song, mpd_Directory, etc */ -+ union { -+ mpd_Directory *directory; -+ mpd_Song *song; -+ mpd_PlaylistFile *playlistFile; -+ } info; -+ } mpd_InfoEntity; -+ -+ mpd_InfoEntity *mpd_newInfoEntity(void); -+ -+ void mpd_freeInfoEntity(mpd_InfoEntity * entity); -+ -+/* INFO COMMANDS AND STUFF */ -+ -+/* use this function to loop over after calling Info/Listall functions */ -+ mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection); -+ -+/* fetches the currently seeletect song (the song referenced by status->song -+ * and status->songid*/ -+ void mpd_sendCurrentSongCommand(mpd_Connection * connection); -+ -+/* songNum of -1, means to display the whole list */ -+ void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum); -+ -+/* songId of -1, means to display the whole list */ -+ void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int songId); -+ -+/* use this to get the changes in the playlist since version _playlist_ */ -+ void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist); -+ -+/** -+ * @param connection: A valid and connected mpd_Connection. -+ * @param playlist: The playlist version you want the diff with. -+ * A more bandwidth efficient version of the mpd_sendPlChangesCommand. -+ * It only returns the pos+id of the changes song. -+ */ -+ void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist); -+ -+/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is -+ * returned) */ -+ void mpd_sendListallCommand(mpd_Connection * connection, const char *dir); -+ -+/* same as sendListallCommand, but also metadata is returned */ -+ void mpd_sendListallInfoCommand(mpd_Connection * connection, const char *dir); -+ -+/* non-recursive version of ListallInfo */ -+ void mpd_sendLsInfoCommand(mpd_Connection * connection, const char *dir); -+ -+#define MPD_TABLE_ARTIST MPD_TAG_ITEM_ARTIST -+#define MPD_TABLE_ALBUM MPD_TAG_ITEM_ALBUM -+#define MPD_TABLE_TITLE MPD_TAG_ITEM_TITLE -+#define MPD_TABLE_FILENAME MPD_TAG_ITEM_FILENAME -+ -+ void mpd_sendSearchCommand(mpd_Connection * connection, int table, const char *str); -+ -+ void mpd_sendFindCommand(mpd_Connection * connection, int table, const char *str); -+ -+/* LIST TAG COMMANDS */ -+ -+/* use this function fetch next artist entry, be sure to free the returned -+ * string. NULL means there are no more. Best used with sendListArtists -+ */ -+ char *mpd_getNextArtist(mpd_Connection * connection); -+ -+ char *mpd_getNextAlbum(mpd_Connection * connection); -+ -+ char *mpd_getNextTag(mpd_Connection * connection, int type); -+ -+/* list artist or albums by artist, arg1 should be set to the artist if -+ * listing albums by a artist, otherwise NULL for listing all artists or albums -+ */ -+ void mpd_sendListCommand(mpd_Connection * connection, int table, const char *arg1); -+ -+/* SIMPLE COMMANDS */ -+ -+ void mpd_sendAddCommand(mpd_Connection * connection, const char *file); -+ -+ int mpd_sendAddIdCommand(mpd_Connection * connection, const char *file); -+ -+ void mpd_sendDeleteCommand(mpd_Connection * connection, int songNum); -+ -+ void mpd_sendDeleteIdCommand(mpd_Connection * connection, int songNum); -+ -+ void mpd_sendSaveCommand(mpd_Connection * connection, const char *name); -+ -+ void mpd_sendLoadCommand(mpd_Connection * connection, const char *name); -+ -+ void mpd_sendRmCommand(mpd_Connection * connection, const char *name); -+ -+ void mpd_sendRenameCommand(mpd_Connection * connection, const char *from, const char *to); -+ -+ void mpd_sendShuffleCommand(mpd_Connection * connection); -+ -+ void mpd_sendClearCommand(mpd_Connection * connection); -+ -+/* use this to start playing at the beginning, useful when in random mode */ -+#define MPD_PLAY_AT_BEGINNING -1 -+ -+ void mpd_sendPlayCommand(mpd_Connection * connection, int songNum); -+ -+ void mpd_sendPlayIdCommand(mpd_Connection * connection, int songNum); -+ -+ void mpd_sendStopCommand(mpd_Connection * connection); -+ -+ void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode); -+ -+ void mpd_sendNextCommand(mpd_Connection * connection); -+ -+ void mpd_sendPrevCommand(mpd_Connection * connection); -+ -+ void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to); -+ -+ void mpd_sendMoveIdCommand(mpd_Connection * connection, int from, int to); -+ -+ void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2); -+ -+ void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1, int song2); -+ -+ void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time); -+ -+ void mpd_sendSeekIdCommand(mpd_Connection * connection, int song, int time); -+ -+ void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode); -+ -+ void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode); -+ -+ void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange); -+ -+/* WARNING: don't use volume command, its depreacted */ -+ void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange); -+ -+ void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds); -+ -+ void mpd_sendUpdateCommand(mpd_Connection * connection, char *path); -+ -+/* returns the update job id, call this after a update command*/ -+ int mpd_getUpdateId(mpd_Connection * connection); -+ -+ void mpd_sendPasswordCommand(mpd_Connection * connection, const char *pass); -+ -+/* after executing a command, when your done with it to get its status -+ * (you want to check connection->error for an error) -+ */ -+ void mpd_finishCommand(mpd_Connection * connection); -+ -+/* command list stuff, use this to do things like add files very quickly */ -+ void mpd_sendCommandListBegin(mpd_Connection * connection); -+ -+ void mpd_sendCommandListOkBegin(mpd_Connection * connection); -+ -+ void mpd_sendCommandListEnd(mpd_Connection * connection); -+ -+/* advance to the next listOk -+ * returns 0 if advanced to the next list_OK, -+ * returns -1 if it advanced to an OK or ACK */ -+ int mpd_nextListOkCommand(mpd_Connection * connection); -+ -+ typedef struct _mpd_OutputEntity { -+ int id; -+ char *name; -+ int enabled; -+ } mpd_OutputEntity; -+ -+ void mpd_sendOutputsCommand(mpd_Connection * connection); -+ -+ mpd_OutputEntity *mpd_getNextOutput(mpd_Connection * connection); -+ -+ void mpd_sendEnableOutputCommand(mpd_Connection * connection, int outputId); -+ -+ void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId); -+ -+ void mpd_freeOutputElement(mpd_OutputEntity * output); -+ -+/** -+ * @param connection a #mpd_Connection -+ * -+ * Queries mpd for the allowed commands -+ */ -+ void mpd_sendCommandsCommand(mpd_Connection * connection); -+ -+/** -+ * @param connection a #mpd_Connection -+ * -+ * Queries mpd for the not allowed commands -+ */ -+ void mpd_sendNotCommandsCommand(mpd_Connection * connection); -+ -+/** -+ * @param connection a #mpd_Connection -+ * -+ * returns the next supported command. -+ * -+ * @returns a string, needs to be free'ed -+ */ -+ char *mpd_getNextCommand(mpd_Connection * connection); -+ -+ void mpd_sendUrlHandlersCommand(mpd_Connection * connection); -+ -+ char *mpd_getNextHandler(mpd_Connection * connection); -+ -+ void mpd_sendTagTypesCommand(mpd_Connection * connection); -+ -+ char *mpd_getNextTagType(mpd_Connection * connection); -+ -+/** -+ * @param connection a MpdConnection -+ * @param path the path to the playlist. -+ * -+ * List the content, with full metadata, of a stored playlist. -+ * -+ */ -+ void mpd_sendListPlaylistInfoCommand(mpd_Connection * connection, char *path); -+ -+/** -+ * @param connection a MpdConnection -+ * @param path the path to the playlist. -+ * -+ * List the content of a stored playlist. -+ * -+ */ -+ void mpd_sendListPlaylistCommand(mpd_Connection * connection, char *path); -+ -+/** -+ * @param connection a #mpd_Connection -+ * @param exact if to match exact -+ * -+ * starts a search, use mpd_addConstraintSearch to add -+ * a constraint to the search, and mpd_commitSearch to do the actual search -+ */ -+ void mpd_startSearch(mpd_Connection * connection, int exact); -+ -+/** -+ * @param connection a #mpd_Connection -+ * @param type -+ * @param name -+ */ -+ void mpd_addConstraintSearch(mpd_Connection * connection, int type, const char *name); -+ -+/** -+ * @param connection a #mpd_Connection -+ */ -+ void mpd_commitSearch(mpd_Connection * connection); -+ -+/** -+ * @param connection a #mpd_Connection -+ * @param type The type to search for -+ * -+ * starts a search for fields... f.e. get a list of artists would be: -+ * @code -+ * mpd_startFieldSearch(connection, MPD_TAG_ITEM_ARTIST); -+ * mpd_commitSearch(connection); -+ * @endcode -+ * -+ * or get a list of artist in genre "jazz" would be: -+ * @code -+ * mpd_startFieldSearch(connection, MPD_TAG_ITEM_ARTIST); -+ * mpd_addConstraintSearch(connection, MPD_TAG_ITEM_GENRE, "jazz") -+ * mpd_commitSearch(connection); -+ * @endcode -+ * -+ * mpd_startSearch will return a list of songs (and you need mpd_getNextInfoEntity) -+ * this one will return a list of only one field (the one specified with type) and you need -+ * mpd_getNextTag to get the results -+ */ -+ void mpd_startFieldSearch(mpd_Connection * connection, int type); -+ -+ void mpd_startPlaylistSearch(mpd_Connection * connection, int exact); -+ -+ void mpd_startStatsSearch(mpd_Connection * connection); -+ -+ void mpd_sendPlaylistClearCommand(mpd_Connection * connection, char *path); -+ -+ void mpd_sendPlaylistAddCommand(mpd_Connection * connection, char *playlist, char *path); -+ -+ void mpd_sendPlaylistMoveCommand(mpd_Connection * connection, char *playlist, int from, int to); -+ -+ void mpd_sendPlaylistDeleteCommand(mpd_Connection * connection, char *playlist, int pos); -+#ifdef __cplusplus -+} -+#endif -+#endif diff --git a/utils/lcd4linux/patches/160-uinput_defs.patch b/utils/lcd4linux/patches/160-uinput_defs.patch deleted file mode 100644 index 44b24b3c8..000000000 --- a/utils/lcd4linux/patches/160-uinput_defs.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/drv_G15.c -+++ b/drv_G15.c -@@ -42,6 +42,7 @@ - - #include - #include -+#include - #include - #include - -@@ -269,8 +270,13 @@ void drv_G15_initKeyHandling(char *devic - } - memset(&device, 0, sizeof(device)); - strncpy(device.name, "G15 Keys", UINPUT_MAX_NAME_SIZE); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - device.id.bustype = BUS_USB; - device.id.version = 4; -+#else -+ device.idbus = BUS_USB; -+ device.idversion = 4; -+#endif - - ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY); - diff --git a/utils/lcd4linux/patches/170-add-generic-spidev-driver.patch b/utils/lcd4linux/patches/170-add-generic-spidev-driver.patch deleted file mode 100644 index 9dcf1cb03..000000000 --- a/utils/lcd4linux/patches/170-add-generic-spidev-driver.patch +++ /dev/null @@ -1,195 +0,0 @@ ---- a/Makefile.am -+++ b/Makefile.am -@@ -71,6 +71,8 @@ drv_generic_i2c.c \ - drv_generic_i2c.h \ - drv_generic_keypad.c \ - drv_generic_keypad.h \ -+drv_generic_spidev.c \ -+drv_generic_spidev.h \ - drv_ASTUSB.c \ - drv_BeckmannEgle.c \ - drv_BWCT.c \ ---- /dev/null -+++ b/drv_generic_spidev.c -@@ -0,0 +1,89 @@ -+/* $Id$ -+ * $URL$ -+ * -+ * generic driver helper for displays connected via SPI bus -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This file is part of LCD4Linux. -+ * -+ * LCD4Linux 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. -+ * -+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "debug.h" -+#include "qprintf.h" -+#include "cfg.h" -+#include "drv_generic_spidev.h" -+ -+static char *generic_spidev_section = ""; -+static char *generic_spidev_driver = ""; -+static int generic_spidev_fd; -+ -+int drv_generic_spidev_open(const char *section, const char *driver) -+{ -+ char *spidev; -+ -+ udelay_init(); -+ -+ generic_spidev_section = (char *) section; -+ generic_spidev_driver = (char *) driver; -+ -+ spidev = cfg_get(generic_spidev_section, "Port", NULL); -+ -+ info("%s: initializing SPI device %s", generic_spidev_driver, spidev); -+ generic_spidev_fd = open(spidev, O_WRONLY); -+ if (generic_spidev_fd < 0) { -+ error("%s: unable to open SPI device %s!\n", generic_spidev_driver, spidev); -+ goto exit_error; -+ } -+ -+ return 0; -+ -+ exit_error: -+ free(spidev); -+ return -1; -+} -+ -+int drv_generic_spidev_close(void) -+{ -+ close(generic_spidev_fd); -+ return 0; -+} -+ -+int drv_generic_spidev_transfer(const int count, struct spi_ioc_transfer *tr) -+{ -+ int ret; -+ -+ ret = ioctl(generic_spidev_fd, SPI_IOC_MESSAGE(count), tr); -+ if (ret < count) { -+ error("%s: can't send SPI message! (%s)\n", -+ generic_spidev_driver, strerror(errno)); -+ return -1; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drv_generic_spidev.h -@@ -0,0 +1,54 @@ -+/* $Id$ -+ * $URL$ -+ * -+ * generic driver helper for displays connected via SPI bus -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2012 The LCD4Linux Team -+ * -+ * This file is part of LCD4Linux. -+ * -+ * LCD4Linux 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. -+ * -+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+/* -+ * -+ * exported fuctions: -+ * -+ * int drv_generic_spidev_open (const char *section, const char *driver) -+ * reads 'Port' entry from config and opens -+ * the SPI device -+ * returns 0 if ok, -1 on failure -+ * -+ * int drv_generic_spidev_close (void) -+ * closes SPI device -+ * returns 0 if ok, -1 on failure -+ * -+ * void drv_generic_spidev_transfer (int count, struct spi_ioc_transfer *tr) -+ * transfer data to/from the SPI device -+ * -+ */ -+ -+#ifndef _DRV_GENERIC_SPIDEV_H_ -+#define _DRV_GENERIC_SPIDEV_H_ -+ -+#include -+ -+int drv_generic_spidev_open(const char *section, const char *driver); -+int drv_generic_spidev_close(void); -+int drv_generic_spidev_transfer(const int count, struct spi_ioc_transfer *tr); -+ -+#endif /* _DRV_GENERIC_SPIDEV_H_ */ ---- a/drivers.m4 -+++ b/drivers.m4 -@@ -301,6 +301,7 @@ PARPORT="no" - SERIAL="no" - I2C="no" - KEYPAD="no" -+SPIDEV="no" - - # generic libraries - LIBUSB="no" -@@ -940,6 +941,12 @@ if test "$LIBJPEG" = "yes"; then - DRVLIBS="$DRVLIBS -ljpeg" - fi - -+# generic spidev driver -+if test "$SPIDEV" = "yes"; then -+ DRIVERS="$DRIVERS drv_generic_spidev.o" -+ AC_DEFINE(WITH_SPIDEV, 1, [SPIDEV driver]) -+fi -+ - # libusb - if test "$LIBUSB" = "yes"; then - DRVLIBS="$DRVLIBS -lusb" ---- a/configure.in -+++ b/configure.in -@@ -118,6 +118,9 @@ AC_ARG_WITH(outb, - - AC_CHECK_HEADERS([asm/io.h] [linux/parport.h linux/ppdev.h], [has_parport="true"], [has_parport="false"]) - -+# check for spidev -+AC_CHECK_HEADERS([linux/spi/spidev.h], [has_spidev="true"], [has_spidev="false"]) -+ - # drivers - sinclude(drivers.m4) - diff --git a/utils/lcd4linux/patches/171-allow-to-specify-drv_generic_graphic_real_clear.patch b/utils/lcd4linux/patches/171-allow-to-specify-drv_generic_graphic_real_clear.patch deleted file mode 100644 index 5a2664307..000000000 --- a/utils/lcd4linux/patches/171-allow-to-specify-drv_generic_graphic_real_clear.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/drv_generic_graphic.c -+++ b/drv_generic_graphic.c -@@ -24,7 +24,7 @@ - * - */ - --/* -+/* - * - * exported functions: - * -@@ -98,6 +98,9 @@ static int INVERTED = 0; - /* must be implemented by the real driver */ - void (*drv_generic_graphic_real_blit) () = NULL; - -+/* can be implemented by the real driver */ -+void (*drv_generic_graphic_real_clear) () = NULL; -+ - - /****************************************/ - /*** generic Framebuffer stuff ***/ -@@ -691,7 +694,10 @@ int drv_generic_graphic_clear(void) - for (i = 0; i < LCOLS * LROWS; i++) - drv_generic_graphic_FB[l][i] = NO_COL; - -- drv_generic_graphic_blit(0, 0, LROWS, LCOLS); -+ if (drv_generic_graphic_real_clear) -+ drv_generic_graphic_real_clear(NO_COL); -+ else -+ drv_generic_graphic_blit(0, 0, LROWS, LCOLS); - - return 0; - } ---- a/drv_generic_graphic.h -+++ b/drv_generic_graphic.h -@@ -40,6 +40,9 @@ extern RGBA NO_COL; /* no color (comple - /* these functions must be implemented by the real driver */ - extern void (*drv_generic_graphic_real_blit) (const int row, const int col, const int height, const int width); - -+/* these functions can be implemented by the real driver */ -+void (*drv_generic_graphic_real_clear) (const RGBA rgba); -+ - /* helper function to get pixel color or gray value */ - extern RGBA drv_generic_graphic_rgb(const int row, const int col); - extern unsigned char drv_generic_graphic_gray(const int row, const int col); diff --git a/utils/lcd4linux/patches/172-add-TEW673GRU-driver.patch b/utils/lcd4linux/patches/172-add-TEW673GRU-driver.patch deleted file mode 100644 index 29a4bf3ec..000000000 --- a/utils/lcd4linux/patches/172-add-TEW673GRU-driver.patch +++ /dev/null @@ -1,552 +0,0 @@ ---- a/drivers.m4 -+++ b/drivers.m4 -@@ -39,7 +39,7 @@ AC_ARG_WITH( - [ Newhaven, Noritake, NULL, Pertelian, PHAnderson,] - [ PICGraphic, picoLCD, picoLCDGraphic, PNG, PPM, RouterBoard,] - [ Sample, SamsungSPF, serdisplib, ShuttleVFD, SimpleLCD, st2205, T6963,] -- [ TeakLCM, Trefon, ULA200, USBHUB, USBLCD, VNC, WincorNixdorf, X11], -+ [ TeakLCM, TEW673GRU, Trefon, ULA200, USBHUB, USBLCD, VNC, WincorNixdorf, X11], - drivers=$withval, - drivers=all - ) -@@ -107,6 +107,7 @@ for driver in $drivers; do - SHUTTLEVFD="yes" - SIMPLELCD="yes" - T6963="yes" -+ TEW673GRU="yes" - TeakLCM="yes" - Trefon="yes" - ULA200="yes" -@@ -260,6 +261,9 @@ for driver in $drivers; do - TeakLCM) - TeakLCM=$val - ;; -+ TEW673GRU) -+ TEW673GRU=$val -+ ;; - Trefon) - Trefon=$val - ;; -@@ -801,6 +805,18 @@ if test "$TeakLCM" = "yes"; then - AC_DEFINE(WITH_TEAK_LCM,1,[TeakLCM driver]) - fi - -+if test "$TEW673GRU" = "yes"; then -+ if test "$has_spidev" = "true"; then -+ GRAPHIC="yes" -+ TEXT="yes" -+ SPIDEV="yes" -+ DRIVERS="$DRIVERS drv_TEW673GRU.o" -+ AC_DEFINE(WITH_TEW673GRU,1,[TEW673GRU driver]) -+ else -+ AC_MSG_WARN(linux/spi/spidev.h not found: TEW673GRU driver disabled) -+ fi -+fi -+ - if test "$Trefon" = "yes"; then - if test "$has_usb" = "true"; then - TEXT="yes" ---- a/drv.c -+++ b/drv.c -@@ -92,6 +92,7 @@ extern DRIVER drv_serdisplib; - extern DRIVER drv_ShuttleVFD; - extern DRIVER drv_SimpleLCD; - extern DRIVER drv_T6963; -+extern DRIVER drv_TEW673GRU; - extern DRIVER drv_TeakLCM; - extern DRIVER drv_Trefon; - extern DRIVER drv_ula200; -@@ -248,6 +249,9 @@ DRIVER *Driver[] = { - #ifdef WITH_TEAK_LCM - &drv_TeakLCM, - #endif -+#ifdef WITH_TEW673GRU -+ &drv_TEW673GRU, -+#endif - #ifdef WITH_TREFON - &drv_Trefon, - #endif ---- a/Makefile.am -+++ b/Makefile.am -@@ -119,6 +119,7 @@ drv_ShuttleVFD.c \ - drv_SimpleLCD.c \ - drv_T6963.c \ - drv_TeakLCM.c \ -+drv_TEW673GRU.c \ - drv_Trefon.c \ - drv_ula200.c \ - drv_USBHUB.c \ ---- /dev/null -+++ b/drv_TEW673GRU.c -@@ -0,0 +1,457 @@ -+/* $Id$ -+ * $URL$ -+ * -+ * TRENDnet TEW673GRU LCD4linux driver -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * based on the Sample driver which is: -+ * Copyright (C) 2005 Michael Reinelt -+ * Copyright (C) 2005, 2006, 2007 The LCD4Linux Team -+ * -+ * This file is part of LCD4Linux. -+ * -+ * LCD4Linux 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. -+ * -+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+/* -+ * exported fuctions: -+ * -+ * struct DRIVER drv_TEW673GRU -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "debug.h" -+#include "cfg.h" -+#include "qprintf.h" -+#include "udelay.h" -+#include "plugin.h" -+#include "widget.h" -+#include "widget_text.h" -+#include "widget_icon.h" -+#include "widget_bar.h" -+#include "drv.h" -+ -+#include "drv_generic_text.h" -+#include "drv_generic_graphic.h" -+#include "drv_generic_spidev.h" -+ -+#ifdef WITH_DMALLOC -+#include -+#endif -+ -+#define TEW673GRU_NUM_COLS 220 -+#define TEW673GRU_NUM_ROWS 176 -+#define TEW673GRU_BPP 2 /* bytes per pixel */ -+ -+#define TEW673GRU_CMD_SIZE 9 -+#define TEW673GRU_NUM_ROW_BYTES (TEW673GRU_NUM_COLS * TEW673GRU_BPP) -+ -+enum { -+ CMD_SHOW_STRING = 49, -+ CMD_SHOW_IMAGE_DIR = 52, -+ CMD_SCREEN_COLOR = 54, -+}; -+ -+static char Name[] = "TEW673GRU"; -+ -+static char *drv_TEW673GRU_FB; -+static long FB_SIZE; -+static int MODE; -+ -+static unsigned int RGBAto16(RGBA rgb) -+{ -+ return (((rgb.R >> 3) << 11) | ((rgb.G >> 2) << 5) | (rgb.B >> 3)); -+} -+ -+static unsigned char color_msb(unsigned int color) -+{ -+ return color >> 8; -+} -+ -+static unsigned char color_lsb(unsigned int color) -+{ -+ return color & 0xff; -+} -+ -+static void drv_TEW673GRU_hw_clear(const unsigned int color) -+{ -+ unsigned char cmd[TEW673GRU_CMD_SIZE]; -+ struct spi_ioc_transfer tr[1]; -+ -+ memset(tr, '\0', sizeof(tr)); -+ memset(cmd, '\0', sizeof(cmd)); -+ -+ cmd[0] = CMD_SCREEN_COLOR; -+ cmd[7] = color_msb(color); -+ cmd[8] = color_lsb(color); -+ -+ tr[0].tx_buf = (unsigned long) cmd; -+ tr[0].len = sizeof(cmd); -+ -+ drv_generic_spidev_transfer(1, tr); -+} -+ -+static void drv_TEW673GRU_hw_send_row(const int row, const int col, const char *data, const int width) -+{ -+ unsigned char cmd[TEW673GRU_CMD_SIZE]; -+ struct spi_ioc_transfer tr[2]; -+ int datasize; -+ -+ memset(tr, '\0', sizeof(tr)); -+ memset(cmd, '\0', sizeof(cmd)); -+ -+ datasize = width * TEW673GRU_BPP; -+ -+ cmd[0] = CMD_SHOW_IMAGE_DIR; -+ cmd[1] = col; -+ cmd[2] = col + width; -+ cmd[3] = row; -+ cmd[4] = row; -+ cmd[5] = datasize >> 8; -+ cmd[6] = datasize & 0xff; -+ -+ tr[0].tx_buf = (unsigned long) cmd; -+ tr[0].len = sizeof(cmd); -+ tr[1].tx_buf = (unsigned long) data; -+ tr[1].len = datasize; -+ -+ drv_generic_spidev_transfer(2, tr); -+} -+ -+static void drv_TEW673GRU_hw_write_string(const int row, const int col, const char *data, const int datasize) -+{ -+ unsigned char cmd[TEW673GRU_CMD_SIZE]; -+ struct spi_ioc_transfer tr[2]; -+ unsigned char len; -+ -+ memset(tr, '\0', sizeof(tr)); -+ memset(cmd, '\0', sizeof(cmd)); -+ -+ len = datasize & 0xff; -+ cmd[0] = CMD_SHOW_STRING; -+ cmd[1] = col; -+ cmd[2] = col + (XRES * len); -+ cmd[3] = row; -+ cmd[4] = row + YRES; -+ cmd[7] = 0; -+ cmd[8] = len; -+ -+ tr[0].tx_buf = (unsigned long) cmd; -+ tr[0].len = sizeof(cmd); -+ tr[1].tx_buf = (unsigned long) data; -+ tr[1].len = datasize; -+ -+ drv_generic_spidev_transfer(2, tr); -+} -+ -+static void drv_TEW673GRU_FB_set_pixel(const int col, const unsigned int color) -+{ -+ int pos; -+ -+ pos = col * TEW673GRU_BPP; -+ drv_TEW673GRU_FB[pos] = color_msb(color); -+ drv_TEW673GRU_FB[pos + 1] = color_lsb(color); -+} -+ -+static void drv_TEW673GRU_blit(const int row, const int col, const int height, const int width) -+{ -+ int r, c; -+ -+ debug("%s: update area r:%d c:%d w:%d h:%d", Name, row, col, height, width); -+ -+ for (r = row; r < row + height; r++) { -+ for (c = col; c < col + width; c++) { -+ unsigned int color; -+ RGBA rgb; -+ -+ rgb = drv_generic_graphic_rgb(r, c); -+ color = RGBAto16(rgb); -+ drv_TEW673GRU_FB_set_pixel(c, color); -+ } -+ -+ if (width) { -+ char *data; -+ -+ data = &drv_TEW673GRU_FB[col * TEW673GRU_BPP]; -+ drv_TEW673GRU_hw_send_row(r, col, data, width); -+ udelay(100 + width * 50); -+ } -+ } -+} -+ -+static void drv_TEW673GRU_clear(RGBA rgba) -+{ -+ unsigned int color; -+ -+ color = RGBAto16(rgba); -+ drv_TEW673GRU_hw_clear(color); -+} -+ -+static void drv_TEW673GRU_write(const int row, const int col, const char *data, const int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) { -+ drv_TEW673GRU_hw_write_string(row * YRES, (col + i) * XRES, " ", 1); -+ udelay(10000); -+ drv_TEW673GRU_hw_write_string(row * YRES, 2 + (col + i) * XRES, " ", 1); -+ udelay(10000); -+ drv_TEW673GRU_hw_write_string(row * YRES, (col + i) * XRES, &data[i], 1); -+ udelay(10000); -+ } -+} -+ -+static int drv_TEW673GRU_open(const char *section) -+{ -+ int err; -+ -+ err = drv_generic_spidev_open(section, Name); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+ -+static int drv_TEW673GRU_close(void) -+{ -+ drv_generic_spidev_close(); -+ return 0; -+} -+ -+static void drv_TEW673GRU_clear_screen(void) -+{ -+ if (MODE) { -+ drv_generic_graphic_clear(); -+ } else { -+ memset(drv_TEW673GRU_FB, ' ', FB_SIZE); -+ drv_TEW673GRU_hw_clear(0x0000); -+ } -+} -+ -+static int drv_TEW673GRU_init_font(const char *section) -+{ -+ char *font; -+ int ret = -1; -+ -+ font = cfg_get(section, "Font", "6x8"); -+ if (font == NULL) { -+ error("%s: no '%s.Font' entry from %s", Name, section, cfg_source()); -+ goto out; -+ } -+ -+ if (*font == '\0') { -+ error("%s: invalid '%s.Font' entry in %s", Name, section, cfg_source()); -+ goto out_free; -+ } -+ -+ XRES = -1; -+ YRES = -1; -+ if (sscanf(font, "%dx%d", &XRES, &YRES) != 2 || -+ XRES < 1 || -+ YRES < 1) { -+ error("%s: bad Font '%s' from %s", Name, font, cfg_source()); -+ goto out_free; -+ } -+ -+ if (XRES != 6 && YRES != 8) { -+ error("%s: bad Font '%s' from %s (only 6x8 at the moment)", -+ Name, font, cfg_source()); -+ goto out_free; -+ } -+ -+ error("%s: font '%s' selected", Name, font); -+ -+ ret = 0; -+ -+out_free: -+ free(font); -+out: -+ return ret; -+} -+ -+static int drv_TEW673GRU_start(const char *section) -+{ -+ int ret; -+ -+ DCOLS = TEW673GRU_NUM_COLS; -+ DROWS = TEW673GRU_NUM_ROWS; -+ -+ if (MODE) { -+ ret = drv_TEW673GRU_init_font(section); -+ if (ret) -+ goto err; -+ -+ FB_SIZE = DCOLS * TEW673GRU_BPP; -+ } else { -+ XRES = 10; -+ YRES = 16; -+ DCOLS = DCOLS / XRES; -+ DROWS = DROWS / YRES; -+ -+ FB_SIZE = DCOLS * DROWS; -+ } -+ -+ if (FB_SIZE) { -+ drv_TEW673GRU_FB = malloc(FB_SIZE); -+ if (drv_TEW673GRU_FB == NULL) { -+ error("%s: framebuffer could not be allocated", Name); -+ goto err; -+ } -+ } -+ -+ ret = drv_TEW673GRU_open(section); -+ if (ret < 0) -+ goto err_free; -+ -+ if (MODE == 0) -+ drv_TEW673GRU_clear_screen(); -+ -+ return 0; -+ -+ err_free: -+ if (drv_TEW673GRU_FB) -+ free(drv_TEW673GRU_FB); -+ err: -+ return -1; -+} -+ -+static int drv_TEW673GRU_greet(const char *msg1, const char *msg2) -+{ -+ if (MODE) -+ return drv_generic_graphic_greet(msg1, msg2); -+ -+ return drv_generic_text_greet(msg1, msg2); -+} -+ -+ -+/****************************************/ -+/*** widget callbacks ***/ -+/****************************************/ -+ -+ -+/* using drv_generic_text_draw(W) */ -+/* using drv_generic_text_icon_draw(W) */ -+/* using drv_generic_text_bar_draw(W) */ -+/* using drv_generic_gpio_draw(W) */ -+ -+ -+/****************************************/ -+/*** exported functions ***/ -+/****************************************/ -+ -+int drv_TEW673GRU_list(void) -+{ -+ printf("TEW673GRU driver"); -+ return 0; -+} -+ -+int drv_TEW673GRU_init(const char *section, const int quiet) -+{ -+ WIDGET_CLASS wc; -+ int ret; -+ -+ cfg_number(section, "Mode", 0, 0, 1, &MODE); -+ -+ if (MODE) { -+ drv_generic_graphic_real_blit = drv_TEW673GRU_blit; -+ drv_generic_graphic_real_clear = drv_TEW673GRU_clear; -+ } else { -+ drv_generic_text_real_write = drv_TEW673GRU_write; -+ } -+ -+ ret = drv_TEW673GRU_start(section); -+ if (ret) -+ return ret; -+ -+ if (MODE) { -+ ret = drv_generic_graphic_init(section, Name); -+ if (ret) -+ return ret; -+ } else { -+ ret = drv_generic_text_init(section, Name); -+ if (ret) -+ return ret; -+ -+ ret = drv_generic_text_icon_init(); -+ if (ret != 0) -+ return ret; -+ -+ ret = drv_generic_text_bar_init(1); -+ if (ret != 0) -+ return ret; -+ -+ drv_generic_text_bar_add_segment(0, 0, 255, ' '); -+ drv_generic_text_bar_add_segment(255, 255, 255, '#'); -+ -+ wc = Widget_Text; -+ wc.draw = drv_generic_text_draw; -+ widget_register(&wc); -+ -+ wc = Widget_Icon; -+ wc.draw = drv_generic_text_icon_draw; -+ widget_register(&wc); -+ -+ wc = Widget_Bar; -+ wc.draw = drv_generic_text_bar_draw; -+ widget_register(&wc); -+ } -+ -+ if (!quiet) { -+ char buffer[40]; -+ qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS); -+ drv_TEW673GRU_greet(buffer, "www.openwrt.org"); -+ sleep(3); -+ drv_TEW673GRU_clear_screen(); -+ } -+ -+ return 0; -+} -+ -+int drv_TEW673GRU_quit(const int quiet) -+{ -+ -+ info("%s: shutting down.", Name); -+ -+ drv_TEW673GRU_clear_screen(); -+ -+ if (!quiet) -+ drv_TEW673GRU_greet("goodbye!", NULL); -+ -+ if (MODE) -+ drv_generic_graphic_quit(); -+ else -+ drv_generic_text_quit(); -+ -+ debug("closing connection"); -+ drv_TEW673GRU_close(); -+ -+ return (0); -+} -+ -+DRIVER drv_TEW673GRU = { -+ .name = Name, -+ .list = drv_TEW673GRU_list, -+ .init = drv_TEW673GRU_init, -+ .quit = drv_TEW673GRU_quit, -+}; ---- a/lcd4linux.conf.sample -+++ b/lcd4linux.conf.sample -@@ -571,6 +571,11 @@ Display FutabaVFD { - } - } - -+Display TEW673GRU { -+ Driver 'TEW673GRU' -+ Font '6x8' -+ Port '/dev/spidev1.0' -+} - - #Plugin KVV { - # StationID '12_701'