72da820
--- cups-1.2.10/backend/runloop.c.usb-paperout	2006-12-06 20:10:16.000000000 +0000
b66134a
+++ cups-1.2.10/backend/runloop.c	2007-05-29 19:21:32.000000000 +0100
72da820
@@ -40,6 +40,14 @@
72da820
 #endif /* __hpux */
72da820
 
72da820
 
72da820
+#ifdef __linux
72da820
+#include <sys/ioctl.h>
72da820
+#include <linux/lp.h>
72da820
+#include <time.h>
72da820
+int linux_usb_paperout_hack = 0;
72da820
+#endif /* __linux */
72da820
+
72da820
+
72da820
 /*
72da820
  * 'backendRunLoop()' - Read and write print and back-channel data.
72da820
  */
72da820
@@ -64,6 +72,9 @@
72da820
 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
72da820
   struct sigaction action;		/* Actions for POSIX signals */
72da820
 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
72da820
+#ifdef __linux
72da820
+  time_t	last_write = 0;		/* Last time write() succeeded */
72da820
+#endif /* __linux */
72da820
 
72da820
 
72da820
   fprintf(stderr, "DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, use_bc=%d)\n",
b66134a
@@ -110,12 +121,9 @@
b66134a
     FD_ZERO(&input);
b66134a
     if (!print_bytes)
b66134a
       FD_SET(print_fd, &input);
b66134a
-    if (use_bc)
b66134a
-      FD_SET(device_fd, &input);
b66134a
 
b66134a
     FD_ZERO(&output);
b66134a
-    if (print_bytes || !use_bc)
b66134a
-      FD_SET(device_fd, &output);
b66134a
+    FD_SET(device_fd, &output);
b66134a
 
b66134a
     if (use_bc)
b66134a
     {
b66134a
@@ -141,14 +149,24 @@
b66134a
     * Check if we have back-channel data ready...
b66134a
     */
b66134a
 
b66134a
-    if (FD_ISSET(device_fd, &input))
b66134a
+    if (use_bc && FD_ISSET(device_fd, &output)) /* finished writing */
b66134a
     {
b66134a
-      if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
b66134a
+      struct timeval nowait;
b66134a
+      fd_set readback;
b66134a
+      FD_ZERO (&readback);
b66134a
+      nowait.tv_sec = 0;
b66134a
+      nowait.tv_usec = 0;
b66134a
+      FD_SET(device_fd, &readback);
b66134a
+      if (select (device_fd + 1, &readback, NULL, NULL, &nowait) &&
b66134a
+	  FD_ISSET(device_fd, &readback))
b66134a
       {
b66134a
-	fprintf(stderr,
b66134a
-	        "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n",
b66134a
-	        CUPS_LLCAST bc_bytes);
b66134a
-        cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
b66134a
+	if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0)
b66134a
+	{
b66134a
+	  fprintf(stderr,
b66134a
+		  "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n",
b66134a
+		  CUPS_LLCAST bc_bytes);
b66134a
+	  cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0);
b66134a
+	}
b66134a
       }
b66134a
     }
b66134a
 
b66134a
@@ -227,6 +245,9 @@
72da820
       }
72da820
       else
72da820
       {
72da820
+#ifdef __linux
72da820
+	last_write = time (NULL);
72da820
+#endif /* __linux */
72da820
         if (paperout)
72da820
 	{
72da820
 	  fputs("STATE: -media-empty-error\n", stderr);
b66134a
@@ -247,7 +268,42 @@
72da820
 	total_bytes += bytes;
72da820
       }
72da820
     }
72da820
+
72da820
+#ifdef __linux
72da820
+    if (linux_usb_paperout_hack)
72da820
+    {
72da820
+      time_t now;
72da820
+      if (!paperout &&
72da820
+	  ((now = time(NULL)) - last_write) > 5)
72da820
+      {
72da820
+	unsigned int status;
72da820
+	if (ioctl (device_fd, LPGETSTATUS, &status) == 0 &&
72da820
+	    (status & LP_POUTPA))
72da820
+	{
72da820
+	  fputs("ERROR: Out of paper!\n", stderr);
72da820
+	  fputs("STATE: +media-empty-error\n", stderr);
72da820
+	  paperout = 1;
72da820
+	}
72da820
+
72da820
+	/* Don't check status for another 5s. */
72da820
+	last_write = now;
72da820
+      }
72da820
+    }
72da820
+#endif /* __linux */
72da820
+  }
72da820
+
72da820
+#ifdef __linux
72da820
+  if (linux_usb_paperout_hack)
72da820
+  {
72da820
+    /* Wait for the last write() to finish. */
72da820
+    do
72da820
+    {
72da820
+      FD_ZERO(&output);
72da820
+      FD_SET(device_fd, &output);
72da820
+    } while (select(device_fd + 1, NULL, &output, NULL, NULL) < 0 &&
72da820
+	     errno == EINTR);
72da820
   }
72da820
+#endif /* __linux */
72da820
 
72da820
  /*
72da820
   * Return with success...
b66134a
--- cups-1.2.10/backend/usb-unix.c.usb-paperout	2007-05-29 19:10:08.000000000 +0100
b66134a
+++ cups-1.2.10/backend/usb-unix.c	2007-05-29 19:10:08.000000000 +0100
72da820
@@ -39,6 +39,11 @@
72da820
 #include "ieee1284.c"
72da820
 #include <sys/select.h>
72da820
 
72da820
+#ifdef __linux
72da820
+#include <unistd.h>
72da820
+#include <fcntl.h>
72da820
+extern int linux_usb_paperout_hack;
72da820
+#endif /* __linux */
72da820
 
72da820
 /*
72da820
  * Local functions...
72da820
@@ -70,6 +75,11 @@
72da820
   (void)argc;
72da820
   (void)argv;
72da820
 
72da820
+#ifdef __linux
72da820
+  /* Get the runloop to check for USB paper-out condition. */
72da820
+  linux_usb_paperout_hack = 1;
72da820
+#endif /* __linux */
72da820
+
72da820
  /*
72da820
   * Open the USB port device...
72da820
   */
72da820
@@ -150,6 +160,12 @@
72da820
 
72da820
   tcsetattr(device_fd, TCSANOW, &opts);
72da820
 
72da820
+#ifdef __linux
72da820
+  /* Put the file descriptor into non-blocking mode so that we
72da820
+   * get a chance to detect paper-out. */
72da820
+  fcntl (device_fd, F_SETFL, fcntl (device_fd, F_GETFL) | O_NONBLOCK);
72da820
+#endif /* __linux */
72da820
+
72da820
  /*
72da820
   * Finally, send the print file...
72da820
   */