[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