summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buschannel.h43
-rw-r--r--src/busloop.c179
-rw-r--r--src/busloop.h39
-rw-r--r--src/busxtloop.c117
-rw-r--r--src/busxtloop.h40
5 files changed, 418 insertions, 0 deletions
diff --git a/src/buschannel.h b/src/buschannel.h
new file mode 100644
index 0000000..2d05ff4
--- /dev/null
+++ b/src/buschannel.h
@@ -0,0 +1,43 @@
+#ifndef _BUSCHANNEL_H
+#define _BUSCHANNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* general Handle */
+
+#ifdef WIN32
+#include <windows.h>
+#define HANDLE SOCKET
+#else
+#define HANDLE int
+#endif
+
+typedef struct _channel *Channel;
+/* callback declenche par la gestion de boucle sur evenement exception sur le canal */
+typedef void (*ChannelHandleDelete)( void *data );
+/* callback declenche par la gestion de boucle sur donnees pretes sur le canal */
+typedef void (*ChannelHandleRead)( Channel channel, HANDLE fd, void *data);
+
+/* fonction appele par le bus pour initialisation */
+typedef void (*ChannelInit)(void);
+
+/* fonction appele par le bus pour mise en place des callback sur le canal */
+typedef Channel (*ChannelSetUp)(
+ HANDLE fd,
+ void *data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read
+ );
+/* fonction appele par le bus pour fermeture du canal */
+typedef void (*ChannelClose)( Channel channel );
+
+/* mise en place des fonction de gestion des canaux */
+void BusSetChannelManagement( ChannelInit init_chan, ChannelSetUp setup_chan, ChannelClose close_chan );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/busloop.c b/src/busloop.c
new file mode 100644
index 0000000..346a505
--- /dev/null
+++ b/src/busloop.c
@@ -0,0 +1,179 @@
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef WIN32
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#endif
+
+
+#include "list.h"
+#include "buschannel.h"
+#include "busloop.h"
+#include "timer.h"
+
+struct _channel {
+ Channel next;
+ HANDLE fd;
+ void *data;
+ int tobedeleted;
+ ChannelHandleDelete handle_delete;
+ ChannelHandleRead handle_read;
+ };
+
+
+
+static Channel channels_list = NULL;
+
+static int channel_initialized = 0;
+
+static fd_set open_fds;
+static int MainLoop = 1;
+
+#ifdef WIN32
+WSADATA WsaData;
+#endif
+
+void BusLoopChannelClose( Channel channel )
+{
+ channel->tobedeleted = 1;
+}
+
+static void BusLoopChannelDelete( Channel channel )
+{
+ if ( channel->handle_delete )
+ (*channel->handle_delete)( channel->data );
+
+ FD_CLR(channel->fd, &open_fds);
+ LIST_REMOVE( channels_list, channel );
+}
+static void ChannelDefferedDelete()
+{
+ Channel channel,next;
+ LIST_EACH_SAFE( channels_list, channel,next)
+ {
+ if ( channel->tobedeleted )
+ {
+ BusLoopChannelDelete( channel );
+ }
+ }
+}
+
+Channel BusLoopChannelSetUp(HANDLE fd, void *data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read
+ )
+{
+ Channel channel;
+
+ LIST_ADD( channels_list, channel );
+ if ( !channel )
+ {
+ fprintf(stderr,"NOK Memory Alloc Error\n");
+ exit(0);
+ }
+ channel->fd = fd;
+ channel->tobedeleted = 0;
+ channel->handle_delete = handle_delete;
+ channel->handle_read = handle_read;
+ channel->data = data;
+
+ FD_SET( channel->fd, &open_fds );
+
+ return channel;
+}
+
+static void BusLoopChannelHandleRead(fd_set *current)
+{
+ Channel channel,next;
+
+ LIST_EACH_SAFE( channels_list, channel, next )
+ {
+ if ( FD_ISSET( channel->fd, current ) )
+ {
+ (*channel->handle_read)(channel,channel->fd,channel->data);
+ }
+ }
+}
+static void BusLoopChannelHandleExcpt(fd_set *current)
+{
+ Channel channel,next;
+ LIST_EACH_SAFE( channels_list, channel, next )
+ {
+ if (FD_ISSET( channel->fd, current ) )
+ {
+ (*channel->handle_delete)(channel->data);
+// BusLoopChannelClose( channel );
+ }
+ }
+}
+
+void BusLoopChannelInit(void)
+{
+#ifdef WIN32
+ int error;
+#else
+ /* pour eviter les plantages quand les autres applis font core-dump */
+ signal( SIGPIPE, SIG_IGN);
+#endif
+ if ( channel_initialized ) return;
+
+ FD_ZERO( &open_fds );
+
+#ifdef WIN32
+ error = WSAStartup( 0x0101, &WsaData );
+ if ( error == SOCKET_ERROR ) {
+ printf( "WSAStartup failed.\n" );
+ }
+#endif
+ channel_initialized = 1;
+}
+
+
+void BusLoopChannelStop(void)
+{
+ MainLoop = 0;
+}
+void BusLoopChannelMainLoop(void(*hook)(void))
+{
+
+fd_set rdset;
+fd_set exset;
+int ready;
+
+
+
+ while (MainLoop) {
+ ChannelDefferedDelete();
+ if ( hook ) (*hook)();
+ rdset = open_fds;
+ exset = open_fds;
+ ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout());
+ if ( ready < 0 && ( errno != EINTR ))
+ {
+ perror("select");
+ return;
+ }
+ TimerScan();
+ if ( ready > 0 )
+ {
+ BusLoopChannelHandleExcpt(&exset);
+ BusLoopChannelHandleRead(&rdset);
+ continue;
+ }
+ }
+}
+
diff --git a/src/busloop.h b/src/busloop.h
new file mode 100644
index 0000000..1eab8b6
--- /dev/null
+++ b/src/busloop.h
@@ -0,0 +1,39 @@
+#ifndef _BUSLOOP_H
+#define _BUSLOOP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "buschannel.h"
+
+/* general Handle */
+
+#define ANYPORT 0
+
+#ifdef WIN32
+#include <windows.h>
+#define HANDLE SOCKET
+#else
+#define HANDLE int
+#endif
+
+extern void BusLoopChannelInit(void);
+extern void BusLoopChannelStop(void);
+extern void BusLoopChannelMainLoop(void(*hook)(void) );
+
+extern Channel BusLoopChannelSetUp(
+ HANDLE fd,
+ void *data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read
+ );
+
+extern void BusLoopChannelClose( Channel channel );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/busxtloop.c b/src/busxtloop.c
new file mode 100644
index 0000000..e95bc45
--- /dev/null
+++ b/src/busxtloop.c
@@ -0,0 +1,117 @@
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef WIN32
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#endif
+
+
+
+#include <X11/Intrinsic.h>
+
+#include "buschannel.h"
+#include "busxtloop.h"
+
+struct _channel {
+ XtInputId id_read;
+ XtInputId id_delete;
+ void *data;
+ void (*handle_delete)( void *data );
+ void (*handle_read)( Channel channel, HANDLE fd, void *data);
+ };
+
+
+static int channel_initialized = 0;
+
+
+static XtAppContext app = NULL;
+
+
+void BusXtChannelClose( Channel channel )
+{
+
+ if ( channel->handle_delete )
+ (*channel->handle_delete)( channel->data );
+ XtRemoveInput( channel->id_read );
+ XtRemoveInput( channel->id_delete );
+}
+
+static void BusXtHandleChannelRead( XtPointer closure, int* source, XtInputId* id )
+{
+ Channel channel = (Channel)closure;
+#ifdef DEBUG
+ printf("Handle Channel read %d\n",*source );
+#endif
+ (*channel->handle_read)(channel,*source,channel->data);
+}
+static void BusXtHandleChannelDelete( XtPointer closure, int* source, XtInputId* id )
+{
+ Channel channel = (Channel)closure;
+#ifdef DEBUG
+ printf("Handle Channel delete %d\n",*source );
+#endif
+ (*channel->handle_delete)(channel->data);
+}
+Channel BusXtChannelSetUp(HANDLE fd, void *data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read
+ )
+{
+ Channel channel;
+
+ channel = XtNew( struct _channel );
+ if ( !channel )
+ {
+ fprintf(stderr,"NOK Memory Alloc Error\n");
+ exit(0);
+ }
+
+ channel->handle_delete = handle_delete;
+ channel->handle_read = handle_read;
+ channel->data = data;
+
+ channel->id_read = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask, BusXtHandleChannelRead, channel);
+ channel->id_delete = XtAppAddInput( app, fd, (XtPointer)XtInputExceptMask, BusXtHandleChannelDelete, channel);
+
+ return channel;
+}
+
+
+void BusXtChannelAppContext( XtAppContext cntx )
+{
+ app = cntx;
+}
+
+void BusXtChannelInit(void)
+{
+
+ if ( channel_initialized ) return;
+
+ /* pour eviter les plantages quand les autres applis font core-dump */
+#ifndef WIN32
+ signal( SIGPIPE, SIG_IGN);
+#endif
+ /* verifie si init correct */
+ if ( !app )
+ {
+ fprintf( stderr, "You Must call BusXtChannelAppContext to Use XtMainLoop !!!\n");
+ exit(-1);
+ }
+ channel_initialized = 1;
+}
+
+
diff --git a/src/busxtloop.h b/src/busxtloop.h
new file mode 100644
index 0000000..7cf029a
--- /dev/null
+++ b/src/busxtloop.h
@@ -0,0 +1,40 @@
+#ifndef _BUSXTLOOP_H
+#define _BUSXTLOOP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <X11/Intrinsic.h>
+
+/* general Handle */
+
+#define ANYPORT 0
+
+#ifdef WIN32
+#include <windows.h>
+#define HANDLE SOCKET
+#else
+#define HANDLE int
+#endif
+
+#include "buschannel.h"
+
+extern void BusXtChannelInit(void);
+
+extern Channel BusXtChannelSetUp(
+ HANDLE fd,
+ void *data,
+ void (*handle_delete)( void *data ),
+ void (*handle_read)( Channel channel, HANDLE fd, void *data)
+ );
+
+extern void BusXtChannelClose( Channel channel );
+
+extern void BusXtChannelAppContext( XtAppContext cntx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif