dnpds40: Rearrange sanity checks, and add in DS80D media validation.

master
Solomon Peachy 8 years ago
parent 152384d82e
commit 8d5b52fe6d

@ -78,6 +78,7 @@ struct dnpds40_ctx {
int ver_major;
int ver_minor;
int media;
int duplex_media;
uint32_t multicut;
int matte;
@ -168,6 +169,19 @@ static char *dnpds40_media_types(int media)
return "Unknown type";
}
static char *dnpds80_duplex_media_types(int media)
{
switch (media) {
case 100: return "8x10.75";
case 200: return "8x12";
default:
break;
}
return "Unknown type";
}
static char *dnpds80_duplex_statuses(int status)
{
switch (status) {
@ -467,6 +481,33 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
}
}
if (ctx->type == P_DNP_DS80D) {
struct dnpds40_cmd cmd;
uint8_t *resp;
int len = 0;
/* Query Duplex Media Info */
dnpds40_build_cmd(&cmd, "INFO", "CUT_PAPER", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (resp) {
char tmp[5];
dnpds40_cleanup_string((char*)resp, len);
memcpy(tmp, resp + 4, 4);
tmp[4] = 0;
ctx->duplex_media = atoi(tmp);
/* Subtract out the paper status */
if (ctx->duplex_media & 3)
ctx->duplex_media -= (ctx->duplex_media & 3);
free(resp);
}
}
#ifdef DNP_ONLY
/* Only allow DNP printers to work. Rebadged versions should not. */
@ -494,6 +535,7 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->supports_fullcut = 1;
break;
case P_DNP_DS80:
case P_DNP_DS80D:
if (FW_VER_CHECK(1,30))
ctx->supports_matte = 1;
break;
@ -545,7 +587,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
int run = 1;
char buf[9] = { 0 };
uint32_t matte, dpi, cutter;
uint32_t dpi;
if (!ctx)
return CUPS_BACKEND_FAILED;
@ -572,11 +614,12 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
}
/* Clear everything out */
matte = 0;
dpi = 0;
cutter = 0;
ctx->matte = 0;
ctx->cutter = 0;
ctx->manual_copies = 0;
ctx->multicut = 0;
ctx->can_rewind = 0;
ctx->buffctrl_offset = ctx->qty_offset = ctx->multicut_offset = 0;
while (run) {
@ -623,7 +666,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
}
if(!memcmp("CNTRL CUTTER", ctx->databuf + ctx->datalen+2, 12)) {
memcpy(buf, ctx->databuf + ctx->datalen + 32, 8);
cutter = atoi(buf);
ctx->cutter = atoi(buf);
}
if(!memcmp("CNTRL BUFFCNTRL", ctx->databuf + ctx->datalen+2, 15)) {
/* If the printer doesn't support matte, it doesn't
@ -640,9 +683,9 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
support buffcntrl. strip it from the stream */
if (ctx->supports_matte) {
memcpy(buf, ctx->databuf + ctx->datalen + 32, 8);
matte = atoi(buf);
ctx->matte = atoi(buf);
} else {
WARNING("Printer FW does not support matte prints, please update\n");
WARNING("Printer FW does not support matte prints, using glossy mode\n");
continue;
}
}
@ -683,7 +726,8 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
/* Validate horizontal size */
memcpy(&y_ppm, ctx->databuf + ctx->datalen + 32 + 18, sizeof(y_ppm));
y_ppm = le32_to_cpu(y_ppm);
if (ctx->type == P_DNP_DS80) {
if (ctx->type == P_DNP_DS80 ||
ctx->type == P_DNP_DS80D) {
if (y_ppm != 2560) {
ERROR("Incorrect horizontal resolution (%d), aborting!\n", y_ppm);
return CUPS_BACKEND_CANCEL;
@ -707,48 +751,68 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
if (!ctx->datalen)
return CUPS_BACKEND_CANCEL;
/* Figure out the number of buffers we need. Most only need one. */
if (ctx->multicut) {
ctx->buf_needed = 1;
if (dpi == 600) {
if (ctx->type == P_DNP_DS620) {
if (ctx->multicut == 5 || // 6x9
ctx->multicut == 31) // 6x4.5*2
ctx->buf_needed = 2;
} else if (ctx->type == P_DNP_DS80) { /* DS80/CX-W */
if (matte && (ctx->multicut == 21 || // A4 length
ctx->multicut == 20 || // 8x4*3
ctx->multicut == 19 || // 8x8+8x4
ctx->multicut == 15 || // 8x6*2
ctx->multicut == 7)) // 8x12
ctx->buf_needed = 2;
} else { /* DS40/CX/RX1/CY/etc */
if (ctx->multicut == 4 || // 6x8
ctx->multicut == 5 || // 6x9
ctx->multicut == 12) // 6x4*2
ctx->buf_needed = 2;
else if (matte && ctx->multicut == 3) // 5x7
ctx->buf_needed = 2;
}
}
} else {
WARNING("Missing or illegal MULTICUT command, can't validate print job against loaded media!\n");
if (!ctx->multicut) {
WARNING("Missing or illegal MULTICUT command!\n");
if (dpi == 300)
ctx->buf_needed = 1;
else
ctx->buf_needed = 2;
goto skip_checks;
}
ctx->matte = (int)matte;
ctx->cutter = cutter;
ctx->can_rewind = 0;
/* Only DS80D supports Cut Paper types */
if (ctx->multicut > 100 &&
ctx->type != P_DNP_DS80D) {
ERROR("Only DS80D supports cut-paper sizes!\n");
return CUPS_BACKEND_CANCEL;
}
DEBUG("dpi %u matte %u mcut %u cutter %d, bufs %d\n",
dpi, matte, ctx->multicut, cutter, ctx->buf_needed);
/* Figure out the number of buffers we need. */
ctx->buf_needed = 1;
if (dpi == 600) {
if (ctx->type == P_DNP_DS620) {
if (ctx->multicut == 5 || // 6x9
ctx->multicut == 31) // 6x4.5*2
ctx->buf_needed = 2;
} else if (ctx->type == P_DNP_DS80) { /* DS80/CX-W */
if (ctx->matte && (ctx->multicut == 21 || // A4 length
ctx->multicut == 20 || // 8x4*3
ctx->multicut == 19 || // 8x8+8x4
ctx->multicut == 15 || // 8x6*2
ctx->multicut == 7)) // 8x12
ctx->buf_needed = 2;
} else if (ctx->type == P_DNP_DS80D) { /* DS80D */
if (ctx->matte) {
if (ctx->multicut == 21 || // A4 length
ctx->multicut == 20 || // 8x4*3
ctx->multicut == 19 || // 8x8+8x4
ctx->multicut == 15 || // 8x6*2
ctx->multicut == 7) // 8x12
ctx->buf_needed = 2;
if (ctx->multicut == 107 || // 8x12
ctx->multicut == 207 ||
ctx->multicut == 307 ||
ctx->multicut == 115 || // 8x6*2
ctx->multicut == 215 ||
ctx->multicut == 315 ||
ctx->multicut == 128 || // 8x4*3
ctx->multicut == 228 ||
ctx->multicut == 328)
ctx->buf_needed = 2;
}
} else { /* DS40/CX/RX1/CY/etc */
if (ctx->multicut == 4 || // 6x8
ctx->multicut == 5 || // 6x9
ctx->multicut == 12) // 6x4*2
ctx->buf_needed = 2;
else if (ctx->matte && ctx->multicut == 3) // 5x7
ctx->buf_needed = 2;
}
}
/* Sanity-check printjob type vs loaded media */
if (ctx->multicut) {
/* Sanity-check type vs loaded media */
if (ctx->multicut < 100) {
switch(ctx->media) {
case 200: //"5x3.5 (L)"
if (ctx->multicut != 1) {
@ -812,9 +876,32 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
ERROR("Unknown media (%d vs %d)!\n", ctx->media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
} else if (ctx->multicut < 400) {
switch(ctx->duplex_media) {
case 100: //"8x10.75"
if (ctx->multicut == 107 || // 8x12
ctx->multicut == 207 ||
ctx->multicut == 307 ||
ctx->multicut == 115 || // 8x6*2
ctx->multicut == 215 ||
ctx->multicut == 315 ||
ctx->multicut == 128 || // 8x4*3
ctx->multicut == 228 ||
ctx->multicut == 328) {
ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
break;
case 200: //"8x12"
/* Everything is legal */
break;
default:
ERROR("Unknown duplexer media (%d vs %d)!\n", ctx->duplex_media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
}
/* Additional santity checks */
/* Additional santity checks, make sure printer support exists */
if ((ctx->multicut == 27 || ctx->multicut == 29) &&
ctx->supports_square) {
ERROR("Printer does not support 6x6 or 5x5 prints, aborting!\n");
@ -854,10 +941,9 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
ctx->manual_copies = 1;
}
if (ctx->matte && !ctx->supports_matte) {
ERROR("Printer FW does not support matte operation, please update!\n");
return CUPS_BACKEND_CANCEL;
}
skip_checks:
DEBUG("dpi %u matte %u mcut %u cutter %d, bufs %d\n",
dpi, ctx->matte, ctx->multicut, ctx->cutter, ctx->buf_needed);
return CUPS_BACKEND_OK;
}
@ -1447,6 +1533,10 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
/* Report media */
INFO("Media Type: '%s'\n", dnpds40_media_types(ctx->media));
/* Report Cut Media */
if (ctx->type == P_DNP_DS80D)
INFO("Duplex Media Type: '%s'\n", dnpds80_duplex_media_types(ctx->media));
if (ctx->supports_mqty_default) {
/* Get Media remaining */
dnpds40_build_cmd(&cmd, "INFO", "MQTY_DEFAULT", 0);
@ -1794,7 +1884,7 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend dnpds40_backend = {
.name = "DNP DS40/DS80/DSRX1/DS620",
.version = "0.64",
.version = "0.65",
.uri_prefix = "dnpds40",
.cmdline_usage = dnpds40_cmdline,
.cmdline_arg = dnpds40_cmdline_arg,

Loading…
Cancel
Save