selphy: Some major internal reworking, inspired by Ake Koomsin

* Ignore SIGPIPE
 * Buffer entire job into memory before sending it to the printer
 * Better informational messages

This patch also enables support for the CUPS backend 'num-copies'
argument.

Ake's patch adds much better error handling, but I need to spend more
time studying it due to the major changes it has on control flow.
This commit is contained in:
Solomon Peachy 2013-05-02 20:27:32 -04:00
parent 771ced4e69
commit eab5c72c27
2 changed files with 90 additions and 41 deletions

View file

@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <libusb-1.0/libusb.h>
@ -150,14 +151,10 @@ done:
return printer_type;
}
static int dump_data_libusb(int remaining, int present, int data_fd,
struct libusb_device_handle *dev,
uint8_t endpoint,
uint8_t *buf, uint16_t buflen) {
static int read_data(int remaining, int present, int data_fd, uint8_t *target,
uint8_t *buf, uint16_t buflen) {
int cnt;
int i;
int wrote = 0;
int num;
while (remaining > 0) {
cnt = read(data_fd, buf + present, (remaining < (buflen-present)) ? remaining : (buflen-present));
@ -170,27 +167,12 @@ static int dump_data_libusb(int remaining, int present, int data_fd,
present = 0;
}
i = libusb_bulk_transfer(dev, endpoint,
buf,
cnt,
&num,
2000);
if (i < 0) {
ERROR("libusb error %d: (%d/%d to 0x%02x)\n", i, num, cnt, endpoint);
return -1;
}
memcpy(target + wrote, buf, cnt);
if (num != cnt) {
/* Realign buffer.. */
present = cnt - num;
memmove(buf, buf + num, present);
}
wrote += num;
remaining -= num;
wrote += cnt;
remaining -= cnt;
}
DEBUG("Wrote %d bytes\n", wrote);
return wrote;
}
@ -367,7 +349,7 @@ int main (int argc, char **argv)
uint8_t rdbuf[READBACK_LEN], rdbuf2[READBACK_LEN];
int last_state = -1, state = S_IDLE;
int plane_len = 0;
int plane_len = 0, header_len = 0, footer_len = 0;
int bw_mode = 0;
int16_t paper_code_offset = -1;
@ -377,9 +359,12 @@ int main (int argc, char **argv)
int data_fd = fileno(stdin);
int copies = 1;
char *uri = getenv("DEVICE_URI");;
char *use_serno = NULL;
uint8_t *plane_y, *plane_m, *plane_c, *footer, *header;
/* Static initialization */
setup_paper_codes();
@ -397,6 +382,8 @@ int main (int argc, char **argv)
/* Are we running as a CUPS backend? */
if (uri) {
if (argv[4])
copies = atoi(argv[4]);
if (argv[6]) { /* IOW, is it specified? */
data_fd = open(argv[6], O_RDONLY);
if (data_fd < 0) {
@ -448,9 +435,35 @@ int main (int argc, char **argv)
ERROR("Unrecognized printjob file format!\n");
exit(1);
}
footer_len = printers[printer_type].foot_length;
header_len = printers[printer_type].init_length;
DEBUG("%sFile intended for a '%s' printer\n", bw_mode? "B/W " : "", printers[printer_type].model);
/* Set up buffers */
plane_y = malloc(plane_len);
plane_m = malloc(plane_len);
plane_c = malloc(plane_len);
header = malloc(header_len);
footer = malloc(footer_len);
if (!plane_y || !plane_m || !plane_c || !header ||
(footer_len && !footer)) {
ERROR("Memory allocation failure!\n");
exit(1);
}
/* Ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
/* Read in entire print job */
memcpy(header, buffer, header_len);
memmove(buffer, buffer+header_len,
MAX_HEADER-header_len);
read_data(plane_len, MAX_HEADER-header_len, data_fd, plane_y, buffer, BUF_LEN);
read_data(plane_len, 0, data_fd, plane_m, buffer, BUF_LEN);
read_data(plane_len, 0, data_fd, plane_c, buffer, BUF_LEN);
read_data(footer_len, 0, data_fd, footer, buffer, BUF_LEN);
close(data_fd); /* We're done */
/* Libusb setup */
libusb_init(&ctx);
found = find_and_enumerate(ctx, &list, use_serno, printer_type, 0);
@ -558,24 +571,22 @@ top:
}
break;
case S_PRINTER_READY:
DEBUG("Sending init sequence (%d bytes)\n", printers[printer_type].init_length);
DEBUG("Sending init sequence (%d bytes)\n", header_len);
INFO("Printing started\n");
/* Send printer init */
ret = libusb_bulk_transfer(dev, endp_down,
buffer,
printers[printer_type].init_length,
header,
header_len,
&num,
2000);
if (ret < 0) {
ERROR("libusb error %d: (%d/%d to 0x%02x)\n", ret, num, printers[printer_type].init_length, endp_down);
ERROR("libusb error %d: (%d/%d to 0x%02x)\n", ret, num, header_len, endp_down);
ret = 4;
goto done_claimed;
}
/* Realign plane data to start of buffer.. */
memmove(buffer, buffer+printers[printer_type].init_length,
MAX_HEADER-printers[printer_type].init_length);
state = S_PRINTER_INIT_SENT;
break;
case S_PRINTER_INIT_SENT:
@ -588,7 +599,11 @@ top:
DEBUG("Sending BLACK plane\n");
else
DEBUG("Sending YELLOW plane\n");
ret = dump_data_libusb(plane_len, MAX_HEADER-printers[printer_type].init_length, data_fd, dev, endp_down, buffer, BUF_LEN);
ret = libusb_bulk_transfer(dev, endp_down,
plane_y,
plane_len,
&num,
10000);
if (ret < 0) {
ret = 4;
goto done_claimed;
@ -605,7 +620,11 @@ top:
break;
case S_PRINTER_READY_M:
DEBUG("Sending MAGENTA plane\n");
ret = dump_data_libusb(plane_len, 0, data_fd, dev, endp_down, buffer, BUF_LEN);
ret = libusb_bulk_transfer(dev, endp_down,
plane_m,
plane_len,
&num,
10000);
if (ret < 0) {
ret = 4;
goto done_claimed;
@ -619,7 +638,11 @@ top:
break;
case S_PRINTER_READY_C:
DEBUG("Sending CYAN plane\n");
ret = dump_data_libusb(plane_len, 0, data_fd, dev, endp_down, buffer, BUF_LEN);
ret = libusb_bulk_transfer(dev, endp_down,
plane_c,
plane_len,
&num,
10000);
if (ret < 0) {
ret = 4;
goto done_claimed;
@ -632,10 +655,17 @@ top:
}
break;
case S_PRINTER_DONE:
if (printers[printer_type].foot_length) {
if (footer_len) {
DEBUG("Sending cleanup sequence\n");
ret = dump_data_libusb(printers[printer_type].foot_length, 0, data_fd, dev, endp_down, buffer, BUF_LEN);
ret = libusb_bulk_transfer(dev, endp_down,
footer,
footer_len,
&num,
2000);
if (ret < 0) {
ERROR("libusb error %d: (%d/%d to 0x%02x)\n", ret, num, footer_len, endp_down);
ret = 4;
goto done_claimed;
}
@ -649,7 +679,15 @@ top:
if (state != S_FINISHED)
goto top;
INFO("Print complete (%d remaining)\n", copies - 1);
if (copies && --copies) {
state = S_IDLE;
goto top;
}
/* Done printing */
INFO("All printing done\n");
ret = 0;
done_claimed:
@ -665,7 +703,17 @@ done:
libusb_free_device_list(list, 1);
libusb_exit(ctx);
close(data_fd);
if (plane_y)
free(plane_y);
if (plane_m)
free(plane_m);
if (plane_c)
free(plane_c);
if (header)
free(header);
if (footer)
free(footer);
return ret;
}

View file

@ -25,9 +25,10 @@
*
*/
#define VERSION "0.44"
#define VERSION "0.45"
#define DEBUG( ... ) fprintf(stderr, "DEBUG: " __VA_ARGS__ )
#define INFO( ... ) fprintf(stderr, "INFO: " __VA_ARGS__ )
#define ERROR( ... ) fprintf(stderr, "ERROR: " __VA_ARGS__ )
#if (__BYTE_ORDER == __LITTLE_ENDIAN)