This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch main
in repository eradio.

View the commit online.

commit 14f694ba9960267888301259d62d299ca518d530
Author: politebot <[email protected]>
AuthorDate: Fri Oct 10 12:41:19 2025 -0500

    Radio player
---
 .gitignore                                         |  14 +-
 Makefile                                           | 106 ++++---
 Makefile.am                                        |   6 +-
 autogen.sh                                         |   1 +
 configure.ac                                       |  18 +-
 data/Makefile.am                                   |   5 +
 ...fl-hello.desktop => efl-internet-radio.desktop} |   0
 data/{efl-hello.svg => efl-internet-radio.svg}     |   0
 src/Makefile.am                                    |   8 +-
 src/main.c                                         | 334 ++++++++++++++++++---
 10 files changed, 386 insertions(+), 106 deletions(-)

diff --git a/.gitignore b/.gitignore
index f4b1aa8..b49cb8b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 # Build artifacts
 *.o
-efl_hello
+efl-internet-radio
+src/efl-internet-radio
 
 # Common build dirs
 build/
@@ -12,17 +13,24 @@ bin/
 Makefile
 Makefile.in
 aclocal.m4
-autom4te.cache
+autom4te.cache/
 compile
 config.h
 config.h.in
+config.h.in~
 config.log
 config.status
 configure
+configure~
 depcomp
 install-sh
+ltmain.sh
 missing
 stamp-h1
 src/Makefile
 src/Makefile.in
-src/.deps
\ No newline at end of file
+src/.deps/
+data/Makefile
+data/Makefile.in
+m4/
+build-aux/
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 77c1105..689055d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.18.1 from Makefile.am.
+# Makefile.in generated by automake 1.17 from Makefile.am.
 # Makefile.  Generated from Makefile.in by configure.
 
-# Copyright (C) 1994-2025 Free Software Foundation, Inc.
+# Copyright (C) 1994-2024 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -72,10 +72,10 @@ am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 am__rm_f = rm -f $(am__rm_f_notfound)
 am__rm_rf = rm -rf $(am__rm_f_notfound)
-pkgdatadir = $(datadir)/efl-boilerplate
-pkgincludedir = $(includedir)/efl-boilerplate
-pkglibdir = $(libdir)/efl-boilerplate
-pkglibexecdir = $(libexecdir)/efl-boilerplate
+pkgdatadir = $(datadir)/efl-internet-radio
+pkgincludedir = $(includedir)/efl-internet-radio
+pkglibdir = $(libdir)/efl-internet-radio
+pkglibexecdir = $(libexecdir)/efl-internet-radio
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
@@ -184,7 +184,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	README.md compile install-sh missing
+	README.md compile depcomp install-sh missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -231,13 +231,13 @@ am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
 distcleancheck_listfiles = \
   find . \( -type f -a \! \
             \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
-ACLOCAL = ${SHELL} '/Users/jamie/repos/efl-boilerplate/missing' aclocal-1.18
+ACLOCAL = ${SHELL} '/home/nights/repos/efl-hello/missing' aclocal-1.17
 AMTAR = $${TAR-tar}
 AM_DEFAULT_VERBOSITY = 1
-AUTOCONF = ${SHELL} '/Users/jamie/repos/efl-boilerplate/missing' autoconf
-AUTOHEADER = ${SHELL} '/Users/jamie/repos/efl-boilerplate/missing' autoheader
-AUTOMAKE = ${SHELL} '/Users/jamie/repos/efl-boilerplate/missing' automake-1.18
-AWK = awk
+AUTOCONF = ${SHELL} '/home/nights/repos/efl-hello/missing' autoconf
+AUTOHEADER = ${SHELL} '/home/nights/repos/efl-hello/missing' autoheader
+AUTOMAKE = ${SHELL} '/home/nights/repos/efl-hello/missing' automake-1.17
+AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
 CFLAGS = -g -O2
@@ -247,14 +247,15 @@ CTAGS = ctags
 CYGPATH_W = echo
 DEFS = -DHAVE_CONFIG_H
 DEPDIR = .deps
-ECHO_C = \c
-ECHO_N = 
+ECHO_C = 
+ECHO_N = -n
 ECHO_T = 
-ELEMENTARY_CFLAGS = -I/opt/homebrew/Cellar/efl/1.28.1/include/elementary-1 -I/opt/homebrew/Cellar/efl/1.28.1/include/ethumb-client-1 -I/opt/homebrew/Cellar/efl/1.28.1/include/emotion-1 -I/opt/homebrew/Cellar/efl/1.28.1/include/efreet-1 -I/opt/homebrew/Cellar/efl/1.28.1/include/ethumb-1 -I/opt/homebrew/Cellar/efl/1.28.1/include/edje-1 -I/opt/homebrew/Cellar/luajit/2.1.1748459687/include/luajit-2.1 -I/opt/homebrew/Cellar/efl/1.28.1/include/ecore-evas-1 -I/opt/homebrew/Cellar/efl/1.28.1/inc [...]
-ELEMENTARY_LIBS = -L/opt/homebrew/Cellar/efl/1.28.1/lib -lelementary -lethumb_client -lemotion -lethumb -ledje -L/opt/homebrew/Cellar/luajit/2.1.1748459687/lib -lluajit-5.1 -lecore_evas -lecore_imf -leio -lefreet -lecore_file -lecore_con -leldbus -lephysics -levas -lector -lecore_input -lecore -leet -lemile -lefl -leo -leina -lm -ldl
+EFL_CFLAGS = -I/usr/include/elementary-1 -I/usr/include/ethumb-client-1 -I/usr/include/emotion-1 -I/usr/include/efreet-1 -I/usr/include/ethumb-1 -I/usr/include/ecore-x-1 -I/usr/include/ecore-wl2-1 -I/usr/include/ecore-drm2-1 -I/usr/include/elput-1 -I/usr/include/edje-1 -I/usr/include/ephysics-1 -I/usr/include/bullet -I/usr/include/ecore-evas-1 -I/usr/include/ecore-input-evas-1 -I/usr/include/ecore-input-1 -I/usr/include/eeze-1 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/e [...]
+EFL_LIBS = -lelementary -lecore_evas -lecore_file -lecore_input -lecore_imf -lecore_con -leldbus -lethumb_client -lethumb -lemotion -lefreet -leio -leet -ledje -levas -lecore -lector -lemile -lephysics -lefl -leo -leina -pthread -lm -lrt -ldl -lluajit-5.1
+EFL_LIBS_NO_CON = -lelementary -lecore_evas -lecore_file -lecore_input -lecore_imf  -leldbus -lethumb_client -lethumb -lemotion -lefreet -leio -leet -ledje -levas -lecore -lector -lemile -lephysics -lefl -leo -leina -pthread -lm -lrt -ldl -lluajit-5.1
 ETAGS = etags
 EXEEXT = 
-INSTALL = /opt/homebrew/bin/ginstall -c
+INSTALL = /usr/bin/install -c
 INSTALL_DATA = ${INSTALL} -m 644
 INSTALL_PROGRAM = ${INSTALL}
 INSTALL_SCRIPT = ${INSTALL}
@@ -262,36 +263,38 @@ INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
 LDFLAGS = 
 LIBOBJS = 
 LIBS = 
+LIBXML_CFLAGS = -I/usr/include/libxml2 -DWITH_GZFILEOP
+LIBXML_LIBS = -lxml2
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} '/Users/jamie/repos/efl-boilerplate/missing' makeinfo
-MKDIR_P = /opt/homebrew/bin/gmkdir -p
+MAKEINFO = ${SHELL} '/home/nights/repos/efl-hello/missing' makeinfo
+MKDIR_P = /usr/bin/mkdir -p
 OBJEXT = o
-PACKAGE = efl-boilerplate
+PACKAGE = efl-internet-radio
 PACKAGE_BUGREPORT = [email protected]
-PACKAGE_NAME = efl-boilerplate
-PACKAGE_STRING = efl-boilerplate 1.0
-PACKAGE_TARNAME = efl-boilerplate
+PACKAGE_NAME = efl-internet-radio
+PACKAGE_STRING = efl-internet-radio 1.0
+PACKAGE_TARNAME = efl-internet-radio
 PACKAGE_URL = 
 PACKAGE_VERSION = 1.0
 PATH_SEPARATOR = :
-PKG_CONFIG = /opt/homebrew/bin/pkg-config
+PKG_CONFIG = /usr/bin/pkg-config
 PKG_CONFIG_LIBDIR = 
-PKG_CONFIG_PATH = 
+PKG_CONFIG_PATH = /usr/local/lib/pkgconfig:/home/nights/GNUstep/Library/Libraries/pkgconfig:/usr/GNUstep/Local/Library/Libraries/pkgconfig:/usr/GNUstep/System/Library/Libraries/pkgconfig
 SET_MAKE = 
 SHELL = /bin/sh
 STRIP = 
 VERSION = 1.0
-abs_builddir = /Users/jamie/repos/efl-boilerplate
-abs_srcdir = /Users/jamie/repos/efl-boilerplate
-abs_top_builddir = /Users/jamie/repos/efl-boilerplate
-abs_top_srcdir = /Users/jamie/repos/efl-boilerplate
+abs_builddir = /home/nights/repos/efl-hello
+abs_srcdir = /home/nights/repos/efl-hello
+abs_top_builddir = /home/nights/repos/efl-hello
+abs_top_srcdir = /home/nights/repos/efl-hello
 ac_ct_CC = gcc
 am__include = include
 am__leading_dot = .
 am__quote = 
 am__rm_f_notfound = 
-am__tar = tar --format=ustar -chf - "$$tardir"
-am__untar = tar -xf -
+am__tar = $${TAR-tar} chof - "$$tardir"
+am__untar = $${TAR-tar} xf -
 am__xargs_n = xargs -n
 bindir = ${exec_prefix}/bin
 build_alias = 
@@ -305,7 +308,7 @@ host_alias =
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = ${SHELL} /Users/jamie/repos/efl-boilerplate/install-sh
+install_sh = ${SHELL} /home/nights/repos/efl-hello/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
@@ -326,10 +329,10 @@ target_alias =
 top_build_prefix = 
 top_builddir = .
 top_srcdir = .
-SUBDIRS = src
+SUBDIRS = src data
 dist_pkgdata_DATA = \
-    data/efl-hello.desktop \
-    data/efl-hello.svg
+    data/efl-internet-radio.desktop \
+    data/efl-internet-radio.svg
 
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -510,7 +513,6 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
-
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -586,10 +588,6 @@ dist-bzip2: distdir
 	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
 	$(am__post_remove_distdir)
 
-dist-bzip3: distdir
-	tardir=$(distdir) && $(am__tar) | bzip3 -c >$(distdir).tar.bz3
-	$(am__post_remove_distdir)
-
 dist-lzip: distdir
 	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
 	$(am__post_remove_distdir)
@@ -634,8 +632,6 @@ distcheck: dist
 	  eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
 	*.tar.bz2*) \
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
-	*.tar.bz3*) \
-	  bzip3 -dc $(distdir).tar.bz3 | $(am__untar) ;;\
 	*.tar.lz*) \
 	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
 	*.tar.xz*) \
@@ -826,19 +822,19 @@ uninstall-am: uninstall-dist_pkgdataDATA
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
 	am--refresh check check-am clean clean-cscope clean-generic \
 	cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
-	dist-bzip3 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \
-	dist-zip dist-zstd distcheck distclean distclean-generic \
-	distclean-hdr distclean-tags distcleancheck distdir \
-	distuninstallcheck dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am \
-	install-dist_pkgdataDATA install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs installdirs-am \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-dist_pkgdataDATA
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	dist-zstd distcheck distclean distclean-generic distclean-hdr \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dist_pkgdataDATA \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-dist_pkgdataDATA
 
 .PRECIOUS: Makefile
 
diff --git a/Makefile.am b/Makefile.am
index 49db89e..75d2dce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = src
+SUBDIRS = src data
 
 dist_pkgdata_DATA = \
-    data/efl-hello.desktop \
-    data/efl-hello.svg
\ No newline at end of file
+    data/efl-internet-radio.desktop \
+    data/efl-internet-radio.svg
\ No newline at end of file
diff --git a/autogen.sh b/autogen.sh
new file mode 120000
index 0000000..b209282
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1 @@
+/usr/bin/autogen.sh
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
index 8e8440d..73a858e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,19 @@
-AC_INIT([efl-boilerplate], [1.0], [[email protected]])
+AC_INIT([efl-internet-radio], [1.0], [[email protected]])
 AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 AC_PROG_CC
 AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile src/Makefile])
-PKG_CHECK_MODULES([ELEMENTARY], [elementary])
+AC_CONFIG_FILES([Makefile src/Makefile data/Makefile])
+
+PKG_CHECK_MODULES([EFL], [
+    ecore-evas
+    eina
+    evas
+    elementary
+    edje
+])
+
+PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
+EFL_LIBS_NO_CON=$(echo $EFL_LIBS | sed 's/-lecore_con//g')
+AC_SUBST(EFL_LIBS_NO_CON)
+
 AC_OUTPUT
\ No newline at end of file
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..e8dad6a
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,5 @@
+desktopdir = $(datadir)/applications
+desktop_DATA = efl-internet-radio.desktop
+
+svgdir = $(datadir)/pixmaps
+svg_DATA = efl-internet-radio.svg
diff --git a/data/efl-hello.desktop b/data/efl-internet-radio.desktop
similarity index 100%
rename from data/efl-hello.desktop
rename to data/efl-internet-radio.desktop
diff --git a/data/efl-hello.svg b/data/efl-internet-radio.svg
similarity index 100%
rename from data/efl-hello.svg
rename to data/efl-internet-radio.svg
diff --git a/src/Makefile.am b/src/Makefile.am
index e18b9a1..f3bedff 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
-bin_PROGRAMS = efl_hello
+bin_PROGRAMS = efl-internet-radio
 
-efl_hello_SOURCES = main.c
+efl_internet_radio_SOURCES = main.c
 
-efl_hello_CFLAGS = $(ELEMENTARY_CFLAGS)
-efl_hello_LDADD = $(ELEMENTARY_LIBS)
\ No newline at end of file
+efl_internet_radio_CFLAGS = $(EFL_CFLAGS)
+efl_internet_radio_LDADD = $(EFL_LIBS) $(LIBXML_LIBS)
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index 237de05..b0a66d5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,48 +1,306 @@
-// Minimal EFL (Elementary) "Hello, World!" application
-//
-// This file serves as a clean, well-commented starting point for
-// EFL-based desktop apps. It demonstrates:
-// - Elementary initialization and shutdown
-// - Creating a standard window
-// - Adding background and a centered label
-// - Entering the main event loop
-//
-// Build & run:
-//   make
-//   make run
-
 #include <Elementary.h>
+#include <Emotion.h>
+#include <Ecore_Con.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+typedef struct _Station
+{
+   const char *name;
+   const char *url;
+   const char *favicon;
+} Station;
+
+typedef struct _AppData
+{
+   Evas_Object *win;
+   Evas_Object *list;
+   Evas_Object *emotion;
+   Evas_Object *search_entry;
+   Evas_Object *search_hoversel;
+   Eina_List *stations;
+} AppData;
+
+static void _win_del_cb(void *data, Evas_Object *obj, void *event_info);
+static void _list_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
+static void _play_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _stop_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _search_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_win_del_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   elm_exit();
+}
+
+static void
+_list_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   Elm_Object_Item *it = event_info;
+   Station *st = elm_object_item_data_get(it);
+
+   emotion_object_file_set(ad->emotion, st->url);
+   emotion_object_play_set(ad->emotion, EINA_TRUE);
+}
+
+
+
+static void
+_play_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   emotion_object_play_set(ad->emotion, EINA_TRUE);
+}
+
+static void
+_pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   emotion_object_play_set(ad->emotion, EINA_FALSE);
+}
+
+static Eina_Bool _url_progress_cb(void *data, int type, void *event_info);
+static Eina_Bool _url_complete_cb(void *data, int type, void *event_info);
+
+typedef struct _Download_Context
+{
+   AppData *ad;
+   xmlParserCtxtPtr ctxt;
+} Download_Context;
+
+static void
+_search_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   const char *search_term = elm_object_text_get(ad->search_entry);
+   const char *search_type = elm_object_text_get(ad->search_hoversel);
+   char url_str[1024];
+   Ecore_Con_Url *url;
+   Download_Context *d_ctx;
+
+   if (!search_term || !search_term[0]) return;
+
+   d_ctx = calloc(1, sizeof(Download_Context));
+   d_ctx->ad = ad;
+
+   snprintf(url_str, sizeof(url_str), "http://de2.api.radio-browser.info/xml/stations/search?%s=%s",
+            search_type, search_term);
+
+   url = ""
+   ecore_con_url_data_set(url, d_ctx);
+   ecore_con_url_get(url);
+}
+
+static Eina_Bool
+_url_progress_cb(void *data, int type, void *event_info)
+{
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_url_data_cb(void *data, int type, void *event_info)
+{
+    Ecore_Con_Event_Url_Data *url_data = event_info;
+    Download_Context *d_ctx = ecore_con_url_data_get(url_data->url_con);
+
+    if (!d_ctx->ctxt)
+      {
+         d_ctx->ctxt = xmlCreatePushParserCtxt(NULL, NULL,
+                                               (const char *)url_data->data, url_data->size,
+                                               "noname.xml");
+      }
+    else
+      xmlParseChunk(d_ctx->ctxt, (const char *)url_data->data, url_data->size, 0);
+
+    return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_url_complete_cb(void *data, int type, void *event_info)
+{
+    Ecore_Con_Event_Url_Complete *ev = event_info;
+    Download_Context *d_ctx = ecore_con_url_data_get(ev->url_con);
+    AppData *ad;
+    xmlDocPtr doc;
+    xmlXPathContextPtr xpathCtx;
+    xmlXPathObjectPtr xpathObj;
+
+    if (!d_ctx) return ECORE_CALLBACK_PASS_ON;
+
+    ad = d_ctx->ad;
+
+    if (!d_ctx->ctxt)
+      {
+         // In case of empty reply, the data callback is not called
+         free(d_ctx);
+         ecore_con_url_free(ev->url_con);
+         return ECORE_CALLBACK_PASS_ON;
+      }
+
+    xmlParseChunk(d_ctx->ctxt, "", 0, 1);
+    doc = d_ctx->ctxt->myDoc;
+    xmlFreeParserCtxt(d_ctx->ctxt);
+    free(d_ctx);
+
+    if (doc == NULL)
+    {
+        printf("Error: could not parse XML\n");
+        ecore_con_url_free(ev->url_con);
+        return ECORE_CALLBACK_PASS_ON;
+    }
+
+
+    xpathCtx = xmlXPathNewContext(doc);
+    if (xpathCtx == NULL)
+    {
+        printf("Error: could not create new XPath context\n");
+        xmlFreeDoc(doc);
+        ecore_con_url_free(ev->url_con);
+        return ECORE_CALLBACK_PASS_ON;
+    }
+
+    xpathObj = xmlXPathEvalExpression((xmlChar *)"//station", xpathCtx);
+    if (xpathObj == NULL)
+    {
+        printf("Error: could not evaluate xpath _expression_\n");
+        xmlXPathFreeContext(xpathCtx);
+        xmlFreeDoc(doc);
+        ecore_con_url_free(ev->url_con);
+        return ECORE_CALLBACK_PASS_ON;
+    }
+
+    elm_list_clear(ad->list);
+
+    for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
+    {
+        xmlNodePtr cur = xpathObj->nodesetval->nodeTab[i];
+        Station *st = calloc(1, sizeof(Station));
+        st->name = eina_stringshare_add((const char *)xmlGetProp(cur, (xmlChar *)"name"));
+        st->url = "" char *)xmlGetProp(cur, (xmlChar *)"url_resolved"));
+        st->favicon = eina_stringshare_add((const char *)xmlGetProp(cur, (xmlChar *)"favicon"));
+        ad->stations = eina_list_append(ad->stations, st);
+
+        Evas_Object *ic = elm_icon_add(ad->win);
+        elm_icon_standard_set(ic, st->favicon);
+        elm_list_item_append(ad->list, st->name, ic, NULL, NULL, st);
+    }
+    elm_list_go(ad->list);
+
+    xmlXPathFreeObject(xpathObj);
+    xmlXPathFreeContext(xpathCtx);
+    xmlFreeDoc(doc);
+    ecore_con_url_free(ev->url_con);
+
+    return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_stop_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   emotion_object_play_set(ad->emotion, EINA_FALSE);
+   emotion_object_position_set(ad->emotion, 0.0);
+}
 
-// Entry point using Elementary’s macro wrapper. This ensures proper
-// initialization and clean shutdown, and keeps main() concise.
 EAPI_MAIN int
 elm_main(int argc, char **argv)
 {
-    // Create a standard window with title and autodel behavior
-    Evas_Object *win = elm_win_util_standard_add("hello", "EFL Hello World");
-    elm_win_autodel_set(win, EINA_TRUE);
+   AppData ad = {0};
 
-    // Optional: a background to occupy the full window
-    Evas_Object *bg = elm_bg_add(win);
-    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    elm_win_resize_object_add(win, bg);
-    evas_object_show(bg);
+   ecore_con_init();
 
-    // Create and configure a label centered in the window
-    Evas_Object *label = elm_label_add(win);
-    elm_object_text_set(label, "Hello, World!");
-    evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    evas_object_size_hint_align_set(label, 0.5, 0.5);
-    elm_win_resize_object_add(win, label);
-    evas_object_show(label);
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
 
-    // Initial window size and show
-    evas_object_resize(win, 400, 240);
-    evas_object_show(win);
+   ad.win = elm_win_add(NULL, "efl-internet-radio", ELM_WIN_BASIC);
+   elm_win_title_set(ad.win, "EFL Internet Radio");
+   elm_win_autodel_set(ad.win, EINA_TRUE);
+   evas_object_smart_callback_add(ad.win, "delete,request", _win_del_cb, &ad);
 
-    // Enter the main loop
-    elm_run();
-    return 0;
+   ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _url_data_cb, &ad);
+   ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _url_complete_cb, &ad);
+
+   Evas_Object *box = elm_box_add(ad.win);
+   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(ad.win, box);
+   evas_object_show(box);
+
+   Evas_Object *search_hbox = elm_box_add(ad.win);
+   elm_box_horizontal_set(search_hbox, EINA_TRUE);
+   evas_object_size_hint_weight_set(search_hbox, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(search_hbox, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(box, search_hbox);
+   evas_object_show(search_hbox);
+
+   ad.search_entry = elm_entry_add(ad.win);
+   elm_entry_single_line_set(ad.search_entry, EINA_TRUE);
+   elm_entry_scrollable_set(ad.search_entry, EINA_TRUE);
+   evas_object_size_hint_weight_set(ad.search_entry, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ad.search_entry, EVAS_HINT_FILL, 0);
+   elm_object_part_text_set(ad.search_entry, "guide", "Search for stations...");
+   elm_box_pack_end(search_hbox, ad.search_entry);
+   evas_object_show(ad.search_entry);
+
+   ad.search_hoversel = elm_hoversel_add(ad.win);
+   elm_hoversel_hover_parent_set(ad.search_hoversel, ad.win);
+   elm_object_text_set(ad.search_hoversel, "name");
+   elm_hoversel_item_add(ad.search_hoversel, "name", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(ad.search_hoversel, "country", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(ad.search_hoversel, "language", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_hoversel_item_add(ad.search_hoversel, "tag", NULL, ELM_ICON_NONE, NULL, NULL);
+   elm_box_pack_end(search_hbox, ad.search_hoversel);
+   evas_object_show(ad.search_hoversel);
+
+   Evas_Object *search_btn = elm_button_add(ad.win);
+   elm_object_text_set(search_btn, "Search");
+   elm_box_pack_end(search_hbox, search_btn);
+   evas_object_show(search_btn);
+
+   ad.list = elm_list_add(ad.win);
+   evas_object_size_hint_weight_set(ad.list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ad.list, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(box, ad.list);
+   evas_object_show(ad.list);
+
+   ad.emotion = emotion_object_add(ad.win);
+   evas_object_size_hint_weight_set(ad.emotion, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ad.emotion, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(box, ad.emotion);
+   evas_object_show(ad.emotion);
+
+   Evas_Object *controls_hbox = elm_box_add(ad.win);
+   elm_box_horizontal_set(controls_hbox, EINA_TRUE);
+   evas_object_size_hint_weight_set(controls_hbox, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(controls_hbox, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(box, controls_hbox);
+   evas_object_show(controls_hbox);
+
+   Evas_Object *play_btn = elm_button_add(ad.win);
+   elm_object_text_set(play_btn, "Play");
+   elm_box_pack_end(controls_hbox, play_btn);
+   evas_object_show(play_btn);
+
+   Evas_Object *pause_btn = elm_button_add(ad.win);
+   elm_object_text_set(pause_btn, "Pause");
+   elm_box_pack_end(controls_hbox, pause_btn);
+   evas_object_show(pause_btn);
+
+   Evas_Object *stop_btn = elm_button_add(ad.win);
+   elm_object_text_set(stop_btn, "Stop");
+   elm_box_pack_end(controls_hbox, stop_btn);
+   evas_object_show(stop_btn);
+
+   evas_object_smart_callback_add(ad.list, "selected", _list_item_selected_cb, &ad);
+   evas_object_smart_callback_add(play_btn, "clicked", _play_btn_clicked_cb, &ad);
+   evas_object_smart_callback_add(pause_btn, "clicked", _pause_btn_clicked_cb, &ad);
+   evas_object_smart_callback_add(stop_btn, "clicked", _stop_btn_clicked_cb, &ad);
+   evas_object_smart_callback_add(search_btn, "clicked", _search_btn_clicked_cb, &ad);
+
+   evas_object_show(ad.win);
+
+   elm_run();
+   ecore_con_shutdown();
+   return 0;
 }
-
-ELM_MAIN()
\ No newline at end of file
+ELM_MAIN()

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to