Play with dbus - implement command interface.

SVN revision: 33050
This commit is contained in:
Kim Woelders 2007-12-08 17:54:38 +00:00
parent 5c524f0840
commit ce90617123
8 changed files with 384 additions and 1 deletions

View File

@ -248,6 +248,14 @@ if test "x$enable_composite" = "xyes"; then
fi
AM_CONDITIONAL(ENABLE_COMPOSITE, test "x$enable_composite" = "xyes")
AC_ARG_ENABLE(dbus,
[ --enable-dbus compile with D-Bus support @<:@default=no@:>@],,
enable_dbus=no)
if test "x$enable_dbus" = "xyes"; then
PKG_CHECK_MODULES(DBUS, dbus-1, AC_DEFINE(USE_DBUS, 1, [dbus support]), enable_dbus=no)
fi
AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes")
AC_CHECK_LIB(Fridge,mass_quantities_of_bass_ale)
AC_CHECK_LIB(Fridge,mass_quantities_of_any_ale,, [
echo "Warning: No ales were found in your refrigerator."
@ -358,6 +366,7 @@ echo "Experimental options - DO NOT USE unless you know what you are doing"
echo " Compile with ecore/ecore_x ... $enable_ecore"
echo " GLX .......................... $enable_glx"
echo " ScreenSaver .................. $enable_xscrnsaver"
echo " D-Bus ........................ $enable_dbus"
echo
echo "Installation path .............. $prefix"
echo

View File

@ -17,7 +17,7 @@ xsession_DATA = $(DESKTOPS)
#xclientsdir = $(sysconfdir)/X11/xinit/Xclients.d
#xclients_SCRIPTS = $(XCLIENTS)
EXTRA_DIST = $(DESKTOPS_IN) $(SCRIPTS) $(ICONS)
EXTRA_DIST = $(DESKTOPS_IN) $(SCRIPTS) $(ICONS) e16-dbus-cmd
e16.desktop: $(top_srcdir)/misc/e16.desktop.in Makefile
e16-gnome.desktop: $(top_srcdir)/misc/e16-gnome.desktop.in Makefile

2
misc/e16-dbus-cmd Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
dbus-send --session --type=method_call --print-reply --dest=$ENL_DBUS_NAME /org/e16/wm org.e16.Command string:"$*"

View File

@ -13,6 +13,9 @@ endif
if ENABLE_COMPOSITE
SRCS_ECOMPMGR = ecompmgr.c ecompmgr.h magwin.c
endif
if ENABLE_DBUS
SRCS_DBUS = edbus.c edbus.h
endif
if USE_ESNPRINTF
SRCS_SNPRINTF = snprintf.c
endif
@ -108,6 +111,7 @@ e16_SOURCES = \
$(SRCS_GNOME) \
$(SRCS_GLX) \
$(SRCS_ECOMPMGR) \
$(SRCS_DBUS) \
$(SRCS_SNPRINTF)
e16_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) \
@ -115,6 +119,7 @@ e16_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) \
$(MODULE_CFLAGS) \
$(IMLIB2_CFLAGS) \
$(X_CFLAGS) \
$(DBUS_CFLAGS) \
-D LOCALEDIR=\"$(localedir)\" \
-D ENLIGHTENMENT_BIN=\"$(bindir)\" \
-D ENLIGHTENMENT_LIB=\"$(pkglibdir)\" \
@ -132,6 +137,7 @@ LDADD = \
$(XINERAMA_LIBS) \
$(X_EXTRA_LIBS) \
$(E_X_LIBS) \
$(DBUS_LIBS) \
-lX11 -lm
if BUILD_MODULES

331
src/edbus.c Normal file
View File

@ -0,0 +1,331 @@
/*
* Copyright (C) 2007 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#include "edbus.h"
#include "events.h"
#include "ipc.h"
#include <dbus/dbus.h>
#define ENABLE_INTROSPECTION 1
#define DEBUG_DBUS 1
#if DEBUG_DBUS
#define Dprintf(fmt...) if(EDebug(EDBUG_TYPE_DBUS))Eprintf(fmt)
#define D2printf(fmt...) if(EDebug(EDBUG_TYPE_DBUS)>1)Eprintf(fmt)
#else
#define Dprintf(fmt...)
#define D2printf(fmt...)
#endif
typedef struct
{
char *name;
DBusConnection *conn;
DBusWatch *watch;
int fd;
} DbusData;
static DbusData dbus_data;
static EventFdDesc *db_efd = NULL;
static dbus_bool_t
DbusWatchAdd(DBusWatch * watch, void *data __UNUSED__)
{
dbus_data.watch = watch;
dbus_data.fd = dbus_watch_get_unix_fd(watch);
D2printf("DbusWatchAdd fd=%d flags=%d\n", dbus_data.fd,
dbus_watch_get_flags(dbus_data.watch));
return TRUE;
}
static void
DbusWatchRemove(DBusWatch * watch __UNUSED__, void *data __UNUSED__)
{
D2printf("DbusWatchRemove\n");
}
#if 0 /* Don't need this */
static void
DbusWatchToggle(DBusWatch * watch __UNUSED__, void *data __UNUSED__)
{
D2printf("DbusWatchToggle\n");
}
#else
#define DbusWatchToggle NULL
#endif
static void
DbusReplyString(DBusConnection * conn, DBusMessage * msg, const char *str)
{
DBusMessage *reply;
DBusMessageIter args;
reply = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(reply, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &str))
goto done;
if (!dbus_connection_send(conn, reply, NULL))
goto done;
dbus_connection_flush(conn);
done:
dbus_message_unref(reply);
}
static void
DbusIpcReply(void *data, const char *str)
{
DBusMessage *msg = (DBusMessage *) data;
if (!str)
str = "ok";
DbusReplyString(dbus_data.conn, msg, str);
}
static void
DbusMethodCommand(DBusConnection * conn, DBusMessage * msg)
{
DBusMessageIter args;
const char *param = "";
if (!dbus_message_iter_init(msg, &args) ||
dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING)
{
DbusReplyString(conn, msg, "String arg required\n");
return;
}
else
dbus_message_iter_get_basic(&args, &param);
IpcExecReply(param, DbusIpcReply, msg);
}
#if ENABLE_INTROSPECTION
/* *INDENT-OFF* */
static const char dbus_introspect_data[] =
"<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'\n"
"'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n"
"<node>\n"
" <interface name='org.freedesktop.DBus.Introspectable'>\n"
" <method name='Introspect'>\n"
" <arg name='data' direction='out' type='s'/>\n"
" </method>\n"
" </interface>\n"
" <interface name='%s'>\n"
" <method name='Command'>\n"
" <arg name='data' direction='out' type='s'/>\n"
" </method>\n"
" <signal name='Signal'>\n"
" <arg name='data' direction='in' type='s'/>\n"
" </signal>\n"
" </interface>\n"
"</node>";
/* *INDENT-ON* */
static void
DbusMsgIntrospect(DBusConnection * conn, DBusMessage * msg)
{
char buf[1024];
D2printf("Introspect\n");
Esnprintf(buf, sizeof(buf), dbus_introspect_data, dbus_data.name);
if (!strcmp(dbus_message_get_path(msg), "/"))
DbusReplyString(conn, msg, buf);
else
DbusReplyString(conn, msg, "");
}
#endif
static DBusHandlerResult
DbusMsgHandler(DBusConnection * conn, DBusMessage * msg,
void *user_data __UNUSED__)
{
int msg_type;
const char *msg_dest, *msg_ifc, *msg_memb;
D2printf("DbusMsgHandler\n");
msg_type = dbus_message_get_type(msg);
msg_dest = dbus_message_get_destination(msg);
msg_ifc = dbus_message_get_interface(msg);
msg_memb = dbus_message_get_member(msg);
switch (msg_type)
{
default: /* Should not be possible */
Dprintf("MESSAGE type=%d\n", msg_type);
break;
case DBUS_MESSAGE_TYPE_METHOD_CALL:
Dprintf("METHOD %s %s\n", msg_ifc, msg_memb);
if (strcmp(msg_dest, dbus_data.name))
break;
if (!strcmp(msg_ifc, "org.e16"))
{
if (!strcmp(msg_memb, "Command"))
DbusMethodCommand(conn, msg);
else
DbusReplyString(conn, msg, "Error");
}
#if ENABLE_INTROSPECTION
else if (!strcmp(msg_ifc, "org.freedesktop.DBus.Introspectable"))
{
if (!strcmp(msg_memb, "Introspect"))
DbusMsgIntrospect(conn, msg);
}
#endif
break;
case DBUS_MESSAGE_TYPE_SIGNAL:
Dprintf("SIGNAL %s %s\n", msg_ifc, msg_memb);
if (!strcmp(msg_ifc, "org.e16"))
{
Dprintf("... for me!\n");
}
break;
}
D2printf("sender = %s\n", dbus_message_get_sender(msg));
D2printf("dest = %s\n", dbus_message_get_destination(msg));
D2printf("path = %s\n", dbus_message_get_path(msg));
D2printf("interface = %s\n", dbus_message_get_interface(msg));
D2printf("member = %s\n", dbus_message_get_member(msg));
return DBUS_HANDLER_RESULT_HANDLED;
}
static void
DbusHandleFd(void)
{
int rc;
D2printf("DbusHandleFd flags=%d\n", dbus_watch_get_flags(dbus_data.watch));
dbus_watch_handle(dbus_data.watch,
DBUS_WATCH_READABLE | DBUS_WATCH_WRITABLE);
for (;;)
{
D2printf("DbusHandleFd: Dispatch flags=%d\n",
dbus_watch_get_flags(dbus_data.watch));
rc = dbus_connection_dispatch(dbus_data.conn);
if (rc == DBUS_DISPATCH_COMPLETE)
break;
}
}
void
DbusInit(void)
{
DBusError dberr;
int err;
char buf[128];
if (Mode.wm.window)
{
sprintf(buf, "org.e16.wm.w%#x", (unsigned int)VRoot.xwin);
}
else
{
const char *s;
s = strchr(Mode.display.name, ':');
if (!s)
return;
sprintf(buf, "org.e16.wm.d%ds%d", atoi(s + 1), VRoot.scr);
}
dbus_data.name = Estrdup(buf);
Esetenv("ENL_DBUS_NAME", dbus_data.name);
dbus_error_init(&dberr);
dbus_data.fd = -1;
dbus_data.conn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
dbus_connection_set_exit_on_disconnect(dbus_data.conn, FALSE);
err = dbus_bus_request_name(dbus_data.conn, dbus_data.name,
DBUS_NAME_FLAG_DO_NOT_QUEUE, &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
if (err != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
Eprintf("*** DbusInit error: Not Primary Owner (%d)\n", err);
return;
}
Esnprintf(buf, sizeof(buf), "type='signal',destination='%s'",
dbus_data.name);
if (EDebug(EDBUG_TYPE_DBUS) > 1) /* Catch all signals if extra debug is enabled */
dbus_bus_add_match(dbus_data.conn, "type='signal'", &dberr);
else
dbus_bus_add_match(dbus_data.conn, buf, &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
Esnprintf(buf, sizeof(buf), "type='method_call',destination='%s'",
dbus_data.name);
dbus_bus_add_match(dbus_data.conn, buf, &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
#if 0 /* Debug */
dbus_bus_add_match(dbus_data.conn, "type='method_return'", &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
dbus_bus_add_match(dbus_data.conn, "type='error'", &dberr);
if (dbus_error_is_set(&dberr))
goto bail_out;
#endif
if (!dbus_connection_add_filter(dbus_data.conn, DbusMsgHandler, NULL, NULL))
return;
err = dbus_connection_set_watch_functions(dbus_data.conn,
DbusWatchAdd, DbusWatchRemove,
DbusWatchToggle, NULL, NULL);
/* Handle pending D-Bus stuff */
DbusHandleFd();
db_efd = EventFdRegister(dbus_data.fd, DbusHandleFd);
return;
bail_out:
if (dbus_error_is_set(&dberr))
{
Eprintf("*** DbusInit error: %s\n", dberr.message);
dbus_error_free(&dberr);
}
return;
}
#if 0 /* No need? */
void
DbusExit(void)
{
}
#endif

29
src/edbus.h Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2007 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _EDBUS_H_
#define _EDBUS_H_
void DbusInit(void);
void DbusExit(void);
#endif /* _EDBUS_H_ */

View File

@ -48,6 +48,7 @@
#define EDBUG_TYPE_PAGER 146
#define EDBUG_TYPE_SELECTION 147
#define EDBUG_TYPE_FONTS 148
#define EDBUG_TYPE_DBUS 149
#define EDBUG_TYPE_COMPMGR 161
#define EDBUG_TYPE_COMPMGR2 162

View File

@ -26,6 +26,7 @@
#include "cursors.h"
#include "desktops.h"
#include "dialog.h"
#include "edbus.h"
#include "eimage.h"
#include "emodule.h"
#include "events.h"
@ -253,6 +254,10 @@ main(int argc, char **argv)
SessionInit();
LoadSnapInfo();
#if USE_DBUS
DbusInit();
#endif
ModulesSignal(ESIGNAL_INIT, NULL);
/* Load the theme */