[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: CVS update: libiberty.tar.gz



  User: pcjc2   
  Date: 06/12/02 09:28:54

  Added:       .        libiberty.tar.gz pcb.rawdbus.automake_support.patch
                        pcb.rawdbus.dbus_code.patch
                        pcb.rawdbus.hid_support.patch
                        pcb.rawdbus.libiberty_bundle.patch
                        pcb.rawdbus.setup_hooks.patch
  Log:
  Added support patches and libiberty.tar.gz for adding raw libdbus support in PCB. (As an alternative to the glib-dbus support which only supports the GTK HID).
  
  
  
  
  Revision  Changes    Path
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/libiberty.tar.gz
  
  	<<Binary file>>
  
  
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/pcb.rawdbus.automake_support.patch
  
  Index: pcb.rawdbus.automake_support.patch
  ===================================================================
  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
  
  
  
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/pcb.rawdbus.dbus_code.patch
  
  Index: pcb.rawdbus.dbus_code.patch
  ===================================================================
  diff -urN /home/pcjc2/pcbsrc/pcb.clean/src/dbus.c src/dbus.c
  --- /home/pcjc2/pcbsrc/pcb.clean/src/dbus.c	1970-01-01 01:00:00.000000000 +0100
  +++ src/dbus.c	2006-12-01 19:29:00.000000000 +0000
  @@ -0,0 +1,392 @@
  +/*
  + * 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
  + */
  +
  +#define DBUS_API_SUBJECT_TO_CHANGE
  +#include <dbus/dbus.h>
  +#include <string.h>
  +
  +#include "dbus.h"
  +#include "dbus-pcbmain.h"
  +#include "dbus-introspect.h"
  +#include "hid.h"
  +#include "data.h"
  +
  +// For lrealpath
  +#include <libiberty.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"
  +
  +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 = 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 = strdup( "" );
  +      if (filename == NULL)
  +        {
  +          fprintf(stderr, "pcb_dbus: Couldn't 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;
  +  int i;
  +
  +  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
  +  hid_actionv( action_name, argc, 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;
  +}
  +
  +
  +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;
  +}
  +
  +
  +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();
  +}
  +
  diff -urN /home/pcjc2/pcbsrc/pcb.clean/src/dbus.h src/dbus.h
  --- /home/pcjc2/pcbsrc/pcb.clean/src/dbus.h	1970-01-01 01:00:00.000000000 +0100
  +++ src/dbus.h	2006-11-30 23:53:13.000000000 +0000
  @@ -0,0 +1,30 @@
  +/*
  + * 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 _DBUS_H_
  +#define _DBUS_H_
  +
  +/* Carry out all actions to setup the D-Bus and register appropriate callbacks */
  +void pcb_dbus_setup();
  +
  +/* Carry out all actions to finalise the D-Bus connection */
  +void pcb_dbus_finish();
  +
  +
  +#endif /* !_DBUS_H */
  diff -urN /home/pcjc2/pcbsrc/pcb.clean/src/dbus-pcbmain.c src/dbus-pcbmain.c
  --- /home/pcjc2/pcbsrc/pcb.clean/src/dbus-pcbmain.c	1970-01-01 01:00:00.000000000 +0100
  +++ src/dbus-pcbmain.c	2006-12-01 19:17:50.000000000 +0000
  @@ -0,0 +1,332 @@
  +/* -*- 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
  + *
  + */
  +
  +#define DBUS_API_SUBJECT_TO_CHANGE
  +#include <dbus/dbus.h>
  +#include <stdio.h>
  +
  +#include "global.h"
  +#include "dbus-pcbmain.h"
  +
  +typedef struct _IOWatchHandler IOWatchHandler;
  +typedef struct _TimeoutHandler TimeoutHandler;
  +
  +struct _IOWatchHandler
  +{
  +  DBusWatch *dbus_watch;
  +  hidval pcb_watch;
  +};
  +
  +struct _TimeoutHandler
  +{
  +  DBusTimeout *dbus_timeout;
  +  hidval pcb_timer;
  +  int interval;
  +};
  +
  +
  +static void
  +block_hook_cb (hidval 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 = data;
  +
  +  // Remove the watch registered with the HID
  +  gui->unwatch_file( handler->pcb_watch );
  +  free( handler );
  +}
  +
  +
  +void
  +io_watch_handler_cb (hidval pcb_watch,
  +                     int fd,
  +                     unsigned int condition,
  +                     hidval 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 = data;
  +
  +  // Remove the timeout registered with the HID
  +  gui->stop_timer( handler->pcb_timer );
  +  free( handler );
  +}
  +
  +
  +void
  +timeout_handler_cb (hidval data)
  +{
  +  TimeoutHandler *handler;
  +  handler = 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 = 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;
  +
  +  // 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;
  +
  +  fd = dbus_watch_get_fd (dbus_watch);
  +
  +  handler = malloc( sizeof( IOWatchHandler ));
  +  handler->dbus_watch = dbus_watch;
  +  handler->pcb_watch = gui->watch_file(fd, pcb_condition, io_watch_handler_cb, (hidval)(void *)handler);
  +
  +  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;
  +
  +  // 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 = malloc( sizeof(TimeoutHandler ) );
  +  handler->dbus_timeout = timeout;
  +  handler->interval = dbus_timeout_get_interval( timeout );
  +  handler->pcb_timer = gui->add_timer( timeout_handler_cb, handler->interval, (hidval)(void *)handler);
  +
  +  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;
  +
  +  /* 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. */
  +  gui->add_block_hook( block_hook_cb, (hidval)(void*)connection );
  +
  +  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");
  +
  +}
  diff -urN /home/pcjc2/pcbsrc/pcb.clean/src/dbus-pcbmain.h src/dbus-pcbmain.h
  --- /home/pcjc2/pcbsrc/pcb.clean/src/dbus-pcbmain.h	1970-01-01 01:00:00.000000000 +0100
  +++ src/dbus-pcbmain.h	2006-12-01 16:15:00.000000000 +0000
  @@ -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 _DBUS_PCBMAIN_H_
  +#define _DBUS_PCBMAIN_H_
  +
  +#define DBUS_API_SUBJECT_TO_CHANGE
  +#include <dbus/dbus.h>
  +
  +void pcb_dbus_connection_setup_with_mainloop (DBusConnection *connection);
  +void pcb_dbus_connection_finish_with_mainloop (DBusConnection *connection);
  +
  +#endif /* !_DBUS_PCBMAIN_H */
  diff -urN /home/pcjc2/pcbsrc/pcb.clean/src/dbus.xml src/dbus.xml
  --- /home/pcjc2/pcbsrc/pcb.clean/src/dbus.xml	1970-01-01 01:00:00.000000000 +0100
  +++ src/dbus.xml	2006-11-30 23:53:13.000000000 +0000
  @@ -0,0 +1,25 @@
  +<?xml version="1.0" encoding="UTF-8" ?>
  +<!-- Should name="/org/geda/seul/pcb" ? -->
  +<node>
  +  <!-- This section isn't needed for the glib binding
  +       but is convenient for our raw binding          -->
  +  <interface name="org.freedesktop.DBus.Introspectable">
  +    <method name="Introspect">
  +      <arg direction="out" type="s" name="data" />
  +    </method>
  +  </interface>
  +  <!-- End section not needed for glib binding        -->
  +  <interface name="org.seul.geda.pcb">
  +    <method name="GetFilename">
  +      <arg direction="out" type="s" />
  +    </method>
  +  </interface>
  +  <interface name="org.seul.geda.pcb.actions">
  +    <method name="ExecAction">
  +      <arg direction="in" type="s" name="action" />
  +      <arg direction="in" type="as" name="args" />
  +      <arg direction="out" type="u" />
  +    </method>
  +  </interface>
  +</node>
  +
  
  
  
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/pcb.rawdbus.hid_support.patch
  
  Index: pcb.rawdbus.hid_support.patch
  ===================================================================
  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: pcb.rawdbus.hid_support.patch,v 1.1 2006/12/02 14:28:54 pcjc2 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,
  
  
  
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/pcb.rawdbus.libiberty_bundle.patch
  
  Index: pcb.rawdbus.libiberty_bundle.patch
  ===================================================================
  --- pcb.rawdbus_tmp/configure.ac	2006-12-01 01:49:17.000000000 +0000
  +++ pcb.rawdbus/configure.ac	2006-12-01 15:35:26.000000000 +0000
  @@ -491,6 +491,29 @@
       esac
   done
   
  +# ------------- libibertiy -------------------
  +
  +dnl The DBus integration code uses libiberty for a portable
  +dnl way to determine the full path of a file
  +if test "x$with_dbus" = "xyes"; then
  +	libiberty_support=yes
  +else
  +	libiberty_support=no
  +fi
  +
  +if test "${libiberty_support}" = "yes"; then
  +	dnl If we have an installed library, prefer it over the bundled one
  +	AC_CHECK_LIB(iberty, lrealpath,
  +		[AC_MSG_NOTICE([Using external libiberty library.])],
  +		[ AC_MSG_NOTICE([Using bundled libiberty library.])
  +			AC_CONFIG_SUBDIRS([libiberty])
  +			LIBIBERTY="../libiberty/libiberty.a"
  +			LIBIBERTY_INCLUDES="-I../include" ] )
  +fi
  +
  +AC_SUBST(LIBIBERTY)
  +AC_SUBST(LIBIBERTY_INCLUDES)
  +
   
   # ------------- dmalloc -------------------
   dnl dmalloc checks
  --- pcb.rawdbus_tmp/Makefile.am	2006-04-14 13:32:37.000000000 +0100
  +++ pcb.rawdbus/Makefile.am	2006-12-01 15:15:56.000000000 +0000
  @@ -6,7 +6,7 @@
   DIRS=		win32 src lib newlib example tools tutorial README_FILES
   SUBDIRS=	${DIRS} @DOC@
   DIST_SUBDIRS=	${DIRS} doc
  -EXTRA_DIST=	autogen.sh globalconst.h README.cvs README.win32
  +EXTRA_DIST=	autogen.sh globalconst.h README.cvs README.win32 libiberty include
   
   DISTCLEANFILES=	configure.lineno
   
  --- pcb.rawdbus_tmp/src/Makefile.am	2006-12-01 01:49:17.000000000 +0000
  +++ pcb.rawdbus/src/Makefile.am	2006-12-01 15:33:05.000000000 +0000
  @@ -155,7 +155,7 @@
   	res_parse.h \
   	hid/common/hidlist.h
   
  -pcb_bin_LDADD = @HIDLIBS@
  +pcb_bin_LDADD = @HIDLIBS@ @LIBIBERTY@
   pcb_bin_DEPENDENCIES = @HIDLIBS@
   
   # Action, Attribute, and Flag lists.
  @@ -165,7 +165,7 @@
   	mv $@.tmp $@
   
   # for globalconst.h
  -INCLUDES=	-I$(top_srcdir) -I$(srcdir)/icons
  +INCLUDES=	-I$(top_srcdir) -I$(srcdir)/icons @LIBIBERTY_INCLUDES@
   
   EXTRA_DIST= \
   	check_icon.data \
  
  
  
  1.1                  eda/geda/xgsch2pcb/support/pcb_libdbus/pcb.rawdbus.setup_hooks.patch
  
  Index: pcb.rawdbus.setup_hooks.patch
  ===================================================================
  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-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs