|
@ -0,0 +1,43 @@
|
|||
*.o
|
||||
*.lo
|
||||
*~
|
||||
.libs
|
||||
.deps
|
||||
.dirstamp
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/libtool.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
Makefile
|
||||
Makefile.in
|
||||
missing
|
||||
stamp-h1
|
||||
edbus-*.tar.*
|
||||
edbus.pc
|
||||
libedbus.la
|
||||
src/examples/connman-list-services
|
||||
src/examples/ofono-dial
|
||||
src/examples/banshee
|
||||
src/examples/complex_types
|
||||
src/examples/complex_types_server
|
||||
src/examples/server
|
||||
src/examples/client
|
||||
doc/Doxyfile
|
||||
doc/html/
|
||||
doc/latex/
|
||||
doc/man/
|
|
@ -0,0 +1,4 @@
|
|||
Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
|
||||
José Roberto de Souza <zehortigoza@profusion.mobi>
|
||||
Leandro Pereira <leandro@profusion.mobi>
|
||||
Lucas De Marchi <lucas.demarchi@profusion.mobi>
|
|
@ -0,0 +1,120 @@
|
|||
ACLOCAL_AMFLAGS = -I m4
|
||||
CLEANFILES =
|
||||
MAINTAINERCLEANFILES =
|
||||
EXTRA_DIST =
|
||||
|
||||
SUBDIRS = doc
|
||||
|
||||
AM_MAKEFLAGS = --no-print-directory
|
||||
AM_CFLAGS = \
|
||||
-include $(top_builddir)/config.h \
|
||||
-I$(top_srcdir)/src/lib \
|
||||
@ECORE_CFLAGS@ \
|
||||
@DBUS_CFLAGS@
|
||||
|
||||
AM_CPPFLAGS = -DEFL_EDBUS_BUILD=1
|
||||
|
||||
includedir = @includedir@/edbus-@VMAJ@/
|
||||
|
||||
SED_PROCESS = \
|
||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(SED) \
|
||||
-e 's,@VERSION\@,$(VERSION),g' \
|
||||
-e 's,@prefix\@,$(prefix),g' \
|
||||
-e 's,@exec_prefix\@,$(exec_prefix),g' \
|
||||
-e 's,@libdir\@,$(libdir),g' \
|
||||
-e 's,@includedir\@,$(includedir),g' \
|
||||
< $< > $@ || rm $@
|
||||
|
||||
%.pc: %.pc.in Makefile
|
||||
$(SED_PROCESS)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = edbus.pc
|
||||
CLEANFILES += edbus.pc
|
||||
EXTRA_DIST += edbus.pc.in
|
||||
|
||||
EXTRA_DIST += \
|
||||
m4/efl_doxygen.m4 \
|
||||
m4/efl_compiler_flag.m4
|
||||
|
||||
|
||||
MAINTAINERCLEANFILES += \
|
||||
aclocal.m4 \
|
||||
compile \
|
||||
config.guess \
|
||||
config.h.in \
|
||||
config.sub \
|
||||
configure \
|
||||
depcomp \
|
||||
install-sh \
|
||||
ltmain.sh \
|
||||
Makefile.in \
|
||||
missing \
|
||||
mkinstalldirs
|
||||
|
||||
lib_LTLIBRARIES = libedbus.la
|
||||
|
||||
include_HEADERS = \
|
||||
src/lib/EDBus.h \
|
||||
src/lib/edbus_connection.h \
|
||||
src/lib/edbus_freedesktop.h \
|
||||
src/lib/edbus_message.h \
|
||||
src/lib/edbus_object.h \
|
||||
src/lib/edbus_pending.h \
|
||||
src/lib/edbus_proxy.h \
|
||||
src/lib/edbus_service.h \
|
||||
src/lib/edbus_signal_handler.h
|
||||
|
||||
libedbus_la_LIBADD = @ECORE_LIBS@ @DBUS_LIBS@
|
||||
libedbus_la_SOURCES = \
|
||||
src/lib/edbus_private.h \
|
||||
src/lib/edbus_private_types.h \
|
||||
src/lib/edbus_proxy.c \
|
||||
src/lib/edbus_core.c \
|
||||
src/lib/edbus_message.c \
|
||||
src/lib/edbus_object.c \
|
||||
src/lib/edbus_pending.c \
|
||||
src/lib/edbus_freedesktop.c \
|
||||
src/lib/edbus_service.c \
|
||||
src/lib/edbus_signal_handler.c
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
src/examples/connman-list-services \
|
||||
src/examples/ofono-dial \
|
||||
src/examples/banshee \
|
||||
src/examples/complex_types \
|
||||
src/examples/complex_types_server \
|
||||
src/examples/server \
|
||||
src/examples/client
|
||||
|
||||
EXAMPLES_LIBS = libedbus.la @ECORE_LIBS@
|
||||
|
||||
src_examples_connman_list_services_SOURCES = \
|
||||
src/examples/connman-list-services.c
|
||||
src_examples_connman_list_services_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_ofono_dial_SOURCES = src/examples/ofono-dial.c
|
||||
src_examples_ofono_dial_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_banshee_SOURCES = src/examples/banshee.c
|
||||
src_examples_banshee_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_complex_types_SOURCES = src/examples/complex_types.c
|
||||
src_examples_complex_types_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_complex_types_server_SOURCES = src/examples/complex_types_server.c
|
||||
src_examples_complex_types_server_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_server_SOURCES = src/examples/server.c
|
||||
src_examples_server_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
src_examples_client_SOURCES = src/examples/client.c
|
||||
src_examples_client_LDADD = $(EXAMPLES_LIBS)
|
||||
|
||||
.PHONY: doc
|
||||
|
||||
# Documentation
|
||||
|
||||
doc:
|
||||
@echo "entering doc/"
|
||||
make -C doc doc
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
autoreconf -f -i
|
||||
|
||||
if [ -z "$NOCONFIGURE" ]; then
|
||||
./configure "$@"
|
||||
fi
|
|
@ -0,0 +1,114 @@
|
|||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
m4_define([v_maj], [1])
|
||||
m4_define([v_min], [7])
|
||||
m4_define([v_mic], [99])
|
||||
m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n']))
|
||||
m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))])
|
||||
##-- When released, remove the dnl on the below line
|
||||
dnl m4_undefine([v_rev])
|
||||
##-- When doing snapshots - change soname. remove dnl on below line
|
||||
dnl m4_define([relname], [ver-pre-svn-07])
|
||||
dnl m4_define([v_rel], [-release relname])
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
m4_ifdef([v_rev], [m4_define([v_ver], [v_maj.v_min.v_mic.v_rev])],
|
||||
[m4_define([v_ver], [v_maj.v_min.v_mic])])
|
||||
m4_define([lt_cur], m4_eval(v_maj + v_min))
|
||||
m4_define([lt_rev], v_mic)
|
||||
m4_define([lt_age], v_min)
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
|
||||
AC_INIT([edbus], [v_ver], [enlightenment-devel@lists.sourceforge.net])
|
||||
AC_PREREQ([2.60])
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
EFL_COMPILER_FLAG([-Wall])
|
||||
EFL_COMPILER_FLAG([-Wextra])
|
||||
EFL_COMPILER_FLAG([-Wshadow])
|
||||
EFL_COMPILER_FLAG([-Wno-unused-parameter])
|
||||
EFL_COMPILER_FLAG([-Wvla])
|
||||
EFL_COMPILER_FLAG([-Wundef])
|
||||
EFL_COMPILER_FLAG([-Wformat=2])
|
||||
EFL_COMPILER_FLAG([-Wlogical-op])
|
||||
EFL_COMPILER_FLAG([-Wsign-compare])
|
||||
EFL_COMPILER_FLAG([-Wformat-security])
|
||||
EFL_COMPILER_FLAG([-Wmissing-include-dirs])
|
||||
EFL_COMPILER_FLAG([-Wformat-nonliteral])
|
||||
EFL_COMPILER_FLAG([-Wold-style-definition])
|
||||
EFL_COMPILER_FLAG([-Wpointer-arith])
|
||||
EFL_COMPILER_FLAG([-Winit-self])
|
||||
EFL_COMPILER_FLAG([-Wdeclaration-after-statement])
|
||||
EFL_COMPILER_FLAG([-Wmissing-declarations])
|
||||
EFL_COMPILER_FLAG([-Wmissing-noreturn])
|
||||
EFL_COMPILER_FLAG([-Wendif-labels])
|
||||
EFL_COMPILER_FLAG([-Wstrict-aliasing=2])
|
||||
EFL_COMPILER_FLAG([-Wwrite-strings])
|
||||
EFL_COMPILER_FLAG([-Wno-long-long])
|
||||
EFL_COMPILER_FLAG([-Wno-overlength-strings])
|
||||
EFL_COMPILER_FLAG([-Wno-missing-field-initializers])
|
||||
EFL_COMPILER_FLAG([-Wno-nested-externs])
|
||||
EFL_COMPILER_FLAG([-Wchar-subscripts])
|
||||
EFL_COMPILER_FLAG([-Wtype-limits])
|
||||
EFL_COMPILER_FLAG([-Wuninitialized])
|
||||
|
||||
AC_LANG_C
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_MKDIR_P
|
||||
AM_PROG_CC_C_O
|
||||
AC_C___ATTRIBUTE__
|
||||
AC_C_VA_LIST_AS_ARRAY
|
||||
|
||||
AC_DISABLE_STATIC
|
||||
define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
|
||||
define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# doxygen program for documentation building
|
||||
EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"])
|
||||
|
||||
PKG_CHECK_MODULES([EINA], [eina >= 1.7.0])
|
||||
PKG_CHECK_MODULES([ECORE], [ecore])
|
||||
PKG_CHECK_MODULES([DBUS], [dbus-1])
|
||||
|
||||
with_max_log_level="EINA_LOG_LEVEL_DBG"
|
||||
AC_ARG_WITH(maximum-log-level,
|
||||
[AC_HELP_STRING([--with-maximum-log-level=NUMBER],
|
||||
[limit log level, any call to EINA_LOG() with values greater than this will be compiled out, ignoring runtime settings, but saving function calls.])],
|
||||
[with_max_log_level="${withval}"], [:])
|
||||
AC_DEFINE_UNQUOTED(EINA_LOG_LEVEL_MAXIMUM, ${with_max_log_level}, [if set, logging is limited to this amount.])
|
||||
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
m4_ifdef([v_rev], , [m4_define([v_rev], [0])])
|
||||
m4_ifdef([v_rel], , [m4_define([v_rel], [])])
|
||||
AC_DEFINE_UNQUOTED(VMAJ, [v_maj], [Major version])
|
||||
AC_DEFINE_UNQUOTED(VMIN, [v_min], [Minor version])
|
||||
AC_DEFINE_UNQUOTED(VMIC, [v_mic], [Micro version])
|
||||
AC_DEFINE_UNQUOTED(VREV, [v_rev], [Revison])
|
||||
version_info="lt_cur:lt_rev:lt_age"
|
||||
release_info="v_rel"
|
||||
AC_SUBST(version_info)
|
||||
AC_SUBST(release_info)
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
VMAJ=v_maj
|
||||
VMIN=v_min
|
||||
AC_SUBST(VMAJ)
|
||||
AC_SUBST(VMIN)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
doc/Doxyfile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,227 @@
|
|||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = EDBus
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY = .
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 2
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
SYMBOL_CACHE_SIZE = 0
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = YES
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = NO
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
INPUT = ../src/lib \
|
||||
./examples.dox
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH = ../src/examples/
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = YES
|
||||
IMAGE_PATH = ../doc/images/
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = NO
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 2
|
||||
IGNORE_PREFIX = EDBUS_ edbus_
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = ./head.html
|
||||
HTML_FOOTER = ./foot.html
|
||||
HTML_STYLESHEET = ./e.css
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
GENERATE_TREEVIEW = NO
|
||||
USE_INLINE_TREES = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
SEARCHENGINE = NO
|
||||
SERVER_BASED_SEARCH = NO
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = YES
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = NO
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = EINA_MAGIC_DEBUG \
|
||||
__UNUSED__= \
|
||||
EINA_ARG_NONNULL()= \
|
||||
EINA_MALLOC= \
|
||||
EINA_WARN_UNUSED_RESULT= \
|
||||
EAPI= \
|
||||
EINA_PURE= \
|
||||
EINA_CONST=
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
CLASS_DIAGRAMS = NO
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = FreeSans.ttf
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = NO
|
||||
COLLABORATION_GRAPH = NO
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = NO
|
||||
INCLUDED_BY_GRAPH = NO
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = NO
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
|
@ -0,0 +1,32 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
.PHONY: doc
|
||||
|
||||
PACKAGE_DOCNAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc
|
||||
|
||||
if EFL_BUILD_DOC
|
||||
|
||||
doc-clean:
|
||||
rm -rf html/ latex/ $(top_builddir)/$(PACKAGE_DOCNAME).tar*
|
||||
|
||||
doc: all
|
||||
$(efl_doxygen)
|
||||
cp $(srcdir)/images/* html/
|
||||
rm -rf $(PACKAGE_DOCNAME).tar*
|
||||
mkdir -p $(PACKAGE_DOCNAME)/doc
|
||||
cp -R html/ latex/ $(PACKAGE_DOCNAME)/doc
|
||||
tar cf $(PACKAGE_DOCNAME).tar $(PACKAGE_DOCNAME)/
|
||||
bzip2 -9 $(PACKAGE_DOCNAME).tar
|
||||
rm -rf $(PACKAGE_DOCNAME)/
|
||||
mv $(PACKAGE_DOCNAME).tar.bz2 $(top_builddir)
|
||||
|
||||
clean-local: doc-clean
|
||||
|
||||
else
|
||||
|
||||
doc:
|
||||
@echo "Documentation not built. Run ./configure --help"
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST = Doxyfile.in $(wildcard images/*.*) e.css head.html foot.html
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
Author:
|
||||
Andres Blanc <andresblanc@gmail.com>
|
||||
DaveMDS Andreoli <dave@gurumeditation.it>
|
||||
|
||||
Supported Browsers:
|
||||
ie7, opera9, konqueror4 and firefox3
|
||||
|
||||
Please use a different file for ie6, ie5, etc. hacks.
|
||||
*/
|
||||
|
||||
|
||||
/* Necessary to place the footer at the bottom of the page */
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#container {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -53px;
|
||||
}
|
||||
|
||||
#footer, #push {
|
||||
height: 53px;
|
||||
}
|
||||
|
||||
|
||||
* html #container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Prevent floating elements overflowing containers */
|
||||
.clear {
|
||||
clear: both;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
/* Flexible & centered layout from 750 to 960 pixels */
|
||||
.layout {
|
||||
max-width: 960px;
|
||||
min-width: 760px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
/*font-family: Lucida Grande, Helvetica, sans-serif;*/
|
||||
font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif
|
||||
}
|
||||
|
||||
/* Prevent design overflowing the viewport in small resolutions */
|
||||
#container {
|
||||
padding-right: 17px;
|
||||
padding-left: 17px;
|
||||
background-image: url(head_bg.png);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
#header {
|
||||
width: 100%;
|
||||
height: 102px;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
width: 63px;
|
||||
height: 63px;
|
||||
background-image: url(e.png);
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#header h1 span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* .menu-container is used to set properties common to .menu and .submenu */
|
||||
#header .menu-container {
|
||||
}
|
||||
|
||||
#header .menu-container ul {
|
||||
list-style-type: none;
|
||||
list-style-position: inside;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#header .menu-container li {
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#header .menu {
|
||||
height: 63px;
|
||||
display: block;
|
||||
background-image: url(menu_bg.png);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
#header .menu ul {
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-image: url(menu_bg_last.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top right;
|
||||
padding-right: 17px;
|
||||
}
|
||||
|
||||
#header .menu li {
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
background-image: url(menu_bg_unsel.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#header .menu a {
|
||||
height: 100%;
|
||||
display: block;
|
||||
color: #cdcdcd;
|
||||
text-decoration: none;
|
||||
font-size: 10pt;
|
||||
line-height: 59px;
|
||||
text-align: center;
|
||||
padding: 0px 15px 0px 15px;
|
||||
}
|
||||
|
||||
#header .menu li:hover {
|
||||
background-image: url(menu_bg_hover.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#header .menu li:hover a {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
#header .menu li.current {
|
||||
background-image: url(menu_bg_current.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#header .menu li.current a {
|
||||
color: #646464;
|
||||
}
|
||||
|
||||
|
||||
/* Hide all the submenus but the current */
|
||||
#header .submenu ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#header .submenu .current {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#header .submenu {
|
||||
font: bold 10px verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#header .submenu a {
|
||||
color: #888888;
|
||||
text-decoration: none;
|
||||
font-size: 0.9em;
|
||||
line-height: 15px;
|
||||
padding:0px 5px 0px 5px;
|
||||
}
|
||||
|
||||
#header .submenu a:hover {
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
#header .submenu li {
|
||||
border-left: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
#header .submenu li:last-child {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
#header .doxytitle {
|
||||
position: absolute;
|
||||
font-size: 1.8em;
|
||||
font-weight: bold;
|
||||
color: #444444;
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
#header small {
|
||||
font-size: 0.4em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
background-image: url(foot_bg.png);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#footer table {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
padding: 5px 30px 5px 30px;
|
||||
font-size: 0.8em;
|
||||
font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
#footer td.copyright {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @page Examples Examples
|
||||
*
|
||||
* Here is a page with some EDBus examples:
|
||||
*
|
||||
* @li @ref banshee
|
||||
* @li @ref simple_dbus_client
|
||||
* @li @ref simple_dbus_server
|
||||
* @li @ref complex_types
|
||||
* @li @ref complex_types_server
|
||||
* @li @ref connman
|
||||
* @li @ref ofono
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page banshee Banshee dbus client
|
||||
*
|
||||
* @include banshee.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page simple_dbus_client Simple dbus client
|
||||
*
|
||||
* @include client.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page simple_dbus_server Simple dbus server
|
||||
*
|
||||
* @include server.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page complex_types Handling with dbus complex types
|
||||
*
|
||||
* @include complex_types.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page complex_types_server Handling with dbus complex types server side
|
||||
*
|
||||
* @include complex_types_server.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page connman Connman
|
||||
*
|
||||
* @include connman-list-services.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page ofono Ofono
|
||||
*
|
||||
* @include ofono-dial.c
|
||||
*/
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
<div id="push"></div>
|
||||
</div> <!-- #content -->
|
||||
</div> <!-- .layout -->
|
||||
|
||||
</div> <!-- #container -->
|
||||
|
||||
|
||||
<div id="footer">
|
||||
<table><tr>
|
||||
<td class="poweredby"><img src="doxygen.png"></td>
|
||||
<td class="copyright">Copyright ©$year Enlightenment</td>
|
||||
<td class="generated">Docs generated $datetime</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
|
||||
<meta name="author" content="Andres Blanc" >
|
||||
|
||||
<link rel="icon" href="images/favicon.png" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
|
||||
<link rel="icon" href="images/favicon.png" type="image/ico">
|
||||
<link rel="shortcut icon" href="images/favicon.png" type="image/ico">
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="e.css">
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="edoxy.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="header">
|
||||
<div class="layout">
|
||||
|
||||
<h1><span>Enlightenment</span></h1>
|
||||
<h2><span>Beauty at your fingertips</span></h2>
|
||||
|
||||
<div class="menu-container">
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li class="current"><a href="http://web.enlightenment.org/p.php?p=docs">Docs</a></li>
|
||||
<li><a href="http://trac.enlightenment.org/e">Tracker</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=contact">Contact</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=contribute">Contribute</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=support">Support</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=download">Download</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=about">About</a></li>
|
||||
<li><a href="http://www.enlightenment.org/p.php?p=news">News</a></li>
|
||||
<li><a href="http://www.enlightenment.org/">Home</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="doxytitle">
|
||||
$projectname Documentation <small>at $date</small>
|
||||
</div>
|
||||
|
||||
<div class="menu-container">
|
||||
<!--<div class="submenu">
|
||||
<ul class="current">
|
||||
<li><a href="group__EUkit__Group.html">EUkit</a></li>
|
||||
<li><a href="group__EOfono__Group.html">EOfono</a></li>
|
||||
<li><a href="group__ENotify__Group.html">ENotify</a></li>
|
||||
<li><a href="group__EHal__Group.html">EHal</a></li>
|
||||
<li><a href="group__EConnman__Group.html">EConnman</a></li>
|
||||
<li><a href="group__EBluez__Group.html">EBluez</a></li>
|
||||
<li><a href="group__EDbus__Group.html">EDbus</a></li>
|
||||
<li class="current"><a href="index.html">Main Page</a></li>
|
||||
</ul>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div class="layout">
|
After Width: | Height: | Size: 3.7 KiB |
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* This file contain a custom doxygen style to match e.org graphics
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
}*/
|
||||
BODY, TD {
|
||||
font-size: 12px;
|
||||
}
|
||||
H1 {
|
||||
text-align: center;
|
||||
font-size: 160%;
|
||||
}
|
||||
H2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
H3 {
|
||||
font-size: 100%;
|
||||
}
|
||||
CAPTION {
|
||||
font-weight: bold
|
||||
}
|
||||
DIV.qindex {
|
||||
width: 100%;
|
||||
background-color: #e8eef2;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.navpath {
|
||||
width: 100%;
|
||||
background-color: #e8eef2;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.navtab {
|
||||
background-color: #e8eef2;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
}
|
||||
TD.navtab {
|
||||
font-size: 70%;
|
||||
}
|
||||
A.qindex {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D;
|
||||
}
|
||||
A.qindex:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D
|
||||
}
|
||||
A.qindex:hover {
|
||||
text-decoration: none;
|
||||
background-color: #ddddff;
|
||||
}
|
||||
A.qindexHL {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
A.qindexHL:hover {
|
||||
text-decoration: none;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
}
|
||||
A.qindexHL:visited {
|
||||
text-decoration: none;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff
|
||||
}
|
||||
A.el {
|
||||
text-decoration: none;
|
||||
font-weight: bold
|
||||
}
|
||||
A.elRef {
|
||||
font-weight: bold
|
||||
}
|
||||
A.code:link {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #0000FF
|
||||
}
|
||||
A.code:visited {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #0000FF
|
||||
}
|
||||
A.codeRef:link {
|
||||
font-weight: normal;
|
||||
color: #0000FF
|
||||
}
|
||||
A.codeRef:visited {
|
||||
font-weight: normal;
|
||||
color: #0000FF
|
||||
}
|
||||
A:hover, A:visited:hover {
|
||||
text-decoration: none;
|
||||
/* background-color: #f2f2ff; */
|
||||
color: #000055;
|
||||
}
|
||||
A.anchor {
|
||||
color: #000;
|
||||
}
|
||||
DL.el {
|
||||
margin-left: -1cm
|
||||
}
|
||||
.fragment {
|
||||
font-family: monospace, fixed;
|
||||
font-size: 95%;
|
||||
}
|
||||
PRE.fragment {
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 2px;
|
||||
margin-right: 8px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
DIV.ah {
|
||||
background-color: black;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px
|
||||
}
|
||||
|
||||
DIV.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
DIV.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
font-size: 90%
|
||||
}
|
||||
/*BODY {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}*/
|
||||
TD.indexkey {
|
||||
background-color: #e8eef2;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TD.indexvalue {
|
||||
background-color: #e8eef2;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TR.memlist {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
P.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
IMG.formulaDsp {
|
||||
}
|
||||
IMG.formulaInl {
|
||||
vertical-align: middle;
|
||||
}
|
||||
SPAN.keyword { color: #008000 }
|
||||
SPAN.keywordtype { color: #604020 }
|
||||
SPAN.keywordflow { color: #e08000 }
|
||||
SPAN.comment { color: #800000 }
|
||||
SPAN.preprocessor { color: #806020 }
|
||||
SPAN.stringliteral { color: #002080 }
|
||||
SPAN.charliteral { color: #008080 }
|
||||
SPAN.vhdldigit { color: #ff00ff }
|
||||
SPAN.vhdlchar { color: #000000 }
|
||||
SPAN.vhdlkeyword { color: #700070 }
|
||||
SPAN.vhdllogic { color: #ff0000 }
|
||||
|
||||
.mdescLeft {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.memItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplParams {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
color: #606060;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.search {
|
||||
color: #003399;
|
||||
font-weight: bold;
|
||||
}
|
||||
FORM.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
INPUT.search {
|
||||
font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #e8eef2;
|
||||
}
|
||||
TD.tiny {
|
||||
font-size: 75%;
|
||||
}
|
||||
a {
|
||||
color: #1A41A8;
|
||||
}
|
||||
a:visited {
|
||||
color: #2A3798;
|
||||
}
|
||||
.dirtab {
|
||||
padding: 4px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #84b0c7;
|
||||
}
|
||||
TH.dirtab {
|
||||
background: #e8eef2;
|
||||
font-weight: bold;
|
||||
}
|
||||
HR {
|
||||
height: 1px;
|
||||
border: none;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
/* Style for detailed member documentation */
|
||||
.memtemplate {
|
||||
font-size: 80%;
|
||||
color: #606060;
|
||||
font-weight: normal;
|
||||
margin-left: 3px;
|
||||
}
|
||||
.memnav {
|
||||
background-color: #e8eef2;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
}
|
||||
.memitem {
|
||||
padding: 4px;
|
||||
background-color: #eef3f5;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #dedeee;
|
||||
-moz-border-radius: 8px 8px 8px 8px;
|
||||
}
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
}
|
||||
.memdoc{
|
||||
padding-left: 10px;
|
||||
}
|
||||
.memproto {
|
||||
background-color: #d5e1e8;
|
||||
width: 100%;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #84b0c7;
|
||||
font-weight: bold;
|
||||
-moz-border-radius: 8px 8px 8px 8px;
|
||||
}
|
||||
.paramkey {
|
||||
text-align: right;
|
||||
}
|
||||
.paramtype {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.paramname {
|
||||
color: #602020;
|
||||
font-style: italic;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* End Styling for detailed member documentation */
|
||||
|
||||
/* for the tree view */
|
||||
.ftvtree {
|
||||
font-family: sans-serif;
|
||||
margin:0.5em;
|
||||
}
|
||||
/* these are for tree view when used as main index */
|
||||
.directory {
|
||||
font-size: 9pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
.directory h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
/* The following two styles can be used to replace the root node title */
|
||||
/* with an image of your choice. Simply uncomment the next two styles, */
|
||||
/* specify the name of your image and be sure to set 'height' to the */
|
||||
/* proper pixel height of your image. */
|
||||
|
||||
/* .directory h3.swap { */
|
||||
/* height: 61px; */
|
||||
/* background-repeat: no-repeat; */
|
||||
/* background-image: url("yourimage.gif"); */
|
||||
/* } */
|
||||
/* .directory h3.swap span { */
|
||||
/* display: none; */
|
||||
/* } */
|
||||
|
||||
.directory > h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
.directory p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.directory div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
}
|
||||
.directory img {
|
||||
vertical-align: -30%;
|
||||
}
|
||||
/* these are for tree view when not used as main index */
|
||||
.directory-alt {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.directory-alt h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
}
|
||||
.directory-alt > h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
.directory-alt p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.directory-alt div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
}
|
||||
.directory-alt img {
|
||||
vertical-align: -30%;
|
||||
}
|
||||
|
After Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 214 B |
After Width: | Height: | Size: 192 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 637 B |
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: edbus
|
||||
Description: D-Bus access from Ecore
|
||||
Requires.private: ecore dbus-1
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -ledbus
|
||||
Cflags: -I${includedir}
|
|
@ -0,0 +1,47 @@
|
|||
dnl Copyright (C) 2004-2008 Kim Woelders
|
||||
dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
|
||||
dnl That code is public domain and can be freely used or copied.
|
||||
dnl Originally snatched from somewhere...
|
||||
|
||||
dnl Macro for checking if the compiler supports __attribute__
|
||||
|
||||
dnl Usage: AC_C___ATTRIBUTE__
|
||||
dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__
|
||||
dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is
|
||||
dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused))
|
||||
dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is
|
||||
dnl defined to nothing.
|
||||
|
||||
AC_DEFUN([AC_C___ATTRIBUTE__],
|
||||
[
|
||||
|
||||
AC_MSG_CHECKING([for __attribute__])
|
||||
|
||||
AC_CACHE_VAL([ac_cv___attribute__],
|
||||
[AC_TRY_COMPILE(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
|
||||
int func(int x);
|
||||
int foo(int x __attribute__ ((unused)))
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
],
|
||||
[],
|
||||
[ac_cv___attribute__="yes"],
|
||||
[ac_cv___attribute__="no"]
|
||||
)])
|
||||
|
||||
AC_MSG_RESULT($ac_cv___attribute__)
|
||||
|
||||
if test "x${ac_cv___attribute__}" = "xyes" ; then
|
||||
AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__])
|
||||
AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused])
|
||||
else
|
||||
AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused])
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
dnl End of ac_attribute.m4
|
|
@ -0,0 +1,48 @@
|
|||
dnl That code is public domain and can be freely used or copied.
|
||||
dnl Originally snatched from somewhere...
|
||||
|
||||
dnl Macro for checking if va_list is an array
|
||||
|
||||
dnl Usage: AC_C_VA_LIST_AS_ARRAY
|
||||
dnl call AC_DEFINE for HAVE_VA_LIST_AS_ARRAY
|
||||
dnl if for this architecture va_list is defined as an array
|
||||
|
||||
AC_DEFUN([AC_C_VA_LIST_AS_ARRAY],
|
||||
[
|
||||
|
||||
AC_MSG_CHECKING([whether va_list is defined as an array])
|
||||
|
||||
AC_CACHE_VAL([ac_cv_valistasarray],
|
||||
[AC_TRY_RUN(
|
||||
[
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
void foo(int i, ...)
|
||||
{
|
||||
va_list ap1, ap2;
|
||||
va_start(ap1, i);
|
||||
ap2 = ap1;
|
||||
if (va_arg(ap2, int) != 123 || va_arg(ap1, int) != 123)
|
||||
exit(1);
|
||||
va_end(ap1);
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
foo(0, 123);
|
||||
return(0);
|
||||
}
|
||||
],
|
||||
[ac_cv_valistasarray="no"],
|
||||
[ac_cv_valistasarray="yes"],
|
||||
[ac_cv_valistasarray="no"]
|
||||
)])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_valistasarray)
|
||||
|
||||
if test "x${ac_cv_valistasarray}" = "xyes" ; then
|
||||
AC_DEFINE([HAVE_VA_LIST_AS_ARRAY], [1], [Define to 1 if va_list is an array])
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
dnl End of ac_valist.m4
|
|
@ -0,0 +1,24 @@
|
|||
dnl Checks if a given compiler switch is supported.
|
||||
dnl If so, this macro adds the flag to the CFLAGS
|
||||
|
||||
AC_DEFUN([EFL_COMPILER_FLAG],
|
||||
[
|
||||
|
||||
CFLAGS_save="${CFLAGS}"
|
||||
CFLAGS="${CFLAGS} $1"
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
AC_MSG_CHECKING([whether the compiler supports $1])
|
||||
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]])],
|
||||
[have_flag="yes"],
|
||||
[have_flag="no"])
|
||||
AC_MSG_RESULT([${have_flag}])
|
||||
|
||||
if test "x${have_flag}" = "xno" ; then
|
||||
CFLAGS="${CFLAGS_save}"
|
||||
fi
|
||||
AC_LANG_POP([C])
|
||||
|
||||
])
|
|
@ -0,0 +1,94 @@
|
|||
dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
|
||||
dnl That code is public domain and can be freely used or copied.
|
||||
|
||||
dnl Macro that check if doxygen is available or not.
|
||||
|
||||
dnl EFL_CHECK_DOXYGEN([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test for the doxygen program
|
||||
dnl Defines efl_doxygen
|
||||
dnl Defines the automake conditionnal EFL_BUILD_DOC
|
||||
dnl
|
||||
AC_DEFUN([EFL_CHECK_DOXYGEN],
|
||||
[
|
||||
|
||||
dnl
|
||||
dnl Disable the build of the documentation
|
||||
dnl
|
||||
AC_ARG_ENABLE([doc],
|
||||
[AC_HELP_STRING(
|
||||
[--disable-doc],
|
||||
[Disable documentation build @<:@default=enabled@:>@])],
|
||||
[
|
||||
if test "x${enableval}" = "xyes" ; then
|
||||
efl_enable_doc="yes"
|
||||
else
|
||||
efl_enable_doc="no"
|
||||
fi
|
||||
],
|
||||
[efl_enable_doc="yes"])
|
||||
|
||||
AC_MSG_CHECKING([whether to build documentation])
|
||||
AC_MSG_RESULT([${efl_enable_doc}])
|
||||
|
||||
if test "x${efl_enable_doc}" = "xyes" ; then
|
||||
|
||||
dnl Specify the file name, without path
|
||||
|
||||
efl_doxygen="doxygen"
|
||||
|
||||
AC_ARG_WITH([doxygen],
|
||||
[AC_HELP_STRING(
|
||||
[--with-doxygen=FILE],
|
||||
[doxygen program to use @<:@default=doxygen@:>@])],
|
||||
|
||||
dnl Check the given doxygen program.
|
||||
|
||||
[efl_doxygen=${withval}
|
||||
AC_CHECK_PROG([efl_have_doxygen],
|
||||
[${efl_doxygen}],
|
||||
[yes],
|
||||
[no])
|
||||
if test "x${efl_have_doxygen}" = "xno" ; then
|
||||
echo "WARNING:"
|
||||
echo "The doxygen program you specified:"
|
||||
echo "${efl_doxygen}"
|
||||
echo "was not found. Please check the path and make sure "
|
||||
echo "the program exists and is executable."
|
||||
AC_MSG_WARN([no doxygen detected. Documentation will not be built])
|
||||
fi
|
||||
],
|
||||
[AC_CHECK_PROG([efl_have_doxygen],
|
||||
[${efl_doxygen}],
|
||||
[yes],
|
||||
[no])
|
||||
if test "x${efl_have_doxygen}" = "xno" ; then
|
||||
echo "WARNING:"
|
||||
echo "The doxygen program was not found in your execute path."
|
||||
echo "You may have doxygen installed somewhere not covered by your path."
|
||||
echo ""
|
||||
echo "If this is the case make sure you have the packages installed, AND"
|
||||
echo "that the doxygen program is in your execute path (see your"
|
||||
echo "shell manual page on setting the \$PATH environment variable), OR"
|
||||
echo "alternatively, specify the program to use with --with-doxygen."
|
||||
AC_MSG_WARN([no doxygen detected. Documentation will not be built])
|
||||
fi
|
||||
])
|
||||
else
|
||||
efl_have_doxygen="no"
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Substitution
|
||||
dnl
|
||||
AC_SUBST([efl_doxygen])
|
||||
|
||||
if ! test "x${efl_have_doxygen}" = "xyes" ; then
|
||||
efl_enable_doc="no"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(EFL_BUILD_DOC, test "x${efl_have_doxygen}" = "xyes")
|
||||
|
||||
AS_IF([test "x$efl_have_doxygen" = "xyes"], [$1], [$2])
|
||||
])
|
||||
|
||||
dnl End of efl_doxygen.m4
|
|
@ -0,0 +1,293 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
static Eina_Bool
|
||||
_timer1_cb(void *data)
|
||||
{
|
||||
printf("\n## ecore_main_loop_quit()\n");
|
||||
ecore_main_loop_quit();
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EDBus_Connection *conn;
|
||||
EDBus_Signal_Handler *sh, *sh2, *sh3, *sh4;
|
||||
|
||||
static void
|
||||
on_get_playlists(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
EDBus_Message_Iter *array, *struct_entry;
|
||||
char *path, *name, *image;
|
||||
int i = 0;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "a(oss)", &array))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
printf("on_get_playlists() \n\n");
|
||||
while (edbus_message_iter_get_and_next(array, 'r', &struct_entry))
|
||||
{
|
||||
if (! edbus_message_iter_arguments_get(struct_entry, "oss", &path, &name, &image))
|
||||
{
|
||||
printf("error on edbus_massage_iterator_arguments_get()");
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
printf("%d - %s | %s | %s\n", i, path, name, image);
|
||||
}
|
||||
printf("end of on_get_playlists()\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
on_introspect(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg, *string;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "s", &string))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("on_introspect() data=\n%s\n\n", string);
|
||||
}
|
||||
|
||||
static void
|
||||
on_next(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
|
||||
printf("on_next()\n");
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_pause(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
|
||||
printf("on_pause()\n");
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_state_changed(void *data, const EDBus_Message *msg)
|
||||
{
|
||||
char *status;
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "on_state_changed error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "s", &status))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("on_state_changed = %s\n", status);
|
||||
}
|
||||
|
||||
static void
|
||||
on_state_changed2(void *data, const EDBus_Message *msg)
|
||||
{
|
||||
char *status;
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "on_state_changed error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "s", &status))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("on_state_changed2 = %s\n", status);
|
||||
edbus_signal_handler_unref(sh2);
|
||||
sh2 = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_owner_changed_by_id(void *data, const EDBus_Message *msg)
|
||||
{
|
||||
char *bus, *older_id, *new_id;
|
||||
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
return;
|
||||
if (!edbus_message_arguments_get(msg, "sss", &bus, &older_id, &new_id))
|
||||
printf("Error getting arguments from NameOwnerChanged");
|
||||
|
||||
printf("on_name_owner_changed_by_id bus = %s older=%s new=%s\n\n",
|
||||
bus, older_id, new_id);
|
||||
|
||||
if (!new_id[0])
|
||||
edbus_signal_handler_unref(sh3);
|
||||
}
|
||||
|
||||
static void
|
||||
on_name_owner_changed(void *data, const EDBus_Message *msg)
|
||||
{
|
||||
char *bus, *older_id, *new_id;
|
||||
const char *name, *text;
|
||||
|
||||
if (edbus_message_error_get(msg, &name, &text))
|
||||
printf("NameOwnerChanged name=%s text=%s", name, text);
|
||||
if (!edbus_message_arguments_get(msg, "sss", &bus, &older_id, &new_id))
|
||||
printf("Error getting arguments from NameOwnerChanged");
|
||||
|
||||
printf("bus = %s older=%s new=%s\n\n", bus, older_id, new_id);
|
||||
|
||||
if (new_id[0])
|
||||
{
|
||||
sh4 = edbus_signal_handler_add(conn,
|
||||
EDBUS_FDO_BUS,
|
||||
EDBUS_FDO_PATH,
|
||||
EDBUS_FDO_INTERFACE,
|
||||
"NameOwnerChanged",
|
||||
on_name_owner_changed_by_id,
|
||||
NULL);
|
||||
edbus_signal_handler_match_extra_set(sh4, "arg1", new_id, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
EDBus_Object *player_engine_obj, *playback_controller_obj, *mediaplayer2_obj;
|
||||
EDBus_Proxy *player_engine, *playback_controler, *introspectable, *playlists;
|
||||
EDBus_Pending *pending;
|
||||
unsigned int bool2 = 1;
|
||||
unsigned int playlist_index = 0;
|
||||
unsigned int playlist_max_count = 30;
|
||||
unsigned int playlist_reverse_order = 0;
|
||||
const char *playlist_order = "asc";
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
player_engine_obj = edbus_object_get(conn, "org.bansheeproject.Banshee",
|
||||
"/org/bansheeproject/Banshee/PlayerEngine");
|
||||
if (!player_engine_obj)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get object\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
playback_controller_obj = edbus_object_get(conn, "org.bansheeproject.Banshee",
|
||||
"/org/bansheeproject/Banshee/PlaybackController");
|
||||
|
||||
mediaplayer2_obj = edbus_object_get(conn, "org.bansheeproject.Banshee",
|
||||
"/org/mpris/MediaPlayer2");
|
||||
|
||||
player_engine = edbus_proxy_get(player_engine_obj,
|
||||
"org.bansheeproject.Banshee.PlayerEngine");
|
||||
if (!player_engine)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get binding\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
introspectable = edbus_proxy_get(player_engine_obj,
|
||||
"org.freedesktop.DBus.Introspectable");
|
||||
if (!introspectable)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get binding\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
playback_controler = edbus_proxy_get(playback_controller_obj,
|
||||
"org.bansheeproject.Banshee.PlaybackController");
|
||||
if (!playback_controler)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get binding\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
edbus_proxy_signal_handler_add(player_engine, "StateChanged", on_state_changed, NULL);
|
||||
|
||||
playlists = edbus_proxy_get(mediaplayer2_obj, "org.mpris.MediaPlayer2.Playlists");
|
||||
|
||||
pending = edbus_proxy_call(introspectable, "Introspect", on_introspect, NULL, -1, "");
|
||||
if (!pending)
|
||||
{
|
||||
fprintf(stderr, "Error: could not call\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pending = edbus_proxy_call(player_engine, "Pause", on_pause, NULL, -1, "");
|
||||
if (!pending)
|
||||
{
|
||||
fprintf(stderr, "Error: could not call\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pending = edbus_proxy_call(playback_controler, "Next", on_next, NULL, -1, "b", bool2);
|
||||
if (!pending)
|
||||
{
|
||||
fprintf(stderr, "Error: could not call\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
edbus_proxy_call(playlists, "GetPlaylists", on_get_playlists, NULL, -1,
|
||||
"uusb", playlist_index, playlist_max_count,
|
||||
playlist_order, playlist_reverse_order);
|
||||
|
||||
sh = edbus_signal_handler_add(conn, "org.bansheeproject.Banshee",
|
||||
"/org/bansheeproject/Banshee/PlayerEngine",
|
||||
"org.bansheeproject.Banshee.PlayerEngine",
|
||||
"StateChanged", on_state_changed, NULL);
|
||||
|
||||
sh2 = edbus_signal_handler_add(conn, "org.bansheeproject.Banshee",
|
||||
"/org/bansheeproject/Banshee/PlayerEngine",
|
||||
"org.bansheeproject.Banshee.PlayerEngine",
|
||||
"StateChanged", on_state_changed2, NULL);
|
||||
|
||||
sh3 = edbus_signal_handler_add(conn,
|
||||
EDBUS_FDO_BUS,
|
||||
EDBUS_FDO_PATH,
|
||||
EDBUS_FDO_INTERFACE,
|
||||
"NameOwnerChanged",
|
||||
on_name_owner_changed,
|
||||
NULL);
|
||||
edbus_signal_handler_match_extra_set(sh3, "arg0", "org.bansheeproject.Banshee", NULL);
|
||||
|
||||
ecore_timer_add(50, _timer1_cb, NULL);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_signal_handler_unref(sh);
|
||||
edbus_proxy_unref(playback_controler);
|
||||
edbus_proxy_unref(introspectable);
|
||||
edbus_object_unref(player_engine_obj);
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
#define BUS "org.Enlightenment"
|
||||
#define PATH "/org/enlightenment"
|
||||
#define INTERFACE "org.enlightenment.Test"
|
||||
#define NTESTS 7
|
||||
|
||||
static int i = 0;
|
||||
static EDBus_Signal_Handler *sh;
|
||||
|
||||
static void
|
||||
_on_alive(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
printf("Alive\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
_on_alive2(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
printf("Alive2\n\n");
|
||||
i++;
|
||||
if (i == 2)
|
||||
edbus_signal_handler_unref(sh);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_hello(void *context, const EDBus_Message *msg)
|
||||
{
|
||||
char *txt;
|
||||
|
||||
if (edbus_message_arguments_get(msg, "s", &txt))
|
||||
printf("%s\n", txt);
|
||||
}
|
||||
|
||||
#define bool_value EINA_TRUE
|
||||
#define byte_value 0xAA
|
||||
#define uint32_value 0xFFFFFFFF
|
||||
#define int32_value 0xFFFFFFFF
|
||||
#define int16_value 0x0000FFFF
|
||||
#define double_value 3.1415926
|
||||
#define string_value "test"
|
||||
|
||||
static void
|
||||
test(void)
|
||||
{
|
||||
static int n = 0;
|
||||
|
||||
n++;
|
||||
if (n == NTESTS)
|
||||
printf("Passed in all tests\n");
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_bool(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
Eina_Bool bool;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "b", &bool))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bool != bool_value) printf("Error on bool\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_byte(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
unsigned char byte;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "y", &byte))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (byte != byte_value) printf("Error on byte\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_uint32(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
unsigned int uint32;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "u", &uint32))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (uint32 != uint32_value) printf("Error on uint32\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_int32(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
int int32;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "i", &int32))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (int32 != (int)int32_value) printf("Error on int32\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_int16(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
short int int16;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "n", &int16))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (int16 != (short int)int16_value) printf("Error on int16\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_double(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
double d;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "d", &d))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (d != double_value) printf("Error on double\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_send_string(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
char *str;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "s", &str))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(str, string_value)) printf("Error on string\n");
|
||||
else test();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_async_test(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
char *str;
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "s", &str))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
EDBus_Object *obj;
|
||||
EDBus_Proxy *proxy;
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
obj = edbus_object_get(conn, BUS, PATH);
|
||||
proxy = edbus_proxy_get(obj, INTERFACE);
|
||||
edbus_proxy_signal_handler_add(proxy, "Alive", _on_alive, NULL);
|
||||
sh = edbus_proxy_signal_handler_add(proxy, "Alive", _on_alive2, NULL);
|
||||
edbus_proxy_signal_handler_add(proxy, "Hello", _on_hello, NULL);
|
||||
|
||||
edbus_proxy_call(proxy, "SendBool", _on_send_bool, NULL, -1, "b", bool_value);
|
||||
edbus_proxy_call(proxy, "SendByte", _on_send_byte, NULL, -1, "y", byte_value);
|
||||
edbus_proxy_call(proxy, "SendUint32", _on_send_uint32, NULL, -1, "u", uint32_value);
|
||||
edbus_proxy_call(proxy, "SendInt32", _on_send_int32, NULL, -1, "i", int32_value);
|
||||
edbus_proxy_call(proxy, "SendInt16", _on_send_int16, NULL, -1, "n", int16_value);
|
||||
edbus_proxy_call(proxy, "SendDouble", _on_send_double, NULL, -1, "d", double_value);
|
||||
edbus_proxy_call(proxy, "SendString", _on_send_string, NULL, -1, "s", string_value);
|
||||
edbus_proxy_call(proxy, "AsyncTest", _on_async_test, NULL, -1, "");
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
#define BUS "com.profusion"
|
||||
#define PATH "/com/profusion/Test"
|
||||
#define IFACE "com.profusion.Test"
|
||||
|
||||
EDBus_Connection *conn;
|
||||
|
||||
static Eina_Bool
|
||||
_timer1_cb(void *data)
|
||||
{
|
||||
printf("\n## ecore_main_loop_quit()\n");
|
||||
ecore_main_loop_quit();
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_plus_one(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
int num2 = 0;
|
||||
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
printf("Message error\n\n");
|
||||
return;
|
||||
}
|
||||
if (!edbus_message_arguments_get(msg, "i", &num2))
|
||||
{
|
||||
printf("Error getting arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("on_plus_one() %d\n", num2);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property_resp2(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname;
|
||||
const char *errmsg;
|
||||
|
||||
printf("set_property_resp2()\n");
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
printf("Message error %s - %s\n\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_property_resp2(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Proxy *proxy = data;
|
||||
EDBus_Message_Iter *variant = NULL;
|
||||
char *type;
|
||||
char *resp2;
|
||||
const char *errname;
|
||||
const char *errmsg;
|
||||
|
||||
printf("get_property_resp2()\n");
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
printf("Message error %s - %s\n\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
if (!edbus_message_arguments_get(msg, "v", &variant))
|
||||
{
|
||||
printf("Error getting arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
type = edbus_message_iter_signature_get(variant);
|
||||
if (type[1])
|
||||
{
|
||||
printf("It is a complex type, not handle yet.\n\n");
|
||||
return;
|
||||
}
|
||||
if (type[0] != 's')
|
||||
{
|
||||
printf("Expected type is string.\n\n");
|
||||
return;
|
||||
}
|
||||
if (!edbus_message_iter_arguments_get(variant, "s", &resp2))
|
||||
{
|
||||
printf("error in edbus_message_iter_arguments_get()\n\n");
|
||||
return;
|
||||
}
|
||||
printf("resp2=%s\n", resp2);
|
||||
free(type);
|
||||
|
||||
edbus_proxy_property_set(proxy, "Resp2", 's', "lalala", set_property_resp2, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_send_array_int(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Message_Iter *array = NULL;
|
||||
int num;
|
||||
|
||||
printf("on_send_array_int()\n");
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
printf("Message error\n\n");
|
||||
return;
|
||||
}
|
||||
if (!edbus_message_arguments_get(msg, "ai", &array))
|
||||
{
|
||||
printf("Error getting arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (edbus_message_iter_get_and_next(array, 'i', &num))
|
||||
{
|
||||
printf("%d\n", num);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_send_array(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Message_Iter *array = NULL;
|
||||
char *txt = NULL;
|
||||
char *string[10];
|
||||
int i = 0;
|
||||
int z;
|
||||
|
||||
printf("on_send_array()\n");
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
printf("Message error\n\n");
|
||||
return;
|
||||
}
|
||||
if (!edbus_message_arguments_get(msg, "as", &array))
|
||||
{
|
||||
printf("Error getting arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (edbus_message_iter_get_and_next(array, 's', &txt))
|
||||
{
|
||||
string[i] = txt;
|
||||
i++;
|
||||
}
|
||||
|
||||
for (z = 0; z < i; z++)
|
||||
printf("string = %s\n", string[z]);
|
||||
}
|
||||
|
||||
static void
|
||||
on_receive_array_with_size(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname;
|
||||
const char *errmsg;
|
||||
|
||||
printf("on_receive_array_with_size()\n");
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_send_variant(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
printf("on_send_variant()\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
on_receive_array(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname;
|
||||
const char *errmsg;
|
||||
|
||||
printf("on_receive_array()\n");
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
EDBus_Object *test2_obj;
|
||||
EDBus_Proxy *test2_proxy;
|
||||
EDBus_Pending *pending;
|
||||
EDBus_Message_Iter *iter, *array_of_string, *variant;
|
||||
EDBus_Message *msg;
|
||||
int size_of_array = 5;
|
||||
const char *array[5] = { "aaaa", "bbbb", "cccc", "dddd", "eeee" };
|
||||
int i;
|
||||
int plus_one = 24;
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
test2_obj = edbus_object_get(conn, BUS, PATH);
|
||||
test2_proxy = edbus_proxy_get(test2_obj, IFACE);
|
||||
|
||||
msg = edbus_proxy_method_call_new(test2_proxy, "ReceiveArray");
|
||||
iter = edbus_message_iter_get(msg);
|
||||
array_of_string = edbus_message_iter_container_new(iter, 'a',"s");
|
||||
if (!array_of_string) printf("array_of_string == NULL\n\n");
|
||||
for (i = 0; i < 5; i++)
|
||||
edbus_message_iter_append_basic(array_of_string, 's', array[i]);
|
||||
edbus_message_iter_container_close(iter, array_of_string);
|
||||
pending = edbus_proxy_send(test2_proxy, msg, on_receive_array, NULL, -1);
|
||||
if (!pending) printf("Error in edbus_proxy_send()\n\n");
|
||||
edbus_message_unref(msg);
|
||||
|
||||
msg = edbus_proxy_method_call_new(test2_proxy, "ReceiveArrayOfStringIntWithSize");
|
||||
iter = edbus_message_iter_get(msg);
|
||||
if (!edbus_message_iter_arguments_set(iter, "ia(si)", size_of_array, &array_of_string))
|
||||
printf("error on edbus_massage_iterator_arguments_set()\n\n");
|
||||
for (i = 0; i < size_of_array; i++)
|
||||
{
|
||||
EDBus_Message_Iter *struct_of_si;
|
||||
edbus_message_iter_arguments_set(array_of_string, "(si)", &struct_of_si);
|
||||
edbus_message_iter_arguments_set(struct_of_si, "si", array[i], i);
|
||||
edbus_message_iter_container_close(array_of_string, struct_of_si);
|
||||
}
|
||||
edbus_message_iter_container_close(iter, array_of_string);
|
||||
pending = edbus_proxy_send(test2_proxy, msg, on_receive_array_with_size, NULL, -1);
|
||||
edbus_message_unref(msg);
|
||||
|
||||
msg = edbus_proxy_method_call_new(test2_proxy, "SendVariantData");
|
||||
iter = edbus_message_iter_get(msg);
|
||||
variant = edbus_message_iter_container_new(iter, 'v', "s");
|
||||
edbus_message_iter_append_basic(variant, 's', "test");
|
||||
edbus_message_iter_container_close(iter, variant);
|
||||
pending = edbus_proxy_send(test2_proxy, msg, on_send_variant, NULL, -1);
|
||||
edbus_message_unref(msg);
|
||||
|
||||
pending = edbus_proxy_call(test2_proxy, "SendArrayInt", on_send_array_int, NULL,
|
||||
-1 , "");
|
||||
|
||||
pending = edbus_proxy_call(test2_proxy, "SendArray", on_send_array, NULL,
|
||||
-1 , "");
|
||||
|
||||
pending = edbus_proxy_call(test2_proxy, "PlusOne", on_plus_one, NULL,
|
||||
-1 , "i", plus_one);
|
||||
|
||||
pending = edbus_proxy_property_get(test2_proxy, "Resp2", get_property_resp2, test2_proxy);
|
||||
|
||||
ecore_timer_add(5, _timer1_cb, NULL);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,351 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
#define BUS "com.profusion"
|
||||
#define PATH "/com/profusion/Test"
|
||||
#define IFACE "com.profusion.Test"
|
||||
|
||||
char *resp2;
|
||||
|
||||
static EDBus_Message *
|
||||
_receive_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
EDBus_Message_Iter *array;
|
||||
char *txt;
|
||||
|
||||
printf("receiveArray\n");
|
||||
if (!edbus_message_arguments_get(msg, "as", &array))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return reply;
|
||||
}
|
||||
|
||||
while (edbus_message_iter_get_and_next(array, 's', &txt))
|
||||
printf("%s\n", txt);
|
||||
|
||||
printf("\n");
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_receive_array_of_string_int_with_size(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
EDBus_Message_Iter *array;
|
||||
EDBus_Message_Iter *struct_si;
|
||||
int size, i = 0;
|
||||
|
||||
printf("receiveArrayOfStringIntWithSize\n");
|
||||
if (!edbus_message_arguments_get(msg, "ia(si)", &size, &array))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return reply;
|
||||
}
|
||||
|
||||
while (edbus_message_iter_get_and_next(array, 'r', &struct_si))
|
||||
{
|
||||
char *txt;
|
||||
char num;
|
||||
|
||||
if (!edbus_message_iter_arguments_get(struct_si, "si", &txt, &num))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return reply;
|
||||
}
|
||||
printf("%s | %d\n", txt, num);
|
||||
i++;
|
||||
}
|
||||
printf("size in msg %d | size read %d\n", size, i);
|
||||
printf("\n");
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_variant(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
EDBus_Message_Iter *variant;
|
||||
char *type;
|
||||
|
||||
printf("sendVariantData\n");
|
||||
if (!edbus_message_arguments_get(msg, "v", &variant))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return reply;
|
||||
}
|
||||
|
||||
type = edbus_message_iter_signature_get(variant);
|
||||
if (type[1] || type[0] == 'v')
|
||||
{
|
||||
printf("It is a complex type, not handle yet.\n");
|
||||
free(type);
|
||||
return reply;
|
||||
}
|
||||
|
||||
switch (type[0])
|
||||
{
|
||||
case 's':
|
||||
case 'o':
|
||||
{
|
||||
char *txt;
|
||||
edbus_message_iter_arguments_get(variant, type, &txt);
|
||||
printf("type = %c value = %s\n", type[0], txt);
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
{
|
||||
int num;
|
||||
edbus_message_iter_arguments_get(variant, type, &num);
|
||||
printf("type = %c value = %d\n", type[0], num);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("Unhandled type\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
free(type);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_array_int(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
EDBus_Message_Iter *iter, *array;
|
||||
int i;
|
||||
|
||||
printf("sendArrayInt\n\n");
|
||||
|
||||
iter = edbus_message_iter_get(reply);
|
||||
array = edbus_message_iter_container_new(iter, 'a', "i");
|
||||
for (i = 0; i < 5; i++)
|
||||
edbus_message_iter_arguments_set(array, "i", i);
|
||||
edbus_message_iter_container_close(iter, array);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
EDBus_Message_Iter *iter, *array;
|
||||
const char *array_string[5] = {"qqqq", "wwwww", "eeeeee", "rrrrr", "ttttt"};
|
||||
int i;
|
||||
|
||||
printf("sendArray\n\n");
|
||||
|
||||
iter = edbus_message_iter_get(reply);
|
||||
array = edbus_message_iter_container_new(iter, 'a', "s");
|
||||
for (i = 0; i < 5; i++)
|
||||
edbus_message_iter_arguments_set(array, "s", array_string[i]);
|
||||
edbus_message_iter_container_close(iter, array);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_plus_one(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
int num;
|
||||
|
||||
printf("plusOne\n\n");
|
||||
if (!edbus_message_arguments_get(msg, "i", &num))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return reply;
|
||||
}
|
||||
num++;
|
||||
edbus_message_arguments_set(reply, "i", num);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_properties_get(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply;
|
||||
char *interface, *property;
|
||||
EDBus_Message_Iter *variant, *iter;
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "ss", &interface, &property))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(interface, IFACE))
|
||||
{
|
||||
reply = edbus_message_error_new(msg,
|
||||
"org.freedesktop.DBus.Error.UnknownInterface",
|
||||
"Interface not found.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (strcmp(property, "Resp2"))
|
||||
{
|
||||
reply = edbus_message_error_new(msg,
|
||||
"org.freedesktop.DBus.Error.UnknownProperty",
|
||||
"Property not found.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
reply = edbus_message_method_return_new(msg);
|
||||
iter = edbus_message_iter_get(reply);
|
||||
variant = edbus_message_iter_container_new(iter, 'v', "s");
|
||||
edbus_message_iter_append_basic(variant, 's', resp2);
|
||||
printf("get %s\n", resp2);
|
||||
edbus_message_iter_container_close(iter, variant);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_properties_set(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply;
|
||||
char *interface, *property, *type, *txt;
|
||||
EDBus_Message_Iter *variant;
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "ssv", &interface, &property, &variant))
|
||||
{
|
||||
printf("Error on edbus_message_arguments_get()\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(interface, IFACE))
|
||||
{
|
||||
reply = edbus_message_error_new(msg,
|
||||
"org.freedesktop.DBus.Error.UnknownInterface",
|
||||
"Interface not found.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (strcmp(property, "Resp2"))
|
||||
{
|
||||
reply = edbus_message_error_new(msg,
|
||||
"org.freedesktop.DBus.Error.UnknownProperty",
|
||||
"Property not found.");
|
||||
return reply;
|
||||
}
|
||||
|
||||
type = edbus_message_iter_signature_get(variant);
|
||||
|
||||
if (type[0] != 's')
|
||||
{
|
||||
reply = edbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidSignature",
|
||||
"Invalid type.");
|
||||
free(type);
|
||||
return reply;
|
||||
}
|
||||
|
||||
reply = edbus_message_method_return_new(msg);
|
||||
edbus_message_iter_arguments_get(variant, "s", &txt);
|
||||
free(type);
|
||||
free(resp2);
|
||||
resp2 = strdup(txt);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static const EDBus_Method methods[] = {
|
||||
{
|
||||
"ReceiveArray", EDBUS_ARGS({"as", "array_of_strings"}),
|
||||
EDBUS_ARGS({"", ""}), _receive_array, 0
|
||||
},
|
||||
{
|
||||
"ReceiveArrayOfStringIntWithSize",
|
||||
EDBUS_ARGS({"i", "size_of_array"}, {"a(si)", "array"}),
|
||||
EDBUS_ARGS({"", ""}), _receive_array_of_string_int_with_size, 0
|
||||
},
|
||||
{
|
||||
"SendVariantData", EDBUS_ARGS({"v", "variant_data"}),
|
||||
EDBUS_ARGS({"", ""}), _send_variant, 0
|
||||
},
|
||||
{
|
||||
"SendArrayInt", EDBUS_ARGS({"", ""}),
|
||||
EDBUS_ARGS({"ai", "array_of_int"}), _send_array_int, 0
|
||||
},
|
||||
{
|
||||
"SendArray", EDBUS_ARGS({"", ""}), EDBUS_ARGS({"as", "array_string"}),
|
||||
_send_array, 0
|
||||
},
|
||||
{
|
||||
"PlusOne", EDBUS_ARGS({"i", "integer"}),
|
||||
EDBUS_ARGS({"i", "integer_plus_one"}), _plus_one, 0
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static const EDBus_Method properties_methods[] = {
|
||||
{
|
||||
"Get", EDBUS_ARGS({"s", "interface"}, {"s", "property"}),
|
||||
EDBUS_ARGS({"v", "value"}), _properties_get, 0
|
||||
},
|
||||
{
|
||||
"Set", EDBUS_ARGS({"s", "interface"}, {"s", "property"}, {"v", "value"}),
|
||||
EDBUS_ARGS({"", ""}), _properties_set, 0
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void
|
||||
on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Connection *conn = data;
|
||||
unsigned int flag;
|
||||
|
||||
resp2 = malloc(sizeof(char) * 5);
|
||||
strcpy(resp2, "test");
|
||||
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
printf("error on on_name_request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "u", &flag))
|
||||
{
|
||||
printf("error geting arguments on on_name_request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(flag & EDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER))
|
||||
{
|
||||
printf("error name already in use\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edbus_service_interface_register(conn, PATH, IFACE, methods, NULL);
|
||||
edbus_service_interface_register(conn, PATH, EDBUS_FDO_INTERFACE_PROPERTIES, properties_methods, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, on_name_request, conn);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
free(resp2);
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
static void
|
||||
on_services_get(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Message_Iter *array, *entry;
|
||||
const char *errname, *errmsg;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "a(oa{sv})", &array))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get array\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (edbus_message_iter_get_and_next(array, 'r', &entry))
|
||||
{
|
||||
EDBus_Message_Iter *properties, *dict_entry;
|
||||
const char *path;
|
||||
|
||||
if (!edbus_message_iter_arguments_get(entry, "oa{sv}", &path, &properties))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get entry contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("service: %s\n", path);
|
||||
|
||||
while (edbus_message_iter_get_and_next(properties, 'e', &dict_entry))
|
||||
{
|
||||
EDBus_Message_Iter *variant;
|
||||
const char *key;
|
||||
|
||||
if (!edbus_message_iter_arguments_get(dict_entry, "sv", &key,
|
||||
&variant))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Error: could not get property contents\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\t%s: type %s\n", key,
|
||||
edbus_message_iter_signature_get(variant));
|
||||
|
||||
/* TODO: get the value from variant */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
EDBus_Object *obj;
|
||||
EDBus_Proxy *manager;
|
||||
EDBus_Pending *pending;
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
if (!conn)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get system bus\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
obj = edbus_object_get(conn, "net.connman", "/");
|
||||
if (!obj)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get object\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
manager = edbus_proxy_get(obj, "net.connman.Manager");
|
||||
if (!manager)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get proxy\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pending = edbus_proxy_call(manager, "GetServices", on_services_get, NULL,
|
||||
-1, "");
|
||||
|
||||
if (!pending)
|
||||
{
|
||||
fprintf(stderr, "Error: could not call\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_proxy_unref(manager);
|
||||
edbus_object_unref(obj);
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
static void
|
||||
on_dial(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
const char *call_path;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
fprintf(stderr, "Error: %s %s\n", errname, errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "o", &call_path))
|
||||
{
|
||||
fprintf(stderr, "Error: could not get call path\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("dialed! call path: %s\n", call_path);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
EDBus_Object *obj;
|
||||
EDBus_Proxy *manager;
|
||||
EDBus_Pending *pending;
|
||||
const char *number, *hide_callerid;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage:\n\t%s <number> [hide_callerid]\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
number = argv[1];
|
||||
hide_callerid = (argc > 2) ? argv[2] : "";
|
||||
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
if (!conn)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get system bus\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
obj = edbus_object_get(conn, "org.ofono", "/");
|
||||
if (!obj)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get object\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
manager = edbus_proxy_get(obj, "org.ofono.Manager");
|
||||
if (!manager)
|
||||
{
|
||||
fprintf(stderr, "Error: could not get proxy\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pending = edbus_proxy_call(manager, "Dial", on_dial, NULL,
|
||||
-1, "ss", number, hide_callerid);
|
||||
if (!pending)
|
||||
{
|
||||
fprintf(stderr, "Error: could not call\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_proxy_unref(manager);
|
||||
edbus_object_unref(obj);
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
#include "EDBus.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
#define BUS "org.Enlightenment"
|
||||
#define PATH "/org/enlightenment"
|
||||
#define INTERFACE "org.enlightenment.Test"
|
||||
|
||||
EDBus_Connection *conn;
|
||||
|
||||
static EDBus_Message *
|
||||
_hello(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(message);
|
||||
edbus_message_arguments_set(reply, "s", "Hello World");
|
||||
printf("Hello\n");
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_quit(const EDBus_Service_Interface *iface, const EDBus_Message *message)
|
||||
{
|
||||
printf("Quit\n");
|
||||
ecore_main_loop_quit();
|
||||
return edbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
TEST_SIGNAL_ALIVE = 0,
|
||||
TEST_SIGNAL_HELLO
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
send_signal_alive(void *data)
|
||||
{
|
||||
EDBus_Service_Interface *iface = data;
|
||||
edbus_service_signal_emit(iface, TEST_SIGNAL_ALIVE);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
send_signal_hello(void *data)
|
||||
{
|
||||
EDBus_Service_Interface *iface = data;
|
||||
edbus_service_signal_emit(iface, TEST_SIGNAL_HELLO, "Hello World");
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_bool(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
Eina_Bool bool;
|
||||
if (!edbus_message_arguments_get(msg, "b", &bool))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "b", bool);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_byte(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
unsigned char byte;
|
||||
if (!edbus_message_arguments_get(msg, "y", &byte))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "y", byte);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_uint32(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
unsigned int uint32;
|
||||
if (!edbus_message_arguments_get(msg, "u", &uint32))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "u", uint32);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_int32(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
int int32;
|
||||
if (!edbus_message_arguments_get(msg, "i", &int32))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "i", int32);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_int16(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
short int int16;
|
||||
if (!edbus_message_arguments_get(msg, "n", &int16))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "n", int16);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_double(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
double d;
|
||||
if (!edbus_message_arguments_get(msg, "d", &d))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "d", d);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_send_string(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
char *txt;
|
||||
if (!edbus_message_arguments_get(msg, "s", &txt))
|
||||
printf("edbus_message_arguments_get() error\n");
|
||||
edbus_message_arguments_set(reply, "s", txt);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_resp_async(void *data)
|
||||
{
|
||||
EDBus_Message *msg = data;
|
||||
edbus_message_arguments_set(msg, "s", "Async test ok");
|
||||
edbus_connection_send(conn, msg, NULL, NULL, -1);
|
||||
edbus_message_unref(msg);
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
_async_test(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||
printf("Received a call to AsyncTest.\n");
|
||||
printf("Response will be send in 5 seconds.\n");
|
||||
ecore_timer_add (5, _resp_async, reply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const EDBus_Signal signals[] = {
|
||||
[TEST_SIGNAL_ALIVE] = {"Alive", EDBUS_ARGS({ NULL, NULL }), 0},
|
||||
[TEST_SIGNAL_HELLO] = {"Hello", EDBUS_ARGS({ "s", "message" }), 0},
|
||||
{ }
|
||||
};
|
||||
|
||||
static const EDBus_Method methods[] = {
|
||||
{
|
||||
"Hello", EDBUS_ARGS({"", ""}), EDBUS_ARGS({"s", "message"}),
|
||||
_hello, 0
|
||||
},
|
||||
{
|
||||
"Quit", EDBUS_ARGS({"", ""}), EDBUS_ARGS({"", ""}),
|
||||
_quit, EDBUS_METHOD_FLAG_DEPRECATED
|
||||
},
|
||||
{ "SendBool", EDBUS_ARGS({"b", "bool"}), EDBUS_ARGS({"b", "bool"}),
|
||||
_send_bool, 0
|
||||
},
|
||||
{ "SendByte", EDBUS_ARGS({"y", "byte"}), EDBUS_ARGS({"y", "byte"}),
|
||||
_send_byte, 0
|
||||
},
|
||||
{ "SendUint32", EDBUS_ARGS({"u", "uint32"}), EDBUS_ARGS({"u", "uint32"}),
|
||||
_send_uint32, 0
|
||||
},
|
||||
{ "SendInt32", EDBUS_ARGS({"i", "int32"}), EDBUS_ARGS({"i", "int32"}),
|
||||
_send_int32, 0
|
||||
},
|
||||
{ "SendInt16", EDBUS_ARGS({"n", "int16"}), EDBUS_ARGS({"n", "int16"}),
|
||||
_send_int16, 0
|
||||
},
|
||||
{ "SendDouble", EDBUS_ARGS({"d", "double"}), EDBUS_ARGS({"d", "double"}),
|
||||
_send_double, 0
|
||||
},
|
||||
{ "SendString", EDBUS_ARGS({"s", "string"}), EDBUS_ARGS({"s", "string"}),
|
||||
_send_string, 0
|
||||
},
|
||||
{ "AsyncTest", EDBUS_ARGS({"", ""}), EDBUS_ARGS({"s", "text"}),
|
||||
_async_test, 0
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void
|
||||
on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Service_Interface *iface;
|
||||
unsigned int flag;
|
||||
|
||||
if (edbus_message_error_get(msg, NULL, NULL))
|
||||
{
|
||||
printf("error on on_name_request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edbus_message_arguments_get(msg, "u", &flag))
|
||||
{
|
||||
printf("error geting arguments on on_name_request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(flag & EDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER))
|
||||
{
|
||||
printf("error name already in use\n");
|
||||
return;
|
||||
}
|
||||
|
||||
iface = edbus_service_interface_register(conn, PATH, INTERFACE, methods,
|
||||
signals);
|
||||
ecore_timer_add(5, send_signal_alive, iface);
|
||||
ecore_timer_add(6, send_signal_hello, iface);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
ecore_init();
|
||||
edbus_init();
|
||||
|
||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
|
||||
on_name_request, NULL);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
edbus_connection_unref(conn);
|
||||
|
||||
edbus_shutdown();
|
||||
ecore_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
#ifndef EDBUS_H
|
||||
#define EDBUS_H
|
||||
|
||||
#include <Eina.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_EDBUS_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_EDBUS_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Core Core
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define EDBUS_VERSION_MAJOR 1
|
||||
#define EDBUS_VERSION_MINOR 6
|
||||
|
||||
#define EDBUS_FDO_BUS "org.freedesktop.DBus"
|
||||
#define EDBUS_FDO_PATH "/org/freedesktop/DBus"
|
||||
#define EDBUS_FDO_INTERFACE EDBUS_FDO_BUS
|
||||
#define EDBUS_FDO_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||
|
||||
typedef struct _EDBus_Version
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int revision;
|
||||
} EDBus_Version;
|
||||
|
||||
EAPI extern const EDBus_Version * edbus_version;
|
||||
|
||||
/**
|
||||
* @brief Initialize edbus.
|
||||
*
|
||||
* @return 1 or greater on success, 0 otherwise
|
||||
*/
|
||||
EAPI int edbus_init(void);
|
||||
/**
|
||||
* @brief Shutdown edbus.
|
||||
*
|
||||
* @return 0 if e_dbus shuts down, greater than 0 otherwise.
|
||||
*/
|
||||
EAPI int edbus_shutdown(void);
|
||||
|
||||
typedef void (*EDBus_Free_Cb)(void *data, const void *deadptr);
|
||||
|
||||
/**
|
||||
* @typedef EDBus_Connection
|
||||
*
|
||||
* Represents a connection of one the type of connection with the DBus daemon.
|
||||
*/
|
||||
typedef struct _EDBus_Connection EDBus_Connection;
|
||||
/**
|
||||
* @typedef EDBus_Object
|
||||
*
|
||||
* Represents a object path already attach with bus name or unique id.
|
||||
*/
|
||||
typedef struct _EDBus_Object EDBus_Object;
|
||||
/**
|
||||
* @typedef EDBus_Proxy
|
||||
*
|
||||
* Represents a interface of a object path.
|
||||
*/
|
||||
typedef struct _EDBus_Proxy EDBus_Proxy;
|
||||
/**
|
||||
* @typedef EDBus_Message
|
||||
*
|
||||
* Represents the way of how the data is send and received in DBus.
|
||||
*/
|
||||
typedef struct _EDBus_Message EDBus_Message;
|
||||
/**
|
||||
* @typedef EDBus_Message_Iter
|
||||
*
|
||||
* Represents an iterator over a complex message type (array, dict, struct,
|
||||
* or variant). Its life is bound to the message that contains
|
||||
* it. The same applies to the returned data.
|
||||
*/
|
||||
typedef struct _EDBus_Message_Iter EDBus_Message_Iter;
|
||||
/**
|
||||
* @typedef EDBus_Pending
|
||||
*
|
||||
* Represents a message that was been sent but has not yet reached its
|
||||
* destination.
|
||||
*/
|
||||
typedef struct _EDBus_Pending EDBus_Pending;
|
||||
/**
|
||||
* @typedef EDBus_Signal_Handler
|
||||
*
|
||||
* Represents a listener that will listen for signals emitted by other
|
||||
* applications.
|
||||
*/
|
||||
typedef struct _EDBus_Signal_Handler EDBus_Signal_Handler;
|
||||
|
||||
typedef void (*EDBus_Message_Cb)(void *data, const EDBus_Message *msg, EDBus_Pending *pending);
|
||||
typedef void (*EDBus_Signal_Cb)(void *data, const EDBus_Message *msg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "edbus_connection.h"
|
||||
#include "edbus_message.h"
|
||||
#include "edbus_signal_handler.h"
|
||||
#include "edbus_pending.h"
|
||||
#include "edbus_object.h"
|
||||
#include "edbus_proxy.h"
|
||||
#include "edbus_freedesktop.h"
|
||||
#include "edbus_service.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,144 @@
|
|||
#ifndef EDBUS_CONNECTION_H
|
||||
#define EDBUS_CONNECTION_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Conneciton Connection
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
EDBUS_CONNECTION_TYPE_UNKNOWN = 0, /**< sentinel, not a real type */
|
||||
EDBUS_CONNECTION_TYPE_SESSION,
|
||||
EDBUS_CONNECTION_TYPE_SYSTEM,
|
||||
EDBUS_CONNECTION_TYPE_STARTER,
|
||||
EDBUS_CONNECTION_TYPE_LAST /**< sentinel, not a real type */
|
||||
} EDBus_Connection_Type;
|
||||
|
||||
#define EDBUS_TIMEOUT_INFINITE ((int) 0x7fffffff)
|
||||
|
||||
/**
|
||||
* @brief Establish a connection to bus and integrate it with the ecore main
|
||||
* loop.
|
||||
*
|
||||
* @param type type of connection e.g EDBUS_CONNECTION_TYPE_SESSION,
|
||||
* EDBUS_CONNECTION_TYPE_SYSTEM or EDBUS_CONNECTION_TYPE_STARTER
|
||||
*
|
||||
* @return connection with bus
|
||||
*/
|
||||
EAPI EDBus_Connection *edbus_connection_get(EDBus_Connection_Type type);
|
||||
|
||||
/**
|
||||
* @brief Increment connection reference count.
|
||||
*
|
||||
* @param conn The given EDBus_Connection object to reference
|
||||
*/
|
||||
EAPI EDBus_Connection *edbus_connection_ref(EDBus_Connection *conn) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Decrement object reference count.
|
||||
*
|
||||
* If reference count reaches 0, the connection to bus will be dropped and all
|
||||
* its children will be invalidated.
|
||||
*/
|
||||
EAPI void edbus_connection_unref(EDBus_Connection *conn) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when connection is freed
|
||||
*
|
||||
* @param conn The connection object to add the callback to.
|
||||
* @param cb callback to be called
|
||||
* @param data passed to callback
|
||||
*/
|
||||
EAPI void edbus_connection_cb_free_add(EDBus_Connection *conn, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_connection_cb_free_add().
|
||||
*/
|
||||
EAPI void edbus_connection_cb_free_del(EDBus_Connection *conn, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Set an attached data pointer to an object with a given string key.
|
||||
*
|
||||
* @param conn The connection object to store data to
|
||||
* @param key to identify data
|
||||
* @param data data that will be stored
|
||||
*/
|
||||
EAPI void edbus_connection_data_set(EDBus_Connection *conn, const char *key, const void *data) EINA_ARG_NONNULL(1, 2, 3);
|
||||
|
||||
/**
|
||||
* @brief Get data stored in connection.
|
||||
*
|
||||
* @param conn connection where data are stored
|
||||
* @param key that identify data
|
||||
*
|
||||
* @return pointer to data if found otherwise NULL
|
||||
*/
|
||||
EAPI void *edbus_connection_data_get(const EDBus_Connection *conn, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Del data stored in connection.
|
||||
*
|
||||
* @param conn connection where data are stored
|
||||
* @param key that identify data
|
||||
*
|
||||
* @return pointer to data if found otherwise NULL
|
||||
*/
|
||||
EAPI void *edbus_connection_data_del(EDBus_Connection *conn, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EDBUS_CONNECTION_EVENT_OBJECT_ADDED = 0,
|
||||
EDBUS_CONNECTION_EVENT_OBJECT_REMOVED,
|
||||
//EDBUS_CONNECTION_EVENT_NAME_OWNER_CHANGED,
|
||||
EDBUS_CONNECTION_EVENT_DEL,
|
||||
EDBUS_CONNECTION_EVENT_LAST /**< sentinel, not a real event type */
|
||||
} EDBus_Connection_Event_Type;
|
||||
|
||||
typedef struct _EDBus_Connection_Event_Object_Added
|
||||
{
|
||||
const char *path;
|
||||
EDBus_Object *object;
|
||||
} EDBus_Connection_Event_Object_Added;
|
||||
|
||||
typedef struct _EDBus_Connection_Event_Object_Removed
|
||||
{
|
||||
const char *path;
|
||||
} EDBus_Connection_Event_Object_Removed;
|
||||
|
||||
typedef struct _EDBus_Connection_Event_Name_Owner_Changed
|
||||
{
|
||||
const char *name;
|
||||
const char *old_id;
|
||||
const char *new_id;
|
||||
} EDBus_Connection_Event_Name_Owner_Changed;
|
||||
|
||||
typedef void (*EDBus_Connection_Event_Cb)(void *data, EDBus_Connection *conn, void *event_info);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when occurs a event of the
|
||||
* type passed.
|
||||
*/
|
||||
EAPI void edbus_connection_event_callback_add(EDBus_Connection *conn, EDBus_Connection_Event_Type type, EDBus_Connection_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_connection_event_callback_add().
|
||||
*/
|
||||
EAPI void edbus_connection_event_callback_del(EDBus_Connection *conn, EDBus_Connection_Event_Type type, EDBus_Connection_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
|
||||
/**
|
||||
* @brief Send a message.
|
||||
*
|
||||
* @param conn the connection where the message will be send
|
||||
* @param msg message that will be send
|
||||
* @param cb if msg is a method call a callback should be passed
|
||||
* to be execute when response arrive
|
||||
* @param cb_data data passed to callback
|
||||
* @param timeout timeout in milliseconds, -1 to default internal value or
|
||||
* EDBUS_TIMEOUT_INFINITE for no timeout
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_connection_send(EDBus_Connection *conn, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
static EDBus_Proxy *
|
||||
get_freedesktop_proxy(EDBus_Connection *conn)
|
||||
{
|
||||
EDBus_Object *freedesktop_obj;
|
||||
|
||||
freedesktop_obj = edbus_object_get(conn, EDBUS_FDO_BUS, EDBUS_FDO_PATH);
|
||||
return edbus_proxy_get(freedesktop_obj, EDBUS_FDO_INTERFACE);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_name_request(EDBus_Connection *conn, const char *name, unsigned int flags, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "RequestName", cb,
|
||||
cb_data, -1, "su", name, flags);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_name_release(EDBus_Connection *conn, const char *name, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "ReleaseName", cb,
|
||||
cb_data, -1, "s", name);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_name_owner_get(EDBus_Connection *conn, const char *name, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "GetNameOwner", cb,
|
||||
cb_data, -1, "s", name);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_name_owner_has(EDBus_Connection *conn, const char *name, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "NameHasOwner", cb,
|
||||
cb_data, -1, "s", name);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_names_list(EDBus_Connection *conn, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "ListNames", cb,
|
||||
cb_data, -1, "");
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_names_activatable_list(EDBus_Connection *conn, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "ListActivatableNames", cb,
|
||||
cb_data, -1, "");
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_name_start(EDBus_Connection *conn, const char *name, unsigned int flags, EDBus_Message_Cb cb, const void *cb_data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
return edbus_proxy_call(get_freedesktop_proxy(conn), "StartServiceByName", cb,
|
||||
cb_data, -1, "su", name, flags);
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
#ifndef EDBUS_FREEDESKTOP_H
|
||||
#define EDBUS_FREEDESKTOP_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Basic Basic Methods
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define EDBUS_NAME_REQUEST_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
|
||||
#define EDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
|
||||
#define EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */
|
||||
|
||||
/* Replies to request for a name */
|
||||
#define EDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */
|
||||
#define EDBUS_NAME_REQUEST_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */
|
||||
#define EDBUS_NAME_REQUEST_REPLY_EXISTS 3 /**< Service is already in the queue */
|
||||
#define EDBUS_NAME_REQUEST_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */
|
||||
|
||||
EAPI EDBus_Pending *edbus_name_request(EDBus_Connection *conn, const char *bus, unsigned int flags, EDBus_Message_Cb cb, const void *cb_data);
|
||||
|
||||
/* Replies to releasing a name */
|
||||
#define EDBUS_NAME_RELEASE_REPLY_RELEASED 1 /**< Service was released from the given name */
|
||||
#define EDBUS_NAME_RELEASE_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
|
||||
#define EDBUS_NAME_RELEASE_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
|
||||
|
||||
EAPI EDBus_Pending *edbus_name_release(EDBus_Connection *conn, const char *bus, EDBus_Message_Cb cb, const void *cb_data);
|
||||
EAPI EDBus_Pending *edbus_name_owner_get(EDBus_Connection *conn, const char *bus, EDBus_Message_Cb cb, const void *cb_data);
|
||||
EAPI EDBus_Pending *edbus_name_owner_has(EDBus_Connection *conn, const char *bus, EDBus_Message_Cb cb, const void *cb_data);
|
||||
EAPI EDBus_Pending *edbus_names_list(EDBus_Connection *conn, EDBus_Message_Cb cb, const void *cb_data);
|
||||
EAPI EDBus_Pending *edbus_names_activatable_list(EDBus_Connection *conn, EDBus_Message_Cb cb, const void *cb_data);
|
||||
|
||||
/* Replies to service starts */
|
||||
#define EDBUS_NAME_START_REPLY_SUCCESS 1 /**< Service was auto started */
|
||||
#define EDBUS_NAME_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
|
||||
|
||||
EAPI EDBus_Pending *edbus_name_start(EDBus_Connection *conn, const char *bus, unsigned int flags, EDBus_Message_Cb cb, const void *cb_data);
|
||||
|
||||
typedef void (*EDBus_Name_Owner_Changed_Cb)(void *data, const char *bus, const char *old_id, const char *new_id);
|
||||
|
||||
EAPI void edbus_name_owner_changed_callback_add(EDBus_Connection *conn, const char *bus, EDBus_Name_Owner_Changed_Cb cb, const void *cb_data);
|
||||
EAPI void edbus_name_owner_changed_callback_del(EDBus_Connection *conn, const char *bus, EDBus_Name_Owner_Changed_Cb cb, const void *cb_data);
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_FDO_Peer org.freedesktop.DBus.Peer
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_object_peer_ping(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1);
|
||||
EAPI EDBus_Pending *edbus_object_peer_machine_id_get(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_FDO_Introspectable org.freedesktop.DBus.Introspectable
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_object_introspect(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_FDO_Properties org.freedesktop.DBus.Properties
|
||||
*
|
||||
* Whenever edbus_proxy_properties_monitor() is called on a
|
||||
* proxy to an object it will automatically listen for properties
|
||||
* changed on that interface, emitting events with
|
||||
* edbus_object_event_type being
|
||||
* #EDBUS_OBJECT_EVENT_PROPERTY_CHANGED and
|
||||
* #EDBUS_OBJECT_EVENT_PROPERTY_REMOVED, as well as
|
||||
* #EDBUS_PROXY_EVENT_PROPERTY_CHANGED and
|
||||
* #EDBUS_PROXY_EVENT_PROPERTY_REMOVED.
|
||||
*
|
||||
* One may manually query the properties
|
||||
* edbus_proxy_property_get() and edbus_proxy_property_get_all()
|
||||
* or listen for changes with
|
||||
* edbus_proxy_properties_changed_callback_add().
|
||||
*
|
||||
* To set property call edbus_proxy_property_set().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
EAPI void edbus_proxy_properties_monitor(EDBus_Proxy *proxy);
|
||||
|
||||
EAPI EDBus_Pending *edbus_proxy_property_get(EDBus_Proxy *proxy, const char *name, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2, 3);
|
||||
EAPI EDBus_Pending *edbus_proxy_property_set(EDBus_Proxy *proxy, const char *name, char type, const void *value, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2, 4);
|
||||
EAPI EDBus_Pending *edbus_proxy_property_get_all(EDBus_Proxy *proxy, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI EDBus_Signal_Handler *edbus_proxy_properties_changed_callback_add(EDBus_Proxy *proxy, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_FDO_ObjectManager org.freedesktop.DBus.ObjectManager
|
||||
*
|
||||
* Whenever edbus_object_managed_objects_monitor() is called on an
|
||||
* object it will start listening for children being added or
|
||||
* interfaces changing on the object itself. It will then emit
|
||||
* events with edbus_object_event_type being
|
||||
* #EDBUS_OBJECT_EVENT_IFACE_ADDED,
|
||||
* #EDBUS_OBJECT_EVENT_IFACE_REMOVED,
|
||||
* #EDBUS_OBJECT_EVENT_PROPERTY_CHANGED and
|
||||
* #EDBUS_OBJECT_EVENT_PROPERTY_REMOVED.
|
||||
*
|
||||
* One may manually query the managed objects with
|
||||
* edbus_object_managed_objects_get() and listen for changes with
|
||||
* edbus_object_interfaces_added_callback_add() and
|
||||
* edbus_object_interfaces_removed_callback_add().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
EAPI void edbus_object_properties_monitor(EDBus_Object *obj);
|
||||
|
||||
EAPI EDBus_Pending *edbus_object_managed_objects_get(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI EDBus_Signal_Handler *edbus_object_interfaces_added_callback_add(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI EDBus_Signal_Handler *edbus_object_interfaces_removed_callback_add(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,792 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
#include <dbus/dbus.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* TODO: mempool of EDBus_Message and EDBus_Message_Iter */
|
||||
|
||||
#define EDBUS_MESSAGE_CHECK(msg) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(msg); \
|
||||
if (!EINA_MAGIC_CHECK(msg, EDBUS_MESSAGE_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(msg, EDBUS_MESSAGE_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN(msg->refcount <= 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_MESSAGE_CHECK_RETVAL(msg, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, retval); \
|
||||
if (!EINA_MAGIC_CHECK(msg, EDBUS_MESSAGE_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(msg, EDBUS_MESSAGE_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(msg->refcount <= 0, retval); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_MESSAGE_ITERATOR_CHECK(iter) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(iter); \
|
||||
if (!EINA_MAGIC_CHECK(iter, EDBUS_MESSAGE_ITERATOR_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(iter, EDBUS_MESSAGE_ITERATOR_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(iter, retval); \
|
||||
if (!EINA_MAGIC_CHECK(iter, EDBUS_MESSAGE_ITERATOR_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(iter, EDBUS_MESSAGE_ITERATOR_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
static Eina_Bool append_basic(char type, va_list *vl, DBusMessageIter *iter);
|
||||
|
||||
Eina_Bool
|
||||
edbus_message_init(void)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_message_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static EDBus_Message_Iter *
|
||||
_message_iterator_new(Eina_Bool writable)
|
||||
{
|
||||
EDBus_Message_Iter *iter;
|
||||
|
||||
iter = calloc(1, sizeof(EDBus_Message_Iter));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
|
||||
EINA_MAGIC_SET(iter, EDBUS_MESSAGE_ITERATOR_MAGIC);
|
||||
iter->writable = writable;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
EDBus_Message *edbus_message_new(Eina_Bool writable)
|
||||
{
|
||||
EDBus_Message *msg = calloc(1, sizeof(EDBus_Message));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
EINA_MAGIC_SET(msg, EDBUS_MESSAGE_MAGIC);
|
||||
msg->refcount = 1;
|
||||
|
||||
msg->iterator = _message_iterator_new(writable);
|
||||
EINA_SAFETY_ON_NULL_GOTO(msg->iterator, fail);
|
||||
|
||||
return msg;
|
||||
|
||||
fail:
|
||||
edbus_message_unref(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_message_method_call_new(const char *dest, const char *path, const char *iface, const char *method)
|
||||
{
|
||||
EDBus_Message *msg;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL);
|
||||
|
||||
msg = edbus_message_new(EINA_TRUE);
|
||||
EINA_SAFETY_ON_NULL_GOTO(msg, fail);
|
||||
|
||||
msg->dbus_msg = dbus_message_new_method_call(dest, path, iface, method);
|
||||
dbus_message_iter_init_append(msg->dbus_msg, &msg->iterator->dbus_iterator);
|
||||
|
||||
return msg;
|
||||
|
||||
fail:
|
||||
edbus_message_unref(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_message_ref(EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
DBG("msg=%p, pre-refcount=%d", msg, msg->refcount);
|
||||
msg->refcount++;
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void
|
||||
_message_iterator_free(EDBus_Message_Iter *iter)
|
||||
{
|
||||
Eina_Inlist *lst, *next;
|
||||
EDBus_Message_Iter *sub;
|
||||
if (!iter) return;
|
||||
|
||||
lst = iter->iterators;
|
||||
while (lst)
|
||||
{
|
||||
next = lst->next;
|
||||
sub = EINA_INLIST_CONTAINER_GET(lst, EDBus_Message_Iter);
|
||||
_message_iterator_free(sub);
|
||||
lst = next;
|
||||
}
|
||||
free(iter);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_message_unref(EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK(msg);
|
||||
DBG("msg=%p, pre-refcount=%d", msg, msg->refcount);
|
||||
msg->refcount--;
|
||||
if (msg->refcount > 0) return;
|
||||
|
||||
DBG("message free %p", msg);
|
||||
|
||||
EINA_MAGIC_SET(msg, EINA_MAGIC_NONE);
|
||||
if (msg->dbus_msg)
|
||||
dbus_message_unref(msg->dbus_msg);
|
||||
msg->dbus_msg = NULL;
|
||||
|
||||
_message_iterator_free(msg->iterator);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_path_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_path(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_interface_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_interface(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_member_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_member(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_destination_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_destination(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_sender_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_sender(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_message_signature_get(const EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
return dbus_message_get_signature(msg->dbus_msg);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_error_get(const EDBus_Message *msg, const char **name, const char **text)
|
||||
{
|
||||
if (name) *name = NULL;
|
||||
if (text) *text = NULL;
|
||||
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
|
||||
|
||||
if (dbus_message_get_type(msg->dbus_msg) != DBUS_MESSAGE_TYPE_ERROR)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (name)
|
||||
*name = dbus_message_get_error_name(msg->dbus_msg);
|
||||
|
||||
if (text)
|
||||
dbus_message_get_args(msg->dbus_msg, NULL, DBUS_TYPE_STRING, text,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_edbus_message_arguments_vget(EDBus_Message *msg, const char *signature, va_list ap)
|
||||
{
|
||||
EDBus_Message_Iter *iter;
|
||||
iter = edbus_message_iter_get(msg);
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
|
||||
return edbus_message_iter_arguments_vget(iter, signature, ap);
|
||||
}
|
||||
|
||||
EAPI EDBus_Message_Iter *
|
||||
edbus_message_iter_get(EDBus_Message *msg)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
/* Something went wrong, msg->iterator should not be NULL */
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg->iterator, NULL);
|
||||
|
||||
return msg->iterator;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_arguments_get(const EDBus_Message *msg, const char *signature, ...)
|
||||
{
|
||||
Eina_Bool ret;
|
||||
va_list ap;
|
||||
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
|
||||
va_start(ap, signature);
|
||||
ret = _edbus_message_arguments_vget((EDBus_Message *)msg, signature, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_arguments_vget(const EDBus_Message *msg, const char *signature, va_list ap)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
return _edbus_message_arguments_vget((EDBus_Message *)msg, signature, ap);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_arguments_vset(EDBus_Message_Iter *iter, const char *signature, va_list ap)
|
||||
{
|
||||
DBusSignatureIter signature_iter;
|
||||
Eina_Bool r = EINA_TRUE;
|
||||
char *type;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
|
||||
dbus_signature_iter_init(&signature_iter, signature);
|
||||
while ((type = dbus_signature_iter_get_signature(&signature_iter)) && r)
|
||||
{
|
||||
if (type[0] != DBUS_TYPE_VARIANT && !type[1])
|
||||
r = append_basic(type[0], MAKE_PTR_FROM_VA_LIST(ap),
|
||||
&iter->dbus_iterator);
|
||||
else
|
||||
{
|
||||
EDBus_Message_Iter **user_itr;
|
||||
EDBus_Message_Iter *sub;
|
||||
|
||||
user_itr = va_arg(ap, EDBus_Message_Iter **);
|
||||
sub = _message_iterator_new(EINA_TRUE);
|
||||
EINA_SAFETY_ON_NULL_GOTO(sub, error);
|
||||
iter->iterators = eina_inlist_append(iter->iterators,
|
||||
EINA_INLIST_GET(sub));
|
||||
|
||||
if (type[0] == DBUS_TYPE_ARRAY)
|
||||
r = dbus_message_iter_open_container(&iter->dbus_iterator,
|
||||
type[0], type+1,
|
||||
&sub->dbus_iterator);
|
||||
else if(type[1] == DBUS_TYPE_VARIANT)
|
||||
{
|
||||
ERR("variant not supported by \
|
||||
edbus_message_iter_arguments_set(), \
|
||||
try edbus_message_iter_container_new()");
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
char real_type;
|
||||
|
||||
if (type[0] == DBUS_STRUCT_BEGIN_CHAR)
|
||||
real_type = DBUS_TYPE_STRUCT;
|
||||
else real_type = DBUS_TYPE_DICT_ENTRY;
|
||||
r = dbus_message_iter_open_container(&iter->dbus_iterator,
|
||||
real_type, NULL,
|
||||
&sub->dbus_iterator);
|
||||
}
|
||||
*user_itr = sub;
|
||||
}
|
||||
|
||||
dbus_free(type);
|
||||
if (!dbus_signature_iter_next(&signature_iter)) break;
|
||||
continue;
|
||||
error:
|
||||
r = EINA_FALSE;
|
||||
dbus_free(type);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_arguments_set(EDBus_Message_Iter *iter, const char *signature, ...)
|
||||
{
|
||||
Eina_Bool r;
|
||||
va_list ap;
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
|
||||
va_start(ap, signature);
|
||||
r = edbus_message_iter_arguments_vset(iter, signature, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
append_basic(char type, va_list *vl, DBusMessageIter *iter)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DBUS_TYPE_BYTE:
|
||||
{
|
||||
uint32_t read_byte = va_arg(*vl, uint32_t);
|
||||
uint8_t byte = read_byte;
|
||||
return dbus_message_iter_append_basic(iter, type, &byte);
|
||||
}
|
||||
case DBUS_TYPE_INT16:
|
||||
{
|
||||
int32_t read_int16 = va_arg(*vl, int32_t);
|
||||
int16_t int16 = read_int16;
|
||||
return dbus_message_iter_append_basic(iter, type, &int16);
|
||||
}
|
||||
case DBUS_TYPE_UINT16:
|
||||
{
|
||||
uint32_t read_uint16 = va_arg(*vl, uint32_t);
|
||||
uint16_t uint16 = read_uint16;
|
||||
return dbus_message_iter_append_basic(iter, type, &uint16);
|
||||
}
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
case DBUS_TYPE_INT32:
|
||||
case DBUS_TYPE_UNIX_FD:
|
||||
{
|
||||
int32_t int32 = va_arg(*vl, int32_t);
|
||||
return dbus_message_iter_append_basic(iter, type, &int32);
|
||||
}
|
||||
case DBUS_TYPE_UINT32:
|
||||
{
|
||||
uint32_t uint32 = va_arg(*vl, uint32_t);
|
||||
return dbus_message_iter_append_basic(iter, type, &uint32);
|
||||
}
|
||||
case DBUS_TYPE_INT64:
|
||||
{
|
||||
int64_t int64 = va_arg(*vl, int64_t);
|
||||
return dbus_message_iter_append_basic(iter, type, &int64);
|
||||
}
|
||||
case DBUS_TYPE_UINT64:
|
||||
{
|
||||
uint64_t uint64 = va_arg(*vl, uint64_t);
|
||||
return dbus_message_iter_append_basic(iter, type, &uint64);
|
||||
}
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
{
|
||||
double double_ieee = va_arg(*vl, double);
|
||||
return dbus_message_iter_append_basic(iter, type, &double_ieee);
|
||||
}
|
||||
case DBUS_TYPE_STRING:
|
||||
case DBUS_TYPE_OBJECT_PATH:
|
||||
case DBUS_TYPE_SIGNATURE:
|
||||
{
|
||||
char *string = va_arg(*vl, char*);
|
||||
return dbus_message_iter_append_basic(iter, type, &string);
|
||||
}
|
||||
default:
|
||||
ERR("Type not handled %c", type);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_edbus_message_arguments_vset(EDBus_Message *msg, const char *signature, va_list ap)
|
||||
{
|
||||
DBusSignatureIter signature_iter;
|
||||
EDBus_Message_Iter *iter;
|
||||
char *type;
|
||||
Eina_Bool r = EINA_TRUE;
|
||||
|
||||
if (!signature || !signature[0]) return EINA_TRUE;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL), EINA_FALSE);
|
||||
|
||||
iter = edbus_message_iter_get(msg);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
|
||||
dbus_signature_iter_init(&signature_iter, signature);
|
||||
while ((type = dbus_signature_iter_get_signature(&signature_iter)) && r)
|
||||
{
|
||||
if (dbus_type_is_basic(type[0]))
|
||||
r = append_basic(type[0], MAKE_PTR_FROM_VA_LIST(ap),
|
||||
&iter->dbus_iterator);
|
||||
else
|
||||
{
|
||||
ERR("edbus_message_arguments_set() and \
|
||||
edbus_message_arguments_vset() only support basic types, \
|
||||
to complex types use edbus_message_iter_* functions");
|
||||
r = EINA_FALSE;
|
||||
}
|
||||
|
||||
dbus_free(type);
|
||||
if (!dbus_signature_iter_next(&signature_iter)) break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_arguments_set(EDBus_Message *msg, const char *signature, ...)
|
||||
{
|
||||
Eina_Bool ret;
|
||||
va_list ap;
|
||||
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
|
||||
va_start(ap, signature);
|
||||
ret = _edbus_message_arguments_vset(msg, signature, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_arguments_vset(EDBus_Message *msg, const char *signature, va_list ap)
|
||||
{
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
return _edbus_message_arguments_vset(msg, signature, ap);
|
||||
}
|
||||
|
||||
EAPI EDBus_Message_Iter *
|
||||
edbus_message_iter_container_new(EDBus_Message_Iter *iter, int type, const char* contained_signature)
|
||||
{
|
||||
EDBus_Message_Iter *sub;
|
||||
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, NULL);
|
||||
sub = _message_iterator_new(EINA_TRUE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sub, NULL);
|
||||
|
||||
if (!dbus_message_iter_open_container(&iter->dbus_iterator, type,
|
||||
contained_signature,
|
||||
&sub->dbus_iterator))
|
||||
goto cleanup;
|
||||
|
||||
iter->iterators = eina_inlist_append(iter->iterators, EINA_INLIST_GET(sub));
|
||||
return sub;
|
||||
|
||||
cleanup:
|
||||
free(sub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_container_close(EDBus_Message_Iter *iter, EDBus_Message_Iter *sub)
|
||||
{
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(sub, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
return dbus_message_iter_close_container(&iter->dbus_iterator,
|
||||
&sub->dbus_iterator);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_append_basic(EDBus_Message_Iter *iter, int type, ...)
|
||||
{
|
||||
Eina_Bool r;
|
||||
va_list vl;
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
|
||||
va_start(vl, type);
|
||||
r = append_basic(type, &vl, &iter->dbus_iterator);
|
||||
va_end(vl);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_message_iter_get_basic(EDBus_Message_Iter *iter, void *value)
|
||||
{
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK(iter);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(iter->writable);
|
||||
dbus_message_iter_get_basic(&iter->dbus_iterator, value);
|
||||
}
|
||||
|
||||
EAPI char*
|
||||
edbus_message_iter_signature_get(EDBus_Message_Iter *iter)
|
||||
{
|
||||
return dbus_message_iter_get_signature(&iter->dbus_iterator);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_next(EDBus_Message_Iter *iter)
|
||||
{
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
return dbus_message_iter_next(&iter->dbus_iterator);
|
||||
}
|
||||
|
||||
static void
|
||||
get_basic(char type, DBusMessageIter *iter, va_list *vl)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DBUS_TYPE_BYTE:
|
||||
{
|
||||
uint8_t *byte = va_arg(*vl, uint8_t *);
|
||||
dbus_message_iter_get_basic(iter, byte);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
{
|
||||
Eina_Bool *boolean = va_arg(*vl, Eina_Bool *);
|
||||
dbus_bool_t val;
|
||||
dbus_message_iter_get_basic(iter, &val);
|
||||
*boolean = val;
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_INT16:
|
||||
{
|
||||
int16_t *int16 = va_arg(*vl, int16_t *);
|
||||
dbus_message_iter_get_basic(iter, int16);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_UINT16:
|
||||
{
|
||||
uint16_t *uint16 = va_arg(*vl, uint16_t *);
|
||||
dbus_message_iter_get_basic(iter, uint16);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_INT32:
|
||||
case DBUS_TYPE_UNIX_FD:
|
||||
{
|
||||
int32_t *int32 = va_arg(*vl, int32_t *);
|
||||
dbus_message_iter_get_basic(iter, int32);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_UINT32:
|
||||
{
|
||||
uint32_t *uint32 = va_arg(*vl, uint32_t *);
|
||||
dbus_message_iter_get_basic(iter, uint32);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_INT64:
|
||||
{
|
||||
int64_t *int64 = va_arg(*vl, int64_t *);
|
||||
dbus_message_iter_get_basic(iter, int64);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_UINT64:
|
||||
{
|
||||
uint64_t *uint64 = va_arg(*vl, uint64_t *);
|
||||
dbus_message_iter_get_basic(iter, uint64);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
{
|
||||
double *double_ieee = va_arg(*vl, double *);
|
||||
dbus_message_iter_get_basic(iter, double_ieee);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_STRING:
|
||||
case DBUS_TYPE_OBJECT_PATH:
|
||||
case DBUS_TYPE_SIGNATURE:
|
||||
{
|
||||
char **string = va_arg(*vl, char**);
|
||||
dbus_message_iter_get_basic(iter, string);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ERR("Type not handled %c", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_fixed_array_get(EDBus_Message_Iter *iter, int signature, void *value, int *n_elements)
|
||||
{
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(
|
||||
(dbus_message_iter_get_element_type(&iter->dbus_iterator) == signature),
|
||||
EINA_FALSE);
|
||||
dbus_message_iter_get_fixed_array(&iter->dbus_iterator, value, n_elements);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful when iterating over arrays
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_get_and_next(EDBus_Message_Iter *iter, char signature, ...)
|
||||
{
|
||||
char type;
|
||||
va_list vl;
|
||||
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
va_start(vl, signature);
|
||||
|
||||
type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
|
||||
if (type == DBUS_TYPE_INVALID) return EINA_FALSE;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(type == signature, EINA_FALSE);
|
||||
|
||||
if (dbus_type_is_basic(type))
|
||||
get_basic(type, &iter->dbus_iterator, &vl);
|
||||
else
|
||||
{
|
||||
EDBus_Message_Iter *sub;
|
||||
EDBus_Message_Iter **iter_var = va_arg(vl, EDBus_Message_Iter**);
|
||||
|
||||
sub = _message_iterator_new(EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sub, EINA_FALSE);
|
||||
dbus_message_iter_recurse(&iter->dbus_iterator,
|
||||
&sub->dbus_iterator);
|
||||
iter->iterators = eina_inlist_append(iter->iterators,
|
||||
EINA_INLIST_GET(sub));
|
||||
|
||||
*iter_var = sub;
|
||||
}
|
||||
va_end(vl);
|
||||
|
||||
dbus_message_iter_next(&iter->dbus_iterator);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_arguments_get(EDBus_Message_Iter *iter, const char *signature, ...)
|
||||
{
|
||||
va_list ap;
|
||||
Eina_Bool ret;
|
||||
|
||||
va_start(ap, signature);
|
||||
ret = edbus_message_iter_arguments_vget(iter, signature, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_message_iter_arguments_vget(EDBus_Message_Iter *iter, const char *signature, va_list ap)
|
||||
{
|
||||
int current_type;
|
||||
DBusSignatureIter signature_iter;
|
||||
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL), EINA_FALSE);
|
||||
|
||||
dbus_signature_iter_init(&signature_iter, signature);
|
||||
current_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
|
||||
while (current_type != DBUS_TYPE_INVALID)
|
||||
{
|
||||
char *iter_sig = dbus_signature_iter_get_signature(&signature_iter);
|
||||
int c = iter_sig[0];
|
||||
|
||||
dbus_free(iter_sig);
|
||||
dbus_signature_iter_next(&signature_iter);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(c == current_type, EINA_FALSE);
|
||||
|
||||
if (dbus_type_is_basic(current_type))
|
||||
get_basic(current_type, &iter->dbus_iterator, MAKE_PTR_FROM_VA_LIST(ap));
|
||||
else
|
||||
{
|
||||
EDBus_Message_Iter **user_itr = va_arg(ap, EDBus_Message_Iter **);
|
||||
EDBus_Message_Iter *sub_itr;
|
||||
|
||||
sub_itr = _message_iterator_new(EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sub_itr, EINA_FALSE);
|
||||
dbus_message_iter_recurse(&iter->dbus_iterator,
|
||||
&sub_itr->dbus_iterator);
|
||||
iter->iterators = eina_inlist_append(iter->iterators,
|
||||
EINA_INLIST_GET(sub_itr));
|
||||
*user_itr = sub_itr;
|
||||
}
|
||||
dbus_message_iter_next(&iter->dbus_iterator);
|
||||
current_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_message_iter_del(EDBus_Message_Iter *iter)
|
||||
{
|
||||
EDBUS_MESSAGE_ITERATOR_CHECK(iter);
|
||||
_message_iterator_free(iter);
|
||||
}
|
||||
|
||||
/* TODO: proper doc
|
||||
* Return the *reply* to @msg, i.e. @msg is the message we are replying to.
|
||||
*/
|
||||
EAPI EDBus_Message *
|
||||
edbus_message_error_new(const EDBus_Message *msg, const char *error_name, const char *error_msg)
|
||||
{
|
||||
EDBus_Message *reply;
|
||||
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(error_name, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(error_msg, NULL);
|
||||
|
||||
reply = edbus_message_new(EINA_FALSE);
|
||||
reply->dbus_msg = dbus_message_new_error(msg->dbus_msg,
|
||||
error_name, error_msg);
|
||||
|
||||
/*
|
||||
* Technically user should not append more arguments in an error message but
|
||||
* we can't leave its iter as NULL.
|
||||
*/
|
||||
dbus_message_iter_init_append(reply->dbus_msg,
|
||||
&reply->iterator->dbus_iterator);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_message_method_return_new(const EDBus_Message *msg)
|
||||
{
|
||||
EDBus_Message *reply;
|
||||
EDBUS_MESSAGE_CHECK_RETVAL(msg, NULL);
|
||||
|
||||
reply = edbus_message_new(EINA_TRUE);
|
||||
reply->dbus_msg = dbus_message_new_method_return(msg->dbus_msg);
|
||||
|
||||
dbus_message_iter_init_append(reply->dbus_msg,
|
||||
&reply->iterator->dbus_iterator);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_message_signal_new(const char *path, const char *interface, const char *name)
|
||||
{
|
||||
EDBus_Message *msg;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(name, NULL);
|
||||
|
||||
msg = edbus_message_new(EINA_TRUE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
|
||||
msg->dbus_msg = dbus_message_new_signal(path, interface, name);
|
||||
dbus_message_iter_init_append(msg->dbus_msg,
|
||||
&msg->iterator->dbus_iterator);
|
||||
|
||||
return msg;
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
#ifndef EDBUS_MESSAGE_H
|
||||
#define EDBUS_MESSAGE_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Message Message
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Constructs a new message to invoke a method on a remote object.
|
||||
*
|
||||
* @param dest bus name or unique id of the remote applications
|
||||
* @param path object path
|
||||
* @param iface interface name
|
||||
* @param method name of method that will be called
|
||||
*
|
||||
* @return a new EDBus_Message, free with edbus_message_unref()
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_message_method_call_new(const char *dest, const char *path, const char *iface, const char *method) EINA_ARG_NONNULL(1, 2, 3, 4) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
|
||||
|
||||
/**
|
||||
* @brief Increase message reference.
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_message_ref(EDBus_Message *msg) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Decrease message reference.
|
||||
* If reference == 0 message will be freed and all your children's.
|
||||
*/
|
||||
EAPI void edbus_message_unref(EDBus_Message *msg) EINA_ARG_NONNULL(1);
|
||||
|
||||
EAPI const char *edbus_message_path_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_message_interface_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_message_member_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_message_destination_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_message_sender_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_message_signature_get(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Creates a new message that is an error reply to another message.
|
||||
*
|
||||
* @param reply the message we're replying to
|
||||
* @param error_name the error name
|
||||
* @param error_msg the error message string
|
||||
*
|
||||
* @return new EDBus_Message, free with edbus_message_unref()
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_message_error_new(const EDBus_Message *reply, const char *error_name, const char *error_msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Constructs a message that is a reply to a method call.
|
||||
*
|
||||
* @param msg the message we're replying to
|
||||
*
|
||||
* @return new EDBus_Message, free with edbus_message_unref()
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_message_method_return_new(const EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Constructs a new message representing a signal emission.
|
||||
*
|
||||
* @param path of the object that was emiting the signal
|
||||
* @param interface
|
||||
* @param name
|
||||
*
|
||||
* @return new EDBus_Message, free with edbus_message_unref()
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_message_signal_new(const char *path, const char *interface, const char *name) EINA_ARG_NONNULL(1, 2, 3) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief If EDBus_Message is a message error return EINA_TRUE and fills
|
||||
* name and text if their pointers is not null.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_error_get(const EDBus_Message *msg, const char **name, const char **text) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Get data from EDBus_Message, for each complete type must have
|
||||
* a pointer to store his value, in case of complex type a
|
||||
* EDBus_Message_Iter will be need.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_arguments_get(const EDBus_Message *msg, const char *signature, ...) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Get data from EDBus_Message, for each complete type must have
|
||||
* a pointer to store his value, in case of complex type a
|
||||
* EDBus_Message_Iter will be need.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_arguments_vget(const EDBus_Message *msg, const char *signature, va_list ap) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Set data to EDBus_Message.
|
||||
*
|
||||
* This function only support basic type from complex type use
|
||||
* edbus_message_iter_* functions.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_arguments_set(EDBus_Message *msg, const char *signature, ...) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Set data to EDBus_Message.
|
||||
*
|
||||
* This function only support basic type from complex type use
|
||||
* edbus_message_iter_* functions.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_arguments_vset(EDBus_Message *msg, const char *signature, va_list ap) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Message_Iter Iterator
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Create and appends a typed iterator to another iterator.
|
||||
*
|
||||
* After append data to returned iterator it must be closed calling
|
||||
* edbus_message_iter_container_close().
|
||||
*
|
||||
* Container types are for example struct, variant, and array.
|
||||
* For variants, the contained_signature should be the type of the single
|
||||
* value inside the variant. For structs and dict entries, contained_signature
|
||||
* should be NULL; it will be set to whatever types you write into the struct.
|
||||
* For arrays, contained_signature should be the type of the array elements.
|
||||
*
|
||||
* @param iter parent of the new iterator
|
||||
* @param type of iterator (e.g struct, dict, variant or array)
|
||||
* @param contained_signature signature of what iterator will store
|
||||
*
|
||||
* @return the new iterator
|
||||
*/
|
||||
EAPI EDBus_Message_Iter *edbus_message_iter_container_new(EDBus_Message_Iter *iter, int type, const char* contained_signature) EINA_ARG_NONNULL(1, 3) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Append a basic type to EDBus_Iterator.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_append_basic(EDBus_Message_Iter *iter, int type, ...) EINA_ARG_NONNULL(1, 3);
|
||||
/**
|
||||
* @brief Set data to EDBus_Message_Iter. For each complete in signature
|
||||
* you need pass the value, in case of complex type a pointer to be allocated a
|
||||
* EDBus_Message_Iter that you need fill and close.
|
||||
*
|
||||
* It's not possible open two iterators at same Iterator. Example:
|
||||
* "aiai", to set this you need create and put the first array with
|
||||
* edbus_message_iter_container_new() fill array with data and close then
|
||||
* you could open the second array with edbus_message_iter_container_new().
|
||||
*
|
||||
* @param iter iterator
|
||||
* @param signature of data
|
||||
* @param ... values
|
||||
*
|
||||
* @note This function don't support variant, use instead
|
||||
* edbus_message_iter_container_new() to create the variant fill
|
||||
* data and close it..
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_arguments_set(EDBus_Message_Iter *iter, const char *signature, ...) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Set data to EDBus_Message_Iter. For each complete in signature
|
||||
* you need pass the value, in case of complex type a pointer to be allocated a
|
||||
* EDBus_Message_Iter that you need fill and close.
|
||||
*
|
||||
* It's not possible open two iterators at same Iterator. Example:
|
||||
* "aiai", to set this you need create and put the first array with
|
||||
* edbus_message_iter_container_new() fill array with data and close then
|
||||
* you could open the second array with edbus_message_iter_container_new().
|
||||
*
|
||||
* @param iter iterator
|
||||
* @param signature of data
|
||||
* @param ap va_list with the values
|
||||
*
|
||||
* @note This function don't support variant, use instead
|
||||
* edbus_message_iter_container_new() to create the variant fill
|
||||
* data and close it.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_arguments_vset(EDBus_Message_Iter *iter, const char *signature, va_list ap) EINA_ARG_NONNULL(1, 2, 3);
|
||||
/**
|
||||
* @brief Closes a container-typed value appended to the message.
|
||||
*
|
||||
* @param iter parent of the sub-iterator
|
||||
* @param sub the iterator that will be closed
|
||||
*
|
||||
* @return EINA_FALSE if iterator was already close or if not enough memory
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_container_close(EDBus_Message_Iter *iter, EDBus_Message_Iter *sub) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Get the main EDBus_Message_Iter from the EDBus_Message.
|
||||
*/
|
||||
EAPI EDBus_Message_Iter *edbus_message_iter_get(EDBus_Message *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Get a basic type from EDBus_Iterator.
|
||||
*/
|
||||
EAPI void edbus_message_iter_get_basic(EDBus_Message_Iter *iter, void *value) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Returns the current signature of a message iterator.
|
||||
*
|
||||
* @note The returned string must be freed.
|
||||
*/
|
||||
EAPI char *edbus_message_iter_signature_get(EDBus_Message_Iter *iter) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Moves the iterator to the next field, if any.
|
||||
* @param iter iterator
|
||||
*
|
||||
* @return if iterator was reach to end return EINA_FALSE
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_next(EDBus_Message_Iter *iter) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Get a complete type from EDBus_Message_Iter if is not at the end
|
||||
* of iterator and move to next field.
|
||||
* Useful to iterate over arrays.
|
||||
*
|
||||
* @param iter iterator
|
||||
* @param type of the next completed type in Iterator
|
||||
* @param ... pointer of where data will be stored
|
||||
*
|
||||
* @param if iterator was reach to end or if type different of the type that
|
||||
* iterator points return EINA_FALSE
|
||||
*
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_get_and_next(EDBus_Message_Iter *iter, char type, ...) EINA_ARG_NONNULL(1, 2, 3);
|
||||
/**
|
||||
* @brief Reads a block of fixed-length values from the message iterator.
|
||||
*
|
||||
* Fixed-length values are those basic types that are not string-like,
|
||||
* such as integers, bool, double. The returned block will be from the
|
||||
* current position in the array until the end of the array.
|
||||
*
|
||||
* There is one exception here: although EDBUS_TYPE_UNIX_FD is considered a
|
||||
* 'fixed' type arrays of this type may not be read with this function.
|
||||
*
|
||||
* The value argument should be the address of a location to store the returned
|
||||
* array. So for int32 it should be a "const dbus_int32_t**" The returned value
|
||||
* is by reference and should not be freed.
|
||||
*
|
||||
* Because the array is not copied, this function runs in constant time and is
|
||||
* fast; it's much preferred over walking the entire array with an iterator.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_fixed_array_get(EDBus_Message_Iter *iter, int signature, void *value, int *n_elements) EINA_ARG_NONNULL(1, 3, 4);
|
||||
/**
|
||||
* @brief Get data from EDBus_Message_Iter, for each complete type must have
|
||||
* a pointer to store his value, in case of complex type a
|
||||
* EDBus_Message_Iter will be need.
|
||||
*
|
||||
* @param iter iterator
|
||||
* @param signature of the complete data types on interator
|
||||
* @param ... pointers of where data will be stored
|
||||
*
|
||||
* @return EINA_FALSE if signature different from signature in iterator
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_arguments_get(EDBus_Message_Iter *iter, const char *signature, ...) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Get data from EDBus_Message_Iter, for each complete type must have
|
||||
* a pointer to store his value, in case of complex type a
|
||||
* EDBus_Message_Iter will be need.
|
||||
*
|
||||
* @param iter iterator
|
||||
* @param signature of the complete data types on interator
|
||||
* @param ap va_list of the pointers of where data will be stored
|
||||
*
|
||||
* @return EINA_FALSE if signature different from signature in iterator
|
||||
*/
|
||||
EAPI Eina_Bool edbus_message_iter_arguments_vget(EDBus_Message_Iter *iter, const char *signature, va_list ap) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Manually delete the iterator.
|
||||
*
|
||||
* Iterators are usually bound to the life of @ref EDBus_Message
|
||||
* they were created from, being deleted automatically once the
|
||||
* message is deleted.
|
||||
*
|
||||
* However when dealing with huge arrays or dicts it may become a
|
||||
* major memory impact to leave the unused iterators alive. By
|
||||
* calling this function one states the iterator is not used anymore
|
||||
* and can be deleted.
|
||||
*
|
||||
* @param iter the iterator to be deleted.
|
||||
*/
|
||||
EAPI void edbus_message_iter_del(EDBus_Message_Iter *iter) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,467 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
/* TODO: mempool of EDBus_Object, Edbus_Object_Context_Event_Cb and
|
||||
* EDBus_Object_Context_Event
|
||||
*/
|
||||
|
||||
#define EDBUS_OBJECT_CHECK(obj) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(obj); \
|
||||
if (!EINA_MAGIC_CHECK(obj, EDBUS_OBJECT_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(obj, EDBUS_OBJECT_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN(obj->refcount <= 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_OBJECT_CHECK_RETVAL(obj, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, retval); \
|
||||
if (!EINA_MAGIC_CHECK(obj, EDBUS_OBJECT_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(obj, EDBUS_OBJECT_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(obj->refcount <= 0, retval); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_OBJECT_CHECK_GOTO(obj, label) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_GOTO(obj, label); \
|
||||
if (!EINA_MAGIC_CHECK(obj, EDBUS_OBJECT_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(obj, EDBUS_OBJECT_MAGIC); \
|
||||
goto label; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_GOTO(obj->refcount <= 0, label); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
Eina_Bool
|
||||
edbus_object_init(void)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_object_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void _edbus_object_event_callback_call(EDBus_Object *obj, EDBus_Object_Event_Type type, const void *event_info);
|
||||
static void _edbus_object_context_event_cb_del(EDBus_Object_Context_Event *ce, EDBus_Object_Context_Event_Cb *ctx);
|
||||
static void _on_connection_free(void *data, const void *dead_pointer);
|
||||
|
||||
static void
|
||||
_edbus_object_call_del(EDBus_Object *obj)
|
||||
{
|
||||
EDBus_Object_Context_Event *ce;
|
||||
|
||||
_edbus_object_event_callback_call(obj, EDBUS_OBJECT_EVENT_DEL, NULL);
|
||||
|
||||
/* clear all del callbacks so we don't call them twice at
|
||||
* _edbus_object_clear()
|
||||
*/
|
||||
ce = obj->event_handlers + EDBUS_OBJECT_EVENT_DEL;
|
||||
while (ce->list)
|
||||
{
|
||||
EDBus_Object_Context_Event_Cb *ctx;
|
||||
|
||||
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
||||
EDBus_Object_Context_Event_Cb);
|
||||
_edbus_object_context_event_cb_del(ce, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_object_clear(EDBus_Object *obj)
|
||||
{
|
||||
EDBus_Signal_Handler *h;
|
||||
EDBus_Pending *p;
|
||||
Eina_List *iter, *iter_next;
|
||||
Eina_Inlist *in_l;
|
||||
DBG("obj=%p, refcount=%d, name=%s, path=%s",
|
||||
obj, obj->refcount, obj->name, obj->path);
|
||||
|
||||
obj->refcount = 1;
|
||||
_edbus_object_call_del(obj);
|
||||
edbus_connection_name_object_del(obj->conn, obj);
|
||||
|
||||
/* NOTE: obj->proxies is deleted from obj->cbs_free. */
|
||||
|
||||
EINA_LIST_FOREACH_SAFE(obj->signal_handlers, iter, iter_next, h)
|
||||
{
|
||||
DBG("obj=%p delete owned signal handler %p %s",
|
||||
obj, h, edbus_signal_handler_match_get(h));
|
||||
edbus_signal_handler_del(h);
|
||||
}
|
||||
EINA_INLIST_FOREACH_SAFE(obj->pendings, in_l, p)
|
||||
{
|
||||
DBG("obj=%p delete owned pending call=%p dest=%s path=%s %s.%s()",
|
||||
obj, p,
|
||||
edbus_pending_destination_get(p),
|
||||
edbus_pending_path_get(p),
|
||||
edbus_pending_interface_get(p),
|
||||
edbus_pending_method_get(p));
|
||||
edbus_pending_cancel(p);
|
||||
}
|
||||
|
||||
edbus_cbs_free_dispatch(&(obj->cbs_free), obj);
|
||||
obj->refcount = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_object_free(EDBus_Object *obj)
|
||||
{
|
||||
unsigned int i;
|
||||
if (obj->proxies)
|
||||
{
|
||||
Eina_Iterator *iterator = eina_hash_iterator_data_new(obj->proxies);
|
||||
EDBus_Proxy *proxy;
|
||||
EINA_ITERATOR_FOREACH (iterator, proxy)
|
||||
ERR("obj=%p alive proxy=%p %s", obj, proxy,
|
||||
edbus_proxy_interface_get(proxy));
|
||||
eina_iterator_free(iterator);
|
||||
eina_hash_free(obj->proxies);
|
||||
}
|
||||
|
||||
if (obj->signal_handlers)
|
||||
{
|
||||
EDBus_Signal_Handler *h;
|
||||
CRITICAL("Object %p released with live signal handlers!", obj);
|
||||
EINA_LIST_FREE (obj->signal_handlers, h)
|
||||
ERR("obj=%p alive handler=%p %s", obj, h,
|
||||
edbus_signal_handler_match_get(h));
|
||||
}
|
||||
|
||||
if (obj->pendings)
|
||||
CRITICAL("Object %p released with live pending calls!", obj);
|
||||
|
||||
for (i = 0; i < EDBUS_OBJECT_EVENT_LAST; i++)
|
||||
{
|
||||
EDBus_Object_Context_Event *ce = obj->event_handlers + i;
|
||||
while (ce->list)
|
||||
{
|
||||
EDBus_Object_Context_Event_Cb *ctx;
|
||||
|
||||
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
||||
EDBus_Object_Context_Event_Cb);
|
||||
_edbus_object_context_event_cb_del(ce, ctx);
|
||||
}
|
||||
eina_list_free(ce->to_delete);
|
||||
}
|
||||
|
||||
eina_stringshare_del(obj->name);
|
||||
eina_stringshare_del(obj->path);
|
||||
EINA_MAGIC_SET(obj, EINA_MAGIC_NONE);
|
||||
|
||||
free(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_connection_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Object *obj = data;
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
_edbus_object_clear(obj);
|
||||
_edbus_object_free(obj);
|
||||
}
|
||||
|
||||
EAPI EDBus_Object *
|
||||
edbus_object_get(EDBus_Connection *conn, const char *bus, const char *path)
|
||||
{
|
||||
EDBus_Object *obj;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bus, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
|
||||
|
||||
obj = edbus_connection_name_object_get(conn, bus, path);
|
||||
if (obj) return obj;
|
||||
|
||||
obj = calloc(1, sizeof(EDBus_Object));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
|
||||
|
||||
obj->conn = conn;
|
||||
obj->refcount = 1;
|
||||
obj->path = eina_stringshare_add(path);
|
||||
obj->name = eina_stringshare_add(bus);
|
||||
obj->proxies = eina_hash_string_small_new(NULL);
|
||||
EINA_SAFETY_ON_NULL_GOTO(obj->proxies, cleanup);
|
||||
EINA_MAGIC_SET(obj, EDBUS_OBJECT_MAGIC);
|
||||
|
||||
edbus_connection_name_object_set(conn, obj);
|
||||
edbus_connection_cb_free_add(obj->conn, _on_connection_free, obj);
|
||||
|
||||
return obj;
|
||||
|
||||
cleanup:
|
||||
eina_stringshare_del(obj->path);
|
||||
eina_stringshare_del(obj->name);
|
||||
free(obj);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _on_signal_handler_free(void *data, const void *dead_pointer);
|
||||
|
||||
static void
|
||||
_edbus_object_unref(EDBus_Object *obj)
|
||||
{
|
||||
obj->refcount--;
|
||||
if (obj->refcount > 0) return;
|
||||
|
||||
edbus_connection_cb_free_del(obj->conn, _on_connection_free, obj);
|
||||
_edbus_object_clear(obj);
|
||||
_edbus_object_free(obj);
|
||||
}
|
||||
|
||||
EAPI EDBus_Object *
|
||||
edbus_object_ref(EDBus_Object *obj)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
DBG("obj=%p, pre-refcount=%d, name=%s, path=%s",
|
||||
obj, obj->refcount, obj->name, obj->path);
|
||||
obj->refcount++;
|
||||
return obj;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_object_unref(EDBus_Object *obj)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
DBG("obj=%p, pre-refcount=%d, name=%s, path=%s",
|
||||
obj, obj->refcount, obj->name, obj->path);
|
||||
_edbus_object_unref(obj);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_object_cb_free_add(EDBus_Object *obj, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
obj->cbs_free = edbus_cbs_free_add(obj->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_object_cb_free_del(EDBus_Object *obj, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
obj->cbs_free = edbus_cbs_free_del(obj->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_object_event_callback_add(EDBus_Object *obj, EDBus_Object_Event_Type type, EDBus_Object_Event_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Object_Context_Event *ce;
|
||||
EDBus_Object_Context_Event_Cb *ctx;
|
||||
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(type >= EDBUS_OBJECT_EVENT_LAST);
|
||||
|
||||
ce = obj->event_handlers + type;
|
||||
|
||||
ctx = calloc(1, sizeof(EDBus_Object_Context_Event_Cb));
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
|
||||
ctx->cb = cb;
|
||||
ctx->cb_data = cb_data;
|
||||
|
||||
ce->list = eina_inlist_append(ce->list, EINA_INLIST_GET(ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_object_context_event_cb_del(EDBus_Object_Context_Event *ce, EDBus_Object_Context_Event_Cb *ctx)
|
||||
{
|
||||
ce->list = eina_inlist_remove(ce->list, EINA_INLIST_GET(ctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_object_event_callback_del(EDBus_Object *obj, EDBus_Object_Event_Type type, EDBus_Object_Event_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Object_Context_Event *ce;
|
||||
EDBus_Object_Context_Event_Cb *iter, *found = NULL;
|
||||
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(type >= EDBUS_OBJECT_EVENT_LAST);
|
||||
|
||||
ce = obj->event_handlers + type;
|
||||
|
||||
EINA_INLIST_FOREACH (ce->list, iter)
|
||||
{
|
||||
if (cb != iter->cb) continue;
|
||||
if ((cb_data) && (cb_data != iter->cb_data)) continue;
|
||||
|
||||
found = iter;
|
||||
break;
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(found);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(found->deleted);
|
||||
|
||||
if (ce->walking)
|
||||
{
|
||||
found->deleted = EINA_TRUE;
|
||||
ce->to_delete = eina_list_append(ce->to_delete, found);
|
||||
return;
|
||||
}
|
||||
|
||||
_edbus_object_context_event_cb_del(ce, found);
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_object_event_callback_call(EDBus_Object *obj, EDBus_Object_Event_Type type, const void *event_info)
|
||||
{
|
||||
EDBus_Object_Context_Event *ce;
|
||||
EDBus_Object_Context_Event_Cb *iter;
|
||||
|
||||
ce = obj->event_handlers + type;
|
||||
|
||||
ce->walking++;
|
||||
EINA_INLIST_FOREACH (ce->list, iter)
|
||||
{
|
||||
if (iter->deleted) continue;
|
||||
iter->cb((void *)iter->cb_data, obj, (void *)event_info);
|
||||
}
|
||||
ce->walking--;
|
||||
if (ce->walking > 0) return;
|
||||
|
||||
EINA_LIST_FREE (ce->to_delete, iter)
|
||||
_edbus_object_context_event_cb_del(ce, iter);
|
||||
}
|
||||
|
||||
EAPI EDBus_Connection *
|
||||
edbus_object_connection_get(const EDBus_Object *obj)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
return obj->conn;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_object_bus_name_get(const EDBus_Object *obj)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
return obj->name;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_object_bus_path_get(const EDBus_Object *obj)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
return obj->path;
|
||||
}
|
||||
|
||||
static void
|
||||
_on_pending_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Object *obj = data;
|
||||
EDBus_Pending *pending = (EDBus_Pending*) dead_pointer;
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
obj->pendings = eina_inlist_remove(obj->pendings, EINA_INLIST_GET(pending));
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_object_send(EDBus_Object *obj, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
|
||||
pending = _edbus_connection_send(obj->conn, msg, cb, cb_data, timeout);
|
||||
if (!cb) return NULL;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
|
||||
|
||||
edbus_pending_cb_free_add(pending, _on_pending_free, obj);
|
||||
obj->pendings = eina_inlist_append(obj->pendings, EINA_INLIST_GET(pending));
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
static void
|
||||
_on_signal_handler_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Object *obj = data;
|
||||
EDBUS_OBJECT_CHECK(obj);
|
||||
obj->signal_handlers = eina_list_remove(obj->signal_handlers, dead_pointer);
|
||||
}
|
||||
|
||||
EAPI EDBus_Signal_Handler *
|
||||
edbus_object_signal_handler_add(EDBus_Object *obj, const char *interface, const char *member, EDBus_Signal_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Signal_Handler *handler;
|
||||
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
|
||||
|
||||
handler = edbus_signal_handler_add(obj->conn, obj->name, obj->path,
|
||||
interface, member, cb, cb_data);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(handler, NULL);
|
||||
|
||||
edbus_signal_handler_cb_free_add(handler, _on_signal_handler_free, obj);
|
||||
obj->signal_handlers = eina_list_append(obj->signal_handlers, handler);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
edbus_object_proxy_add(EDBus_Object *obj, EDBus_Proxy *proxy)
|
||||
{
|
||||
return eina_hash_add(obj->proxies, edbus_proxy_interface_get(proxy), proxy);
|
||||
}
|
||||
|
||||
EDBus_Proxy *
|
||||
edbus_object_proxy_get(EDBus_Object *obj, const char *interface)
|
||||
{
|
||||
return eina_hash_find(obj->proxies, interface);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
edbus_object_proxy_del(EDBus_Object *obj, EDBus_Proxy *proxy, const char *interface)
|
||||
{
|
||||
return eina_hash_del(obj->proxies, interface, proxy);
|
||||
}
|
||||
|
||||
static EDBus_Proxy *
|
||||
get_peer_proxy(EDBus_Object *obj)
|
||||
{
|
||||
return edbus_proxy_get(obj, "org.freedesktop.DBus.Peer");
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_object_peer_ping(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
return edbus_proxy_call(get_peer_proxy(obj), "Ping", cb,
|
||||
data, -1, "");
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_object_peer_machine_id_get(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
return edbus_proxy_call(get_peer_proxy(obj), "GetMachineId", cb,
|
||||
data, -1, "");
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_object_introspect(EDBus_Object *obj, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBus_Proxy *introspectable;
|
||||
EDBUS_OBJECT_CHECK_RETVAL(obj, NULL);
|
||||
|
||||
introspectable = edbus_proxy_get(obj, "org.freedesktop.DBus.Introspectable");
|
||||
return edbus_proxy_call(introspectable, "Introspect", cb, data, -1, "");
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
#ifndef EDBUS_OBJECT_H
|
||||
#define EDBUS_OBJECT_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Object_Mapper Object Mapper
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Get a object of the following bus and path.
|
||||
*
|
||||
* @param conn connection where object belongs
|
||||
* @param bus name of bus or unique-id of who listen for calls of this object
|
||||
* @param path object path of this object
|
||||
*/
|
||||
EAPI EDBus_Object *edbus_object_get(EDBus_Connection *conn, const char *bus, const char *path) EINA_ARG_NONNULL(1, 2, 3) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Increase object reference.
|
||||
*/
|
||||
EAPI EDBus_Object *edbus_object_ref(EDBus_Object *obj) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Decrease object reference.
|
||||
* If reference == 0 object will be freed and all your children's.
|
||||
*/
|
||||
EAPI void edbus_object_unref(EDBus_Object *obj) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when object will be freed.
|
||||
*
|
||||
* @param obj object that you want to know when it will be free
|
||||
* @param cb callback that will be execute
|
||||
* @param data passed to callback
|
||||
*/
|
||||
EAPI void edbus_object_cb_free_add(EDBus_Object *obj, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_object_cb_free_add().
|
||||
*/
|
||||
EAPI void edbus_object_cb_free_del(EDBus_Object *obj, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EDBUS_OBJECT_EVENT_IFACE_ADDED = 0,
|
||||
EDBUS_OBJECT_EVENT_IFACE_REMOVED,
|
||||
EDBUS_OBJECT_EVENT_PROPERTY_CHANGED,
|
||||
EDBUS_OBJECT_EVENT_PROPERTY_REMOVED,
|
||||
EDBUS_OBJECT_EVENT_DEL,
|
||||
EDBUS_OBJECT_EVENT_LAST /**< sentinel, not a real event type */
|
||||
} EDBus_Object_Event_Type;
|
||||
|
||||
typedef struct _EDBus_Object_Event_Interface_Added
|
||||
{
|
||||
const char *interface;
|
||||
EDBus_Proxy *proxy;
|
||||
} EDBus_Object_Event_Interface_Added;
|
||||
|
||||
typedef struct _EDBus_Object_Event_Interface_Removed
|
||||
{
|
||||
const char *interface;
|
||||
} EDBus_Object_Event_Interface_Removed;
|
||||
|
||||
typedef struct _EDBus_Object_Event_Property_Changed
|
||||
{
|
||||
const char *interface;
|
||||
EDBus_Proxy *proxy;
|
||||
const char *name;
|
||||
const Eina_Value *value;
|
||||
} EDBus_Object_Event_Property_Changed;
|
||||
|
||||
typedef struct _EDBus_Object_Event_Property_Removed
|
||||
{
|
||||
const char *interface;
|
||||
EDBus_Proxy *proxy;
|
||||
const char *name;
|
||||
} EDBus_Object_Event_Property_Removed;
|
||||
|
||||
typedef void (*EDBus_Object_Event_Cb)(void *data, EDBus_Object *obj, void *event_info);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when occurs a event of the
|
||||
* type passed.
|
||||
*/
|
||||
EAPI void edbus_object_event_callback_add(EDBus_Object *obj, EDBus_Object_Event_Type type, EDBus_Object_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_object_event_callback_add().
|
||||
*/
|
||||
EAPI void edbus_object_event_callback_del(EDBus_Object *obj, EDBus_Object_Event_Type type, EDBus_Object_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
|
||||
EAPI EDBus_Connection *edbus_object_connection_get(const EDBus_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_object_bus_name_get(const EDBus_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_object_bus_path_get(const EDBus_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Send a message.
|
||||
*
|
||||
* @param obj the msg will be send in connection that obj belongs
|
||||
* @param msg message that will be send
|
||||
* @param cb if msg is a method call a callback should be passed
|
||||
* to be execute when response arrive
|
||||
* @param cb_data data passed to callback
|
||||
* @param timeout timeout in milliseconds, -1 to default internal value or
|
||||
* EDBUS_TIMEOUT_INFINITE for no timeout
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_object_send(EDBus_Object *obj, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Add a signal handler.
|
||||
*
|
||||
* @param obj where the signal is emitted
|
||||
* @param interface of the signal
|
||||
* @param member name of the signal
|
||||
* @param cb callback that will be called when this signal is received
|
||||
* @param cb_data data that will be passed to callback
|
||||
*/
|
||||
EAPI EDBus_Signal_Handler *edbus_object_signal_handler_add(EDBus_Object *obj, const char *interface, const char *member, EDBus_Signal_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 4);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,260 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
/* TODO: mempool of EDBus_Pending */
|
||||
#define EDBUS_PENDING_CHECK(pending) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(pending); \
|
||||
if (!EINA_MAGIC_CHECK(pending, EDBUS_PENDING_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(pending, EDBUS_PENDING_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_PENDING_CHECK_RETVAL(pending, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, retval); \
|
||||
if (!EINA_MAGIC_CHECK(pending, EDBUS_PENDING_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(pending, EDBUS_PENDING_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
static void edbus_pending_dispatch(EDBus_Pending *pending, EDBus_Message *msg);
|
||||
|
||||
Eina_Bool
|
||||
edbus_pending_init(void)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_pending_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
cb_pending(DBusPendingCall *dbus_pending, void *user_data)
|
||||
{
|
||||
EDBus_Message *msg;
|
||||
EDBus_Pending *pending = user_data;
|
||||
|
||||
if (!dbus_pending_call_get_completed(dbus_pending))
|
||||
{
|
||||
INF("timeout to pending %p", pending);
|
||||
dbus_pending_call_cancel(dbus_pending);
|
||||
msg = edbus_message_error_new(pending->msg_sent,
|
||||
"org.enlightenment.DBus.Timeout",
|
||||
"This call was not completed.");
|
||||
edbus_pending_dispatch(pending, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = edbus_message_new(EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN(msg);
|
||||
msg->dbus_msg = dbus_pending_call_steal_reply(dbus_pending);
|
||||
if (!msg->dbus_msg)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_GOTO(pending->cb, cleanup);
|
||||
|
||||
msg->dbus_msg = dbus_message_new_error(NULL,
|
||||
"org.enlightenment.DBus.NoReply",
|
||||
"There was no reply to this method call.");
|
||||
EINA_SAFETY_ON_NULL_GOTO(msg->dbus_msg, cleanup);
|
||||
}
|
||||
|
||||
dbus_message_iter_init(msg->dbus_msg, &msg->iterator->dbus_iterator);
|
||||
edbus_pending_dispatch(pending, msg);
|
||||
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
edbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_pending_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Connection *conn = data;
|
||||
edbus_connection_pending_del(conn, (void *)dead_pointer);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_connection_send(EDBus_Connection *conn, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
|
||||
pending = _edbus_connection_send(conn, msg, cb, cb_data, timeout);
|
||||
if (!cb) return NULL;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
|
||||
|
||||
edbus_connection_pending_add(conn, pending);
|
||||
edbus_pending_cb_free_add(pending, _on_pending_free, conn);
|
||||
return pending;
|
||||
}
|
||||
|
||||
EDBus_Pending *
|
||||
_edbus_connection_send(EDBus_Connection *conn, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
EDBus_Message *error_msg;
|
||||
DBG("conn=%p, msg=%p, cb=%p, cb_data=%p, timeout=%f",
|
||||
conn, msg, cb, cb_data, timeout);
|
||||
|
||||
if (!cb)
|
||||
{
|
||||
dbus_connection_send(conn->dbus_conn, msg->dbus_msg, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pending = calloc(1, sizeof(EDBus_Pending));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
|
||||
|
||||
pending->cb = cb;
|
||||
pending->cb_data = cb_data;
|
||||
pending->conn = conn;
|
||||
pending->dest = eina_stringshare_add(dbus_message_get_member(msg->dbus_msg));
|
||||
pending->interface = eina_stringshare_add(dbus_message_get_interface(msg->dbus_msg));
|
||||
pending->method = eina_stringshare_add(dbus_message_get_member(msg->dbus_msg));
|
||||
pending->path = eina_stringshare_add(dbus_message_get_path(msg->dbus_msg));
|
||||
pending->msg_sent = edbus_message_ref(msg);
|
||||
EINA_MAGIC_SET(pending, EDBUS_PENDING_MAGIC);
|
||||
|
||||
if (!dbus_connection_send_with_reply(conn->dbus_conn,
|
||||
msg->dbus_msg,
|
||||
&pending->dbus_pending, timeout))
|
||||
{
|
||||
error_msg = edbus_message_error_new(msg, "org.enlightenment.DBus.NoConnection",
|
||||
"EDBus_Connection was closed.");
|
||||
edbus_pending_dispatch(pending, error_msg);
|
||||
return NULL;
|
||||
}
|
||||
if (dbus_pending_call_set_notify(pending->dbus_pending, cb_pending, pending, NULL))
|
||||
return pending;
|
||||
|
||||
dbus_pending_call_cancel(pending->dbus_pending);
|
||||
error_msg = edbus_message_error_new(pending->msg_sent,
|
||||
"org.enlightenment.DBus.Error",
|
||||
"Error when try set callback to message.");
|
||||
edbus_pending_dispatch(pending, error_msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_pending_data_set(EDBus_Pending *pending, const char *key, const void *data)
|
||||
{
|
||||
EDBUS_PENDING_CHECK(pending);
|
||||
EINA_SAFETY_ON_NULL_RETURN(key);
|
||||
EINA_SAFETY_ON_NULL_RETURN(data);
|
||||
edbus_data_set(&(pending->data), key, data);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
edbus_pending_data_get(const EDBus_Pending *pending, const char *key)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||
return edbus_data_get(&(((EDBus_Pending *)pending)->data), key);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
edbus_pending_data_del(EDBus_Pending *pending, const char *key)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||
return edbus_data_del(&(((EDBus_Pending *)pending)->data), key);
|
||||
}
|
||||
|
||||
static void
|
||||
edbus_pending_dispatch(EDBus_Pending *pending, EDBus_Message *msg)
|
||||
{
|
||||
DBG("pending=%p msg=%p", pending, msg);
|
||||
if (pending->cb)
|
||||
pending->cb((void *)pending->cb_data, msg, pending);
|
||||
|
||||
edbus_cbs_free_dispatch(&(pending->cbs_free), pending);
|
||||
edbus_data_del_all(&(pending->data));
|
||||
|
||||
if (msg) edbus_message_unref(msg);
|
||||
edbus_message_unref(pending->msg_sent);
|
||||
dbus_pending_call_unref(pending->dbus_pending);
|
||||
|
||||
pending->cb = NULL;
|
||||
pending->dbus_pending = NULL;
|
||||
eina_stringshare_del(pending->dest);
|
||||
eina_stringshare_del(pending->path);
|
||||
eina_stringshare_del(pending->interface);
|
||||
eina_stringshare_del(pending->method);
|
||||
EINA_MAGIC_SET(pending, EINA_MAGIC_NONE);
|
||||
free(pending);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_pending_cancel(EDBus_Pending *pending)
|
||||
{
|
||||
EDBus_Message *error_message;
|
||||
EDBUS_PENDING_CHECK(pending);
|
||||
EINA_SAFETY_ON_NULL_RETURN(pending->dbus_pending);
|
||||
|
||||
DBG("pending=%p", pending);
|
||||
dbus_pending_call_cancel(pending->dbus_pending);
|
||||
|
||||
error_message = edbus_message_error_new(pending->msg_sent,
|
||||
"org.enlightenment.DBus.Canceled",
|
||||
"Canceled by user.");
|
||||
edbus_pending_dispatch(pending, error_message);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_pending_cb_free_add(EDBus_Pending *pending, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PENDING_CHECK(pending);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
pending->cbs_free = edbus_cbs_free_add(pending->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_pending_cb_free_del(EDBus_Pending *pending, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PENDING_CHECK(pending);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
pending->cbs_free = edbus_cbs_free_del(pending->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_pending_destination_get(const EDBus_Pending *pending)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
return pending->dest;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_pending_path_get(const EDBus_Pending *pending)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
return pending->path;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_pending_interface_get(const EDBus_Pending *pending)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
return pending->interface;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_pending_method_get(const EDBus_Pending *pending)
|
||||
{
|
||||
EDBUS_PENDING_CHECK_RETVAL(pending, NULL);
|
||||
return pending->method;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef EDBUS_PENDING_H
|
||||
#define EDBUS_PENDING_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Pending Pending
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
EAPI void edbus_pending_data_set(EDBus_Pending *pending, const char *key, const void *data) EINA_ARG_NONNULL(1, 2, 3);
|
||||
EAPI void *edbus_pending_data_get(const EDBus_Pending *pending, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI void *edbus_pending_data_del(EDBus_Pending *pending, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI void edbus_pending_cancel(EDBus_Pending *pending) EINA_ARG_NONNULL(1);
|
||||
|
||||
EAPI const char *edbus_pending_destination_get(const EDBus_Pending *pending) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_pending_path_get(const EDBus_Pending *pending) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_pending_interface_get(const EDBus_Pending *pending) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_pending_method_get(const EDBus_Pending *pending) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when pending will be freed.
|
||||
*/
|
||||
EAPI void edbus_pending_cb_free_add(EDBus_Pending *pending, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_pending_cb_free_add().
|
||||
*/
|
||||
EAPI void edbus_pending_cb_free_del(EDBus_Pending *pending, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef EDBUS_PRIVATE_H
|
||||
#define EDBUS_PRIVATE_H
|
||||
|
||||
#include <Eina.h>
|
||||
#include "eina_safety_checks.h"
|
||||
#include "EDBus.h"
|
||||
#include "edbus_private_types.h"
|
||||
|
||||
extern int _edbus_log_dom;
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_edbus_log_dom, __VA_ARGS__)
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_edbus_log_dom, __VA_ARGS__)
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_edbus_log_dom, __VA_ARGS__)
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_edbus_log_dom, __VA_ARGS__)
|
||||
#define CRITICAL(...) EINA_LOG_DOM_CRIT(_edbus_log_dom, __VA_ARGS__)
|
||||
|
||||
#define EDBUS_CONNECTION_MAGIC (0xdb050001)
|
||||
#define EDBUS_MESSAGE_MAGIC (0xdb050002)
|
||||
#define EDBUS_SIGNAL_HANDLER_MAGIC (0xdb050003)
|
||||
#define EDBUS_PENDING_MAGIC (0xdb050004)
|
||||
#define EDBUS_OBJECT_MAGIC (0xdb050005)
|
||||
#define EDBUS_PROXY_MAGIC (0xdb050006)
|
||||
#define EDBUS_MESSAGE_ITERATOR_MAGIC (0xdb050007)
|
||||
#define EDBUS_SERVICE_INTERFACE_MAGIC (0xdb050008)
|
||||
|
||||
void edbus_cbs_free_dispatch(Eina_Inlist **p_lst, const void *dead_pointer);
|
||||
Eina_Inlist *edbus_cbs_free_add(Eina_Inlist *lst, EDBus_Free_Cb cb, const void *data);
|
||||
Eina_Inlist *edbus_cbs_free_del(Eina_Inlist *lst, EDBus_Free_Cb cb, const void *data);
|
||||
|
||||
void edbus_data_set(Eina_Inlist **p_lst, const char *key, const void *data) EINA_ARG_NONNULL(1, 2, 3);
|
||||
void *edbus_data_get(Eina_Inlist **p_lst, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
void *edbus_data_del(Eina_Inlist **p_lst, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
void edbus_data_del_all(Eina_Inlist **p_list) EINA_ARG_NONNULL(1);
|
||||
|
||||
Eina_Bool edbus_message_init(void);
|
||||
void edbus_message_shutdown(void);
|
||||
EDBus_Message *edbus_message_new(Eina_Bool writable);
|
||||
|
||||
Eina_Bool edbus_signal_handler_init(void);
|
||||
void edbus_signal_handler_shutdown(void);
|
||||
|
||||
Eina_Bool edbus_pending_init(void);
|
||||
void edbus_pending_shutdown(void);
|
||||
|
||||
Eina_Bool edbus_object_init(void);
|
||||
void edbus_object_shutdown(void);
|
||||
|
||||
Eina_Bool edbus_proxy_init(void);
|
||||
void edbus_proxy_shutdown(void);
|
||||
|
||||
Eina_Bool edbus_service_init(void);
|
||||
void edbus_service_shutdown(void);
|
||||
|
||||
void edbus_connection_event_callback_call(EDBus_Connection *conn, EDBus_Connection_Event_Type type, const void *event_info) EINA_ARG_NONNULL(1);
|
||||
|
||||
Eina_Bool edbus_object_proxy_del(EDBus_Object *obj, EDBus_Proxy *proxy, const char *interface) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
void edbus_connection_signal_handler_add(EDBus_Connection *conn, EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1, 2);
|
||||
void edbus_connection_pending_add(EDBus_Connection *conn, EDBus_Pending *pending) EINA_ARG_NONNULL(1, 2);
|
||||
void edbus_connection_signal_handler_del(EDBus_Connection *conn, EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1, 2);
|
||||
void edbus_connection_signal_handler_del(EDBus_Connection *conn, EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1, 2);
|
||||
void edbus_connection_pending_del(EDBus_Connection *conn, EDBus_Pending *pending) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
EDBus_Object *edbus_connection_name_object_get(EDBus_Connection *conn, const char *name, const char *path);
|
||||
void edbus_connection_name_object_set(EDBus_Connection *conn, EDBus_Object *obj);
|
||||
|
||||
Eina_Bool edbus_object_proxy_add(EDBus_Object *obj, EDBus_Proxy *proxy) EINA_ARG_NONNULL(1, 2);
|
||||
EDBus_Proxy *edbus_object_proxy_get(EDBus_Object *obj, const char *interface);
|
||||
|
||||
void edbus_connection_name_object_del(EDBus_Connection *conn, const EDBus_Object *obj);
|
||||
EDBus_Connection_Name *edbus_connection_name_get(EDBus_Connection *conn, const char *name);
|
||||
void edbus_connection_name_owner_monitor(EDBus_Connection *conn, EDBus_Connection_Name *cn, Eina_Bool enable);
|
||||
|
||||
EDBus_Pending *_edbus_connection_send(EDBus_Connection *conn, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout);
|
||||
|
||||
#ifdef HAVE_VA_LIST_AS_ARRAY
|
||||
#define MAKE_PTR_FROM_VA_LIST(arg) ((va_list *)(arg))
|
||||
#else
|
||||
#define MAKE_PTR_FROM_VA_LIST(arg) (&(arg))
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,168 @@
|
|||
#ifndef EDBUS_PRIVATE_TYPES_H
|
||||
#define EDBUS_PRIVATE_TYPES_H 1
|
||||
|
||||
#include "EDBus.h"
|
||||
#include <Eina.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
typedef struct _EDBus_Connection_Name
|
||||
{
|
||||
const char *name;
|
||||
const char *unique_id;
|
||||
Eina_Hash *objects;
|
||||
int refcount;
|
||||
struct
|
||||
{
|
||||
Eina_Inlist *list; //EDBus_Connection_Context_NOC_Cb
|
||||
int walking;
|
||||
Eina_List *to_delete;
|
||||
} event_handlers;
|
||||
EDBus_Signal_Handler *name_owner_changed;
|
||||
} EDBus_Connection_Name;
|
||||
|
||||
typedef struct _EDBus_Object_Context_Event_Cb
|
||||
{
|
||||
EINA_INLIST;
|
||||
EDBus_Object_Event_Cb cb;
|
||||
const void *cb_data;
|
||||
Eina_Bool deleted : 1;
|
||||
} EDBus_Object_Context_Event_Cb;
|
||||
|
||||
typedef struct _EDBus_Object_Context_Event
|
||||
{
|
||||
Eina_Inlist *list;
|
||||
int walking;
|
||||
Eina_List *to_delete;
|
||||
} EDBus_Object_Context_Event;
|
||||
|
||||
|
||||
typedef struct _EDBus_Connection_Context_Event
|
||||
{
|
||||
Eina_Inlist *list;
|
||||
int walking;
|
||||
Eina_List *to_delete;
|
||||
} EDBus_Connection_Context_Event;
|
||||
|
||||
struct _EDBus_Connection
|
||||
{
|
||||
EINA_MAGIC;
|
||||
EINA_INLIST;
|
||||
int refcount;
|
||||
EDBus_Connection_Type type;
|
||||
DBusConnection *dbus_conn;
|
||||
Eina_Hash *names; //EDBus_Connection_Name
|
||||
Eina_Inlist *data;
|
||||
Eina_Inlist *cbs_free;
|
||||
Eina_Inlist *signal_handlers;
|
||||
Eina_Inlist *pendings;
|
||||
Eina_Inlist *fd_handlers;
|
||||
Eina_Inlist *timeouts;
|
||||
Ecore_Idler *idler;
|
||||
Eina_Bool running_signal;
|
||||
EDBus_Connection_Context_Event event_handlers[EDBUS_CONNECTION_EVENT_LAST];
|
||||
};
|
||||
|
||||
struct _EDBus_Object
|
||||
{
|
||||
EINA_MAGIC;
|
||||
EINA_INLIST;
|
||||
int refcount;
|
||||
EDBus_Connection *conn;
|
||||
const char *name;
|
||||
const char *path;
|
||||
Eina_Hash *proxies;
|
||||
Eina_Inlist *pendings;
|
||||
Eina_List *signal_handlers;
|
||||
Eina_Inlist *cbs_free;
|
||||
EDBus_Object_Context_Event event_handlers[EDBUS_OBJECT_EVENT_LAST];
|
||||
};
|
||||
|
||||
struct _EDBus_Signal_Handler
|
||||
{
|
||||
EINA_MAGIC;
|
||||
EINA_INLIST;
|
||||
int refcount;
|
||||
const char *sender;
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const char *member;
|
||||
Eina_Strbuf *match;
|
||||
Eina_Inlist *args;
|
||||
Eina_Inlist_Sorted_State *state_args;
|
||||
EDBus_Connection *conn;
|
||||
EDBus_Signal_Cb cb;
|
||||
EDBus_Connection_Name *bus;
|
||||
const void *cb_data;
|
||||
Eina_Inlist *cbs_free;
|
||||
Eina_Bool dangling;
|
||||
};
|
||||
|
||||
struct _EDBus_Pending
|
||||
{
|
||||
EINA_MAGIC;
|
||||
EINA_INLIST;
|
||||
EDBus_Message_Cb cb;
|
||||
const void *cb_data;
|
||||
DBusPendingCall *dbus_pending;
|
||||
EDBus_Connection *conn;
|
||||
const char *dest;
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const char *method;
|
||||
Eina_Inlist *data;
|
||||
Eina_Inlist *cbs_free;
|
||||
EDBus_Message *msg_sent;
|
||||
};
|
||||
|
||||
struct _EDBus_Message_Iter
|
||||
{
|
||||
EINA_MAGIC;
|
||||
EINA_INLIST;
|
||||
DBusMessageIter dbus_iterator;
|
||||
Eina_Inlist *iterators;
|
||||
Eina_Bool writable;
|
||||
};
|
||||
|
||||
struct _EDBus_Message
|
||||
{
|
||||
EINA_MAGIC;
|
||||
int refcount;
|
||||
DBusMessage *dbus_msg;
|
||||
EDBus_Message_Iter *iterator;
|
||||
};
|
||||
|
||||
typedef struct _EDBus_Service_Object
|
||||
{
|
||||
EDBus_Connection *conn;
|
||||
const char *path;
|
||||
Eina_Hash *interfaces;
|
||||
Eina_Strbuf *introspection_data;
|
||||
Eina_Bool introspection_dirty;
|
||||
Eina_Inlist *data;
|
||||
} EDBus_Service_Object;
|
||||
|
||||
struct _EDBus_Service_Interface
|
||||
{
|
||||
EINA_MAGIC;
|
||||
const char *name;
|
||||
Eina_Hash *methods;
|
||||
const EDBus_Signal *signals;
|
||||
Eina_Array *sign_of_signals;
|
||||
EDBus_Service_Object *obj;
|
||||
};
|
||||
|
||||
typedef struct _Signal_Argument
|
||||
{
|
||||
EINA_INLIST;
|
||||
unsigned short index;
|
||||
const char *value;
|
||||
} Signal_Argument;
|
||||
|
||||
typedef struct _EDBus_Real_Method
|
||||
{
|
||||
const EDBus_Method *method;
|
||||
const char *in;
|
||||
} EDBus_Real_Method;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,542 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
|
||||
/* TODO: mempool of EDBus_Proxy, Edbus_Proxy_Context_Event_Cb and
|
||||
* EDBus_Proxy_Context_Event
|
||||
*/
|
||||
|
||||
typedef struct _EDBus_Proxy_Context_Event_Cb
|
||||
{
|
||||
EINA_INLIST;
|
||||
EDBus_Proxy_Event_Cb cb;
|
||||
const void *cb_data;
|
||||
Eina_Bool deleted : 1;
|
||||
} EDBus_Proxy_Context_Event_Cb;
|
||||
|
||||
typedef struct _EDBus_Proxy_Context_Event
|
||||
{
|
||||
Eina_Inlist *list;
|
||||
int walking;
|
||||
Eina_List *to_delete;
|
||||
} EDBus_Proxy_Context_Event;
|
||||
|
||||
struct _EDBus_Proxy
|
||||
{
|
||||
EINA_MAGIC;
|
||||
int refcount;
|
||||
EDBus_Object *obj;
|
||||
const char *interface;
|
||||
Eina_Inlist *pendings;
|
||||
Eina_List *handlers;
|
||||
Eina_Inlist *cbs_free;
|
||||
EDBus_Proxy_Context_Event event_handlers[EDBUS_PROXY_EVENT_LAST];
|
||||
};
|
||||
|
||||
#define EDBUS_PROXY_CHECK(proxy) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(proxy); \
|
||||
if (!EINA_MAGIC_CHECK(proxy, EDBUS_PROXY_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(proxy, EDBUS_PROXY_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN(proxy->refcount <= 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_PROXY_CHECK_RETVAL(proxy, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, retval); \
|
||||
if (!EINA_MAGIC_CHECK(proxy, EDBUS_PROXY_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(proxy, EDBUS_PROXY_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(proxy->refcount <= 0, retval); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_PROXY_CHECK_GOTO(proxy, label) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_GOTO(proxy, label); \
|
||||
if (!EINA_MAGIC_CHECK(proxy, EDBUS_PROXY_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(proxy, EDBUS_PROXY_MAGIC); \
|
||||
goto label; \
|
||||
} \
|
||||
EINA_SAFETY_ON_TRUE_GOTO(proxy->refcount <= 0, label); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
Eina_Bool
|
||||
edbus_proxy_init(void)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_proxy_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void _edbus_proxy_event_callback_call(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, const void *event_info);
|
||||
static void _edbus_proxy_context_event_cb_del(EDBus_Proxy_Context_Event *ce, EDBus_Proxy_Context_Event_Cb *ctx);
|
||||
|
||||
static void
|
||||
_edbus_proxy_call_del(EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBus_Proxy_Context_Event *ce;
|
||||
|
||||
_edbus_proxy_event_callback_call(proxy, EDBUS_PROXY_EVENT_DEL, NULL);
|
||||
|
||||
/* clear all del callbacks so we don't call them twice at
|
||||
* _edbus_proxy_clear()
|
||||
*/
|
||||
ce = proxy->event_handlers + EDBUS_PROXY_EVENT_DEL;
|
||||
while (ce->list)
|
||||
{
|
||||
EDBus_Proxy_Context_Event_Cb *ctx;
|
||||
|
||||
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
||||
EDBus_Proxy_Context_Event_Cb);
|
||||
_edbus_proxy_context_event_cb_del(ce, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_proxy_clear(EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBus_Signal_Handler *h;
|
||||
EDBus_Pending *p;
|
||||
Eina_List *iter, *iter_next;
|
||||
Eina_Inlist *in_l;
|
||||
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
|
||||
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
||||
proxy->refcount = 1;
|
||||
edbus_object_proxy_del(proxy->obj, proxy, proxy->interface);
|
||||
_edbus_proxy_call_del(proxy);
|
||||
|
||||
EINA_LIST_FOREACH_SAFE(proxy->handlers, iter, iter_next, h)
|
||||
{
|
||||
DBG("proxy=%p delete owned signal handler %p %s",
|
||||
proxy, h, edbus_signal_handler_match_get(h));
|
||||
edbus_signal_handler_del(h);
|
||||
}
|
||||
|
||||
EINA_INLIST_FOREACH_SAFE(proxy->pendings, in_l, p)
|
||||
{
|
||||
DBG("proxy=%p delete owned pending call=%p dest=%s path=%s %s.%s()",
|
||||
proxy, p,
|
||||
edbus_pending_destination_get(p),
|
||||
edbus_pending_path_get(p),
|
||||
edbus_pending_interface_get(p),
|
||||
edbus_pending_method_get(p));
|
||||
edbus_pending_cancel(p);
|
||||
}
|
||||
|
||||
edbus_cbs_free_dispatch(&(proxy->cbs_free), proxy);
|
||||
proxy->refcount = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_proxy_free(EDBus_Proxy *proxy)
|
||||
{
|
||||
unsigned int i;
|
||||
if (proxy->handlers)
|
||||
{
|
||||
EDBus_Signal_Handler *h;
|
||||
CRITICAL("Proxy %p released with live signal handlers!", proxy);
|
||||
EINA_LIST_FREE (proxy->handlers, h)
|
||||
ERR("proxy=%p alive handler=%p %s", proxy, h,
|
||||
edbus_signal_handler_match_get(h));
|
||||
}
|
||||
|
||||
if (proxy->pendings)
|
||||
CRITICAL("Proxy %p released with live pending calls!", proxy);
|
||||
|
||||
for (i = 0; i < EDBUS_PROXY_EVENT_LAST; i++)
|
||||
{
|
||||
EDBus_Proxy_Context_Event *ce = proxy->event_handlers + i;
|
||||
while (ce->list)
|
||||
{
|
||||
EDBus_Proxy_Context_Event_Cb *ctx;
|
||||
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
||||
EDBus_Proxy_Context_Event_Cb);
|
||||
_edbus_proxy_context_event_cb_del(ce, ctx);
|
||||
}
|
||||
eina_list_free(ce->to_delete);
|
||||
}
|
||||
|
||||
eina_stringshare_del(proxy->interface);
|
||||
EINA_MAGIC_SET(proxy, EINA_MAGIC_NONE);
|
||||
free(proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_object_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Proxy *proxy = data;
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
|
||||
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
||||
_edbus_proxy_clear(proxy);
|
||||
_edbus_proxy_free(proxy);
|
||||
}
|
||||
|
||||
EAPI EDBus_Proxy *
|
||||
edbus_proxy_get(EDBus_Object *obj, const char *interface)
|
||||
{
|
||||
EDBus_Proxy *proxy;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
|
||||
|
||||
proxy = edbus_object_proxy_get(obj, interface);
|
||||
if (proxy) return proxy;
|
||||
|
||||
proxy = calloc(1, sizeof(EDBus_Proxy));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);
|
||||
|
||||
proxy->refcount = 1;
|
||||
proxy->obj = obj;
|
||||
proxy->interface = eina_stringshare_add(interface);
|
||||
EINA_MAGIC_SET(proxy, EDBUS_PROXY_MAGIC);
|
||||
if (!edbus_object_proxy_add(obj, proxy))
|
||||
goto cleanup;
|
||||
edbus_object_cb_free_add(obj, _on_object_free, proxy);
|
||||
|
||||
return proxy;
|
||||
|
||||
cleanup:
|
||||
eina_stringshare_del(proxy->interface);
|
||||
free(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _on_signal_handler_free(void *data, const void *dead_pointer);
|
||||
|
||||
static void
|
||||
_edbus_proxy_unref(EDBus_Proxy *proxy)
|
||||
{
|
||||
proxy->refcount--;
|
||||
if (proxy->refcount > 0) return;
|
||||
|
||||
edbus_object_cb_free_del(proxy->obj, _on_object_free, proxy);
|
||||
_edbus_proxy_clear(proxy);
|
||||
_edbus_proxy_free(proxy);
|
||||
}
|
||||
|
||||
EAPI EDBus_Proxy *
|
||||
edbus_proxy_ref(EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
|
||||
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
||||
proxy->refcount++;
|
||||
return proxy;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_proxy_unref(EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
|
||||
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
||||
_edbus_proxy_unref(proxy);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_proxy_cb_free_add(EDBus_Proxy *proxy, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
proxy->cbs_free = edbus_cbs_free_add(proxy->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_proxy_cb_free_del(EDBus_Proxy *proxy, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
proxy->cbs_free = edbus_cbs_free_del(proxy->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_proxy_event_callback_add(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, EDBus_Proxy_Event_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Proxy_Context_Event *ce;
|
||||
EDBus_Proxy_Context_Event_Cb *ctx;
|
||||
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(type >= EDBUS_PROXY_EVENT_LAST);
|
||||
|
||||
ce = proxy->event_handlers + type;
|
||||
|
||||
ctx = calloc(1, sizeof(EDBus_Proxy_Context_Event_Cb));
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
ctx->cb = cb;
|
||||
ctx->cb_data = cb_data;
|
||||
|
||||
ce->list = eina_inlist_append(ce->list, EINA_INLIST_GET(ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_proxy_context_event_cb_del(EDBus_Proxy_Context_Event *ce, EDBus_Proxy_Context_Event_Cb *ctx)
|
||||
{
|
||||
ce->list = eina_inlist_remove(ce->list, EINA_INLIST_GET(ctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_proxy_event_callback_del(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, EDBus_Proxy_Event_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Proxy_Context_Event *ce;
|
||||
EDBus_Proxy_Context_Event_Cb *iter, *found = NULL;
|
||||
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(type >= EDBUS_PROXY_EVENT_LAST);
|
||||
|
||||
ce = proxy->event_handlers + type;
|
||||
|
||||
EINA_INLIST_FOREACH (ce->list, iter)
|
||||
{
|
||||
if (cb != iter->cb) continue;
|
||||
if ((cb_data) && (cb_data != iter->cb_data)) continue;
|
||||
|
||||
found = iter;
|
||||
break;
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(found);
|
||||
EINA_SAFETY_ON_TRUE_RETURN(found->deleted);
|
||||
|
||||
if (ce->walking)
|
||||
{
|
||||
found->deleted = EINA_TRUE;
|
||||
ce->to_delete = eina_list_append(ce->to_delete, found);
|
||||
return;
|
||||
}
|
||||
|
||||
_edbus_proxy_context_event_cb_del(ce, found);
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_proxy_event_callback_call(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, const void *event_info)
|
||||
{
|
||||
EDBus_Proxy_Context_Event *ce;
|
||||
EDBus_Proxy_Context_Event_Cb *iter;
|
||||
|
||||
ce = proxy->event_handlers + type;
|
||||
|
||||
ce->walking++;
|
||||
EINA_INLIST_FOREACH (ce->list, iter)
|
||||
{
|
||||
if (iter->deleted) continue;
|
||||
iter->cb((void *)iter->cb_data, proxy, (void *)event_info);
|
||||
}
|
||||
ce->walking--;
|
||||
if (ce->walking > 0) return;
|
||||
|
||||
EINA_LIST_FREE (ce->to_delete, iter)
|
||||
_edbus_proxy_context_event_cb_del(ce, iter);
|
||||
}
|
||||
|
||||
EAPI EDBus_Object *
|
||||
edbus_proxy_object_get(const EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
return proxy->obj;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_proxy_interface_get(const EDBus_Proxy *proxy)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
return proxy->interface;
|
||||
}
|
||||
|
||||
static void
|
||||
_on_pending_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Proxy *proxy = data;
|
||||
EDBus_Pending *pending = (EDBus_Pending *)dead_pointer;
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
proxy->pendings = eina_inlist_remove(proxy->pendings,
|
||||
EINA_INLIST_GET(pending));
|
||||
}
|
||||
|
||||
static EDBus_Pending *
|
||||
_edbus_proxy_send(EDBus_Proxy *proxy, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
|
||||
pending = _edbus_connection_send(proxy->obj->conn, msg, cb, cb_data, timeout);
|
||||
if (!cb) return NULL;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
|
||||
|
||||
edbus_pending_cb_free_add(pending, _on_pending_free, proxy);
|
||||
proxy->pendings = eina_inlist_append(proxy->pendings,
|
||||
EINA_INLIST_GET(pending));
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_send(EDBus_Proxy *proxy, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
|
||||
return _edbus_proxy_send(proxy, msg, cb, cb_data, timeout);
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_proxy_method_call_new(EDBus_Proxy *proxy, const char *member)
|
||||
{
|
||||
EDBus_Message *msg;
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
|
||||
msg = edbus_message_method_call_new(
|
||||
edbus_object_bus_name_get(proxy->obj),
|
||||
edbus_object_bus_path_get(proxy->obj),
|
||||
proxy->interface, member);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static EDBus_Pending *
|
||||
_edbus_proxy_vcall(EDBus_Proxy *proxy, const char *member, EDBus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
EDBus_Message *msg = edbus_proxy_method_call_new(proxy, member);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
||||
|
||||
if (!edbus_message_arguments_vset(msg, signature, ap))
|
||||
{
|
||||
edbus_message_unref(msg);
|
||||
ERR("Error setting arguments");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pending = _edbus_proxy_send(proxy, msg, cb, cb_data, timeout);
|
||||
edbus_message_unref(msg);
|
||||
return pending;
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_call(EDBus_Proxy *proxy, const char *member, EDBus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, ...)
|
||||
{
|
||||
EDBus_Pending *pending;
|
||||
va_list ap;
|
||||
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
|
||||
|
||||
va_start(ap, signature);
|
||||
pending = _edbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
|
||||
signature, ap);
|
||||
va_end(ap);
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_vcall(EDBus_Proxy *proxy, const char *member, EDBus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
|
||||
|
||||
return _edbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
|
||||
signature, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_signal_handler_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Proxy *proxy = data;
|
||||
EDBUS_PROXY_CHECK(proxy);
|
||||
proxy->handlers = eina_list_remove(proxy->handlers, dead_pointer);
|
||||
}
|
||||
|
||||
EAPI EDBus_Signal_Handler *
|
||||
edbus_proxy_signal_handler_add(EDBus_Proxy *proxy, const char *member, EDBus_Signal_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Signal_Handler *handler;
|
||||
const char *name, *path;
|
||||
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
|
||||
|
||||
name = edbus_object_bus_name_get(proxy->obj);
|
||||
path = edbus_object_bus_path_get(proxy->obj);
|
||||
|
||||
handler = edbus_signal_handler_add(proxy->obj->conn, name, path,
|
||||
proxy->interface, member, cb, cb_data);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(handler, NULL);
|
||||
|
||||
edbus_signal_handler_cb_free_add(handler, _on_signal_handler_free, proxy);
|
||||
proxy->handlers = eina_list_append(proxy->handlers, handler);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
static EDBus_Proxy *
|
||||
get_properties_proxy(EDBus_Proxy *proxy)
|
||||
{
|
||||
return edbus_proxy_get(proxy->obj, EDBUS_FDO_INTERFACE_PROPERTIES);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_property_get(EDBus_Proxy *proxy, const char *name, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
return edbus_proxy_call(get_properties_proxy(proxy), "Get", cb, data, -1,
|
||||
"ss", proxy->interface, name);
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_property_set(EDBus_Proxy *proxy, const char *name, char type, const void *value, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBus_Message *msg;
|
||||
EDBus_Message_Iter *iter, *variant;
|
||||
EDBus_Pending *pending;
|
||||
char sig[2];
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
if (!dbus_type_is_basic(type))
|
||||
{
|
||||
ERR("Only basic types may be set using edbus_proxy_property_set()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig[0] = type;
|
||||
sig[1] = 0;
|
||||
msg = edbus_proxy_method_call_new(get_properties_proxy(proxy), "Set");
|
||||
iter = edbus_message_iter_get(msg);
|
||||
edbus_message_iter_append_basic(iter, 's', proxy->interface);
|
||||
edbus_message_iter_append_basic(iter, 's', name);
|
||||
variant = edbus_message_iter_container_new(iter, 'v', sig);
|
||||
edbus_message_iter_append_basic(variant, type, value);
|
||||
edbus_message_iter_container_close(iter, variant);
|
||||
|
||||
pending = edbus_proxy_send(get_properties_proxy(proxy), msg, cb, data, -1);
|
||||
edbus_message_unref(msg);
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
EAPI EDBus_Pending *
|
||||
edbus_proxy_property_get_all(EDBus_Proxy *proxy, EDBus_Message_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
||||
return edbus_proxy_call(get_properties_proxy(proxy), "GetAll", cb, data, -1,
|
||||
"s", proxy->interface);
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef EDBUS_PROXY_H
|
||||
#define EDBUS_PROXY_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Proxy Proxy
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Get a proxy of the following interface name in a EDBus_Object.
|
||||
*/
|
||||
EAPI EDBus_Proxy *edbus_proxy_get(EDBus_Object *obj, const char *interface) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* @brief Increase proxy reference.
|
||||
*/
|
||||
EAPI EDBus_Proxy *edbus_proxy_ref(EDBus_Proxy *proxy) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Decrease proxy reference.
|
||||
* If reference == 0 proxy will be freed and all your children's.
|
||||
*/
|
||||
EAPI void edbus_proxy_unref(EDBus_Proxy *proxy) EINA_ARG_NONNULL(1);
|
||||
|
||||
EAPI EDBus_Object *edbus_proxy_object_get(const EDBus_Proxy *proxy) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_proxy_interface_get(const EDBus_Proxy *proxy) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
EAPI void edbus_proxy_data_set(EDBus_Proxy *proxy, const char *key, const void *data) EINA_ARG_NONNULL(1, 2, 3);
|
||||
EAPI void *edbus_proxy_data_get(const EDBus_Proxy *proxy, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
EAPI void *edbus_proxy_data_del(EDBus_Proxy *proxy, const char *key) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when occurs a event of the
|
||||
* type passed.
|
||||
*/
|
||||
EAPI void edbus_proxy_cb_free_add(EDBus_Proxy *proxy, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_proxy_cb_free_add().
|
||||
*/
|
||||
EAPI void edbus_proxy_cb_free_del(EDBus_Proxy *proxy, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Constructs a new message to invoke a method on a remote interface.
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_proxy_method_call_new(EDBus_Proxy *proxy, const char *member);
|
||||
|
||||
/**
|
||||
* @brief Send a message.
|
||||
*
|
||||
* @param proxy the msg will be send in connection that proxy belongs
|
||||
* @param msg message that will be send
|
||||
* @param cb if msg is a method call a callback should be passed
|
||||
* @param cb_data data passed to callback
|
||||
* @param timeout timeout in milliseconds, -1 to default internal value or
|
||||
* EDBUS_TIMEOUT_INFINITE for no timeout
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_proxy_send(EDBus_Proxy *proxy, EDBus_Message *msg, EDBus_Message_Cb cb, const void *cb_data, double timeout) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Call a method in proxy.
|
||||
* Send a method call to interface that proxy belong with data.
|
||||
*
|
||||
* @param proxy
|
||||
* @param member method name
|
||||
* @param cb if msg is a method call a callback should be passed
|
||||
* to be execute when response arrive
|
||||
* @param cb_data data passed to callback
|
||||
* @param timeout timeout in milliseconds, -1 to default internal value or
|
||||
* EDBUS_TIMEOUT_INFINITE for no timeout
|
||||
* @param signature of data that will be send
|
||||
* @param ... data value
|
||||
*
|
||||
* @note This function only support basic type to complex types use
|
||||
* edbus_message_iter_* functions.
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_proxy_call(EDBus_Proxy *proxy, const char *member, EDBus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, ...) EINA_ARG_NONNULL(1, 2, 6);
|
||||
/**
|
||||
* @brief Call a method in proxy.
|
||||
* Send a method call to interface that proxy belong with data.
|
||||
*
|
||||
* @param proxy
|
||||
* @param member method name
|
||||
* @param cb callback that will be called when response arrive.
|
||||
* @param cb_data data passed to callback
|
||||
* @param timeout timeout in milliseconds, -1 to default internal value or
|
||||
* EDBUS_TIMEOUT_INFINITE for no timeout
|
||||
* @param signature of data that will be send
|
||||
* @param ap va_list of data value
|
||||
*
|
||||
* @note This function only support basic type to complex types use
|
||||
* edbus_message_iter_* functions.
|
||||
*/
|
||||
EAPI EDBus_Pending *edbus_proxy_vcall(EDBus_Proxy *proxy, const char *member, EDBus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap) EINA_ARG_NONNULL(1, 2, 6);
|
||||
/**
|
||||
* @brief Add a signal handler.
|
||||
*
|
||||
* @param proxy interface where the signal is emitted
|
||||
* @param member name of the signal
|
||||
* @param cb callback that will be called when this signal is received
|
||||
* @param cb_data data that will be passed to callback
|
||||
*/
|
||||
EAPI EDBus_Signal_Handler *edbus_proxy_signal_handler_add(EDBus_Proxy *proxy, const char *member, EDBus_Signal_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EDBUS_PROXY_EVENT_PROPERTY_CHANGED = 0,
|
||||
EDBUS_PROXY_EVENT_PROPERTY_REMOVED,
|
||||
EDBUS_PROXY_EVENT_DEL,
|
||||
EDBUS_PROXY_EVENT_LAST /**< sentinel, not a real event type */
|
||||
} EDBus_Proxy_Event_Type;
|
||||
|
||||
typedef struct _EDBus_Proxy_Event_Property_Changed
|
||||
{
|
||||
const char *name;
|
||||
const Eina_Value *value;
|
||||
} EDBus_Proxy_Event_Property_Changed;
|
||||
|
||||
typedef struct _EDBus_Proxy_Event_Property_Removed
|
||||
{
|
||||
const char *interface;
|
||||
EDBus_Proxy *proxy;
|
||||
const char *name;
|
||||
} EDBus_Proxy_Event_Property_Removed;
|
||||
|
||||
typedef void (*EDBus_Proxy_Event_Cb)(void *data, EDBus_Proxy *proxy, void *event_info);
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when occurs a event of the
|
||||
* type passed.
|
||||
*/
|
||||
EAPI void edbus_proxy_event_callback_add(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, EDBus_Proxy_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_connection_event_callback_add().
|
||||
*/
|
||||
EAPI void edbus_proxy_event_callback_del(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, EDBus_Proxy_Event_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 3);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,616 @@
|
|||
#include "edbus_private_types.h"
|
||||
#include "edbus_private.h"
|
||||
|
||||
#define DBUS_ANNOTATION(name, value) \
|
||||
"<annotation" \
|
||||
" name=\"org.freedesktop.DBus." name "\"" \
|
||||
" value=\"" value "\"" \
|
||||
"/>"
|
||||
|
||||
#define DBUS_ANNOTATION_DEPRECATED DBUS_ANNOTATION("Deprecated", "true")
|
||||
#define DBUS_ANNOTATION_NOREPLY DBUS_ANNOTATION("Method.NoReply", "true")
|
||||
|
||||
#define EDBUS_SERVICE_INTERFACE_CHECK(obj) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(obj); \
|
||||
if (!EINA_MAGIC_CHECK(obj, EDBUS_SERVICE_INTERFACE_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(obj, EDBUS_SERVICE_INTERFACE_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(obj, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, retval); \
|
||||
if (!EINA_MAGIC_CHECK(obj, EDBUS_SERVICE_INTERFACE_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(obj, EDBUS_SERVICE_INTERFACE_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
static void _object_unregister(DBusConnection *conn, void *user_data);
|
||||
static DBusHandlerResult _object_handler(DBusConnection *conn, DBusMessage *message, void *user_data);
|
||||
static void _object_free(EDBus_Service_Object *obj);
|
||||
static void _interface_free(EDBus_Service_Interface *interface);
|
||||
static void _on_connection_free(void *data, const void *dead_pointer);
|
||||
|
||||
static DBusObjectPathVTable vtable = {
|
||||
_object_unregister,
|
||||
_object_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EDBus_Service_Interface *introspectable;
|
||||
|
||||
static void
|
||||
_instrospect_append_signal(Eina_Strbuf *buf, const EDBus_Signal *sig)
|
||||
{
|
||||
int i;
|
||||
const char *part, *name;
|
||||
|
||||
eina_strbuf_append_printf(buf, "<signal name=\"%s\">", sig->name);
|
||||
if (sig->flags & EDBUS_SIGNAL_FLAG_DEPRECATED)
|
||||
eina_strbuf_append(buf, DBUS_ANNOTATION_DEPRECATED);
|
||||
|
||||
for (i = 0; &sig->args[i] && sig->args[i].signature; i++)
|
||||
{
|
||||
part = sig->args[i].signature;
|
||||
name = sig->args[i].name;
|
||||
|
||||
if (name && name[0])
|
||||
eina_strbuf_append_printf(buf, "<arg type=\"%s\" name=\"%s\"/>",
|
||||
part, name);
|
||||
else
|
||||
eina_strbuf_append_printf(buf, "<arg type=\"%s\"/>", part);
|
||||
}
|
||||
eina_strbuf_append(buf, "</signal>");
|
||||
}
|
||||
|
||||
static void
|
||||
_introspect_append_method(Eina_Strbuf *buf, const EDBus_Method *method)
|
||||
{
|
||||
int i;
|
||||
const char *part, *name;
|
||||
|
||||
eina_strbuf_append_printf(buf, "<method name=\"%s\">", method->member);
|
||||
if (method->flags & EDBUS_METHOD_FLAG_DEPRECATED)
|
||||
eina_strbuf_append(buf, DBUS_ANNOTATION_DEPRECATED);
|
||||
if (method->flags & EDBUS_METHOD_FLAG_NOREPLY)
|
||||
eina_strbuf_append(buf, DBUS_ANNOTATION_NOREPLY);
|
||||
|
||||
for (i = 0; &method->in[i] && method->in[i].signature; i++)
|
||||
{
|
||||
part = method->in[i].signature;
|
||||
name = method->in[i].name;
|
||||
|
||||
if (name && name[0])
|
||||
eina_strbuf_append_printf(buf,
|
||||
"<arg type=\"%s\" name=\"%s\" direction=\"in\"/>",
|
||||
part, name);
|
||||
else
|
||||
eina_strbuf_append_printf(buf, "<arg type=\"%s\" direction=\"in\"/>",
|
||||
part);
|
||||
}
|
||||
|
||||
for (i = 0; &method->out[i] && method->out[i].signature; i++)
|
||||
{
|
||||
part = method->out[i].signature;
|
||||
name = method->out[i].name;
|
||||
|
||||
if (name && name[0])
|
||||
eina_strbuf_append_printf(buf,
|
||||
"<arg type=\"%s\" name=\"%s\" direction=\"out\"/>",
|
||||
part, name);
|
||||
else
|
||||
eina_strbuf_append_printf(buf, "<arg type=\"%s\" direction=\"out\"/>",
|
||||
part);
|
||||
}
|
||||
eina_strbuf_append(buf, "</method>");
|
||||
}
|
||||
|
||||
static void
|
||||
_introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface)
|
||||
{
|
||||
EDBus_Real_Method *method;
|
||||
Eina_Iterator *iterator;
|
||||
unsigned short i;
|
||||
unsigned int size;
|
||||
|
||||
eina_strbuf_append_printf(buf, "<interface name=\"%s\">", iface->name);
|
||||
iterator = eina_hash_iterator_data_new(iface->methods);
|
||||
EINA_ITERATOR_FOREACH(iterator, method)
|
||||
_introspect_append_method(buf, method->method);
|
||||
eina_iterator_free(iterator);
|
||||
|
||||
size = eina_array_count(iface->sign_of_signals);
|
||||
for (i = 0; i < size; i++)
|
||||
_instrospect_append_signal(buf, &iface->signals[i]);
|
||||
|
||||
eina_strbuf_append(buf, "</interface>");
|
||||
}
|
||||
|
||||
static EDBus_Message *
|
||||
cb_introspect(const EDBus_Service_Interface *_iface, const EDBus_Message *message)
|
||||
{
|
||||
EDBus_Service_Object *obj = _iface->obj;
|
||||
EDBus_Message *reply = edbus_message_method_return_new(message);
|
||||
if (obj->introspection_dirty || !obj->introspection_data)
|
||||
{
|
||||
Eina_Iterator *iterator;
|
||||
EDBus_Service_Interface *iface;
|
||||
|
||||
if (obj->introspection_data)
|
||||
eina_strbuf_reset(obj->introspection_data);
|
||||
else
|
||||
obj->introspection_data = eina_strbuf_new();
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj->introspection_data, NULL);
|
||||
|
||||
eina_strbuf_append(obj->introspection_data, "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">");
|
||||
eina_strbuf_append_printf(obj->introspection_data,
|
||||
"<node name=\"%s\">", obj->path);
|
||||
|
||||
iterator = eina_hash_iterator_data_new(obj->interfaces);
|
||||
EINA_ITERATOR_FOREACH(iterator, iface)
|
||||
_introspect_append_interface(obj->introspection_data, iface);
|
||||
eina_iterator_free(iterator);
|
||||
eina_strbuf_append(obj->introspection_data, "</node>");
|
||||
|
||||
obj->introspection_dirty = EINA_FALSE;
|
||||
}
|
||||
|
||||
edbus_message_arguments_set(reply, "s", eina_strbuf_string_get(obj->introspection_data));
|
||||
return reply;
|
||||
}
|
||||
|
||||
static const EDBus_Method instrospect = { "Introspect", EDBUS_ARGS({ "", "" }),
|
||||
EDBUS_ARGS({ "s", "xml" }),
|
||||
cb_introspect, 0
|
||||
};
|
||||
|
||||
static void
|
||||
_introspectable_create(void)
|
||||
{
|
||||
EDBus_Real_Method *r_instrospect;
|
||||
introspectable = calloc(1, sizeof(EDBus_Service_Interface));
|
||||
EINA_SAFETY_ON_NULL_RETURN(introspectable);
|
||||
|
||||
r_instrospect = malloc(sizeof(EDBus_Real_Method));
|
||||
EINA_SAFETY_ON_NULL_RETURN(r_instrospect);
|
||||
r_instrospect->in = "";
|
||||
r_instrospect->method = &instrospect;
|
||||
|
||||
EINA_MAGIC_SET(introspectable, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||
introspectable->sign_of_signals = eina_array_new(1);
|
||||
introspectable->name = eina_stringshare_add("org.freedesktop.DBus.Introspectable");
|
||||
introspectable->methods = eina_hash_string_small_new(NULL);
|
||||
|
||||
eina_hash_add(introspectable->methods, instrospect.member, r_instrospect);
|
||||
}
|
||||
|
||||
static void
|
||||
_instrospectable_free(void)
|
||||
{
|
||||
EDBus_Real_Method *method;
|
||||
method = eina_hash_find(introspectable->methods, instrospect.member);
|
||||
eina_stringshare_del(method->in);
|
||||
free(method);
|
||||
eina_hash_free(introspectable->methods);
|
||||
eina_stringshare_del(introspectable->name);
|
||||
eina_array_free(introspectable->sign_of_signals);
|
||||
free(introspectable);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
edbus_service_init(void)
|
||||
{
|
||||
_introspectable_create();
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(introspectable, EINA_FALSE);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_service_shutdown(void)
|
||||
{
|
||||
_instrospectable_free();
|
||||
}
|
||||
|
||||
static EDBus_Service_Object *
|
||||
_edbus_service_object_add(EDBus_Connection *conn, const char *path)
|
||||
{
|
||||
EDBus_Service_Object *obj;
|
||||
|
||||
obj = calloc(1, sizeof(EDBus_Service_Object));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
|
||||
|
||||
if (!dbus_connection_register_object_path(conn->dbus_conn, path, &vtable,
|
||||
obj))
|
||||
{
|
||||
free(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->conn = conn;
|
||||
obj->path = eina_stringshare_add(path);
|
||||
obj->interfaces = eina_hash_string_superfast_new(NULL);
|
||||
edbus_connection_cb_free_add(conn, _on_connection_free, obj);
|
||||
|
||||
eina_hash_add(obj->interfaces, introspectable->name, introspectable);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static EDBus_Service_Interface *
|
||||
_edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface)
|
||||
{
|
||||
EDBus_Service_Interface *iface;
|
||||
|
||||
iface = eina_hash_find(obj->interfaces, interface);
|
||||
if (iface) return iface;
|
||||
|
||||
iface = calloc(1, sizeof(EDBus_Service_Interface));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
|
||||
|
||||
EINA_MAGIC_SET(iface, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||
iface->name = eina_stringshare_add(interface);
|
||||
iface->methods = eina_hash_string_superfast_new(NULL);
|
||||
iface->obj = obj;
|
||||
eina_hash_add(obj->interfaces, iface->name, iface);
|
||||
return iface;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_edbus_service_method_add(EDBus_Service_Interface *interface, EDBus_Method *method)
|
||||
{
|
||||
EDBus_Real_Method *rm;
|
||||
Eina_Strbuf *buf;
|
||||
int z;
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(!!eina_hash_find(interface->methods,
|
||||
method->member), EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(method->member, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(method->cb, EINA_FALSE);
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
for (z = 0; &method->in[z] && method->in[z].signature; z++)
|
||||
eina_strbuf_append(buf, method->in[z].signature);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(
|
||||
dbus_signature_validate(eina_strbuf_string_get(buf), NULL),
|
||||
error);
|
||||
|
||||
rm = malloc(sizeof(EDBus_Real_Method));
|
||||
EINA_SAFETY_ON_NULL_GOTO(rm, error);
|
||||
rm->method = method;
|
||||
rm->in = eina_stringshare_add(eina_strbuf_string_get(buf));
|
||||
eina_strbuf_free(buf);
|
||||
|
||||
//check if out is valid
|
||||
buf = eina_strbuf_new();
|
||||
for (z = 0; &method->out[z] && method->out[z].signature; z++)
|
||||
eina_strbuf_append(buf, method->out[z].signature);
|
||||
EINA_SAFETY_ON_FALSE_GOTO(
|
||||
dbus_signature_validate(eina_strbuf_string_get(buf), NULL),
|
||||
invalid_out);
|
||||
|
||||
eina_strbuf_free(buf);
|
||||
eina_hash_add(interface->methods, method->member, rm);
|
||||
return EINA_TRUE;
|
||||
|
||||
invalid_out:
|
||||
eina_stringshare_del(rm->in);
|
||||
free(rm);
|
||||
error:
|
||||
eina_strbuf_free(buf);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI EDBus_Service_Interface *
|
||||
edbus_service_interface_register(EDBus_Connection *conn, const char *path, const char *interface, const EDBus_Method methods[], const EDBus_Signal signals[])
|
||||
{
|
||||
EDBus_Service_Object *obj;
|
||||
EDBus_Service_Interface *iface;
|
||||
EDBus_Method *method;
|
||||
unsigned short i, z;
|
||||
Eina_Strbuf *buf = NULL;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(path, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(interface, EINA_FALSE);
|
||||
|
||||
if (!dbus_connection_get_object_path_data(conn->dbus_conn, path,
|
||||
(void*)&obj))
|
||||
{
|
||||
ERR("Invalid object path");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (obj == NULL)
|
||||
obj = _edbus_service_object_add(conn, path);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
|
||||
|
||||
iface = _edbus_service_interface_add(obj, interface);
|
||||
if (!iface)
|
||||
{
|
||||
if (eina_hash_population(obj->interfaces) < 2)
|
||||
_object_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (method = (EDBus_Method *)methods; method && method->member; method++)
|
||||
_edbus_service_method_add(iface, method);
|
||||
|
||||
if (!iface->sign_of_signals)
|
||||
iface->sign_of_signals = eina_array_new(1);
|
||||
for (i = 0; &signals[i] && signals[i].name; i++)
|
||||
{
|
||||
buf = eina_strbuf_new();
|
||||
for (z = 0; &signals[i].args[z] && signals[i].args[z].signature; z++)
|
||||
eina_strbuf_append(buf, signals[i].args[z].signature);
|
||||
|
||||
if (!dbus_signature_validate(eina_strbuf_string_get(buf), NULL))
|
||||
{
|
||||
ERR("Signal with invalid signature: interface=%s signal=%s",
|
||||
iface->name, signals[i].name);
|
||||
eina_strbuf_free(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
eina_array_push(iface->sign_of_signals,
|
||||
eina_stringshare_add(eina_strbuf_string_get(buf)));
|
||||
eina_strbuf_free(buf);
|
||||
}
|
||||
iface->signals = signals;
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
static void
|
||||
_interface_free(EDBus_Service_Interface *interface)
|
||||
{
|
||||
unsigned size, i;
|
||||
Eina_Iterator *iterator;
|
||||
EDBus_Real_Method *method;
|
||||
if (interface == introspectable) return;
|
||||
|
||||
iterator = eina_hash_iterator_data_new(interface->methods);
|
||||
EINA_ITERATOR_FOREACH(iterator, method)
|
||||
{
|
||||
eina_stringshare_del(method->in);
|
||||
free(method);
|
||||
}
|
||||
eina_iterator_free(iterator);
|
||||
eina_hash_free(interface->methods);
|
||||
eina_stringshare_del(interface->name);
|
||||
size = eina_array_count(interface->sign_of_signals);
|
||||
for (i = 0; i < size; i++)
|
||||
eina_stringshare_del(eina_array_data_get(interface->sign_of_signals, i));
|
||||
eina_array_free(interface->sign_of_signals);
|
||||
free(interface);
|
||||
}
|
||||
|
||||
static void
|
||||
_object_free(EDBus_Service_Object *obj)
|
||||
{
|
||||
Eina_Iterator *iterator;
|
||||
EDBus_Service_Interface *iface;
|
||||
|
||||
iterator = eina_hash_iterator_data_new(obj->interfaces);
|
||||
EINA_ITERATOR_FOREACH(iterator, iface)
|
||||
_interface_free(iface);
|
||||
|
||||
edbus_data_del_all(&obj->data);
|
||||
|
||||
eina_hash_free(obj->interfaces);
|
||||
eina_iterator_free(iterator);
|
||||
if (obj->introspection_data)
|
||||
eina_strbuf_free(obj->introspection_data);
|
||||
eina_stringshare_del(obj->path);
|
||||
free(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_connection_free(void *data, const void *dead_pointer)
|
||||
{
|
||||
EDBus_Service_Object *obj = data;
|
||||
dbus_connection_unregister_object_path(obj->conn->dbus_conn, obj->path);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_service_interface_unregister(EDBus_Service_Interface *iface)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK(iface);
|
||||
eina_hash_del(iface->obj->interfaces, NULL, iface);
|
||||
if (eina_hash_population(iface->obj->interfaces) < 2)
|
||||
edbus_service_object_unregister(iface);
|
||||
_interface_free(iface);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_service_object_unregister(EDBus_Service_Interface *iface)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK(iface);
|
||||
/*
|
||||
* It will be freed when _object_unregister() is called
|
||||
* by libdbus.
|
||||
*/
|
||||
edbus_connection_cb_free_del(iface->obj->conn, _on_connection_free, iface->obj);
|
||||
dbus_connection_unregister_object_path(iface->obj->conn->dbus_conn, iface->obj->path);
|
||||
}
|
||||
|
||||
static void
|
||||
_object_unregister(DBusConnection *conn, void *user_data)
|
||||
{
|
||||
EDBus_Service_Object *obj = user_data;
|
||||
_object_free(obj);
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
_object_handler(DBusConnection *conn, DBusMessage *msg, void *user_data)
|
||||
{
|
||||
EDBus_Service_Object *obj;
|
||||
EDBus_Service_Interface *iface;
|
||||
EDBus_Real_Method *method;
|
||||
EDBus_Message *edbus_msg;
|
||||
EDBus_Message *reply;
|
||||
|
||||
obj = user_data;
|
||||
if (!obj) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
DBG("Connection@%p Got message:\n"
|
||||
" Type: %s\n"
|
||||
" Path: %s\n"
|
||||
" Interface: %s\n"
|
||||
" Member: %s\n"
|
||||
" Sender: %s", obj->conn,
|
||||
dbus_message_type_to_string(dbus_message_get_type(msg)),
|
||||
dbus_message_get_path(msg),
|
||||
dbus_message_get_interface(msg),
|
||||
dbus_message_get_member(msg),
|
||||
dbus_message_get_sender(msg));
|
||||
|
||||
iface = eina_hash_find(obj->interfaces, dbus_message_get_interface(msg));
|
||||
if (!iface) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
method = eina_hash_find(iface->methods, dbus_message_get_member(msg));
|
||||
if (!method) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
edbus_msg = edbus_message_new(EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(edbus_msg, DBUS_HANDLER_RESULT_NEED_MEMORY);
|
||||
edbus_msg->dbus_msg = msg;
|
||||
dbus_message_iter_init(edbus_msg->dbus_msg, &edbus_msg->iterator->dbus_iterator);
|
||||
|
||||
if (method->in && !dbus_message_has_signature(msg, method->in))
|
||||
{
|
||||
char buf[DBUS_MAXIMUM_SIGNATURE_LENGTH +
|
||||
sizeof("Expected signature: ")];
|
||||
snprintf(buf, sizeof(buf), "Expected signature: %s", method->in);
|
||||
reply = edbus_message_error_new(edbus_msg,
|
||||
DBUS_ERROR_INVALID_SIGNATURE, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iface->obj)
|
||||
reply = method->method->cb(iface, edbus_msg);
|
||||
else
|
||||
{
|
||||
//if iface does have obj it is some of FreeDesktop interfaces:
|
||||
//Introspectable, Properties...
|
||||
EDBus_Service_Interface *cpy;
|
||||
cpy = calloc(1, sizeof(EDBus_Service_Interface));
|
||||
if (!cpy)
|
||||
{
|
||||
dbus_message_ref(edbus_msg->dbus_msg);
|
||||
edbus_message_unref(edbus_msg);
|
||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
}
|
||||
cpy->obj = obj;
|
||||
reply = method->method->cb(cpy, edbus_msg);
|
||||
free(cpy);
|
||||
}
|
||||
}
|
||||
|
||||
dbus_message_ref(edbus_msg->dbus_msg);
|
||||
edbus_message_unref(edbus_msg);
|
||||
if (!reply) return DBUS_HANDLER_RESULT_HANDLED;
|
||||
|
||||
_edbus_connection_send(obj->conn, reply, NULL, NULL, -1);
|
||||
edbus_message_unref(reply);
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
EAPI EDBus_Connection *
|
||||
edbus_service_connection_get(const EDBus_Service_Interface *iface)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, NULL);
|
||||
return iface->obj->conn;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_service_object_path_get(const EDBus_Service_Interface *iface)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, NULL);
|
||||
return iface->obj->path;
|
||||
}
|
||||
|
||||
EAPI EDBus_Message *
|
||||
edbus_service_signal_new(EDBus_Service_Interface *iface, unsigned int signal_id)
|
||||
{
|
||||
unsigned size;
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||
size = eina_array_count(iface->sign_of_signals);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(signal_id < size, EINA_FALSE);
|
||||
|
||||
return edbus_message_signal_new(iface->obj->path, iface->name,
|
||||
iface->signals[signal_id].name);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_service_signal_emit(EDBus_Service_Interface *iface, unsigned int signal_id, ...)
|
||||
{
|
||||
EDBus_Message *sig;
|
||||
va_list ap;
|
||||
Eina_Bool r;
|
||||
const char *signature;
|
||||
unsigned size;
|
||||
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||
size = eina_array_count(iface->sign_of_signals);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(signal_id < size, EINA_FALSE);
|
||||
|
||||
sig = edbus_service_signal_new(iface, signal_id);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sig, EINA_FALSE);
|
||||
|
||||
signature = eina_array_data_get(iface->sign_of_signals, signal_id);
|
||||
va_start(ap, signal_id);
|
||||
r = edbus_message_arguments_vset(sig, signature, ap);
|
||||
va_end(ap);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(r, EINA_FALSE);
|
||||
|
||||
edbus_service_signal_send(iface, sig);
|
||||
edbus_message_unref(sig);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_service_signal_send(EDBus_Service_Interface *iface, EDBus_Message *signal_msg)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(signal_msg, EINA_FALSE);
|
||||
_edbus_connection_send(iface->obj->conn, signal_msg, NULL, NULL, -1);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_service_object_data_set(EDBus_Service_Interface *iface, const char *key, const void *data)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK(iface);
|
||||
EINA_SAFETY_ON_NULL_RETURN(key);
|
||||
EINA_SAFETY_ON_NULL_RETURN(data);
|
||||
edbus_data_set(&(iface->obj->data), key, data);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
edbus_service_object_data_get(const EDBus_Service_Interface *iface, const char *key)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||
return edbus_data_get(&(((EDBus_Service_Object *)iface->obj)->data), key);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
edbus_service_object_data_del(EDBus_Service_Interface *iface, const char *key)
|
||||
{
|
||||
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||
return edbus_data_del(&(((EDBus_Service_Object *)iface->obj)->data), key);
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
#ifndef EDBUS_SERVICE_H
|
||||
#define EDBUS_SERVICE_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Service Service
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define EDBUS_METHOD_FLAG_DEPRECATED 1
|
||||
#define EDBUS_METHOD_FLAG_NOREPLY (1 << 1)
|
||||
|
||||
#define EDBUS_SIGNAL_FLAG_DEPRECATED 1
|
||||
|
||||
typedef struct _EDBus_Arg_Info
|
||||
{
|
||||
const char *signature;
|
||||
const char *name;
|
||||
} EDBus_Arg_Info;
|
||||
|
||||
/**
|
||||
* @brief Used to insert complete types to signature of methods or signals.
|
||||
*
|
||||
* Example: EDBUS_ARGS({"s", "interface"}, {"s", "property"})
|
||||
* The signature will be "ss" and each string will have a tag name on
|
||||
* introspect XML with the respective name.
|
||||
*/
|
||||
#define EDBUS_ARGS(args...) (const EDBus_Arg_Info[]){ args, { } }
|
||||
|
||||
typedef struct _EDBus_Service_Interface EDBus_Service_Interface;
|
||||
typedef EDBus_Message * (*EDBus_Method_Cb)(const EDBus_Service_Interface *iface, const EDBus_Message *message);
|
||||
|
||||
typedef struct _EDBus_Method
|
||||
{
|
||||
const char *member;
|
||||
const EDBus_Arg_Info *in;
|
||||
const EDBus_Arg_Info *out;
|
||||
EDBus_Method_Cb cb;
|
||||
unsigned int flags;
|
||||
} EDBus_Method;
|
||||
|
||||
typedef struct _EDBus_Signal
|
||||
{
|
||||
const char *name;
|
||||
const EDBus_Arg_Info *args;
|
||||
unsigned int flags;
|
||||
} EDBus_Signal;
|
||||
|
||||
/**
|
||||
* @brief Register a interface on the passed path and connection.
|
||||
*
|
||||
* @param conn where the interface should listen
|
||||
* @param path object path
|
||||
* @param iface interface
|
||||
* @param methods array of the methods that should be registered in this
|
||||
* interface, the last item of array should be filled with NULL
|
||||
* @param signals array of signal that this interface send, the last item
|
||||
* of array should be filled with NULL
|
||||
*
|
||||
* @note methods and signals must be static variables
|
||||
*
|
||||
* @return Interface
|
||||
*/
|
||||
EAPI EDBus_Service_Interface *edbus_service_interface_register(EDBus_Connection *conn, const char *path, const char *interface, const EDBus_Method methods[], const EDBus_Signal signals[]);
|
||||
/**
|
||||
* @brief Unregister a interface.
|
||||
* If this is the last interface of object path, the object path will be
|
||||
* remove too.
|
||||
*/
|
||||
EAPI void edbus_service_interface_unregister(EDBus_Service_Interface *iface);
|
||||
/**
|
||||
* @brief Unregister all interfaces of the object path that this interface belongs
|
||||
* and the object path.
|
||||
*/
|
||||
EAPI void edbus_service_object_unregister(EDBus_Service_Interface *iface);
|
||||
EAPI EDBus_Connection *edbus_service_connection_get(const EDBus_Service_Interface *iface);
|
||||
EAPI const char *edbus_service_object_path_get(const EDBus_Service_Interface *iface);
|
||||
|
||||
/**
|
||||
* @brief Emit a signal handler of the interface with non-complex types.
|
||||
* Each signal handler have a internal id, the first signal handler of
|
||||
* interface is = 0 the second = 1 and go on.
|
||||
*
|
||||
* @param iface interface of the signal
|
||||
* @param signal_id id of signal
|
||||
* @param ... values that will be send on signal
|
||||
*/
|
||||
EAPI Eina_Bool edbus_service_signal_emit(EDBus_Service_Interface *iface, unsigned int signal_id, ...) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Create signal message.
|
||||
* Each signal handler have a internal id, the first signal handler of
|
||||
* interface is = 0 the second = 1 and go on.
|
||||
* This function is used when signal have complex types.
|
||||
*
|
||||
* @param iface interface of the signal
|
||||
* @param signal_id id of signal
|
||||
*/
|
||||
EAPI EDBus_Message *edbus_service_signal_new(EDBus_Service_Interface *iface, unsigned int signal_id) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Send a signal message.
|
||||
*/
|
||||
EAPI Eina_Bool edbus_service_signal_send(EDBus_Service_Interface *iface, EDBus_Message *signal_msg) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Store data at object path, this data can be get from all interfaces
|
||||
* of the same object.
|
||||
*
|
||||
* @param iface interface that belong to the object path where data will
|
||||
* be stored
|
||||
* @param key to identify data
|
||||
* @param data
|
||||
*/
|
||||
EAPI void edbus_service_object_data_set(EDBus_Service_Interface *iface, const char *key, const void *data);
|
||||
/**
|
||||
* @brief Get data stored in object path.
|
||||
*
|
||||
* @param iface interface that belong to the object path where data are stored
|
||||
* @param key that identify data
|
||||
*
|
||||
* @return pointer to data if found otherwise NULL
|
||||
*/
|
||||
EAPI void *edbus_service_object_data_get(const EDBus_Service_Interface *iface, const char *key);
|
||||
/**
|
||||
* @brief Del data stored in object path.
|
||||
*
|
||||
* @param iface interface that belong to the object path where data are stored
|
||||
* @param key that identify data
|
||||
*
|
||||
* @return pointer to data if found otherwise NULL
|
||||
*/
|
||||
EAPI void *edbus_service_object_data_del(EDBus_Service_Interface *iface, const char *key);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
|
@ -0,0 +1,340 @@
|
|||
#include "edbus_private.h"
|
||||
#include "edbus_private_types.h"
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
/* TODO: mempool of EDBus_Signal_Handler */
|
||||
|
||||
#define SENDER_KEY "sender"
|
||||
#define PATH_KEY "path"
|
||||
#define INTERFACE_KEY "interface"
|
||||
#define MEMBER_KEY "member"
|
||||
#define ARG_X_KEY "arg%u"
|
||||
|
||||
#define EDBUS_SIGNAL_HANDLER_CHECK(handler) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN(handler); \
|
||||
if (!EINA_MAGIC_CHECK(handler, EDBUS_SIGNAL_HANDLER_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(handler, EDBUS_SIGNAL_HANDLER_MAGIC); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, retval) \
|
||||
do \
|
||||
{ \
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(handler, retval); \
|
||||
if (!EINA_MAGIC_CHECK(handler, EDBUS_SIGNAL_HANDLER_MAGIC)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL(handler, EDBUS_SIGNAL_HANDLER_MAGIC); \
|
||||
return retval; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
static void _edbus_signal_handler_del(EDBus_Signal_Handler *handler);
|
||||
static void _edbus_signal_handler_clean(EDBus_Signal_Handler *handler);
|
||||
|
||||
Eina_Bool
|
||||
edbus_signal_handler_init(void)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
edbus_signal_handler_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_match_append(Eina_Strbuf *match, const char *key, const char *value)
|
||||
{
|
||||
if (value == NULL || !value[0]) return;
|
||||
|
||||
if ((eina_strbuf_length_get(match) + strlen(",=''") + strlen(key) + strlen(value))
|
||||
>= DBUS_MAXIMUM_MATCH_RULE_LENGTH)
|
||||
{
|
||||
ERR("cannot add match %s='%s' to %s: too long!", key, value,
|
||||
eina_strbuf_string_get(match));
|
||||
return;
|
||||
}
|
||||
|
||||
eina_strbuf_append_printf(match, ",%s='%s'", key, value);
|
||||
}
|
||||
|
||||
#define ARGX "arg"
|
||||
|
||||
static int
|
||||
_sort_arg(const void *d1, const void *d2)
|
||||
{
|
||||
const Signal_Argument *arg1, *arg2;
|
||||
arg1 = d1;
|
||||
arg2 = d2;
|
||||
return arg1->index - arg2->index;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
edbus_signal_handler_match_extra_set(EDBus_Signal_Handler *sh, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *key = NULL, *value;
|
||||
Signal_Argument *arg;
|
||||
DBusError err;
|
||||
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(sh, EINA_FALSE);
|
||||
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_remove_match(sh->conn->dbus_conn,
|
||||
eina_strbuf_string_get(sh->match), &err);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(dbus_error_is_set(&err), EINA_FALSE);
|
||||
|
||||
va_start(ap, sh);
|
||||
do
|
||||
{
|
||||
if (!key)
|
||||
{
|
||||
key = va_arg(ap, char *);
|
||||
continue;
|
||||
}
|
||||
value = va_arg(ap, char *);
|
||||
arg = calloc(1, sizeof(Signal_Argument));
|
||||
EINA_SAFETY_ON_NULL_GOTO(arg, error);
|
||||
|
||||
if (!strncmp(key, ARGX, strlen(ARGX)))
|
||||
{
|
||||
int id = atoi(key+strlen(ARGX)-1);
|
||||
arg->index = (unsigned short)id;
|
||||
arg->value = eina_stringshare_add(value);
|
||||
sh->args = eina_inlist_sorted_state_insert(sh->args,
|
||||
EINA_INLIST_GET(arg),
|
||||
_sort_arg,
|
||||
sh->state_args);
|
||||
_match_append(sh->match, key, value);
|
||||
}
|
||||
key = NULL;
|
||||
} while(key);
|
||||
va_end(ap);
|
||||
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_add_match(sh->conn->dbus_conn,
|
||||
eina_strbuf_string_get(sh->match), &err);
|
||||
if (!dbus_error_is_set(&err))
|
||||
return EINA_TRUE;
|
||||
|
||||
ERR("Error setting new match.");
|
||||
return EINA_FALSE;
|
||||
|
||||
error:
|
||||
va_end(ap);
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_add_match(sh->conn->dbus_conn,
|
||||
eina_strbuf_string_get(sh->match), &err);
|
||||
if (dbus_error_is_set(&err))
|
||||
ERR("Error setting partial extra arguments.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI EDBus_Signal_Handler *
|
||||
edbus_signal_handler_add(EDBus_Connection *conn, const char *sender, const char *path, const char *interface, const char *member, EDBus_Signal_Cb cb, const void *cb_data)
|
||||
{
|
||||
EDBus_Signal_Handler *sh;
|
||||
Eina_Strbuf *match;
|
||||
DBusError err;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
|
||||
DBG("conn=%p, sender=%s, path=%s, interface=%s, member=%s, cb=%p %p",
|
||||
conn, sender, path, interface, member, cb, cb_data);
|
||||
|
||||
sh = calloc(1, sizeof(EDBus_Signal_Handler));
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sh, NULL);
|
||||
|
||||
match = eina_strbuf_new();
|
||||
EINA_SAFETY_ON_NULL_GOTO(match, cleanup_create_strbuf);
|
||||
eina_strbuf_append(match, "type='signal'");
|
||||
_match_append(match, SENDER_KEY, sender);
|
||||
_match_append(match, PATH_KEY, path);
|
||||
_match_append(match, INTERFACE_KEY, interface);
|
||||
_match_append(match, MEMBER_KEY, member);
|
||||
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_add_match(conn->dbus_conn, eina_strbuf_string_get(match), &err);
|
||||
if (dbus_error_is_set(&err)) goto cleanup;
|
||||
|
||||
if (sender && sender[0] != ':' && strcmp(sender, EDBUS_FDO_BUS))
|
||||
{
|
||||
sh->bus = edbus_connection_name_get(conn, sender);
|
||||
if (!sh->bus) goto cleanup;
|
||||
edbus_connection_name_owner_monitor(conn, sh->bus, EINA_TRUE);
|
||||
}
|
||||
|
||||
sh->cb = cb;
|
||||
sh->cb_data = cb_data;
|
||||
sh->conn = conn;
|
||||
sh->interface = eina_stringshare_add(interface);
|
||||
sh->member = eina_stringshare_add(member);
|
||||
sh->path = eina_stringshare_add(path);
|
||||
sh->sender = eina_stringshare_add(sender);
|
||||
sh->match = match;
|
||||
sh->refcount = 1;
|
||||
sh->dangling = EINA_FALSE;
|
||||
sh->state_args = eina_inlist_sorted_state_new();
|
||||
EINA_MAGIC_SET(sh, EDBUS_SIGNAL_HANDLER_MAGIC);
|
||||
|
||||
edbus_connection_signal_handler_add(conn, sh);
|
||||
return sh;
|
||||
|
||||
cleanup:
|
||||
eina_strbuf_free(match);
|
||||
cleanup_create_strbuf:
|
||||
free(sh);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
signal_handler_deleter(void *data)
|
||||
{
|
||||
EDBus_Signal_Handler *handler = data;
|
||||
_edbus_signal_handler_del(handler);
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_signal_handler_clean(EDBus_Signal_Handler *handler)
|
||||
{
|
||||
DBusError err;
|
||||
|
||||
if (handler->dangling) return;
|
||||
|
||||
edbus_connection_signal_handler_del(handler->conn, handler);
|
||||
if (handler->bus)
|
||||
edbus_connection_name_owner_monitor(handler->conn, handler->bus,
|
||||
EINA_FALSE);
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_remove_match(handler->conn->dbus_conn,
|
||||
eina_strbuf_string_get(handler->match), &err);
|
||||
handler->dangling = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_edbus_signal_handler_del(EDBus_Signal_Handler *handler)
|
||||
{
|
||||
Eina_Inlist *list;
|
||||
Signal_Argument *arg;
|
||||
DBG("handler %p, refcount=%d, conn=%p %s",
|
||||
handler, handler->refcount, handler->conn, handler->sender);
|
||||
edbus_cbs_free_dispatch(&(handler->cbs_free), handler);
|
||||
EINA_MAGIC_SET(handler, EINA_MAGIC_NONE);
|
||||
|
||||
/* after cbs_free dispatch these shouldn't exit, error if they do */
|
||||
|
||||
eina_stringshare_del(handler->sender);
|
||||
eina_stringshare_del(handler->path);
|
||||
eina_stringshare_del(handler->interface);
|
||||
eina_stringshare_del(handler->member);
|
||||
eina_strbuf_free(handler->match);
|
||||
EINA_INLIST_FOREACH_SAFE(handler->args, list, arg)
|
||||
{
|
||||
eina_stringshare_del(arg->value);
|
||||
free(arg);
|
||||
}
|
||||
eina_inlist_sorted_state_free(handler->state_args);
|
||||
free(handler);
|
||||
}
|
||||
|
||||
EAPI EDBus_Signal_Handler *
|
||||
edbus_signal_handler_ref(EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
DBG("handler=%p, pre-refcount=%d, match=%s",
|
||||
handler, handler->refcount, eina_strbuf_string_get(handler->match));
|
||||
handler->refcount++;
|
||||
return handler;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_signal_handler_unref(EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK(handler);
|
||||
DBG("handler=%p, pre-refcount=%d, match=%s",
|
||||
handler, handler->refcount, eina_strbuf_string_get(handler->match));
|
||||
handler->refcount--;
|
||||
if (handler->refcount > 0) return;
|
||||
|
||||
_edbus_signal_handler_clean(handler);
|
||||
|
||||
if (handler->conn->running_signal)
|
||||
ecore_idler_add(signal_handler_deleter, handler);
|
||||
else
|
||||
_edbus_signal_handler_del(handler);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_signal_handler_del(EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK(handler);
|
||||
_edbus_signal_handler_clean(handler);
|
||||
edbus_signal_handler_unref(handler);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_signal_handler_cb_free_add(EDBus_Signal_Handler *handler, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK(handler);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
handler->cbs_free = edbus_cbs_free_add(handler->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
edbus_signal_handler_cb_free_del(EDBus_Signal_Handler *handler, EDBus_Free_Cb cb, const void *data)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK(handler);
|
||||
EINA_SAFETY_ON_NULL_RETURN(cb);
|
||||
handler->cbs_free = edbus_cbs_free_del(handler->cbs_free, cb, data);
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_signal_handler_sender_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return handler->sender;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_signal_handler_path_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return handler->path;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_signal_handler_interface_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return handler->interface;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_signal_handler_member_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return handler->member;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
edbus_signal_handler_match_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return eina_strbuf_string_get(handler->match);
|
||||
}
|
||||
|
||||
EAPI EDBus_Connection *
|
||||
edbus_signal_handler_connection_get(const EDBus_Signal_Handler *handler)
|
||||
{
|
||||
EDBUS_SIGNAL_HANDLER_CHECK_RETVAL(handler, NULL);
|
||||
return handler->conn;
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef EDBUS_SIGNAL_HANDLER_H
|
||||
#define EDBUS_SIGNAL_HANDLER_H 1
|
||||
|
||||
/**
|
||||
* @defgroup EDBus_Signal_Handler Signal Handler
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Add a signal handler.
|
||||
*
|
||||
* @param conn connection where the signal is emitted
|
||||
* @param sender bus name or unique id of where the signal is emitted
|
||||
* @param path path of remote object
|
||||
* @param interface that signal belongs
|
||||
* @param member name of the signal
|
||||
* @param cb callback that will be called when this signal is received
|
||||
* @param cb_data data that will be passed to callback
|
||||
*/
|
||||
EAPI EDBus_Signal_Handler *edbus_signal_handler_add(EDBus_Connection *conn, const char *sender, const char *path, const char *interface, const char *member, EDBus_Signal_Cb cb, const void *cb_data) EINA_ARG_NONNULL(1, 6);
|
||||
|
||||
/**
|
||||
* @brief Increase signal handler reference.
|
||||
*/
|
||||
EAPI EDBus_Signal_Handler *edbus_signal_handler_ref(EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Decrease signal handler reference.
|
||||
* If reference == 0 signal handler will be freed.
|
||||
*/
|
||||
EAPI void edbus_signal_handler_unref(EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Decrease signal handler reference like edbus_signal_handler_unref()
|
||||
* but if reference > 0 this signal handler will stop listen signals. In other
|
||||
* words will be canceled but memory will not be freed.
|
||||
*/
|
||||
EAPI void edbus_signal_handler_del(EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1);
|
||||
/**
|
||||
* @brief Add extra argument in match of signal handler to obtain specifics signals.
|
||||
*
|
||||
* Example:
|
||||
* edbus_signal_handler_match_extra_set(sh, "arg0", "org.bansheeproject.Banshee", "arg1", "", NULL);
|
||||
* With this extra arguments this signal handler callback only will be called
|
||||
* when Banshee is started.
|
||||
*
|
||||
* @note For now is only supported argX.
|
||||
*
|
||||
* @param sh signal handler
|
||||
* @param ... variadic of key and value and must be ended with a NULL
|
||||
*
|
||||
* @note To information:
|
||||
* http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
|
||||
*/
|
||||
EAPI Eina_Bool edbus_signal_handler_match_extra_set(EDBus_Signal_Handler *sh, ...) EINA_ARG_NONNULL(1) EINA_SENTINEL;
|
||||
|
||||
/**
|
||||
* @brief Add a callback function to be called when signal handler will be freed.
|
||||
*/
|
||||
EAPI void edbus_signal_handler_cb_free_add(EDBus_Signal_Handler *handler, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
/**
|
||||
* @brief Remove callback registered in edbus_signal_handler_cb_free_add().
|
||||
*/
|
||||
EAPI void edbus_signal_handler_cb_free_del(EDBus_Signal_Handler *handler, EDBus_Free_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
EAPI const char *edbus_signal_handler_sender_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_signal_handler_path_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_signal_handler_interface_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_signal_handler_member_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
EAPI const char *edbus_signal_handler_match_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
EAPI EDBus_Connection *edbus_signal_handler_connection_get(const EDBus_Signal_Handler *handler) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|