[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gEDA-dev: PCB DBus support code
Hi,
I've cleaned some of my code to support libdbus in PCB in the hope its
infrastructure can be included in CVS PCB.
The new files:
dbus.c
dbus.h
dbus.xml
dbus-pcbmain.c
dbus-pcbmain.h
Are not attached to avoid creating too much traffic. The two .c files
still need a work before they are production ready. I'll send these
files in a separate email.
The patches attached should be useful / applicable without the above
files.
pcb.rawdbus.hid_support: Should be ready to apply after review.
(Includes the memory leak bugfix I posted earlier - sorry)
diffstat pcb.rawdbus.hid_support.patch
hid.h | 25 ++++++++
hid/common/extents.c | 4 +
hid/common/hidnogui.c | 39 +++++++++++++
hid/gtk/gtkhid-main.c | 148
++++++++++++++++++++++++++++++++++++++++++++++++++
hid/lesstif/main.c | 121 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 337 insertions(+)
pcb.rawdbus.automake_support.patch: Should be ready to apply after
review. Should work on its own unless dbus support configured in, where
it needs the above dbus related source files!
diffstat pcb.rawdbus.automake_support.patch
configure.ac | 36 ++++++++++++++++++++++++++++++++++--
src/Makefile.am | 26 ++++++++++++++++++++++++--
2 files changed, 58 insertions(+), 4 deletions(-)
diffstat pcb.rawdbus.setup_hooks.patch: Should be ready to apply after
review. Should work on its own, as HAVE_DBUS is not defined.
main.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--
Peter Clifton
Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA
Tel: +44 (0)7729 980173 - (No signal in the lab!)
Index: configure.ac
===================================================================
RCS file: /cvsroot/pcb/pcb/configure.ac,v
retrieving revision 1.67
diff -U3 -p -r1.67 configure.ac
--- configure.ac 18 Oct 2006 05:59:57 -0000 1.67
+++ configure.ac 1 Dec 2006 00:04:52 -0000
@@ -187,6 +187,38 @@ then
HIDLIST=
fi
+AC_MSG_CHECKING([for whether to use DBUS])
+AC_ARG_WITH([dbus],
+[ --with-dbus Specify if DBUS IPC is to be included],
+[],[])
+AC_MSG_RESULT([$with_dbus])
+AM_CONDITIONAL(WITH_DBUS, test x$with_dbus = xyes)
+
+if test "x$with_dbus" = "xyes"; then
+ case " $with_gui " in
+ *\ gtk\ *) ;;
+ *\ lesstif\ *) ;;
+ * ) AC_MSG_ERROR([DBUS selected, but only works with a mainloop capable GUI HID])
+ esac
+
+ # Check for pkg-config
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ if test "$PKG_CONFIG" = "no"; then
+ AC_MSG_ERROR([Cannot find pkg-config, make sure it is installed and in your PATH])
+ fi
+
+ PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.61, ,
+ [AC_MSG_ERROR([Cannot find dbus-1 >= 0.61, install it and rerun ./configure
+Please review the following errors:
+$DBUS_PKG_ERRORS])]
+ )
+ DBUS_VERSION=`$PKG_CONFIG dbus-1 --modversion`
+
+ AC_DEFINE([HAVE_DBUS], 1,
+ [Define to 1 if DBUS IPC is to be compiled in])
+
+fi
+
AC_MSG_CHECKING([for which printer to use])
AC_ARG_WITH([printer],
[ --with-printer= Specify the printer: lpr [[default=lpr]]],
@@ -505,8 +537,8 @@ fi
AC_MSG_RESULT([no])
])
-CFLAGS="$CFLAGS $X_CFLAGS $GTK_CFLAGS"
-LIBS="$LIBS $XM_LIBS $X_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS"
+CFLAGS="$CFLAGS $X_CFLAGS $DBUS_CFLAGS $GTK_CFLAGS"
+LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS"
# if we have gcc then add -Wall
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/pcb/pcb/src/Makefile.am,v
retrieving revision 1.30
diff -U3 -p -r1.30 Makefile.am
--- src/Makefile.am 9 Oct 2006 00:35:25 -0000 1.30
+++ src/Makefile.am 1 Dec 2006 00:04:52 -0000
@@ -138,6 +138,11 @@ PCB_SRCS = \
hid/hidint.h
pcb_bin_SOURCES = ${PCB_SRCS} core_lists.h
+EXTRA_pcb_bin_SOURCES = \
+ dbus-pcbmain.c \
+ dbus.h \
+ dbus.c
+
BUILT_SOURCES = \
core_lists.h \
hid/gtk/gtk_lists.h \
@@ -177,7 +182,8 @@ EXTRA_DIST= \
$(srcdir)/hid/ps/hid.conf \
Pcb.ad.in \
pcb-menu.res \
- pcbtest.sh.in
+ pcbtest.sh.in \
+ dbus.xml
AM_YFLAGS= -d
@@ -223,6 +229,21 @@ hid/gtk/gtk_lists.h : ${LIBGTK_SRCS} Mak
(for f in ${LIBGTK_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp
mv $@.tmp $@
+# If we are building with dbus support, we need some extra files
+if WITH_DBUS
+dbus-introspect.h : dbus.xml Makefile
+ echo '/* AUTOMATICALLY GENERATED FROM dbus.xml DO NOT EDIT */' > $@.tmp
+ echo "static char *pcb_dbus_introspect_xml =" > $@.tmp
+ sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/"/' < dbus.xml >> $@.tmp
+ echo ";" >> $@.tmp
+ mv $@.tmp $@
+
+
+PCB_SRCS+= dbus-pcbmain.c dbus.c dbus.h
+BUILT_SOURCES+= dbus-introspect.h
+
+endif
+
# If we are building on win32, then compile in some icons for the
# desktop and application toolbar
if WIN32
@@ -314,7 +335,8 @@ DISTCLEANFILES= pcbtest.sh Pcb .test/Pcb
hid/lesstif/lesstif_lists.h \
hid/png/png_lists.h \
hid/ps/ps_lists.h \
- core_lists.h
+ core_lists.h \
+ dbus-introspect.h
# create wrapper script that lets you test pcb prior to installation
Index: src/hid.h
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid.h,v
retrieving revision 1.15
diff -U3 -p -r1.15 hid.h
--- src/hid.h 9 Oct 2006 00:35:25 -0000 1.15
+++ src/hid.h 1 Dec 2006 00:04:52 -0000
@@ -196,6 +196,17 @@ extern "C"
/* Callers should use this. */
#define SL(type,side) (~0xfff | SL_##type | SL_##side##_SIDE)
+/* File Watch flags */
+/* Based upon those in dbus/dbus-connection.h */
+typedef enum
+{
+ PCB_WATCH_READABLE = 1 << 0, /**< As in POLLIN */
+ PCB_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */
+ PCB_WATCH_ERROR = 1 << 2, /**< As in POLLERR */
+ PCB_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP */
+} PCBWatchFlags;
+
+
/* This is the main HID structure. */
typedef struct
{
@@ -381,6 +392,20 @@ extern "C"
/* Use this to stop a timer that hasn't triggered yet. */
void (*stop_timer) (hidval timer);
+ /* Causes func to be called when some condition occurs on the file
+ descriptor passed. Conditions include data for reading, writing,
+ hangup, and errors. user_data can be anything, it's just passed
+ to func. */
+ hidval (*watch_file) (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
+ hidval user_data);
+ /* Use this to stop a file watch. */
+ void (*unwatch_file) (hidval watch);
+
+ /* Causes func to be called in the mainloop prior to blocking */
+ hidval (*add_block_hook) (void (*func) (hidval data), hidval data);
+ /* Use this to stop a mainloop block hook. */
+ void (*stop_block_hook) (hidval block_hook);
+
/* Various dialogs */
/* Log a message to the log window. */
Index: src/hid/common/extents.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/common/extents.c,v
retrieving revision 1.7
diff -U3 -p -r1.7 extents.c
--- src/hid/common/extents.c 9 Oct 2006 00:35:26 -0000 1.7
+++ src/hid/common/extents.c 1 Dec 2006 00:04:52 -0000
@@ -211,6 +211,10 @@ static HID extents_hid = {
0 /* extents_set_crosshair */ ,
0 /* extents_add_timer */ ,
0 /* extents_stop_timer */ ,
+ 0 /* extents_watch_file */ ,
+ 0 /* extents_unwatch_file */ ,
+ 0 /* extents_add_block_hook */ ,
+ 0 /* extents_stop_block_hook */ ,
0 /* extents_log */ ,
0 /* extents_logv */ ,
Index: src/hid/common/hidnogui.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/common/hidnogui.c,v
retrieving revision 1.7
diff -U3 -p -r1.7 hidnogui.c
--- src/hid/common/hidnogui.c 9 Oct 2006 00:35:26 -0000 1.7
+++ src/hid/common/hidnogui.c 1 Dec 2006 00:04:52 -0000
@@ -211,6 +211,37 @@ nogui_stop_timer (hidval timer)
CRASH;
}
+static hidval
+nogui_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
+ hidval user_data)
+{
+ hidval rv;
+ CRASH;
+ rv.lval = 0;
+ return rv;
+}
+
+static void
+nogui_unwatch_file (hidval watch)
+{
+ CRASH;
+}
+
+static hidval
+nogui_add_block_hook (void (*func) (hidval data), hidval data)
+{
+ hidval rv;
+ CRASH;
+ rv.ptr = NULL;
+ return rv;
+}
+
+static void
+nogui_stop_block_hook (hidval block_hook)
+{
+ CRASH;
+}
+
static void
nogui_log (const char *fmt, ...)
{
@@ -310,6 +341,10 @@ HID hid_nogui = {
nogui_set_crosshair,
nogui_add_timer,
nogui_stop_timer,
+ nogui_watch_file,
+ nogui_unwatch_file,
+ nogui_add_block_hook,
+ nogui_stop_block_hook,
nogui_log,
nogui_logv,
nogui_confirm_dialog,
@@ -353,6 +388,10 @@ apply_default_hid (HID * d, HID * s)
AD (set_crosshair);
AD (add_timer);
AD (stop_timer);
+ AD (watch_file);
+ AD (unwatch_file);
+ AD (add_block_hook);
+ AD (stop_block_hook);
AD (log);
AD (logv);
AD (confirm_dialog);
Index: src/hid/gtk/gtkhid-main.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/gtk/gtkhid-main.c,v
retrieving revision 1.25
diff -U3 -p -r1.25 gtkhid-main.c
--- src/hid/gtk/gtkhid-main.c 14 Nov 2006 05:29:42 -0000 1.25
+++ src/hid/gtk/gtkhid-main.c 1 Dec 2006 00:04:52 -0000
@@ -876,6 +876,146 @@ ghid_stop_timer (hidval timer)
void *ptr = timer.ptr;
gtk_timeout_remove (((GuiTimer *) ptr)->id);
+ g_free( ptr );
+}
+
+typedef struct
+{
+ void (*func) ( hidval, int, unsigned int, hidval );
+ hidval user_data;
+ int fd;
+ GIOChannel *channel;
+ gint id;
+}
+GuiWatch;
+
+ /* We need a wrapper around the hid file watch to pass the correct flags
+ */
+static gboolean
+ghid_watch (GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ unsigned int pcb_condition = 0;
+ GuiWatch *watch = (GuiWatch*)data;
+
+ if (condition & G_IO_IN)
+ pcb_condition |= PCB_WATCH_READABLE;
+ if (condition & G_IO_OUT)
+ pcb_condition |= PCB_WATCH_WRITABLE;
+ if (condition & G_IO_ERR)
+ pcb_condition |= PCB_WATCH_ERROR;
+ if (condition & G_IO_HUP)
+ pcb_condition |= PCB_WATCH_HANGUP;
+
+ (*watch->func) ((hidval)(void *)watch, watch->fd, pcb_condition, watch->user_data);
+ ghid_mode_cursor (Settings.Mode);
+
+ return TRUE; /* Leave watch on */
+}
+
+hidval
+ghid_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
+ hidval user_data)
+{
+ GuiWatch *watch = g_new0 (GuiWatch, 1);
+ hidval ret;
+ unsigned int glib_condition = 0;
+
+ if (condition & PCB_WATCH_READABLE)
+ glib_condition |= G_IO_IN;
+ if (condition & PCB_WATCH_WRITABLE)
+ glib_condition |= G_IO_OUT;
+ if (condition & PCB_WATCH_ERROR)
+ glib_condition |= G_IO_ERR;
+ if (condition & PCB_WATCH_HANGUP)
+ glib_condition |= G_IO_HUP;
+
+ watch->func = func;
+ watch->user_data = user_data;
+ watch->fd = fd;
+ watch->channel = g_io_channel_unix_new( fd );
+ watch->id = g_io_add_watch( watch->channel, glib_condition, ghid_watch, watch );
+
+ ret.ptr = (void *) watch;
+ return ret;
+}
+
+void
+ghid_unwatch_file (hidval data)
+{
+ GuiWatch *watch = (GuiWatch*)data.ptr;
+
+ g_io_channel_shutdown( watch->channel, TRUE, NULL );
+ g_io_channel_unref( watch->channel );
+ g_free( watch );
+}
+
+typedef struct
+{
+ GSource source;
+ void (*func) (hidval user_data);
+ hidval user_data;
+} BlockHookSource;
+
+static gboolean ghid_block_hook_prepare (GSource *source,
+ gint *timeout);
+static gboolean ghid_block_hook_check (GSource *source);
+static gboolean ghid_block_hook_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+
+static GSourceFuncs ghid_block_hook_funcs = {
+ ghid_block_hook_prepare,
+ ghid_block_hook_check,
+ ghid_block_hook_dispatch,
+ NULL // No destroy notification
+};
+
+static gboolean
+ghid_block_hook_prepare (GSource *source,
+ gint *timeout)
+{
+ hidval data = ((BlockHookSource *)source)->user_data;
+ ((BlockHookSource *)source)->func( data );
+ return FALSE;
+}
+
+static gboolean
+ghid_block_hook_check (GSource *source)
+{
+ return FALSE;
+}
+
+static gboolean
+ghid_block_hook_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ return FALSE;
+}
+
+static hidval
+ghid_add_block_hook (void (*func) (hidval data),
+ hidval user_data)
+{
+ hidval ret;
+ BlockHookSource *source;
+
+ source = (BlockHookSource *)g_source_new (&ghid_block_hook_funcs, sizeof( BlockHookSource ));
+
+ source->func = func;
+ source->user_data = user_data;
+
+ g_source_attach ((GSource *)source, NULL);
+
+ ret.ptr = (void *) source;
+ return ret;
+}
+
+static void
+ghid_stop_block_hook (hidval mlpoll)
+{
+ GSource *source = (GSource *)mlpoll.ptr;
+ g_source_destroy( source );
}
int
@@ -968,6 +1108,10 @@ HID ghid_hid = {
ghid_set_crosshair,
ghid_add_timer,
ghid_stop_timer,
+ ghid_watch_file,
+ ghid_unwatch_file,
+ ghid_add_block_hook,
+ ghid_stop_block_hook,
ghid_log,
ghid_logv,
@@ -1021,6 +1165,10 @@ HID ghid_extents = {
0 /* ghid_set_crosshair */ ,
0 /* ghid_add_timer */ ,
0 /* ghid_stop_timer */ ,
+ 0 /* ghid_watch_file */ ,
+ 0 /* ghid_unwatch_file */ ,
+ 0 /* ghid_add_block_hook */ ,
+ 0 /* ghid_stop_block_hook */ ,
0 /* ghid_log */ ,
0 /* ghid_logv */ ,
Index: src/hid/lesstif/main.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/lesstif/main.c,v
retrieving revision 1.38
diff -U3 -p -r1.38 main.c
--- src/hid/lesstif/main.c 10 Oct 2006 10:49:58 -0000 1.38
+++ src/hid/lesstif/main.c 1 Dec 2006 00:04:53 -0000
@@ -29,6 +29,8 @@
#include <dmalloc.h>
#endif
+#include <sys/poll.h>
+
RCSID ("$Id: main.c,v 1.38 2006/10/10 10:49:58 danmc Exp $");
#ifndef XtRDouble
@@ -3320,6 +3322,121 @@ lesstif_stop_timer (hidval hv)
free (ts);
}
+
+typedef struct
+{
+ void (*func) ( hidval, int, unsigned int, hidval );
+ hidval user_data;
+ int fd;
+ XtInputId id;
+}
+WatchStruct;
+
+ /* We need a wrapper around the hid file watch because to pass the correct flags
+ */
+static void
+lesstif_watch_cb (XtPointer client_data, int *fid, XtInputId * id)
+{
+ unsigned int pcb_condition = 0;
+ struct pollfd fds;
+ short condition;
+
+ WatchStruct *watch = (WatchStruct*)client_data;
+
+ fds.fd = watch->fd;
+ fds.events = POLLIN | POLLOUT;
+ poll( &fds, 1, 0 );
+ condition = fds.revents;
+
+ // Should we only include those we were asked to watch?
+ if (condition & POLLIN)
+ pcb_condition |= PCB_WATCH_READABLE;
+ if (condition & POLLOUT)
+ pcb_condition |= PCB_WATCH_WRITABLE;
+ if (condition & POLLERR)
+ pcb_condition |= PCB_WATCH_ERROR;
+ if (condition & POLLHUP)
+ pcb_condition |= PCB_WATCH_HANGUP;
+
+ (*watch->func) ((hidval)(void *)watch, watch->fd, pcb_condition, watch->user_data);
+
+ return;
+}
+
+hidval
+lesstif_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
+ hidval user_data)
+{
+ WatchStruct *watch = malloc (sizeof(WatchStruct));
+ hidval ret;
+ unsigned int xt_condition = 0;
+
+ if (condition & PCB_WATCH_READABLE)
+ xt_condition |= XtInputReadMask;
+ if (condition & PCB_WATCH_WRITABLE)
+ xt_condition |= XtInputWriteMask;
+ if (condition & PCB_WATCH_ERROR)
+ xt_condition |= XtInputExceptMask;
+ if (condition & PCB_WATCH_HANGUP)
+ xt_condition |= XtInputExceptMask;
+
+ watch->func = func;
+ watch->user_data = user_data;
+ watch->fd = fd;
+ watch->id = XtAppAddInput( app_context, fd, (XtPointer)xt_condition, lesstif_watch_cb, watch );
+
+ ret.ptr = (void *) watch;
+ return ret;
+}
+
+void
+lesstif_unwatch_file (hidval data)
+{
+ WatchStruct *watch = (WatchStruct*)data.ptr;
+ XtRemoveInput( watch->id );
+ free( watch );
+}
+
+typedef struct
+{
+ XtBlockHookId id;
+ void (*func) (hidval user_data);
+ hidval user_data;
+} BlockHookStruct;
+
+static void lesstif_block_hook_cb(XtPointer user_data);
+
+static void
+lesstif_block_hook_cb (XtPointer user_data)
+{
+ BlockHookStruct *block_hook = (BlockHookStruct *)user_data;
+ block_hook->func( block_hook->user_data );
+}
+
+static hidval
+lesstif_add_block_hook (void (*func) (hidval data), hidval user_data )
+{
+ hidval ret;
+ BlockHookStruct *block_hook = malloc( sizeof( BlockHookStruct ));
+
+ block_hook->func = func;
+ block_hook->user_data = user_data;
+
+ block_hook->id = XtAppAddBlockHook( app_context, lesstif_block_hook_cb, (XtPointer)block_hook );
+
+ ret.ptr = (void *) block_hook;
+ return ret;
+}
+
+static void
+lesstif_stop_block_hook (hidval mlpoll)
+{
+ BlockHookStruct *block_hook = (BlockHookStruct *)mlpoll.ptr;
+ XtRemoveBlockHook( block_hook->id );
+ free( block_hook );
+}
+
+
extern void lesstif_logv (const char *fmt, va_list ap);
extern int lesstif_confirm_dialog (char *msg, ...);
@@ -3529,6 +3646,10 @@ HID lesstif_gui = {
lesstif_set_crosshair,
lesstif_add_timer,
lesstif_stop_timer,
+ lesstif_watch_file,
+ lesstif_unwatch_file,
+ lesstif_add_block_hook,
+ lesstif_stop_block_hook,
lesstif_log,
lesstif_logv,
Index: src/main.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/main.c,v
retrieving revision 1.60
diff -U3 -p -r1.60 main.c
--- src/main.c 21 Oct 2006 14:38:30 -0000 1.60
+++ src/main.c 1 Dec 2006 00:04:52 -0000
@@ -55,6 +55,10 @@
/* This next one is so we can print the help messages. */
#include "hid/hidint.h"
+#ifdef HAVE_DBUS
+#include "dbus.h"
+#endif
+
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif
@@ -767,7 +771,13 @@ main (int argc, char *argv[])
if (Settings.init_done == 0)
{
Settings.init_done = 1;
+#if HAVE_DBUS
+ pcb_dbus_setup();
+#endif
gui->do_export (0);
+#if HAVE_DBUS
+ pcb_dbus_finish();
+#endif
}
return (0);
_______________________________________________
geda-dev mailing list
geda-dev@moria.seul.org
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev