Index: dbus/HACKING =================================================================== --- dbus/HACKING (nonexistent) +++ dbus/HACKING (revision 11265) @@ -0,0 +1,5 @@ +Needs scconfig detection. Does anyone use dbus? + +Makefile: + EXTRA_DIST += dbus.xml + DISTCLEAN_FILES += dbus-introspect.h \ Index: dbus/Makefile =================================================================== --- dbus/Makefile (nonexistent) +++ dbus/Makefile (revision 11265) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_dbus + +clean: + rm *.o *.so 2>/dev/null ; true Index: dbus/Plug.tmpasm =================================================================== --- dbus/Plug.tmpasm (nonexistent) +++ dbus/Plug.tmpasm (revision 11265) @@ -0,0 +1,30 @@ +put /local/pcb/mod {dbus} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/dbus/dbus.o $(PLUGDIR)/dbus/dbus-pcbmain.o @] + +switch /local/pcb/dbus/controls + case {disable} + # create the introspect header even if disabled so make dep works + put /local/tmp { $(PLUGDIR)/dbus/dbus-introspect.tmp } + append /local/pcb/DEPDEPS [@ $(PLUGDIR)/dbus/dbus-introspect.h @] + end; + default + put /local/pcb/mod/CFLAGS /target/libs/sul/dbus/cflags + put /local/pcb/mod/LDFLAGS /target/libs/sul/dbus/ldflags + + put /local/tmp { $(PLUGDIR)/dbus/dbus-introspect.tmp } + end +end + +append /local/pcb/RULES [@ +# DBUS xml embedded +$(PLUGDIR)/dbus/dbus-introspect.h: $(PLUGDIR)/dbus/dbus.xml $(CQUOTE) + $(CQUOTE) -n pcb_dbus_introspect_xml < $(PLUGDIR)/dbus/dbus.xml > $(PLUGDIR)/dbus/dbus-introspect.h +@] + +put /local/pcb/mod/CLEANFILES { $(PLUGDIR)/dbus/dbus-introspect.h } + +switch /local/pcb/dbus/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: dbus/SCCONFIG.dbus.patch =================================================================== --- dbus/SCCONFIG.dbus.patch (nonexistent) +++ dbus/SCCONFIG.dbus.patch (revision 11265) @@ -0,0 +1,19 @@ +Index: hooks.c +=================================================================== +--- hooks.c (revision 11262) ++++ hooks.c (working copy) +@@ -624,14 +624,6 @@ + put("cc/rdynamic", ""); + + /* plugin dependencies */ +- if (plug_is_enabled("dbus")) { +- require("libs/sul/dbus/presents", 0, 0); +- if (!istrue(get("libs/sul/dbus/presents"))) { +- report_repeat("WARNING: disabling the DBUS interface plugin because libdbus is not found or not configured...\n"); +- hook_custom_arg("Disable-dbus", NULL); +- } +- } +- + plugin_deps(1); + + if (plug_is_enabled("gpmi")) { Index: dbus/dbus-pcbmain.c =================================================================== --- dbus/dbus-pcbmain.c (nonexistent) +++ dbus/dbus-pcbmain.c (revision 11265) @@ -0,0 +1,310 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-pcbmain.c PCB HID main loop integration + * + * Adapted from dbus-gmain.c from dbus-glib bindings: + * Copyright (C) 2002, 2003 CodeFactory AB + * Copyright (C) 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include "config.h" + +#define DBUS_API_SUBJECT_TO_CHANGE +#include +#include +#include +#include "dbus-pcbmain.h" +#include "hid.h" + +typedef struct _IOWatchHandler IOWatchHandler; +typedef struct _TimeoutHandler TimeoutHandler; + +struct _IOWatchHandler { + DBusWatch *dbus_watch; + pcb_hidval_t pcb_watch; +}; + +struct _TimeoutHandler { + DBusTimeout *dbus_timeout; + pcb_hidval_t pcb_timer; + int interval; +}; + + +static void block_hook_cb(pcb_hidval_t data) +{ + DBusConnection *connection = (DBusConnection *) data.ptr; + if (dbus_connection_get_dispatch_status(connection) != DBUS_DISPATCH_DATA_REMAINS) + return; + + /* TODO: IS THIS NEEDED? */ + /* dbus_connection_ref (connection); */ + + /* Only dispatch once - we don't want to starve other mainloop users */ + dbus_connection_dispatch(connection); + + /* dbus_connection_unref (connection); */ + return; +} + +static void io_watch_handler_dbus_freed(void *data) +{ + IOWatchHandler *handler; + handler = (IOWatchHandler *) data; + + /* Remove the watch registered with the HID */ + if (pcb_gui != NULL) + pcb_gui->unwatch_file(handler->pcb_watch); + free(handler); +} + + +void io_watch_handler_cb(pcb_hidval_t pcb_watch, int fd, unsigned int condition, pcb_hidval_t data) +{ + IOWatchHandler *handler; + unsigned int dbus_condition = 0; + + handler = (IOWatchHandler *) data.ptr; + + /* TODO: IS THIS NEEDED? */ + /* if (connection) + dbus_connection_ref (connection); */ + + if (condition & PCB_WATCH_READABLE) + dbus_condition |= DBUS_WATCH_READABLE; + if (condition & PCB_WATCH_WRITABLE) + dbus_condition |= DBUS_WATCH_WRITABLE; + if (condition & PCB_WATCH_ERROR) + dbus_condition |= DBUS_WATCH_ERROR; + if (condition & PCB_WATCH_HANGUP) + dbus_condition |= DBUS_WATCH_HANGUP; + + /* We don't touch the handler after this, because DBus + * may have disabled the watch and thus killed the handler + */ + dbus_watch_handle(handler->dbus_watch, dbus_condition); + handler = NULL; + + /*if (connection) + dbus_connection_unref (connection); */ + + return; +} + + +static void timeout_handler_dbus_freed(void *data) +{ + TimeoutHandler *handler; + handler = (TimeoutHandler *) data; + + /* Remove the timeout registered with the HID */ + pcb_gui->stop_timer(handler->pcb_timer); + free(handler); +} + + +void timeout_handler_cb(pcb_hidval_t data) +{ + TimeoutHandler *handler; + handler = (TimeoutHandler *) data.ptr; + + /* Re-add the timeout, as PCB will remove the current one + Do this before calling to dbus, incase DBus removes the timeout. + We can't touch handler after libdbus has been run for this reason. */ + handler->pcb_timer = pcb_gui->add_timer(timeout_handler_cb, handler->interval, data); + + dbus_timeout_handle(handler->dbus_timeout); +} + + +static dbus_bool_t watch_add(DBusWatch * dbus_watch, void *data) +{ + IOWatchHandler *handler; + int fd; + unsigned int pcb_condition; + unsigned int dbus_flags; + pcb_hidval_t temp; + + /* We won't create a watch until it becomes enabled. */ + if (!dbus_watch_get_enabled(dbus_watch)) + return TRUE; + + dbus_flags = dbus_watch_get_flags(dbus_watch); + + pcb_condition = PCB_WATCH_ERROR | PCB_WATCH_HANGUP; + if (dbus_flags & DBUS_WATCH_READABLE) + pcb_condition |= PCB_WATCH_READABLE; + if (dbus_flags & DBUS_WATCH_WRITABLE) + pcb_condition |= PCB_WATCH_READABLE; + +#if HAVE_DBUS_WATCH_GET_UNIX_FD + fd = dbus_watch_get_unix_fd(dbus_watch); +#else + fd = dbus_watch_get_fd(dbus_watch); +#endif + + handler = (IOWatchHandler *) malloc(sizeof(IOWatchHandler)); + temp.ptr = (void *) handler; + handler->dbus_watch = dbus_watch; + handler->pcb_watch = pcb_gui->watch_file(fd, pcb_condition, io_watch_handler_cb, temp); + + dbus_watch_set_data(dbus_watch, handler, io_watch_handler_dbus_freed); + return TRUE; +} + +static void watch_remove(DBusWatch * dbus_watch, void *data) +{ + /* Free the associated data. Its destroy callback removes the watch */ + dbus_watch_set_data(dbus_watch, NULL, NULL); +} + +static void watch_toggled(DBusWatch * dbus_watch, void *data) +{ + /* Simply add/remove the watch completely */ + if (dbus_watch_get_enabled(dbus_watch)) + watch_add(dbus_watch, data); + else + watch_remove(dbus_watch, data); +} + + +static dbus_bool_t timeout_add(DBusTimeout * timeout, void *data) +{ + TimeoutHandler *handler; + pcb_hidval_t temp; + + /* We can't create a timeout without a GUI */ + if (pcb_gui == NULL) + return TRUE; + + /* We won't create a timeout until it becomes enabled. */ + if (!dbus_timeout_get_enabled(timeout)) + return TRUE; + + /*FIXME: Need to store the interval, as PCB requires us + to manually re-add the timer each time it expires. + This is non-ideal, and hopefully can be changed? */ + + handler = (TimeoutHandler *) malloc(sizeof(TimeoutHandler)); + temp.ptr = (void *) handler; + handler->dbus_timeout = timeout; + handler->interval = dbus_timeout_get_interval(timeout); + handler->pcb_timer = pcb_gui->add_timer(timeout_handler_cb, handler->interval, temp); + + dbus_timeout_set_data(timeout, handler, timeout_handler_dbus_freed); + return TRUE; +} + +static void timeout_remove(DBusTimeout * timeout, void *data) +{ + /* Free the associated data. Its destroy callback removes the timer */ + dbus_timeout_set_data(timeout, NULL, NULL); +} + +static void timeout_toggled(DBusTimeout * timeout, void *data) +{ + /* Simply add/remove the timeout completely */ + if (dbus_timeout_get_enabled(timeout)) + timeout_add(timeout, data); + else + timeout_remove(timeout, data); +} + +void dispatch_status_changed(DBusConnection * conn, DBusDispatchStatus new_status, void *data) +{ + /* TODO: Can use this eventually to add one-shot idle work-functions to dispatch + remaining IO. It could possibly replace the block_hook polling mechanism. + (We could use a one-shot block_book to dispatch the work though.) + + *** NO DISPATCHING TO BE DONE INSIDE THIS FUNCTION *** */ +} + +/* END INTERNALS */ + + +/** + * Sets the watch and timeout functions of a #DBusConnection + * to integrate the connection with the GUI HID's main loop. + * + * @param connection the connection + */ +void pcb_dbus_connection_setup_with_mainloop(DBusConnection * connection) +{ + /* ConnectionSetup *cs; */ + pcb_hidval_t temp; + + /* FIXME we never free the slot, so its refcount just keeps growing, + * which is kind of broken. + */ + /* dbus_connection_allocate_data_slot (&connection_slot); + if (connection_slot < 0) + goto nomem; */ + +#if 0 + cs = connection_setup_new(connection); + + if (!dbus_connection_set_data(connection, connection_slot, cs, (DBusFreeFunction) connection_setup_free)) + goto nomem; +#endif + + if (!dbus_connection_set_watch_functions(connection, watch_add, watch_remove, watch_toggled, NULL, NULL)) +/* cs, NULL))*/ + goto nomem; + + if (!dbus_connection_set_timeout_functions(connection, timeout_add, timeout_remove, timeout_toggled, NULL, NULL)) +/* cs, NULL))*/ + goto nomem; + + dbus_connection_set_dispatch_status_function(connection, dispatch_status_changed, NULL, NULL); +/* cs, NULL);*/ + + /* Register a new mainloop hook to mop up any unfinished IO. */ + temp.ptr = (void *) connection; + pcb_gui->add_block_hook(block_hook_cb, temp); + + return; +nomem: + fprintf(stderr, "Not enough memory to set up DBusConnection for use with PCB\n"); +} + +void pcb_dbus_connection_finish_with_mainloop(DBusConnection * connection) +{ + /*ConnectionSetup *cs; + + cs = dbus_connection_get_data (connection, connection_slot ); + + Replace the stored data with NULL, thus freeing the old data + DBus will call the function connection_setup_free() which we registered earlier + dbus_connection_set_data (connection, connection_slot, NULL, NULL ); + + dbus_connection_free_data_slot( &connection_slot ); */ + + if (!dbus_connection_set_watch_functions(connection, NULL, NULL, NULL, NULL, NULL)) + goto nomem; + + if (!dbus_connection_set_timeout_functions(connection, NULL, NULL, NULL, NULL, NULL)) + goto nomem; + + dbus_connection_set_dispatch_status_function(connection, NULL, NULL, NULL); + return; +nomem: + fprintf(stderr, "Not enough memory when cleaning up DBusConnection mainloop integration\n"); + +} Index: dbus/dbus-pcbmain.h =================================================================== --- dbus/dbus-pcbmain.h (nonexistent) +++ dbus/dbus-pcbmain.h (revision 11265) @@ -0,0 +1,29 @@ +/* + * PCB, an interactive printed circuit board editor + * D-Bus IPC logic + * Copyright (C) 2006 University of Cambridge + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef PCB_DBUS_PCBMAIN_H +#define PCB_DBUS_PCBMAIN_H + +#define DBUS_API_SUBJECT_TO_CHANGE +#include + +void pcb_dbus_connection_setup_with_mainloop(DBusConnection * connection); +void pcb_dbus_connection_finish_with_mainloop(DBusConnection * connection); + +#endif /* !PCB_DBUS_PCBMAIN_H */ Index: dbus/dbus.c =================================================================== --- dbus/dbus.c (nonexistent) +++ dbus/dbus.c (revision 11265) @@ -0,0 +1,391 @@ +/* + * PCB, an interactive printed circuit board editor + * D-Bus IPC logic + * Copyright (C) 2006 University of Cambridge + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * D-Bus code originally derrived from example-service.c in the dbus-glib bindings + */ + +#warning scconfig TODO: detect this in scconfig: +/* Define to 1 if you have the `dbus_watch_get_unix_fd' function. */ +/* #undef HAVE_DBUS_WATCH_GET_UNIX_FD */ + + + +#define DBUS_API_SUBJECT_TO_CHANGE +#include +#include + +#include "dbus-pcbmain.h" +#include "dbus-introspect.h" +#include "board.h" +#include "config.h" +#include "data.h" +#include "plugins.h" +#include "hid_actions.h" +#include "event.h" +#include "compat_misc.h" +#include "hid.h" + +/* For lrealpath */ +#include "compat_lrealpath.h" + + +#define PCB_DBUS_CANONICAL_NAME "org.seul.geda.pcb" +#define PCB_DBUS_OBJECT_PATH "/org/seul/geda/pcb" +#define PCB_DBUS_INTERFACE "org.seul.geda.pcb" +#define PCB_DBUS_ACTIONS_INTERFACE "org.seul.geda.pcb.actions" + +const char *dbus_cookie = "dbus plugin"; + +static DBusConnection *pcb_dbus_conn; + +static DBusHandlerResult handle_get_filename(DBusConnection * connection, DBusMessage * message, void *data) +{ + DBusMessage *reply; + DBusMessageIter iter; + DBusHandlerResult result; + char *filename; + + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* TODO: Should check the message signature matches what we expect? */ + + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + fprintf(stderr, "pcb_dbus: Couldn't create reply message\n"); + return result; + } + dbus_message_iter_init_append(reply, &iter); + + if (PCB->Filename) + filename = pcb_lrealpath(PCB->Filename); + else + filename = NULL; + + if (filename == NULL) { +#ifdef DEBUG + fprintf(stderr, "pcb_dbus: DEBUG: Couldn't get working filename, assuming none\n"); +#endif + filename = pcb_strdup(""); + if (filename == NULL) { + fprintf(stderr, "pcb_dbus: Couldn't pcb_strdup( \"\" ) for the filename\n"); + goto out; + } + } + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &filename)) { + fprintf(stderr, "pcb_dbus: Couldn't append return filename string to message reply, Out Of Memory!\n"); + free(filename); + goto out; + } + free(filename); + if (!dbus_connection_send(connection, reply, NULL)) { + fprintf(stderr, "pcb_dbus: Couldn't send message, Out Of Memory!\n"); + goto out; + } + result = DBUS_HANDLER_RESULT_HANDLED; + +out: + dbus_message_unref(reply); + return result; +} + + +static DBusHandlerResult handle_exec_action(DBusConnection * connection, DBusMessage * message, void *data) +{ + DBusMessage *reply; + DBusMessageIter iter; + DBusHandlerResult result; + DBusError err; + dbus_uint32_t retval; + char *action_name; + char **argv; + int argc; +#ifdef DEBUG + int i; +#endif + + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* TODO: Should check the message signature matches what we expect? */ + + /* initialise the error struct */ + dbus_error_init(&err); + + /* DON'T FREE action_name, as it belongs to DBUS, + * DO FREE argv, using dbus_free_string_array() + */ + argv = NULL; + if (!dbus_message_get_args(message, + &err, + DBUS_TYPE_STRING, &action_name, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &argv, &argc, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Failed to read method arguments\n"); + if (argv) + dbus_free_string_array(argv); + return result; + } + +#ifdef DEBUG + fprintf(stderr, "pcb_dbus: DEBUG: Executing action: %s(", action_name); + if (argc > 0) + fprintf(stderr, " \"%s\"", argv[0]); + for (i = 1; i < argc; i++) + fprintf(stderr, ", \"%s\"", argv[i]); + fprintf(stderr, " )\n"); +#endif + + /* TODO: Proper return value from actions */ + pcb_hid_actionv(action_name, argc, (const char**)argv); + retval = 0; + + dbus_free_string_array(argv); + + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + fprintf(stderr, "pcb_dbus: Couldn't create reply message\n"); + return result; + } + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &retval)) { + fprintf(stderr, "pcb_dbus: Couldn't sent message, Out Of Memory!\n"); + goto out; + } + + if (!dbus_connection_send(connection, reply, NULL)) { + fprintf(stderr, "pcb_dbus: Couldn't send message, Out Of Memory!\n"); + goto out; + } + + result = DBUS_HANDLER_RESULT_HANDLED; +out: + dbus_message_unref(reply); + return result; +} + + +static DBusHandlerResult handle_introspect(DBusConnection * connection, DBusMessage * message, void *data) +{ + DBusMessage *reply; + DBusMessageIter iter; + DBusHandlerResult result; + + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + fprintf(stderr, "pcb_dbus: Couldn't create reply message\n"); + return result; + } + dbus_message_iter_init_append(reply, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pcb_dbus_introspect_xml)) { + fprintf(stderr, "pcb_dbus: Couldn't add introspect XML to message return\n"); + goto out; + } + if (!dbus_connection_send(pcb_dbus_conn, reply, NULL)) { + fprintf(stderr, "pcb_dbus: Couldn't queue reply message for sending\n"); + goto out; + } + result = DBUS_HANDLER_RESULT_HANDLED; +out: + dbus_message_unref(reply); + return result; +} + +static void unregister_dbus_handler(DBusConnection * connection, void *data) +{ +} + + +static DBusHandlerResult handle_dbus_message(DBusConnection * connection, DBusMessage * message, void *data) +{ + int msg_type; + msg_type = dbus_message_get_type(message); + + switch (msg_type) { + case DBUS_MESSAGE_TYPE_METHOD_CALL: + { + const char *method_name; + const char *interface_name; + + method_name = dbus_message_get_member(message); + if (method_name == NULL) { + fprintf(stderr, "pcb_dbus: Method had no name specified\n"); + break; + } + + interface_name = dbus_message_get_interface(message); + if (interface_name == NULL) { + fprintf(stderr, "pcb_dbus: Method had no interface specified\n"); + break; + } + + if (strcmp(interface_name, PCB_DBUS_INTERFACE) == 0) { + if (strcmp(method_name, "GetFilename") == 0) { + return handle_get_filename(connection, message, data); + } + fprintf(stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); + break; + } + else if (strcmp(interface_name, PCB_DBUS_ACTIONS_INTERFACE) == 0) { + if (strcmp(method_name, "ExecAction") == 0) { + return handle_exec_action(connection, message, data); + } + fprintf(stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); + break; + } + else if (strcmp(interface_name, DBUS_INTERFACE_INTROSPECTABLE) == 0) { + if (strcmp(method_name, "Introspect") == 0) { + return handle_introspect(connection, message, data); + } + fprintf(stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); + break; + } + else { + fprintf(stderr, "pcb_dbus: Interface '%s' was not recognised\n", interface_name); + break; + } + } + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + fprintf(stderr, "pcb_dbus: DBUG: Method return message\n"); + /* WON'T ACTUALLY BE ANY UNLESS WE MAKE AN ASYNCRONOUS CALL? */ + break; + + case DBUS_MESSAGE_TYPE_ERROR: + fprintf(stderr, "pcb_dbus: DEBUG: Error message\n"); + /* HOPE NOT! */ + break; + + case DBUS_MESSAGE_TYPE_SIGNAL: + fprintf(stderr, "pcb_dbus: DEBUG: Signal message\n"); + /* NONE AT PRESENT */ + break; + + default: + fprintf(stderr, "pcb_dbus: DEBUG: Message type wasn't one we know about!\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +static void pcb_dbus_setup(void) +{ + DBusError err; + int ret; + const DBusObjectPathVTable object_vtable = { + unregister_dbus_handler, + handle_dbus_message, + NULL, NULL, NULL, NULL + }; + + /* Initialise the error variable */ + dbus_error_init(&err); + + /* Connect to the bus */ + pcb_dbus_conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "pcb_dbus: DBus connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (pcb_dbus_conn == NULL) + return; + + /* Request the canonical name for PCB on the bus */ + ret = dbus_bus_request_name(pcb_dbus_conn, PCB_DBUS_CANONICAL_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "pcb_dbus: DBus name error (%s)\n", err.message); + dbus_error_free(&err); + } + if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && ret != DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { + fprintf(stderr, "pcb_dbus: Couldn't gain ownership or queued ownership of the canonical DBus name\n"); + return; + } + + if (!dbus_connection_register_object_path(pcb_dbus_conn, PCB_DBUS_OBJECT_PATH, &object_vtable, NULL /* void * user_data */ + )) { + fprintf(stderr, "pcb_dbus: Couldn't register DBUS handler for %s\n", PCB_DBUS_OBJECT_PATH); + return; + } + + /* Setup intergration with the pcb mainloop */ + pcb_dbus_connection_setup_with_mainloop(pcb_dbus_conn); + +/* dbus_error_free(&err); */ + return; +} + + +static void pcb_dbus_finish(void) +{ + DBusError err; + + /* Initialise the error variable */ + dbus_error_init(&err); + + /* TODO: Could emit a "goodbye" signal here? */ + + dbus_connection_flush(pcb_dbus_conn); + + dbus_connection_unregister_object_path(pcb_dbus_conn, PCB_DBUS_OBJECT_PATH); + + dbus_bus_release_name(pcb_dbus_conn, PCB_DBUS_CANONICAL_NAME, &err); + + dbus_error_free(&err); + + pcb_dbus_connection_finish_with_mainloop(pcb_dbus_conn); + + dbus_connection_close(pcb_dbus_conn); + dbus_connection_unref(pcb_dbus_conn); + + /* Call DBus shutdown. This doesn't work with shared connections, + only private ones (like we took out earlier). + If any future module / plugin to PCB wants to use DBus too, + we must remove this call. DBus will get shut-down when the app exits. */ + dbus_shutdown(); +} + +static void dbus_gui_init(void *user_data, int argc, pcb_event_arg_t argv[]) +{ + + /* this can not be done from init, before the gui starts, as it needs + to register fd watches in the GUI. Also won't play well together with GUI + switches... */ + + pcb_dbus_setup(); +} + +int pplg_check_ver_dbus(int ver_needed) { return 0; } + +void pplg_uninit_dbus(void) +{ + pcb_dbus_finish(); + pcb_event_unbind_allcookie(dbus_cookie); +/* pcb_hid_remove_actions_by_cookie(dbus_cookie);*/ +} + +#include "dolists.h" +int pplg_init_dbus(void) +{ +/* PCB_REGISTER_ACTIONS(debug_action_list, dbus_cookie)*/ + pcb_event_bind(PCB_EVENT_GUI_INIT, dbus_gui_init, NULL, dbus_cookie); + return 0; +} Index: dbus/dbus.mk =================================================================== --- dbus/dbus.mk (nonexistent) +++ dbus/dbus.mk (revision 11265) @@ -0,0 +1,11 @@ +append /local/pcb/OBJS {dbus-pcbmain.o dbus.o} + +append /local/pcb/RULES [@ +# dbus +dbus-introspect.h : dbus.xml Makefile + echo '/* AUTOMATICALLY GENERATED FROM dbus.xml DO NOT EDIT */' > $@.tmp + echo "static const char *pcb_dbus_introspect_xml =" > $@.tmp + sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/"/' < dbus.xml >> $@.tmp + echo ";" >> $@.tmp + mv $@.tmp $@ +@] Index: dbus/dbus.pup =================================================================== --- dbus/dbus.pup (nonexistent) +++ dbus/dbus.pup (revision 11265) @@ -0,0 +1,7 @@ +$class feature +$short DBUS interface +$long Remote control PCB using DBUS. +$state deprecated +$lstate needs to install the xml? +default disable +autoload 1 Index: dbus/dbus.xml =================================================================== --- dbus/dbus.xml (nonexistent) +++ dbus/dbus.xml (revision 11265) @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + +