--- server/drivers/port.h
+++ server/drivers/port.h	2006-03-26 19:45:58.416006888 -0300
@@ -15,6 +15,8 @@
  *
  * Access to ports over 0x3FF by Joris Robijn, 04/2003
  *
+ * ppdev support by Andrés Trapanotto 03/2006
+ *
  */
 
 /*
@@ -57,10 +59,75 @@
 
 #include <stdio.h>
 
+struct pp_driver
+{
+#ifdef __linux__
+  int fd,mode;
+#else
+  int base_addr;
+#endif
+  unsigned char data,control,status;
+} ;
+
+/*  ------------------------------------------------------------- */
+/*  Use ppdev <linux/ppdev.h> (Linux)                             */
+#if defined HAVE_PPDEV
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/parport.h>
+#include <linux/ppdev.h>
+
+/* Libc5 */
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+extern int pp_read_data     ( struct pp_driver * );
+extern int pp_read_status   ( struct pp_driver * );
+extern int pp_read_control  ( struct pp_driver * );
+extern int pp_write_data    ( struct pp_driver * );
+extern int pp_write_status  ( struct pp_driver * ); /* Obsolete */
+extern int pp_write_control ( struct pp_driver * );
+extern int pp_init  ( struct pp_driver * , char * );
+extern int pp_bye   ( struct pp_driver * );
+extern int pp_port  ( unsigned short , unsigned char , unsigned char );
+
+/* The following 6 functions are used by the drivers that don't use ppdev natively */
+static inline int  port_in ( unsigned short port )
+{
+  return pp_port ( port, 0, 0);
+}
+
+static inline void port_out    ( unsigned short port, unsigned char val)
+{
+ pp_port ( port, 1, val);
+ return;
+}
+
+static inline int  port_access ( unsigned short port )
+{
+ return pp_port ( port, 2, 0);
+}
+
+static inline int  port_deny ( unsigned short port )
+{
+ return pp_port ( port, 3, 0);
+}
+
+static inline int  port_access_multiple ( unsigned short port, int val)
+{
+ return pp_port ( port, 2, 0);
+}
+
+static inline int  port_deny_multiple   ( unsigned short port, int val)
+{
+ return pp_port ( port, 3, 0);
+}
+
 /*  ------------------------------------------------------------- */
 /*  Use ioperm, inb and outb in <sys/io.h> (Linux) */
 /*  And iopl for higher addresses of PCI LPT cards */
-#if defined HAVE_IOPERM
+#elif defined HAVE_IOPERM
 
 /* Glibc2 and Glibc1 */
 # ifdef HAVE_SYS_IO_H 
--- server/drivers/port.c
+++ server/drivers/port.c	2006-03-26 19:45:58.416006888 -0300
@@ -0,0 +1,254 @@
+/* $id$
+ * Low level ppdev based I/O functions
+ *
+ * This file is released under the GPL. See file COPYING in this
+ * package for further details.
+ *
+ * ppdev support by Andrés Trapanotto 03/2005
+ */
+
+/*
+This file defines 8 functions for port I/O (2 obsolete ones):
+
+int pp_read_data ( struct pp_driver * driver );         -- NOT IMPLEMENTED --
+        Read a byte from data port
+        Returns 0 if successful, -1 if failed
+
+int pp_read_status ( struct pp_driver * driver );
+        Read a byte from status port
+        Returns 0 if successful, -1 if failed
+
+int pp_read_control ( struct pp_driver * driver );
+        Read a byte from control port
+        Returns 0 if successful, -1 if failed
+
+int pp_write_data ( struct pp_driver * driver );
+        Write a byte to data port
+        Returns 0 if successful, -1 if failed
+
+int pp_write_status ( struct pp_driver * driver );      -- Obsolete --
+        Write a byte to status port
+        Returns 0 if successful, -1 if failed
+
+int pp_write_control ( struct pp_driver * driver );
+        Write a byte to control port
+        Returns 0 if successful, -1 if failed
+
+int  pp_init ( struct pp_driver * driver, char * device )
+        Get access to a specific port (/dev/parport0,1,2)
+        Returns 0 if successful, -1 if failed
+
+int  pp_bye  ( struct pp_driver * driver)
+        Close access to a specific port
+        Returns 0 if successful, -1 if failed
+
+ppdev support:
+- If the drivers is writted to work with ppdev, it has to have a pp_driver where the ppdev data and descriptors will be
+  stored. I can be part of private_data :)
+  Then, the driver have to use pp_* functions to open/close/write/read the parallel port
+
+- If the driver isn't writted to work woth ppdev, you can compile the project using USE_PPDEV and it will use ppdev
+  anyway :)
+
+- The idea is that drivers can be modified to use ppdev, and then port_* functions can be removed.
+*/
+
+#include <port.h>
+
+#if defined HAVE_PPDEV
+#include <string.h>
+
+/*
+// I think that it is useless by now
+int  pp_read_data ( struct pp_driver * driver)
+{
+  return (-1);
+//  return ioctl (driver->fd, PPRDATA, &(driver->data));
+}
+*/
+
+int  pp_read_status ( struct pp_driver * driver)
+{
+  return ioctl (driver->fd, PPRSTATUS, &(driver->status));
+}
+
+int  pp_read_control ( struct pp_driver * driver)
+{
+  return ioctl (driver->fd, PPRCONTROL, &(driver->control));
+}
+
+int pp_write_data ( struct pp_driver * driver)
+{
+  return ioctl (driver->fd, PPWDATA, &(driver->data));
+}
+
+/*
+int pp_write_status ( struct pp_driver * driver)                -- Obsolete --
+  return (-1);
+//  return ioctl (driver->fd, PPWSTATUS, driver->status);
+}
+*/
+
+int pp_write_control ( struct pp_driver * driver)
+{
+  return ioctl (driver->fd, PPWCONTROL, &(driver->control));
+}
+
+int  pp_init ( struct pp_driver * driver, char * device )
+{
+   int retval=0,modes,dir;
+
+   driver->fd=open (device,O_RDWR);
+   if (driver->fd<0) {
+      fprintf (stderr, "Error opening %s",device);
+      exit (-1);
+      return -1;
+   }
+
+   retval=ioctl (driver->fd, PPCLAIM);
+   if (retval<0) {
+      fprintf (stderr, "I can't get %s",device);
+      return retval;
+   }
+
+/* Is mandatory to set the data direction  */
+ dir=0;  /* Data Forward */
+ retval=ioctl (driver->fd, PPDATADIR, &dir);
+ if (retval<0) {
+    fprintf (stderr,"\nError setting the data direction on %s ",device);
+    close (driver->fd);
+    return (-1);
+    }
+
+return 0;
+}
+
+int  pp_bye  ( struct pp_driver * driver)
+{
+ int retval;
+
+ retval=ioctl (driver->fd, PPRELEASE);
+ if (retval<0)
+    fprintf (stderr,"\nI can't free the parallel port.");
+
+ close (driver->fd);
+
+ return retval;
+}
+
+/* The following function is used by the drivers that don't use ppdev natively */
+int  pp_port (unsigned short port, unsigned char arg, unsigned char val )
+{
+  static struct pp_driver driver;
+  static int init=-1;
+  int retval=0;
+  char device[200];
+
+  switch (arg) {
+     case 0:   // Read Port
+     case 1:   // Write Port
+     case 3:   // Close Parallel Port
+       if (!init){
+          fprintf (stderr, "You must initialize the parallel port before using it!\n");
+          exit (-1);
+       }
+       break;  // Doesn't matters
+     case 2:
+       if (init>0) return 0;  //Already initializated
+       break;  // Doesn't matters
+     default:
+       fprintf (stderr,"HEY! Programmer! What are you doing?\n");
+       exit (-1);
+  }
+
+  switch (arg) {
+     case 0:   // Read Parallel Port
+       switch (port&0x03) {
+          case 0x00:
+             return (-1);
+/*             retval=pp_read_data (&driver);                                   -- NOT IMPLEMENTED --
+             if (retval<0) fprintf (stderr, "ERROR: Reading data bus.\n");
+             retval=driver.data;
+*/
+             break;
+
+          case 0x01:
+             retval=pp_read_status (&driver);
+             if (retval<0) fprintf (stderr, "ERROR: Reading status lines.\n");
+             retval=driver.status;
+             break;
+
+          case 0x02:
+             retval=pp_read_control (&driver);
+             if (retval<0) fprintf (stderr, "ERROR: Reading control lines.\n");
+             retval=driver.control;
+             break;
+          default:
+             fprintf (stderr,"HEY! Programmer! ¿What are you doing?\n");
+             exit (-1);
+       }
+       break;
+
+     case 1:   // Write Parallel Port
+       switch (port&0x03) {
+          case 0x00:
+             driver.data=val;
+             retval=pp_write_data (&driver);
+             if (retval<0) fprintf (stderr, "ERROR: Writing data bus.\n");
+             break;
+
+          case 0x01:
+             return (-1);
+/*             driver.status=val;                                               -- Obsolete --
+             retval=pp_write_status (&driver);
+             if (retval<0) fprintf (stderr, "ERROR: Writing status lines.\n");
+*/
+             break;
+
+          case 0x02:
+             driver.control=val;
+             retval=pp_write_control (&driver);
+             if (retval<0) fprintf (stderr, "ERROR: Writing control lines.\n");
+             break;
+          default:
+             fprintf (stderr,"HEY! Programmer! ¿What are you doing?\n");
+             exit (-1);
+       }
+       break;
+       
+     case 2:   // Init Parallel Port
+               // It's possible to add a selection of which parallel port you want
+               // to use but is easier to implement use of pp_* in your driver and
+               // select the parallel port there. :)
+
+/* Sick code...
+       switch (port) {
+          case 0x378:
+             strcpy (device, "/dev/parport0");
+             break;
+          case 0x278:
+             strcpy (device, "/dev/parport1");
+             break;
+          case 0x3BC:
+             strcpy (device, "/dev/parport2");
+             break;
+          default:
+             strcpy (device, "/dev/parport0");
+       }
+*/
+       strcpy (device, "/dev/parport0");
+       retval=pp_init (&driver, device);
+       if (retval==0) init=1;
+       break;
+       
+     case 3:   // Close Parallel Port
+       retval=pp_bye (&driver);
+       if (retval==0) init=-1;
+       break;
+  }
+
+ return retval;
+}
+
+#endif /*  HAVE_PPDEV */
+


syntax highlighted by Code2HTML, v. 0.9.1