diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buschannel.h | 43 | ||||
-rw-r--r-- | src/busloop.c | 179 | ||||
-rw-r--r-- | src/busloop.h | 39 | ||||
-rw-r--r-- | src/busxtloop.c | 117 | ||||
-rw-r--r-- | src/busxtloop.h | 40 |
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 |