--- parallel.c	2015-11-29 14:28:19.000000000 +0100
+++ parallel.c.libieee1284	2015-11-29 21:10:52.714562832 +0100
@@ -27,6 +27,11 @@
 
 #ifdef  USE_PARALLEL
 
+#define USE_LIBIEEE1284
+#if     defined USE_LIBIEEE1284 && defined USE_PPDEV
+#undef  USE_PPDEV
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef  HAVE_UNISTD_H
@@ -39,7 +44,9 @@
 #include <linux/ppdev.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
-#elif   defined __linux__ && defined __GLIBC__  // USE_PPDEV
+#elif   defined USE_LIBIEEE1284                 // USE_PPDEV
+#include <ieee1284.h>
+#elif   defined __linux__ && defined __GLIBC__  // USE_LIBIEEE1284
 #ifdef  HAVE_SYS_IO_H                           // necessary for some Linux/PPC configs
 #include <sys/io.h>                             // ioperm() (glibc), in{b, w}(), out{b, w}()
 #else
@@ -98,8 +105,12 @@
 
 #if     defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__
 static int parport_io_fd;
-#ifdef  USE_PPDEV
+#endif
+#if     defined USE_PPDEV || defined USE_LIBIEEE1284
 static enum { FORWARD = 0, REVERSE } parport_io_direction;
+#ifdef  USE_LIBIEEE1284
+static struct parport *libieee1284_port;
+#else
 static int parport_io_mode;
 #endif
 #endif
@@ -119,7 +130,7 @@
 #endif
 
 
-#if     defined _WIN32 || defined __CYGWIN__
+#if     (defined _WIN32 || defined __CYGWIN__) && !defined USE_LIBIEEE1284
 
 #define NODRIVER_MSG "ERROR: No (working) I/O port driver. Please see the FAQ, question 4\n"
 
@@ -178,7 +189,7 @@
 static void (*output_word) (unsigned short, unsigned short) = outpw_func;
 
 #endif
-#endif // _WIN32 || __CYGWIN__
+#endif // (_WIN32 || __CYGWIN__) && !USE_LIBIEEE1284
 
 
 #if     defined __i386__ || defined __x86_64__  // GCC && x86
@@ -281,6 +292,43 @@
       exit (1);
     }
   return byte;
+#elif   defined USE_LIBIEEE1284
+  int ppreg = port - ucon64.parport;
+  unsigned char byte;
+
+  switch (ppreg)
+    {
+    case 0:                                     // data
+      if (parport_io_direction == FORWARD)      // dir is forward?
+        {
+          parport_io_direction = REVERSE;       // change it to reverse
+          ieee1284_data_dir (libieee1284_port, parport_io_direction);
+        }
+      byte = (unsigned char) ieee1284_read_data (libieee1284_port);
+      break;
+    case 1:                                     // status
+      byte = (unsigned char) (ieee1284_read_status (libieee1284_port) ^ S1284_INVERTED);
+      break;
+    case 2:                                     // control
+      byte = (unsigned char) (ieee1284_read_control (libieee1284_port) ^ C1284_INVERTED);
+      break;
+    case 3:                                     // EPP/ECP address
+      ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+      break;
+    case 4:                                     // EPP/ECP data
+      ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+      break;
+    case 0x402:                                 // ECP register
+      puts ("WARNING: Ignored read from ECP register, returning 0");
+      byte = 0;
+      break;
+    default:
+      fprintf (stderr,
+               "ERROR: inportb() tried to read from an unsupported port (0x%x)\n",
+               port);
+      exit (1);
+    }
+  return byte;
 #elif   defined __BEOS__
   st_ioport_t temp;
 
@@ -364,6 +412,26 @@
       exit (1);
     }
   return buf[0] | buf[1] << 8;                  // words are read in little endian format
+#elif   defined USE_LIBIEEE1284
+  int ppreg = port - ucon64.parport;
+  unsigned char buf[2];
+
+  switch (ppreg)
+    {
+    case 3:                                     // EPP/ECP address
+      ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+      break;
+    case 4:                                     // EPP/ECP data
+      ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+      break;
+    // the data, status, control and ECP registers should only be accessed in "8-bit mode"
+    default:
+      fprintf (stderr,
+               "ERROR: inportw() tried to read from an unsupported port (0x%x)\n",
+               port);
+      exit (1);
+    }
+  return buf[0] | buf[1] << 8;                  // words are read in little endian format
 #elif   defined __BEOS__
   st_ioport_t temp;
 
@@ -440,6 +508,37 @@
                port);
       exit (1);
     }
+#elif   defined USE_LIBIEEE1284
+  int ppreg = port - ucon64.parport;
+
+  switch (ppreg)
+    {
+    case 0:                                     // data
+      if (parport_io_direction == REVERSE)      // dir is reverse?
+        {
+          parport_io_direction = FORWARD;       // change it to forward
+          ieee1284_data_dir (libieee1284_port, parport_io_direction);
+        }
+      ieee1284_write_data (libieee1284_port, byte);
+      break;
+    case 2:                                     // control
+      ieee1284_write_control (libieee1284_port, (unsigned char) (byte ^ C1284_INVERTED));
+      break;
+    case 3:                                     // EPP/ECP address
+      ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+      break;
+    case 4:                                     // EPP/ECP data
+      ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+      break;
+    case 0x402:                                 // ECP register
+      puts ("WARNING: Ignored write to ECP register");
+      break;
+    default:
+      fprintf (stderr,
+               "ERROR: outportb() tried to write to an unsupported port (0x%x)\n",
+               port);
+      exit (1);
+    }
 #elif   defined __BEOS__
   st_ioport_t temp;
 
@@ -505,6 +604,28 @@
                port);
       exit (1);
     }
+#elif   defined USE_LIBIEEE1284
+  int ppreg = port - ucon64.parport;
+  unsigned char buf[2];
+
+  // words are written in little endian format
+  buf[0] = (unsigned char) word;
+  buf[1] = word >> 8;
+  switch (ppreg)
+    {
+    case 3:                                     // EPP/ECP address
+      ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+      break;
+    case 4:                                     // EPP/ECP data
+      ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+      break;
+    // the data, control and ECP registers should only be accessed in "8-bit mode"
+    default:
+      fprintf (stderr,
+               "ERROR: outportw() tried to write to an unsupported port (0x%x)\n",
+               port);
+      exit (1);
+    }
 #elif   defined __BEOS__
   st_ioport_t temp;
 
@@ -535,7 +656,7 @@
 }
 
 
-#if     (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
+#if     (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
 #define DETECT_MAX_CNT 1000
 static int
 parport_probe (unsigned short port)
@@ -563,6 +684,7 @@
 #endif
 
 
+#ifndef USE_LIBIEEE1284
 #ifdef  _WIN32
 static LONG
 new_exception_filter (LPEXCEPTION_POINTERS exception_pointers)
@@ -590,6 +712,7 @@
   return EXCEPTION_CONTINUE_SEARCH;
 }
 #endif
+#endif
 
 
 unsigned short
@@ -649,6 +772,48 @@
 
   parport_io_direction = FORWARD;               // set forward direction as default
   ioctl (parport_io_fd, PPDATADIR, &parport_io_direction);
+#elif   defined USE_LIBIEEE1284
+  struct parport_list list;
+  int capabilities, ucon64_parport;
+
+  if (port == PARPORT_UNKNOWN)
+    port = 0;
+
+  if (ieee1284_find_ports (&list, 0) != E1284_OK)
+    {
+      fputs ("ERROR: Could not get port list\n", stderr);
+      exit (1);
+    }
+
+  if (port < list.portc)
+    libieee1284_port = list.portv[port];
+  else
+    {
+      fprintf (stderr, "ERROR: libieee1284 port %d not available\n", port);
+      exit (1);
+    }
+
+  if (ieee1284_open (libieee1284_port, F1284_EXCL, &capabilities) != E1284_OK)
+    {
+      fprintf (stderr, "ERROR: Could not open libieee1284 port %d\n", port);
+      exit (1);
+    }
+  // TODO: Handle ECP mode correctly
+  if (ucon64.parport_mode == UCON64_EPP || ucon64.parport_mode == UCON64_ECP)
+    if ((capabilities & (CAP1284_EPP | CAP1284_ECP)) == 0)
+      puts ("WARNING: EPP or ECP mode was requested, but not available");
+
+  ieee1284_free_ports (&list);
+
+  if (ieee1284_claim (libieee1284_port) != E1284_OK)
+    {
+      fprintf (stderr, "ERROR: Could not claim libieee1284 port %d\n", port);
+      ieee1284_close (libieee1284_port);
+      exit (1);
+    }
+
+  parport_io_direction = FORWARD;
+  ieee1284_data_dir (libieee1284_port, parport_io_direction);
 #elif   defined __BEOS__
   parport_io_fd = open ("/dev/misc/ioport", O_RDWR | O_NONBLOCK);
   if (parport_io_fd == -1)
@@ -711,7 +876,7 @@
     }
 #endif
 
-#if     defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV
+#if     defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
   /*
     Some code needs us to switch to the real uid and gid. However, other code
     needs access to I/O ports other than the standard printer port registers.
@@ -731,7 +896,7 @@
              stderr);
       exit (1);                                 // Don't return, if iopl() fails port access
     }                                           //  causes core dump
-#endif // __linux__ && (__i386__ || __x86_64__) && !USE_PPDEV
+#endif // __linux__ && (__i386__ || __x86_64__) && !USE_PPDEV && !USE_LIBIEEE1284
 
 #ifdef  __OpenBSD__ // || defined __NetBSD__, add after feature request ;-)
   // We use i386_iopl() on OpenBSD for the same reasons we use iopl() on Linux
@@ -745,7 +910,7 @@
     }
 #endif
 
-#if     (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
+#if     (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
 
 #if     defined _WIN32 || defined __CYGWIN__
   /*
@@ -922,16 +1087,16 @@
           exit (1);
         }
     }
-#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV
+#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV && !USE_LIBIEEE1284
 
-#ifdef  USE_PPDEV
+#if     defined USE_PPDEV || defined USE_LIBIEEE1284
   // the following two calls need a valid value for ucon64.parport
   ucon64_parport = ucon64.parport;
   ucon64.parport = port;
 #endif
   outportb (port + PARPORT_CONTROL, inportb (port + PARPORT_CONTROL) & 0x0f);
   // bit 4 = 0 => IRQ disable for ACK, bit 5-7 unused
-#ifdef  USE_PPDEV
+#if     defined USE_PPDEV || defined USE_LIBIEEE1284
   ucon64.parport = ucon64_parport;
 #endif
 
@@ -949,6 +1114,9 @@
   ioctl (parport_io_fd, PPNEGOT, &parport_io_mode);
   ioctl (parport_io_fd, PPRELEASE);
   close (parport_io_fd);
+#elif   defined USE_LIBIEEE1284
+  ieee1284_release (libieee1284_port);
+  ieee1284_close (libieee1284_port);
 #elif   defined __BEOS__ || defined __FreeBSD__
   close (parport_io_fd);
 #elif   defined AMIGA
@@ -970,6 +1138,9 @@
 {
 #ifdef  USE_PPDEV
   printf ("Using parallel port device: %s\n", ucon64.parport_dev);
+#elif   defined USE_LIBIEEE1284
+  printf ("Using parallel port device: %s, base address 0x%lx\n",
+          libieee1284_port->filename, libieee1284_port->base_addr); // ->name
 #elif   defined AMIGA
   printf ("Using parallel port device: %s, port %d\n", ucon64.parport_dev, ucon64.parport);
 #else
