/* Socket communication between canvas and a C program */


/* Here is example code : */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define uchar unsigned char

/* Remark about buffer size for sysread() given for perl also applies for read() here. */

#define MSGBUFSIZE 100000
#define REPLYBUFSIZE 1000

uchar msgbuf[MSGBUFSIZE] ;
uchar* msgbufnext = msgbuf ;
uchar replybuf[REPLYBUFSIZE] ;
int sockfd ;

void ConnectToCanvas( void ){
   struct sockaddr_un sockstructun ;
   int sunlen ;
   uchar* sockfilename = (uchar*)"/tmp/canvas.sock" ;
   int ck ;

   sockfd = socket( PF_UNIX, SOCK_STREAM, 0 );
   if( sockfd < 0 ){ printf("ERROR: cant create socket.\n"); exit(0); }
   sockstructun.sun_family = AF_UNIX ;
   strcpy( sockstructun.sun_path , (char*)sockfilename );
   sunlen = SUN_LEN( &sockstructun );
   ck = connect( sockfd, (struct sockaddr *) &sockstructun , sunlen );
   if( 0 > ck ){ printf("ERROR: nok connect.\n"); exit(0); }
   }

void SendMessage( void ){ /* sends buffered message */
   int len ;
   int ck ;

   len = msgbufnext - msgbuf ; if( len <= 0 ){ printf("nothing to send"); return ; }

   /* zero termination is desirable but not required : */
   if( *msgbufnext != 0 ){ *(msgbufnext++)= 0 ; } len++ ;

   ck = write( sockfd, msgbuf, len );
   if( ck != len ){ printf("ERROR: wrote %d of %d bytes\n", ck, len ); }
   msgbufnext = msgbuf ;

   /* wait for server to send a reply, by doing a blocking read : */
   ck = read( sockfd, replybuf, REPLYBUFSIZE - 1 ); /* leave space for terminator */
   if( ck < 0 ){ printf("failed read.\n"); exit(0); }
   /* don't rely on received string being terminated : */
   replybuf[ck] = 0 ;
   printf("got reply, size=%d string=%s\n", ck, replybuf );
   }

void AppendMessage( void* newmsg ){
   int len ;

   len = strlen( (char*)newmsg );
   if( MSGBUFSIZE - (msgbufnext - msgbuf) - 1 < len ){ SendMessage(); }
   if( len > MSGBUFSIZE - 1 ){ printf("message too long\n"); exit(0); }
   if( msgbufnext != msgbuf ){ *(msgbufnext++) = '\n' ; }
   memcpy( msgbufnext, newmsg, len ); msgbufnext += len ;
   }

int main( void ){
   ConnectToCanvas();
   AppendMessage("drawline 10 10 100 100");
   AppendMessage("setdrawcolor 255 0 0 255");
   AppendMessage("flushlayer\nshowimobuf");
   SendMessage();
   AppendMessage("drawline 10 100 100 10");
   AppendMessage("setdrawcolor 255 255 128 0");
   AppendMessage("flushlayer\nshowimobuf");
   SendMessage();
   return(0);
   }

/* compile with :
pushd /my/prive/projects/Canvas/v4/doc
cc csocketexample.c -o csocketexample -W -Wall
popd
*/