aboutsummaryrefslogtreecommitdiff
path: root/externals/vanilla
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2010-12-13 01:01:52 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2010-12-13 01:01:52 +0000
commit8cd5a0079b644c5b9bc95072e269be8457d56a97 (patch)
treea47384d88c20bfa65e587bc27db5829f3d498c9f /externals/vanilla
parentf12b0d7aa5d1f996b25ede45a2938dc1a1529e53 (diff)
refactored x_net.c into netsend.c netreceive.c
svn path=/trunk/; revision=14598
Diffstat (limited to 'externals/vanilla')
-rw-r--r--externals/vanilla/Makefile2
-rw-r--r--externals/vanilla/lib_x_net.c5
-rw-r--r--externals/vanilla/netreceive.c195
-rw-r--r--externals/vanilla/netsend.c180
4 files changed, 376 insertions, 6 deletions
diff --git a/externals/vanilla/Makefile b/externals/vanilla/Makefile
index 5b74ca77..e9ba5ac6 100644
--- a/externals/vanilla/Makefile
+++ b/externals/vanilla/Makefile
@@ -5,7 +5,7 @@ LIBRARY_NAME = vanilla
# add your .c source files, one object per file, to the SOURCES
# variable, help files will be included automatically
-SOURCES = abs~.c bng.c clip~.c cnv.c dbtopow~.c dbtorms~.c exp~.c ftom~.c hradio.c hsl.c hslider.c key.c keyname.c keyup.c list.c log~.c mtof~.c my_canvas.c my_numbox.c nbx.c openpanel.c powtodb~.c pow~.c print.c qlist.c radiobut.c radiobutton.c rdb.c rmstodb~.c rsqrt~.c savepanel.c sqrt~.c textfile.c tgl.c toggle.c vradio.c vsl.c vslider.c vu.c wrap~.c
+SOURCES = abs~.c bng.c clip~.c cnv.c dbtopow~.c dbtorms~.c exp~.c ftom~.c hradio.c hsl.c hslider.c key.c keyname.c keyup.c list.c log~.c mtof~.c my_canvas.c my_numbox.c nbx.c netsend.c netreceive.c openpanel.c powtodb~.c pow~.c print.c qlist.c radiobut.c radiobutton.c rdb.c rmstodb~.c rsqrt~.c savepanel.c sqrt~.c textfile.c tgl.c toggle.c vradio.c vsl.c vslider.c vu.c wrap~.c
# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
# be included automatically
diff --git a/externals/vanilla/lib_x_net.c b/externals/vanilla/lib_x_net.c
deleted file mode 100644
index c2a109aa..00000000
--- a/externals/vanilla/lib_x_net.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "../../pd/src/x_net.c"
-void lib_x_net_setup(void)
-{
- x_net_setup();
-}
diff --git a/externals/vanilla/netreceive.c b/externals/vanilla/netreceive.c
new file mode 100644
index 00000000..8e332f54
--- /dev/null
+++ b/externals/vanilla/netreceive.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* network */
+
+#include "m_pd.h"
+#include "s_stuff.h"
+
+#include <sys/types.h>
+#include <string.h>
+#ifdef MSW
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <stdio.h>
+#define SOCKET_ERROR -1
+#endif
+
+static t_class *netreceive_class;
+
+typedef struct _netreceive
+{
+ t_object x_obj;
+ t_outlet *x_msgout;
+ t_outlet *x_connectout;
+ int x_connectsocket;
+ int x_nconnections;
+ int x_udp;
+} t_netreceive;
+
+static void netreceive_notify(t_netreceive *x)
+{
+ outlet_float(x->x_connectout, --x->x_nconnections);
+}
+
+static void netreceive_doit(void *z, t_binbuf *b)
+{
+ t_atom messbuf[1024];
+ t_netreceive *x = (t_netreceive *)z;
+ int msg, natom = binbuf_getnatom(b);
+ t_atom *at = binbuf_getvec(b);
+ for (msg = 0; msg < natom;)
+ {
+ int emsg;
+ for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
+ && at[emsg].a_type != A_SEMI; emsg++)
+ ;
+ if (emsg > msg)
+ {
+ int i;
+ for (i = msg; i < emsg; i++)
+ if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
+ {
+ pd_error(x, "netreceive: got dollar sign in message");
+ goto nodice;
+ }
+ if (at[msg].a_type == A_FLOAT)
+ {
+ if (emsg > msg + 1)
+ outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
+ else outlet_float(x->x_msgout, at[msg].a_w.w_float);
+ }
+ else if (at[msg].a_type == A_SYMBOL)
+ outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
+ emsg-msg-1, at + msg + 1);
+ }
+ nodice:
+ msg = emsg + 1;
+ }
+}
+
+static void netreceive_connectpoll(t_netreceive *x)
+{
+ int fd = accept(x->x_connectsocket, 0, 0);
+ if (fd < 0) post("netreceive: accept failed");
+ else
+ {
+ t_socketreceiver *y = socketreceiver_new((void *)x,
+ (t_socketnotifier)netreceive_notify,
+ (x->x_msgout ? netreceive_doit : 0), 0);
+ sys_addpollfn(fd, (t_fdpollfn)socketreceiver_read, y);
+ outlet_float(x->x_connectout, ++x->x_nconnections);
+ }
+}
+
+static void *netreceive_new(t_symbol *compatflag,
+ t_floatarg fportno, t_floatarg udpflag)
+{
+ t_netreceive *x;
+ struct sockaddr_in server;
+ int sockfd, portno = fportno, udp = (udpflag != 0);
+ int old = !strcmp(compatflag->s_name , "old");
+ int intarg;
+ /* create a socket */
+ sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0);
+#if 0
+ fprintf(stderr, "receive socket %d\n", sockfd);
+#endif
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (0);
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+
+#if 1
+ /* ask OS to allow another Pd to repoen this port after we close it. */
+ intarg = 1;
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&intarg, sizeof(intarg)) < 0)
+ post("setsockopt (SO_REUSEADDR) failed\n");
+#endif
+#if 0
+ intarg = 0;
+ if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
+ &intarg, sizeof(intarg)) < 0)
+ post("setsockopt (SO_RCVBUF) failed\n");
+#endif
+ /* Stream (TCP) sockets are set NODELAY */
+ if (!udp)
+ {
+ intarg = 1;
+ if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
+ (char *)&intarg, sizeof(intarg)) < 0)
+ post("setsockopt (TCP_NODELAY) failed\n");
+ }
+ /* assign server port number */
+ server.sin_port = htons((u_short)portno);
+
+ /* name the socket */
+ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
+ {
+ sys_sockerror("bind");
+ sys_closesocket(sockfd);
+ return (0);
+ }
+ x = (t_netreceive *)pd_new(netreceive_class);
+ if (old)
+ {
+ /* old style, nonsecure version */
+ x->x_msgout = 0;
+ }
+ else x->x_msgout = outlet_new(&x->x_obj, &s_anything);
+
+ if (udp) /* datagram protocol */
+ {
+ t_socketreceiver *y = socketreceiver_new((void *)x,
+ (t_socketnotifier)netreceive_notify,
+ (x->x_msgout ? netreceive_doit : 0), 1);
+ sys_addpollfn(sockfd, (t_fdpollfn)socketreceiver_read, y);
+ x->x_connectout = 0;
+ }
+ else /* streaming protocol */
+ {
+ if (listen(sockfd, 5) < 0)
+ {
+ sys_sockerror("listen");
+ sys_closesocket(sockfd);
+ sockfd = -1;
+ }
+ else
+ {
+ sys_addpollfn(sockfd, (t_fdpollfn)netreceive_connectpoll, x);
+ x->x_connectout = outlet_new(&x->x_obj, &s_float);
+ }
+ }
+ x->x_connectsocket = sockfd;
+ x->x_nconnections = 0;
+ x->x_udp = udp;
+
+ return (x);
+}
+
+static void netreceive_free(t_netreceive *x)
+{
+ /* LATER make me clean up open connections */
+ if (x->x_connectsocket >= 0)
+ {
+ sys_rmpollfn(x->x_connectsocket);
+ sys_closesocket(x->x_connectsocket);
+ }
+}
+
+static void netreceive_setup(void)
+{
+ netreceive_class = class_new(gensym("netreceive"),
+ (t_newmethod)netreceive_new, (t_method)netreceive_free,
+ sizeof(t_netreceive), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT,
+ A_DEFSYM, 0);
+}
diff --git a/externals/vanilla/netsend.c b/externals/vanilla/netsend.c
new file mode 100644
index 00000000..c3c9e90e
--- /dev/null
+++ b/externals/vanilla/netsend.c
@@ -0,0 +1,180 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* network */
+
+#include "m_pd.h"
+#include "s_stuff.h"
+
+#include <sys/types.h>
+#include <string.h>
+#ifdef MSW
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <stdio.h>
+#define SOCKET_ERROR -1
+#endif
+
+static t_class *netsend_class;
+
+typedef struct _netsend
+{
+ t_object x_obj;
+ int x_fd;
+ int x_protocol;
+} t_netsend;
+
+static void *netsend_new(t_floatarg udpflag)
+{
+ t_netsend *x = (t_netsend *)pd_new(netsend_class);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_fd = -1;
+ x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
+ return (x);
+}
+
+static void netsend_connect(t_netsend *x, t_symbol *hostname,
+ t_floatarg fportno)
+{
+ struct sockaddr_in server;
+ struct hostent *hp;
+ int sockfd;
+ int portno = fportno;
+ int intarg;
+ if (x->x_fd >= 0)
+ {
+ error("netsend_connect: already connected");
+ return;
+ }
+
+ /* create a socket */
+ sockfd = socket(AF_INET, x->x_protocol, 0);
+#if 0
+ fprintf(stderr, "send socket %d\n", sockfd);
+#endif
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return;
+ }
+ /* connect socket using hostname provided in command line */
+ server.sin_family = AF_INET;
+ hp = gethostbyname(hostname->s_name);
+ if (hp == 0)
+ {
+ post("bad host?\n");
+ return;
+ }
+#if 0
+ intarg = 0;
+ if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
+ &intarg, sizeof(intarg)) < 0)
+ post("setsockopt (SO_RCVBUF) failed\n");
+#endif
+ /* for stream (TCP) sockets, specify "nodelay" */
+ if (x->x_protocol == SOCK_STREAM)
+ {
+ intarg = 1;
+ if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
+ (char *)&intarg, sizeof(intarg)) < 0)
+ post("setsockopt (TCP_NODELAY) failed\n");
+ }
+ memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
+
+ /* assign client port number */
+ server.sin_port = htons((u_short)portno);
+
+ post("connecting to port %d", portno);
+ /* try to connect. LATER make a separate thread to do this
+ because it might block */
+ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
+ sys_sockerror("connecting stream socket");
+ sys_closesocket(sockfd);
+ return;
+ }
+ x->x_fd = sockfd;
+ outlet_float(x->x_obj.ob_outlet, 1);
+}
+
+static void netsend_disconnect(t_netsend *x)
+{
+ if (x->x_fd >= 0)
+ {
+ sys_closesocket(x->x_fd);
+ x->x_fd = -1;
+ outlet_float(x->x_obj.ob_outlet, 0);
+ }
+}
+
+static void netsend_send(t_netsend *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (x->x_fd >= 0)
+ {
+ t_binbuf *b = binbuf_new();
+ char *buf, *bp;
+ int length, sent;
+ t_atom at;
+ binbuf_add(b, argc, argv);
+ SETSEMI(&at);
+ binbuf_add(b, 1, &at);
+ binbuf_gettext(b, &buf, &length);
+ for (bp = buf, sent = 0; sent < length;)
+ {
+ static double lastwarntime;
+ static double pleasewarn;
+ double timebefore = sys_getrealtime();
+ int res = send(x->x_fd, bp, length-sent, 0);
+ double timeafter = sys_getrealtime();
+ int late = (timeafter - timebefore > 0.005);
+ if (late || pleasewarn)
+ {
+ if (timeafter > lastwarntime + 2)
+ {
+ post("netsend blocked %d msec",
+ (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
+ pleasewarn = 0;
+ lastwarntime = timeafter;
+ }
+ else if (late) pleasewarn += timeafter - timebefore;
+ }
+ if (res <= 0)
+ {
+ sys_sockerror("netsend");
+ netsend_disconnect(x);
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ t_freebytes(buf, length);
+ binbuf_free(b);
+ }
+ else error("netsend: not connected");
+}
+
+static void netsend_free(t_netsend *x)
+{
+ netsend_disconnect(x);
+}
+
+static void netsend_setup(void)
+{
+ netsend_class = class_new(gensym("netsend"), (t_newmethod)netsend_new,
+ (t_method)netsend_free,
+ sizeof(t_netsend), 0, A_DEFFLOAT, 0);
+ class_addmethod(netsend_class, (t_method)netsend_connect,
+ gensym("connect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netsend_class, (t_method)netsend_disconnect,
+ gensym("disconnect"), 0);
+ class_addmethod(netsend_class, (t_method)netsend_send, gensym("send"),
+ A_GIMME, 0);
+}