diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configure.ac | 11 | ||||
-rw-r--r-- | src/lpt.c | 116 |
2 files changed, 100 insertions, 27 deletions
diff --git a/src/configure.ac b/src/configure.ac index 175858a..2b81b3e 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -349,6 +349,8 @@ then EXT=$with_extension fi +AC_CHECK_HEADER(linux/ppdev.h, [ have_ppdev="yes" ], [ have_ppdev="no" ]) + dnl check for LPT AC_MSG_CHECKING("parallel-port") if test "$enable_lpt" != "no" @@ -358,6 +360,7 @@ then DFLAGS="$DFLAGS -DZ_WANT_LPT" echo "yes (forced)" else + cat > conftest.c << EOF # include <sys/io.h> int main(){ @@ -371,7 +374,13 @@ EOF if $CC $INCLUDES -o conftest.o conftest.c > /dev/null 2>&1 then DFLAGS="$DFLAGS -DZ_WANT_LPT" - echo "yes" + if test "x$have_ppdev" = "xyes" + then + DFLAGS="$DFLAGS -DHAVE_PPDEV" + echo "yes (with device-support)" + else + echo "yes" + fi else echo "no" fi @@ -24,7 +24,6 @@ Olaf Matthes: porting to WindozeNT/2000/XP Thomas Musil: adding "control-output" and "input" */ - #define BASE0 0x3bc #define BASE1 0x378 #define BASE2 0x278 @@ -39,6 +38,15 @@ #ifdef Z_WANT_LPT # include <stdlib.h> +# include <errno.h> + +# ifdef HAVE_PPDEV +# include <sys/ioctl.h> +# include <linux/ppdev.h> +# include <linux/parport.h> +# include <fcntl.h> +# endif /* HAVE_PPDEV */ + # ifdef __WIN32__ /* on windoze everything is so complicated... */ @@ -89,15 +97,21 @@ typedef struct _lpt t_object x_obj; unsigned long port; + int device; /* file descriptor of device, in case we are using one ...*/ int mode; // MODE_IOPERM, MODE_IOPL } t_lpt; static void lpt_float(t_lpt *x, t_floatarg f) { + unsigned char b = f; #ifdef Z_WANT_LPT +# ifdef HAVE_PPDEV + if (x->device>0){ + ioctl (x->device, PPWDATA, &b); + } else +# endif if (x->port) { - unsigned char b = f; sys_outb(b, x->port+0); } #endif /* Z_WANT_LPT */ @@ -105,9 +119,14 @@ static void lpt_float(t_lpt *x, t_floatarg f) static void lpt_control(t_lpt *x, t_floatarg f) { + unsigned char b = f; +# ifdef HAVE_PPDEV + if (x->device>0){ + ioctl (x->device, PPWCONTROL, &b); + } else +# endif #ifdef Z_WANT_LPT if (x->port) { - unsigned char b = f; sys_outb(b, x->port+2); } #endif /* Z_WANT_LPT */ @@ -115,6 +134,13 @@ static void lpt_control(t_lpt *x, t_floatarg f) static void lpt_bang(t_lpt *x) { +# ifdef HAVE_PPDEV + if (x->device>0){ + unsigned char b=0; + ioctl (x->device, PPRCONTROL, &b); + outlet_float(x->x_obj.ob_outlet, (float)b); + } else +# endif #ifdef Z_WANT_LPT if (x->port) { outlet_float(x->x_obj.ob_outlet, (float)sys_inb(x->port+1)); @@ -126,16 +152,18 @@ static void lpt_bang(t_lpt *x) static void *lpt_new(t_symbol *s, int argc, t_atom *argv) { t_lpt *x = (t_lpt *)pd_new(lpt_class); + char*devname=atom_getsymbol(argv)->s_name; if(s==gensym("lp")) error("lpt: the use of 'lp' has been deprecated; use 'lpt' instead"); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("control")); outlet_new(&x->x_obj, gensym("float")); x->mode = MODE_NONE; x->port = 0; + x->device = -1; #ifdef Z_WANT_LPT - if ((argc==0)||(argv->a_type==A_FLOAT)) { /* FLOAT specifies a parallel port */ switch ((int)((argc)?atom_getfloat(argv):0)) { @@ -158,35 +186,64 @@ static void *lpt_new(t_symbol *s, int argc, t_atom *argv) we ignore the file (device) case by now; LATER think about this */ - x->port=strtol(atom_getsymbol(argv)->s_name, 0, 16); + int bla; + x->device=-1; + x->port=strtol(devname, 0, 16); + if(0==x->port){ + x->port=-1; +#ifdef HAVE_PPDEV + x->device = open(devname, O_RDWR); + if(x->device<0){ + error("lpt: bad device %s", devname); + return(x); + } else { + if (ioctl (x->device, PPCLAIM)) { + perror ("PPCLAIM"); + close (x->device); + return(x); + } + } +#endif /* HAVE_PPDEV */ + } } - if (!x->port || x->port>65535){ + if ((x->device<0) && (!x->port || x->port>65535)){ post("lpt : bad port %x", x->port); x->port = 0; return (x); } - - if (x->port && x->port < 0x400){ - if (ioperm(x->port, 8, 1)) { - x->mode=MODE_NONE; - } else x->mode = MODE_IOPERM; - } - if(x->mode==MODE_NONE){ - if (iopl(3)){ - x->mode=MODE_NONE; - } else x->mode=MODE_IOPL; - count_iopl++; - // post("iopl.............................%d", count_iopl); - } - - if(x->mode==MODE_NONE){ - error("lpt : couldn't get write permissions"); - x->port = 0; - return (x); + if (x->device<0){ + /* this is ugly: when using a named device, + * we are currently assuming that we have read/write-access + * of course, this is not necessary true + */ + /* furthermore, we might also use the object + * withOUT write permissions + * (just reading the parport) + */ + if (x->port && x->port < 0x400){ + if (ioperm(x->port, 8, 1)) { + x->mode=MODE_NONE; + } else x->mode = MODE_IOPERM; + } + if(x->mode==MODE_NONE){ + if (iopl(3)){ + x->mode=MODE_NONE; + } else x->mode=MODE_IOPL; + count_iopl++; + // post("iopl.............................%d", count_iopl); + } + + if(x->mode==MODE_NONE){ + error("lpt : couldn't get write permissions"); + x->port = 0; + return (x); + } } - - post("connected to port %x in mode '%s'", x->port, (x->mode==MODE_IOPL)?"iopl":"ioperm"); + if(x->device>0) + post("connected to device %s", devname); + else + post("connected to port %x in mode '%s'", x->port, (x->mode==MODE_IOPL)?"iopl":"ioperm"); if (x->mode==MODE_IOPL)post("warning: this might seriously damage your pc..."); #else error("zexy has been compiled without [lpt]!"); @@ -198,6 +255,13 @@ static void *lpt_new(t_symbol *s, int argc, t_atom *argv) static void lpt_free(t_lpt *x) { #ifdef Z_WANT_LPT +# ifdef HAVE_PPDEV + if (x->device>0){ + ioctl (x->device, PPRELEASE); + close(x->device); + x->device=0; + } else +# endif if (x->port) { if (x->mode==MODE_IOPERM && ioperm(x->port, 8, 0)) error("lpt: couldn't clean up device"); else if (x->mode==MODE_IOPL && (!--count_iopl) && iopl(0)) |