dnpds40: More granular detection of the number of buffers needed to
print a given job. 300dpi, only 1 buffer needed. 600dpi w/ DS80: if matte and >8x11 length, 2 needed 600dpi w/ DS40: if matte and 5x7, 2 needed. if >=6x8 length, 2 needed
This commit is contained in:
parent
2886b6ecd7
commit
7914f95d9c
|
@ -60,9 +60,8 @@ struct dnpds40_ctx {
|
||||||
uint8_t endp_up;
|
uint8_t endp_up;
|
||||||
uint8_t endp_down;
|
uint8_t endp_down;
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
int y_res;
|
|
||||||
int buf_needed;
|
int buf_needed;
|
||||||
uint8_t *qty_offset;
|
uint8_t *qty_offset;
|
||||||
|
|
||||||
|
@ -152,8 +151,8 @@ static char *dnpds40_statuses(char *str)
|
||||||
case 1010: return "No Scrap Box";
|
case 1010: return "No Scrap Box";
|
||||||
case 1100: return "Paper End";
|
case 1100: return "Paper End";
|
||||||
case 1200: return "Ribbon End";
|
case 1200: return "Ribbon End";
|
||||||
case 1300: return "Paper jam";
|
case 1300: return "Paper Jam";
|
||||||
case 1400: return "Ribbon error";
|
case 1400: return "Ribbon Error";
|
||||||
case 1500: return "Paper Definition Error";
|
case 1500: return "Paper Definition Error";
|
||||||
case 1600: return "Data Error";
|
case 1600: return "Data Error";
|
||||||
case 2000: return "Head Voltage Error";
|
case 2000: return "Head Voltage Error";
|
||||||
|
@ -171,7 +170,7 @@ static char *dnpds40_statuses(char *str)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unkown type";
|
return "Unkown Error";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dnpds40_do_cmd(struct dnpds40_ctx *ctx,
|
static int dnpds40_do_cmd(struct dnpds40_ctx *ctx,
|
||||||
|
@ -321,6 +320,8 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
|
||||||
int i, j, run = 1;
|
int i, j, run = 1;
|
||||||
char buf[9] = { 0 };
|
char buf[9] = { 0 };
|
||||||
|
|
||||||
|
uint32_t matte = 0, multicut = 0, dpi = 0;
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -329,6 +330,15 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
|
||||||
ctx->databuf = NULL;
|
ctx->databuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There's no way to figure out the total job length in advance, we
|
||||||
|
have to parse the stream until we get to the image plane data,
|
||||||
|
and even then the stream can contain arbitrary commands later.
|
||||||
|
|
||||||
|
So instead, we allocate a buffer of the maximum possible length,
|
||||||
|
then parse the incoming stream until we hit the START command at
|
||||||
|
the end of the job.
|
||||||
|
*/
|
||||||
|
|
||||||
ctx->datalen = 0;
|
ctx->datalen = 0;
|
||||||
ctx->databuf = malloc(MAX_PRINTJOB_LEN);
|
ctx->databuf = malloc(MAX_PRINTJOB_LEN);
|
||||||
if (!ctx->databuf) {
|
if (!ctx->databuf) {
|
||||||
|
@ -336,12 +346,9 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX no way to figure out print job length without parsing stream
|
|
||||||
// until we get to the plane data
|
|
||||||
|
|
||||||
/* Read in command header */
|
|
||||||
while (run) {
|
while (run) {
|
||||||
int remain;
|
int remain;
|
||||||
|
/* Read in command header */
|
||||||
i = read(data_fd, ctx->databuf + ctx->datalen,
|
i = read(data_fd, ctx->databuf + ctx->datalen,
|
||||||
sizeof(struct dnpds40_cmd));
|
sizeof(struct dnpds40_cmd));
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
|
@ -379,17 +386,47 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
|
||||||
if(!memcmp("CNTRL QTY", ctx->databuf + ctx->datalen+2, 9)) {
|
if(!memcmp("CNTRL QTY", ctx->databuf + ctx->datalen+2, 9)) {
|
||||||
ctx->qty_offset = ctx->databuf + ctx->datalen + 32;
|
ctx->qty_offset = ctx->databuf + ctx->datalen + 32;
|
||||||
}
|
}
|
||||||
|
if(!memcmp("CNTRL OVERCOAT", ctx->databuf + ctx->datalen+2, 14)) {
|
||||||
|
memcpy(buf, ctx->databuf + ctx->datalen + 32, 8);
|
||||||
|
matte = atoi(buf);
|
||||||
|
matte = le32_to_cpu(matte);
|
||||||
|
}
|
||||||
|
if(!memcmp("CNTRL MULTICUT", ctx->databuf + ctx->datalen+2, 14)) {
|
||||||
|
memcpy(buf, ctx->databuf + ctx->datalen + 32, 8);
|
||||||
|
multicut = atoi(buf);
|
||||||
|
multicut = le32_to_cpu(multicut);
|
||||||
|
}
|
||||||
if(!memcmp("IMAGE YPLANE", ctx->databuf + ctx->datalen + 2, 12)) {
|
if(!memcmp("IMAGE YPLANE", ctx->databuf + ctx->datalen + 2, 12)) {
|
||||||
uint32_t x;
|
uint32_t x_ppm;
|
||||||
memcpy(&x, ctx->databuf + ctx->datalen + 32 + 42, sizeof(x));
|
memcpy(&x_ppm, ctx->databuf + ctx->datalen + 32 + 42, sizeof(x_ppm));
|
||||||
x = le32_to_cpu(x);
|
x_ppm = le32_to_cpu(x_ppm);
|
||||||
|
|
||||||
if (x == 23615) {
|
ctx->buf_needed = 1;
|
||||||
ctx->y_res = 600;
|
dpi = 300;
|
||||||
ctx->buf_needed = 2; // XXX not always true.
|
|
||||||
} else { // x == 11808 or anything else..
|
if (x_ppm == 23615) { /* pixels per meter, aka 600dpi */
|
||||||
ctx->y_res = 300;
|
dpi = 600;
|
||||||
ctx->buf_needed = 1;
|
if (ctx->type == P_DNP_DS80) { /* DS80/CX-W */
|
||||||
|
if (matte && (multicut == 21 || // A4 length
|
||||||
|
multicut == 20 || // 8x4*3
|
||||||
|
multicut == 19 || // 8x8+8x4
|
||||||
|
multicut == 15 || // 8x6*2
|
||||||
|
multicut == 7)) // 8x12
|
||||||
|
ctx->buf_needed = 2;
|
||||||
|
} else { /* DS40/CX/CY/etc */
|
||||||
|
if (multicut == 4 || // 6x8
|
||||||
|
multicut == 5 || // 6x9
|
||||||
|
multicut == 12) // 6x4*2
|
||||||
|
ctx->buf_needed = 2;
|
||||||
|
else if (matte && multicut == 3) // 5x7
|
||||||
|
ctx->buf_needed = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are missing a multicut command,
|
||||||
|
we can't parse this job so must assume
|
||||||
|
worst case size needing both buffers! */
|
||||||
|
if (!multicut)
|
||||||
|
ctx->buf_needed = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +437,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
|
||||||
/* Add in the size of this chunk */
|
/* Add in the size of this chunk */
|
||||||
ctx->datalen += sizeof(struct dnpds40_cmd) + j;
|
ctx->datalen += sizeof(struct dnpds40_cmd) + j;
|
||||||
}
|
}
|
||||||
|
DEBUG("dpi %d matte %d mcut %d bufs %d\n", dpi, matte, multicut, ctx->buf_needed);
|
||||||
if (!ctx->datalen)
|
if (!ctx->datalen)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -450,9 +488,9 @@ top:
|
||||||
return -1;
|
return -1;
|
||||||
dnpds40_cleanup_string((char*)resp, len);
|
dnpds40_cleanup_string((char*)resp, len);
|
||||||
|
|
||||||
|
/* Check to see if we have sufficient buffers */
|
||||||
if (!strcmp("FBP00", (char*)resp) ||
|
if (!strcmp("FBP00", (char*)resp) ||
|
||||||
(ctx->buf_needed == 1 && !strcmp("FBP01", (char*)resp))) {
|
(ctx->buf_needed == 1 && !strcmp("FBP01", (char*)resp))) {
|
||||||
/* We don't have enough buffers */
|
|
||||||
INFO("Insufficient printer buffers, retrying...\n");
|
INFO("Insufficient printer buffers, retrying...\n");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
goto top;
|
goto top;
|
||||||
|
@ -911,7 +949,7 @@ static int dnpds40_cmdline_arg(void *vctx, int run, char *arg1, char *arg2)
|
||||||
/* Exported */
|
/* Exported */
|
||||||
struct dyesub_backend dnpds40_backend = {
|
struct dyesub_backend dnpds40_backend = {
|
||||||
.name = "DNP DS40/DS80",
|
.name = "DNP DS40/DS80",
|
||||||
.version = "0.24",
|
.version = "0.25",
|
||||||
.uri_prefix = "dnpds40",
|
.uri_prefix = "dnpds40",
|
||||||
.cmdline_usage = dnpds40_cmdline,
|
.cmdline_usage = dnpds40_cmdline,
|
||||||
.cmdline_arg = dnpds40_cmdline_arg,
|
.cmdline_arg = dnpds40_cmdline_arg,
|
||||||
|
|
Loading…
Reference in New Issue