aboutsummaryrefslogtreecommitdiff
path: root/ext/ivy/ivy.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ivy/ivy.c')
-rw-r--r--ext/ivy/ivy.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/ext/ivy/ivy.c b/ext/ivy/ivy.c
new file mode 100644
index 0000000..aea51c7
--- /dev/null
+++ b/ext/ivy/ivy.c
@@ -0,0 +1,299 @@
+/**
+ * Copyright (C) 2007 Gregoire Lejeune <gregoire.lejeune@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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
+ */
+
+#include "rb_ivy.h"
+
+void ruby_ivy_free( RbTIvy *pRbTIvy ) {
+ if (pRbTIvy != NULL)
+ free(pRbTIvy);
+}
+
+void ruby_ivy_mark( RbTIvy *pRbTIvy ) {
+ if( pRbTIvy == NULL ) return;
+ if( !NIL_P(pRbTIvy->strAgentName) ) rb_gc_mark( pRbTIvy->strAgentName );
+ if( !NIL_P(pRbTIvy->strReadyMsg) ) rb_gc_mark( pRbTIvy->strReadyMsg );
+}
+
+VALUE ruby_ivy_new( VALUE class ) {
+
+ RbTIvy *pRbTIvy;
+
+ pRbTIvy = (RbTIvy *)malloc(sizeof(RbTIvy));
+ if( pRbTIvy == NULL )
+ rb_raise(rb_eNoMemError, "No memory left for IVY struct");
+
+ return( Data_Wrap_Struct( class, ruby_ivy_mark, ruby_ivy_free, pRbTIvy ) );
+}
+
+/** o = IVY.new( strAgentName, [strReadyMessage] ) */
+static VALUE ruby_ivy_initialize( int iNbArgs, VALUE *vArgs, VALUE class ) {
+
+ RbTIvy *pRbTIvy;
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ if( iNbArgs < 1 || iNbArgs > 2 ) {
+ rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs );
+ }
+
+ pRbTIvy->strAgentName = vArgs[0];
+ if( iNbArgs == 2 ) {
+ pRbTIvy->strReadyMsg = vArgs[1];
+ } else {
+ pRbTIvy->strReadyMsg = Qnil;
+ }
+
+ IvyInit( STR2CSTR( pRbTIvy->strAgentName ), NULL, NULL, NULL, NULL, NULL );
+
+ return( class );
+}
+
+/** ------------------------------------------------------------------------ */
+
+void ruby_ivy_message_free( RbTIvyMsg *pRbTIvyMsg ) {
+ if (pRbTIvyMsg != NULL)
+ free(pRbTIvyMsg);
+}
+
+void ruby_ivy_message_mark( RbTIvyMsg *pRbTIvyMsg ) {
+ if( pRbTIvyMsg == NULL ) return;
+ if( !NIL_P(pRbTIvyMsg->cb) ) rb_gc_mark( pRbTIvyMsg->cb );
+ if( !NIL_P(pRbTIvyMsg->data) ) rb_gc_mark( pRbTIvyMsg->data );
+ if( !NIL_P(pRbTIvyMsg->regexp) ) rb_gc_mark( pRbTIvyMsg->regexp );
+}
+
+/** o = IVY::Message.new() */
+// VALUE ruby_ivy_message_new( VALUE class, VALUE cb, VALUE data, VALUE regexp ) {
+VALUE ruby_ivy_message_new( VALUE class, VALUE data, VALUE regexp ) {
+ RbTIvyMsg *pRbTIvyMsg;
+
+ pRbTIvyMsg = (RbTIvyMsg *)malloc(sizeof(RbTIvyMsg));
+ if( pRbTIvyMsg == NULL )
+ rb_raise(rb_eNoMemError, "No memory left for IVY::MESSAGE struct");
+
+ pRbTIvyMsg->cb = rb_block_proc( );
+ pRbTIvyMsg->data = data;
+ pRbTIvyMsg->regexp = regexp;
+ pRbTIvyMsg->id = IvyBindMsg( callback, (void*)pRbTIvyMsg, STR2CSTR( pRbTIvyMsg->regexp ) );
+
+ return( Data_Wrap_Struct( class, ruby_ivy_message_mark, ruby_ivy_message_free, pRbTIvyMsg ) );
+}
+
+/** ------------------------------------------------------------------------ */
+
+void ruby_ivy_client_free( RbTIvyClient *pRbTIvyClient ) {
+ if (pRbTIvyClient != NULL)
+ free(pRbTIvyClient);
+}
+
+void ruby_ivy_client_mark( RbTIvyClient *pRbTIvyClient ) {
+ if( pRbTIvyClient == NULL ) return;
+}
+
+VALUE ruby_ivy_client_new_internal( VALUE class, IvyClientPtr client ) {
+ RbTIvyClient *pRbTIvyClient;
+
+ pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient));
+ if( pRbTIvyClient == NULL )
+ rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct");
+
+ pRbTIvyClient->client = client;
+
+ return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) );
+}
+
+/** o = IVY::Client.new( xClientName ) */
+VALUE ruby_ivy_client_new( VALUE class, VALUE clientName ) {
+ RbTIvyClient *pRbTIvyClient;
+
+ pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient));
+ if( pRbTIvyClient == NULL )
+ rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct");
+
+ pRbTIvyClient->client = IvyGetApplication( STR2CSTR( clientName ) );
+
+ return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) );
+}
+
+/** ------------------------------------------------------------------------ */
+
+VALUE ruby_ivy_appname( VALUE class ) {
+ RbTIvyClient *pRbTIvyClient;
+ char *xAppName = NULL;
+
+ Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient );
+
+ if( pRbTIvyClient->client != NULL )
+ xAppName = IvyGetApplicationName( pRbTIvyClient->client );
+
+ return( rb_str_new2( xAppName ) );
+}
+
+VALUE ruby_ivy_apphost( VALUE class ) {
+ RbTIvyClient *pRbTIvyClient;
+ char *xAppHost = NULL;
+
+ Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient );
+
+ if( pRbTIvyClient->client != NULL )
+ xAppHost = IvyGetApplicationHost( pRbTIvyClient->client );
+
+ return( rb_str_new2( xAppHost ) );
+}
+
+/** ------------------------------------------------------------------------ */
+
+VALUE ruby_ivy_start( int iNbArgs, VALUE *vArgs, VALUE class ) {
+ RbTIvy *pRbTIvy;
+ const char *bus = NULL;
+
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ if( iNbArgs == 0 ) {
+ bus = getenv( "IVYBUS" );
+ } else if( iNbArgs == 1 ) {
+ bus = STR2CSTR( vArgs[0] );
+ } else {
+ rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs );
+ }
+
+ IvyStart( bus );
+
+ return( Qnil );
+}
+
+VALUE ruby_ivy_mainloop( VALUE class ) {
+ RbTIvy *pRbTIvy;
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ IvyMainLoop( );
+
+ return( Qnil );
+}
+
+VALUE ruby_ivy_stop( VALUE class ) {
+ RbTIvy *pRbTIvy;
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ IvyStop( );
+
+ return( Qnil );
+}
+
+VALUE ruby_ivy_sendmsg( VALUE class, VALUE message ) {
+ RbTIvy *pRbTIvy;
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ IvySendMsg( STR2CSTR( message ) );
+
+ return( Qnil );
+}
+
+VALUE ruby_ivy_applist( VALUE class ) {
+ RbTIvy *pRbTIvy;
+ char *xAppList = NULL;
+ VALUE aryResult = rb_ary_new();
+
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ xAppList = IvyGetApplicationList( "|" );
+ xAppList = strtok( xAppList, "|" );
+ while( xAppList ) {
+ rb_ary_push( aryResult, rb_str_new2( xAppList ) );
+ xAppList = strtok (NULL, " ");
+ }
+ return( aryResult );
+}
+
+/** ------------------------------------------------------------------------ */
+
+// VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) {
+VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) {
+ VALUE method;
+ RbTIvy *pRbTIvy;
+
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
+
+ return( ruby_ivy_message_new( cIvyMsg, data, regexp ) );
+}
+
+VALUE ruby_ivy_unbindmsg( VALUE class ) {
+ RbTIvyMsg *pRbTIvyMsg;
+ Data_Get_Struct( class, RbTIvyMsg, pRbTIvyMsg );
+
+ if( pRbTIvyMsg->id != NULL ) {
+ IvyUnbindMsg( pRbTIvyMsg->id );
+ pRbTIvyMsg->id = NULL;
+ } else {
+ rb_warn( "IVY::Message not binded!" );
+ }
+
+ return( Qnil );
+}
+
+/** ------------------------------------------------------------------------ */
+
+static void callback( IvyClientPtr app, void *data, int argc, char **argv ) {
+ RbTIvyMsg *pRbTIvyMsg = (RbTIvyMsg *)data;
+
+ int callID = rb_intern ("call");
+ VALUE res;
+
+ int i;
+ VALUE *aryArgs;
+
+ aryArgs = (VALUE *)malloc( sizeof( VALUE ) );
+
+ aryArgs[0] = ruby_ivy_client_new_internal( cIvyClient, app ); // IvyClientPtr app
+ aryArgs[1] = pRbTIvyMsg->data; // void *data
+ aryArgs[2] = rb_ary_new();
+ for( i = 0; i < argc; i++ ) {
+ rb_ary_push( aryArgs[2], rb_str_new2( argv[i] ) );
+ }
+
+ res = rb_funcall2( pRbTIvyMsg->cb, callID, 3, aryArgs );
+}
+
+/** ------------------------------------------------------------------------ */
+
+void Init_ivy( void ) {
+ cIvy = rb_define_class( "IVY", rb_cObject );
+ cIvyMsg = rb_define_class_under( cIvy, "Message", rb_cObject );
+ cIvyClient = rb_define_class_under( cIvy, "Client", rb_cObject );
+
+ rb_define_const( cIvy, "RB_IVY_VERSION", rb_str_new2(RUBY_RBIVY_VERSION) );
+ rb_define_const( cIvy, "IVY_VERSION", rb_str_new2(RUBY_IVY_VERSION) );
+
+ rb_define_alloc_func( cIvy, ruby_ivy_new );
+ rb_define_private_method( cIvy, "initialize", ruby_ivy_initialize, -1);
+
+ // IVY
+ rb_define_method( cIvy, "start", ruby_ivy_start, -1 );
+ rb_define_method( cIvy, "mainloop", ruby_ivy_mainloop, 0 );
+ rb_define_method( cIvy, "stop", ruby_ivy_stop, 0 );
+ rb_define_method( cIvy, "sendmsg", ruby_ivy_sendmsg, 1 );
+ rb_define_method( cIvy, "applicationList", ruby_ivy_applist, 0 );
+ rb_define_method( cIvy, "bindmsg", ruby_ivy_bindmsg, 2 ); // renvoi un message de type IVY::MESSAGE
+
+ // IVY::Message
+ rb_define_method( cIvyMsg, "unbindmsg", ruby_ivy_unbindmsg, 0 );
+
+ // IVY::Client
+ rb_define_singleton_method( cIvyClient, "new", ruby_ivy_client_new, 1 );
+ rb_define_method( cIvyClient, "applicationName", ruby_ivy_appname, 0);
+ rb_define_method( cIvyClient, "applicationHost", ruby_ivy_apphost, 0);
+}