all: add new marker query support to backends and rejigger as needed.

This commit is contained in:
Solomon Peachy 2018-04-27 15:40:09 -04:00
parent 06dbf0fa91
commit 5669fb3552
13 changed files with 912 additions and 723 deletions

8
README
View file

@ -299,6 +299,8 @@
Notes:
This backend does not support reporting marker levels.
[1] Format of curvedata file:
256 entries each of Yellow, Magenta, Cyan mappings:
@ -598,6 +600,8 @@
This backend does not support additional commands.
This backend does not support reporting marker levels.
***************************************************************************
BACKEND=mitsu70x
@ -725,6 +729,8 @@
-s Query printer status
This backend does not support reporting marker levels.
***************************************************************************
BACKEND=dnpds40
@ -807,4 +813,6 @@ Notes:
-E Eject card in printer
-R Reset printer
This backend does not support reporting marker levels.
***************************************************************************

View file

@ -78,8 +78,6 @@
#define READBACK_LEN 12
struct printer_data; /* Forward declaration */
struct printer_data {
int type; /* P_??? */
char *model; /* eg "SELPHY ES1" */
@ -122,19 +120,16 @@ static char *generic_pgcode_names(uint8_t *rdbuf, struct printer_data *printer)
static uint8_t es1_error_detect(uint8_t *rdbuf)
{
if (rdbuf[1] == 0x01) {
if (rdbuf[9] == 0x00) {
if (rdbuf[9] == 0x00)
ERROR("Cover open!\n");
} else {
else
ERROR("Unknown error %02x\n", rdbuf[9]);
}
return 1;
} else if (rdbuf[4] == 0x01 && rdbuf[5] == 0xff &&
rdbuf[6] == 0xff && rdbuf[7] == 0xff) {
ATTR("marker-levels=%d\n", 0);
ERROR("No media loaded!\n");
return 1;
} else if (rdbuf[0] == 0x0f) {
ATTR("marker-levels=%d\n", 0);
ERROR("Out of media!\n");
return 1;
}
@ -154,13 +149,11 @@ static uint8_t es2_error_detect(uint8_t *rdbuf)
rdbuf[4] == 0x05 &&
rdbuf[5] == 0x05 &&
rdbuf[6] == 0x02) {
ATTR("marker-levels=%d\n", 0);
ERROR("No media loaded!\n");
return 1;
}
if (rdbuf[0] == 0x14) {
ATTR("marker-levels=%d\n", 0);
ERROR("Out of media!\n");
return 1;
}
@ -171,19 +164,16 @@ static uint8_t es2_error_detect(uint8_t *rdbuf)
static uint8_t es3_error_detect(uint8_t *rdbuf)
{
if (rdbuf[8] == 0x01) {
if (rdbuf[10] == 0x0f) {
if (rdbuf[10] == 0x0f)
ERROR("Communications Error\n");
} else if (rdbuf[10] == 0x01) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[10] == 0x01)
ERROR("No media loaded!\n");
} else {
else
ERROR("Unknown error - %02x + %02x\n",
rdbuf[8], rdbuf[10]);
}
return 1;
} else if (rdbuf[8] == 0x03 &&
rdbuf[10] == 0x02) {
ATTR("marker-levels=%d\n", 0);
ERROR("No media loaded!\n");
return 1;
} else if (rdbuf[8] == 0x08 &&
@ -213,13 +203,11 @@ static uint8_t es40_error_detect(uint8_t *rdbuf)
if (rdbuf[3] == 0x01)
ERROR("Generic communication error\n");
else if (rdbuf[3] == 0x32) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[3] == 0x32)
ERROR("Cover open or media empty!\n");
} else
else
ERROR("Unknown error - %02x\n", rdbuf[3]);
return 1;
}
@ -233,18 +221,15 @@ static uint8_t cp790_error_detect(uint8_t *rdbuf)
ERROR("No paper tray loaded!\n");
return 1;
} else if (rdbuf[3]) {
if ((rdbuf[3] & 0xf) == 0x02) { // 0x12 0x22
ATTR("marker-levels=%d\n", 0);
if ((rdbuf[3] & 0xf) == 0x02) // 0x12 0x22
ERROR("No paper tray loaded!\n");
} else if ((rdbuf[3] & 0xf) == 0x03) { // 0x13 0x23
ATTR("marker-levels=%d\n", 0);
else if ((rdbuf[3] & 0xf) == 0x03) // 0x13 0x23
ERROR("Empty paper tray or feed error!\n");
} else if (rdbuf[3] == 0x11)
else if (rdbuf[3] == 0x11)
ERROR("Paper feed error!\n");
else if (rdbuf[3] == 0x21) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[3] == 0x21)
ERROR("Ribbon depleted!\n");
} else
else
ERROR("Unknown error - %02x\n", rdbuf[3]);
return 1;
}
@ -265,16 +250,13 @@ static uint8_t cp10_error_detect(uint8_t *rdbuf)
if (!rdbuf[2])
return 0;
if (rdbuf[2] == 0x80) {
ATTR("marker-levels=%d\n", 0);
if (rdbuf[2] == 0x80)
ERROR("No ribbon loaded\n");
} else if (rdbuf[2] == 0x08) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[2] == 0x08)
ERROR("Ribbon depleted!\n");
} else if (rdbuf[2] == 0x01) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[2] == 0x01)
ERROR("No paper loaded!\n");
} else
else
ERROR("Unknown error - %02x\n", rdbuf[2]);
return 1;
}
@ -284,15 +266,13 @@ static uint8_t cpxxx_error_detect(uint8_t *rdbuf)
if (!rdbuf[2])
return 0;
if (rdbuf[2] == 0x01) {
ATTR("marker-levels=%d\n", 0);
if (rdbuf[2] == 0x01)
ERROR("Paper feed problem!\n");
} else if (rdbuf[2] == 0x04)
else if (rdbuf[2] == 0x04)
ERROR("Ribbon problem!\n");
else if (rdbuf[2] == 0x08) {
ATTR("marker-levels=%d\n", 0);
else if (rdbuf[2] == 0x08)
ERROR("Ribbon depleted!\n");
} else
else
ERROR("Unknown error - %02x\n", rdbuf[2]);
return 1;
}
@ -563,6 +543,7 @@ struct canonselphy_ctx {
int type;
struct printer_data *printer;
struct marker marker;
uint8_t bw_mode;
@ -648,7 +629,8 @@ static int canonselphy_attach(void *vctx, struct libusb_device_handle *dev,
struct canonselphy_ctx *ctx = vctx;
struct libusb_device *device;
struct libusb_device_descriptor desc;
int i;
int i, num;
uint8_t rdbuf[READBACK_LEN];
UNUSED(jobid);
@ -675,7 +657,27 @@ static int canonselphy_attach(void *vctx, struct libusb_device_handle *dev,
return CUPS_BACKEND_FAILED;
}
/* TODO: Query & Update Marker */
/* Read printer status. Twice. */
i = read_data(ctx->dev, ctx->endp_up,
rdbuf, READBACK_LEN, &num);
if (i < 0)
return CUPS_BACKEND_FAILED;
i = read_data(ctx->dev, ctx->endp_up,
rdbuf, READBACK_LEN, &num);
if (i < 0)
return CUPS_BACKEND_FAILED;
/* Fill out marker structure */
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = ctx->printer->pgcode_names? ctx->printer->pgcode_names(rdbuf, ctx->printer) : "Unknown";
ctx->marker.levelmax = -1; /* Unknown */
if (ctx->printer->error_detect(rdbuf))
ctx->marker.levelnow = 0; /* Out of media */
else
ctx->marker.levelnow = -3; /* Unknown but OK */
return CUPS_BACKEND_OK;
}
@ -866,14 +868,6 @@ static int canonselphy_main_loop(void *vctx, int copies) {
if (ret < 0)
return CUPS_BACKEND_FAILED;
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n", ctx->printer->pgcode_names? ctx->printer->pgcode_names(rdbuf, ctx->printer) : "Unknown");
ATTR("marker-types=ribbonWax\n");
ATTR("marker-levels=%d\n", -3); /* ie Unknown but OK */
top:
if (state != last_state) {
@ -894,6 +888,7 @@ top:
/* Error detection */
if (ctx->printer->error_detect(rdbuf)) {
dump_markers(&ctx->marker, 1, 0);
if (ctx->printer->clear_error_len)
/* Try to clear error state */
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->printer->clear_error, ctx->printer->clear_error_len)))
@ -1104,6 +1099,35 @@ static void canonselphy_cmdline(void)
DEBUG("\t\t[ -s ] # Query printer status\n");
}
static int canonselphy_query_markers(void *vctx, struct marker **markers, int *count)
{
struct canonselphy_ctx *ctx = vctx;
uint8_t rdbuf[READBACK_LEN];
int ret, num;
/* Read in the printer status, twice. */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
if (ctx->printer->error_detect(rdbuf))
ctx->marker.levelnow = 0;
else
ctx->marker.levelnow = -3;
*markers = &ctx->marker;
*count = 1;
return CUPS_BACKEND_OK;
}
static const char *canonselphy_prefixes[] = {
"canonselphy",
"selphycp10", "selphycp100", "selphycp200", "selphycp220",
@ -1119,7 +1143,7 @@ static const char *canonselphy_prefixes[] = {
struct dyesub_backend canonselphy_backend = {
.name = "Canon SELPHY CP/ES (legacy)",
.version = "0.99",
.version = "0.100",
.uri_prefixes = canonselphy_prefixes,
.cmdline_usage = canonselphy_cmdline,
.cmdline_arg = canonselphy_cmdline_arg,
@ -1128,6 +1152,7 @@ struct dyesub_backend canonselphy_backend = {
.teardown = canonselphy_teardown,
.read_parse = canonselphy_read_parse,
.main_loop = canonselphy_main_loop,
.query_markers = canonselphy_query_markers,
.devices = {
{ USB_VID_CANON, USB_PID_CANON_CP10, P_CP10, NULL, "selphycp10"},
{ USB_VID_CANON, USB_PID_CANON_CP100, P_CP_XXX, NULL, "selphycp100"},

View file

@ -69,6 +69,8 @@ struct selphyneo_ctx {
uint8_t *databuf;
uint32_t datalen;
struct marker marker;
};
static char *selphyneo_statuses(uint8_t sts)
@ -195,6 +197,8 @@ static int selphyneo_attach(void *vctx, struct libusb_device_handle *dev,
struct selphyneo_ctx *ctx = vctx;
struct libusb_device *device;
struct libusb_device_descriptor desc;
struct selphyneo_readback rdback;
int ret, num;
UNUSED(jobid);
@ -205,7 +209,24 @@ static int selphyneo_attach(void *vctx, struct libusb_device_handle *dev,
device = libusb_get_device(dev);
libusb_get_device_descriptor(device, &desc);
// TODO: Query & Update Marker
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = selphynew_pgcodes(rdback.data[6]);
ctx->marker.levelmax = -1;
ctx->marker.levelnow = -3;
return CUPS_BACKEND_OK;
}
@ -292,20 +313,6 @@ static int selphyneo_main_loop(void *vctx, int copies) {
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n", selphynew_pgcodes(rdback.data[6]));
ATTR("marker-types=ribbonWax\n");
top:
INFO("Waiting for printer idle\n");
@ -326,18 +333,20 @@ top:
break;
case 0x0A:
ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]);
ATTR("marker-levels=%d\n", 0);
ctx->marker.levelnow = 0;
dump_markers(&ctx->marker, 1, 0);
return CUPS_BACKEND_CANCEL;
default:
ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]);
ATTR("marker-levels=%d\n", 0);
ctx->marker.levelnow = 0;
dump_markers(&ctx->marker, 1, 0);
return CUPS_BACKEND_STOP;
}
sleep(1);
} while(1);
ATTR("marker-levels=%d\n", -3); /* ie Unknown but OK */
dump_markers(&ctx->marker, 1, 0);
INFO("Sending spool data\n");
/* Send the data over in 256K chunks */
@ -380,11 +389,13 @@ top:
break;
case 0x0A:
ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]);
ATTR("marker-levels=%d\n", 0);
ctx->marker.levelnow = 0;
dump_markers(&ctx->marker, 1, 0);
return CUPS_BACKEND_CANCEL;
default:
ERROR("Printer error: %s (%02x)\n", selphyneo_errors(rdback.data[2]), rdback.data[2]);
ATTR("marker-levels=%d\n", 0);
ctx->marker.levelnow = 0;
dump_markers(&ctx->marker, 1, 0);
return CUPS_BACKEND_STOP;
}
@ -440,6 +451,37 @@ static void selphyneo_cmdline(void)
DEBUG("\t\t[ -s ] # Query printer status\n");
}
static int selphyneo_query_markers(void *vctx, struct marker **markers, int *count)
{
struct selphyneo_ctx *ctx = vctx;
struct selphyneo_readback rdback;
int ret, num;
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
if (rdback.data[2])
ctx->marker.levelnow = 0;
else
ctx->marker.levelnow = -3;
*markers = &ctx->marker;
*count = 1;
return CUPS_BACKEND_OK;
}
static const char *canonselphyneo_prefixes[] = {
"canonselphyneo",
"selphycp820", "selphycp910", "selphycp1000", "selphycp1200", "selphycp1300",
@ -448,7 +490,7 @@ static const char *canonselphyneo_prefixes[] = {
struct dyesub_backend canonselphyneo_backend = {
.name = "Canon SELPHY CP (new)",
.version = "0.15",
.version = "0.16",
.uri_prefixes = canonselphyneo_prefixes,
.cmdline_usage = selphyneo_cmdline,
.cmdline_arg = selphyneo_cmdline_arg,
@ -457,6 +499,7 @@ struct dyesub_backend canonselphyneo_backend = {
.teardown = selphyneo_teardown,
.read_parse = selphyneo_read_parse,
.main_loop = selphyneo_main_loop,
.query_markers = selphyneo_query_markers,
.devices = {
{ USB_VID_CANON, USB_PID_CANON_CP820, P_CP910, NULL, "selphycp820"},
{ USB_VID_CANON, USB_PID_CANON_CP910, P_CP910, NULL, "selphycp910"},

View file

@ -91,6 +91,8 @@ struct dnpds40_ctx {
int correct_count;
int needs_mlot;
struct marker marker;
uint32_t native_width;
int supports_6x9;
int supports_2x6;
@ -548,6 +550,35 @@ static void *dnpds40_init(void)
((ctx->ver_major > (__major)) || \
(ctx->ver_major == (__major) && ctx->ver_minor >= (__minor)))
static int dnpds40_query_mqty(struct dnpds40_ctx *ctx)
{
struct dnpds40_cmd cmd;
uint8_t *resp;
int len = 0, count;
/* Get Media remaining */
dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
return -1;
dnpds40_cleanup_string((char*)resp, len);
count = atoi((char*)resp+4);
free(resp);
if (count) {
/* Old-sk00l models report one less than they should */
if (!ctx->correct_count)
count++;
count -= ctx->mediaoffset;
}
return count;
}
static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{
@ -588,6 +619,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ptr = strtok(NULL, ".");
ctx->ver_minor = atoi(ptr);
free(resp);
} else {
return CUPS_BACKEND_FAILED;
}
/* Get Serial Number */
@ -598,6 +631,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
dnpds40_cleanup_string((char*)resp, len);
ctx->serno = (char*) resp;
/* Do NOT free resp! */
} else {
return CUPS_BACKEND_FAILED;
}
/* Query Media Info */
@ -619,6 +654,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media--;
free(resp);
} else {
return CUPS_BACKEND_FAILED;
}
}
@ -667,6 +704,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->duplex_media -= (ctx->duplex_media & 3);
free(resp);
} else {
return CUPS_BACKEND_FAILED;
}
}
@ -809,6 +848,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
if (resp) {
ctx->mediaoffset = atoi((char*)resp+4);
free(resp);
} else {
return CUPS_BACKEND_FAILED;
}
} else if (!ctx->correct_count) {
ctx->mediaoffset = 50;
@ -827,6 +868,8 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = atoi((char*)resp+4);
free(resp);
ctx->media_count_new -= ctx->mediaoffset;
} else {
return CUPS_BACKEND_FAILED;
}
} else {
/* Look it up for legacy models & FW */
@ -849,7 +892,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = 180;
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
break;
@ -865,7 +908,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = 350;
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
break;
@ -884,7 +927,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = 280;
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
break;
@ -900,7 +943,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = 280;
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
break;
@ -914,18 +957,25 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->media_count_new = 110;
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
break;
default:
ctx->media_count_new = 999; // non-zero
ctx->media_count_new = 0;
break;
}
}
// TODO: fail out on other errors
// TODO: Update Marker
/* Fill out marker structure */
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = dnpds40_media_types(ctx->media);
ctx->marker.levelmax = ctx->media_count_new;
ctx->marker.levelnow = dnpds40_query_mqty(ctx);
if (ctx->marker.levelnow < 0)
return CUPS_BACKEND_FAILED;
return CUPS_BACKEND_OK;
}
@ -1484,14 +1534,6 @@ static int dnpds40_main_loop(void *vctx, int copies) {
if (!!ctx->matte != ctx->last_matte)
buf_needed = 2;
if (ctx->media_count_new) {
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n", dnpds40_media_types(ctx->media));
ATTR("marker-types=ribbonWax\n");
}
/* RX1HS requires HS media, but the only way to tell is that the
HS media reports a lot code, while the non-HS media does not. */
if (ctx->needs_mlot) {
@ -1579,29 +1621,12 @@ top:
{
/* Figure out remaining native prints */
dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
ctx->marker.levelnow = dnpds40_query_mqty(ctx);
if (ctx->marker.levelnow < 0)
return CUPS_BACKEND_FAILED;
dump_markers(&ctx->marker, 1, 0);
dnpds40_cleanup_string((char*)resp, len);
count = atoi((char*)resp+4);
free(resp);
if (count) {
/* Old-sk00l models report one less than they should */
if (!ctx->correct_count)
count++;
count -= ctx->mediaoffset;
}
if (ctx->media_count_new) {
ATTR("marker-levels=%d\n", count * 100 / ctx->media_count_new);
ATTR("marker-message=\"%d native prints remaining on '%s' ribbon\"\n", count, dnpds40_media_types(ctx->media));
}
count = ctx->marker.levelnow; // For logic below.
/* See if we can rewind to save media */
if (ctx->can_rewind && ctx->supports_rewind) {
@ -1648,7 +1673,6 @@ top:
return CUPS_BACKEND_STOP;
}
#endif
if (count < copies) {
WARNING("Printer does not have sufficient remaining media (%d) to complete job (%d)\n", copies, count);
}
@ -1771,11 +1795,8 @@ top:
count -= ctx->mediaoffset;
}
if (ctx->media_count_new) {
ATTR("marker-levels=%d\n", count * 100 / ctx->media_count_new);
ATTR("marker-message=\"%d native prints remaining on '%s' ribbon\"\n", count, dnpds40_media_types(ctx->media));
}
ctx->marker.levelnow = count;
dump_markers(&ctx->marker, 1, 0);
}
/* Clean up */
@ -2306,24 +2327,10 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
INFO("Native Prints Available on New Media: %u\n", ctx->media_count_new);
/* Get Media remaining */
dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
count = dnpds40_query_mqty(ctx);
if (count < 0)
return CUPS_BACKEND_FAILED;
dnpds40_cleanup_string((char*)resp, len);
count = atoi((char*)resp+4);
free(resp);
if (count) {
/* Old-sk00l models report one less than they should */
if (!ctx->correct_count)
count++;
count -= ctx->mediaoffset;
}
INFO("Native Prints Remaining on Media: %d\n", count);
if (ctx->supports_rewind) {
@ -2699,6 +2706,20 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
return 0;
}
static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count)
{
struct dnpds40_ctx *ctx = vctx;
*markers = &ctx->marker;
*count = 1;
ctx->marker.levelnow = dnpds40_query_mqty(ctx);
if (ctx->marker.levelnow < 0)
return CUPS_BACKEND_FAILED;
return CUPS_BACKEND_OK;
}
static const char *dnpds40_prefixes[] = {
"dnp_citizen",
"dnpds40", "dnpds80", "dnpds80dx", "dnpds620", "dnpds820", "dnprx1",
@ -2724,7 +2745,7 @@ static const char *dnpds40_prefixes[] = {
/* Exported */
struct dyesub_backend dnpds40_backend = {
.name = "DNP DS-series / Citizen C-series",
.version = "0.100",
.version = "0.101",
.uri_prefixes = dnpds40_prefixes,
.cmdline_usage = dnpds40_cmdline,
.cmdline_arg = dnpds40_cmdline_arg,
@ -2734,6 +2755,7 @@ struct dyesub_backend dnpds40_backend = {
.read_parse = dnpds40_read_parse,
.main_loop = dnpds40_main_loop,
.query_serno = dnpds40_query_serno,
.query_markers = dnpds40_query_markers,
.devices = {
{ USB_VID_CITIZEN, USB_PID_DNP_DS40, P_DNP_DS40, NULL, "dnpds40"}, // Also Citizen CX
{ USB_VID_CITIZEN, USB_PID_DNP_DS80, P_DNP_DS80, NULL, "dnpds80"}, // Also Citizen CX-W and Mitsubishi CP-3800DW

View file

@ -178,10 +178,10 @@ struct kodak605_ctx {
struct kodak605_media_list *media;
struct marker marker;
uint8_t *databuf;
int datalen;
uint8_t last_donor;
};
static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_list *media)
@ -218,6 +218,40 @@ static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_li
return 0;
}
static int kodak605_get_status(struct kodak605_ctx *ctx, struct kodak605_status *sts)
{
uint8_t cmdbuf[4];
int ret, num = 0;
/* Send Status Query */
cmdbuf[0] = 0x01;
cmdbuf[1] = 0x00;
cmdbuf[2] = 0x00;
cmdbuf[3] = 0x00;
if ((ret = send_data(ctx->dev, ctx->endp_down,
cmdbuf, sizeof(cmdbuf))))
return ret;
/* Read in the printer status */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) sts, sizeof(*sts), &num);
if (ret < 0)
return ret;
if (num < (int)sizeof(*sts)) {
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*sts));
return CUPS_BACKEND_FAILED;
}
if (sts->hdr.result != RESULT_SUCCESS) {
ERROR("Unexpected response from status query (%x)!\n", sts->hdr.result);
return CUPS_BACKEND_FAILED;
}
return 0;
}
static void *kodak605_init(void)
{
struct kodak605_ctx *ctx = malloc(sizeof(struct kodak605_ctx));
@ -240,6 +274,7 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev,
struct kodak605_ctx *ctx = vctx;
struct libusb_device *device;
struct libusb_device_descriptor desc;
struct kodak605_status sts;
ctx->dev = dev;
ctx->endp_up = endp_up;
@ -256,16 +291,23 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev,
if (!ctx->jobid)
ctx->jobid++;
/* Init */
ctx->last_donor = 255;
/* Query media info */
if (kodak605_get_media(ctx, ctx->media)) {
ERROR("Can't query media\n");
return CUPS_BACKEND_FAILED;
}
// TODO: Update Marker
/* Update status */
if (kodak605_get_status(ctx, &sts)) {
ERROR("Can't query status\n");
return CUPS_BACKEND_FAILED;
}
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = kodak68xx_mediatypes(ctx->media->type);
ctx->marker.levelmax = 100; /* Ie percentage */
ctx->marker.levelnow = sts.donor;
return CUPS_BACKEND_OK;
}
@ -337,40 +379,6 @@ static int kodak605_read_parse(void *vctx, int data_fd) {
return CUPS_BACKEND_OK;
}
static int kodak605_get_status(struct kodak605_ctx *ctx, struct kodak605_status *sts)
{
uint8_t cmdbuf[4];
int ret, num = 0;
/* Send Status Query */
cmdbuf[0] = 0x01;
cmdbuf[1] = 0x00;
cmdbuf[2] = 0x00;
cmdbuf[3] = 0x00;
if ((ret = send_data(ctx->dev, ctx->endp_down,
cmdbuf, sizeof(cmdbuf))))
return ret;
/* Read in the printer status */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) sts, sizeof(*sts), &num);
if (ret < 0)
return ret;
if (num < (int)sizeof(*sts)) {
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*sts));
return CUPS_BACKEND_FAILED;
}
if (sts->hdr.result != RESULT_SUCCESS) {
ERROR("Unexpected response from status query (%x)!\n", sts->hdr.result);
return CUPS_BACKEND_FAILED;
}
return 0;
}
static int kodak605_main_loop(void *vctx, int copies) {
struct kodak605_ctx *ctx = vctx;
@ -396,22 +404,15 @@ static int kodak605_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_HOLD;
}
/* Tell CUPS about the consumables we report */
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type));
ATTR("marker-types=ribbonWax\n");
INFO("Waiting for printer idle\n");
while(1) {
if ((ret = kodak605_get_status(ctx, &sts)))
return CUPS_BACKEND_FAILED;
if (ctx->last_donor != sts.donor) {
ctx->last_donor = sts.donor;
ATTR("marker-levels=%u\n", sts.donor);
if (ctx->marker.levelnow != sts.donor) {
ctx->marker.levelnow = sts.donor;
dump_markers(&ctx->marker, 1, 0);
}
// XXX check for errors
@ -470,13 +471,12 @@ static int kodak605_main_loop(void *vctx, int copies) {
if ((kodak605_get_status(ctx, &sts)) != 0)
return CUPS_BACKEND_FAILED;
if (ctx->marker.levelnow != sts.donor) {
ctx->marker.levelnow = sts.donor;
dump_markers(&ctx->marker, 1, 0);
}
// XXX check for errors
if (ctx->last_donor != sts.donor) {
ctx->last_donor = sts.donor;
ATTR("marker-levels=%u\n", sts.donor);
} // XXX check for errors ?
/* Wait for completion */
if (sts.b1_id == ctx->jobid && sts.b1_complete == sts.b1_total)
break;
@ -677,6 +677,23 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
return 0;
}
static int kodak605_query_markers(void *vctx, struct marker **markers, int *count)
{
struct kodak605_ctx *ctx = vctx;
struct kodak605_status sts;
/* Query printer status */
if (kodak605_get_status(ctx, &sts))
return CUPS_BACKEND_FAILED;
ctx->marker.levelnow = sts.donor;
*markers = &ctx->marker;
*count = 1;
return CUPS_BACKEND_OK;
}
static const char *kodak605_prefixes[] = {
"kodak605",
NULL,
@ -685,7 +702,7 @@ static const char *kodak605_prefixes[] = {
/* Exported */
struct dyesub_backend kodak605_backend = {
.name = "Kodak 605",
.version = "0.28",
.version = "0.29",
.uri_prefixes = kodak605_prefixes,
.cmdline_usage = kodak605_cmdline,
.cmdline_arg = kodak605_cmdline_arg,
@ -694,6 +711,7 @@ struct dyesub_backend kodak605_backend = {
.teardown = kodak605_teardown,
.read_parse = kodak605_read_parse,
.main_loop = kodak605_main_loop,
.query_markers = kodak605_query_markers,
.devices = {
{ USB_VID_KODAK, USB_PID_KODAK_605, P_KODAK_605, "Kodak", "kodaka605"},
{ 0, 0, 0, NULL, NULL}

View file

@ -239,7 +239,7 @@ struct kodak6800_ctx {
uint8_t *databuf;
int datalen;
uint8_t last_donor;
struct marker marker;
};
static const char *kodak68xx_mediatypes(int type)
@ -278,8 +278,6 @@ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx,
return 0;
}
static void kodak68x0_dump_mediainfo(struct kodak68x0_media_readback *media)
{
int i;
@ -1018,6 +1016,7 @@ static int kodak6800_attach(void *vctx, struct libusb_device_handle *dev,
struct kodak6800_ctx *ctx = vctx;
struct libusb_device *device;
struct libusb_device_descriptor desc;
struct kodak68x0_status_readback status;
ctx->dev = dev;
ctx->endp_up = endp_up;
@ -1034,16 +1033,21 @@ static int kodak6800_attach(void *vctx, struct libusb_device_handle *dev,
if (!ctx->jobid)
ctx->jobid++;
/* Init */
ctx->last_donor = 255;
/* Query media info */
if (kodak6800_get_mediainfo(ctx, ctx->media)) {
ERROR("Can't query media\n");
return CUPS_BACKEND_FAILED;
}
// TODO: Update Marker
/* Query printer status */
if (kodak6800_get_status(ctx, &status))
return CUPS_BACKEND_FAILED;
ctx->marker.color = "#00FFFF#FF00FF#FFFF00";
ctx->marker.name = kodak68xx_mediatypes(ctx->media->type);
ctx->marker.levelmax = 100; /* Ie percentage */
ctx->marker.levelnow = status.donor;
return CUPS_BACKEND_OK;
}
@ -1143,22 +1147,15 @@ static int kodak6800_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_HOLD;
}
/* Tell CUPS about the consumables we report */
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type));
ATTR("marker-types=ribbonWax\n");
INFO("Waiting for printer idle\n");
while(1) {
if (kodak6800_get_status(ctx, &status))
return CUPS_BACKEND_FAILED;
if (ctx->last_donor != status.donor) {
ctx->last_donor = status.donor;
ATTR("marker-levels=%u\n", status.donor);
if (ctx->marker.levelnow != status.donor) {
ctx->marker.levelnow = status.donor;
dump_markers(&ctx->marker, 1, 0);
}
if (status.status1 == STATE_STATUS1_ERROR) {
@ -1231,9 +1228,9 @@ static int kodak6800_main_loop(void *vctx, int copies) {
if (kodak6800_get_status(ctx, &status))
return CUPS_BACKEND_FAILED;
if (ctx->last_donor != status.donor) {
ctx->last_donor = status.donor;
ATTR("marker-levels=%u\n", status.donor);
if (ctx->marker.levelnow != status.donor) {
ctx->marker.levelnow = status.donor;
dump_markers(&ctx->marker, 1, 0);
}
if (status.status1 == STATE_STATUS1_ERROR) {
@ -1261,6 +1258,23 @@ static int kodak6800_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_OK;
}
static int kodak6800_query_markers(void *vctx, struct marker **markers, int *count)
{
struct kodak6800_ctx *ctx = vctx;
struct kodak68x0_status_readback status;
/* Query printer status */
if (kodak6800_get_status(ctx, &status))
return CUPS_BACKEND_FAILED;
ctx->marker.levelnow = status.donor;
*markers = &ctx->marker;
*count = 1;
return CUPS_BACKEND_OK;
}
static const char *kodak6800_prefixes[] = {
"kodak68x0",
"kodak6800", "kodak6850",
@ -1270,7 +1284,7 @@ static const char *kodak6800_prefixes[] = {
/* Exported */
struct dyesub_backend kodak6800_backend = {
.name = "Kodak 6800/6850",
.version = "0.60",
.version = "0.61",
.uri_prefixes = kodak6800_prefixes,
.cmdline_usage = kodak6800_cmdline,
.cmdline_arg = kodak6800_cmdline_arg,
@ -1280,6 +1294,7 @@ struct dyesub_backend kodak6800_backend = {
.read_parse = kodak6800_read_parse,
.main_loop = kodak6800_main_loop,
.query_serno = kodak6800_query_serno,
.query_markers = kodak6800_query_markers,
.devices = {
{ USB_VID_KODAK, USB_PID_KODAK_6800, P_KODAK_6800, "Kodak", "kodak6800"},
{ USB_VID_KODAK, USB_PID_KODAK_6850, P_KODAK_6850, "Kodak", "kodak6850"},

View file

@ -909,7 +909,7 @@ struct dyesub_backend magicard_backend = {
.main_loop = magicard_main_loop,
.devices = {
{ USB_VID_MAGICARD, USB_PID_MAGICARD_TANGO2E, P_MAGICARD, NULL, "tango2e"},
{ USB_VID_MAGICARD, USB_PID_MAGICARD_ENDURO, P_MAGICARD, NULL, "enduro"},
{ USB_VID_MAGICARD, USB_PID_MAGICARD_ENDURO, P_MAGICARD, NULL, "enduro"},
{ USB_VID_MAGICARD, USB_PID_MAGICARD_ENDUROPLUS, P_MAGICARD, NULL, "enduroplus"},
{ USB_VID_MAGICARD, 0xFFFF, P_MAGICARD, NULL, "magicard"},
{ 0, 0, 0, NULL, "magicard"}

View file

@ -136,14 +136,16 @@ struct mitsu70x_ctx {
uint8_t *databuf;
int datalen;
struct marker marker[2];
uint32_t matte;
uint16_t jobid;
uint16_t rows;
uint16_t cols;
uint16_t last_donor_l;
uint16_t last_donor_u;
uint16_t last_l;
uint16_t last_u;
int num_decks;
char *laminatefname;
@ -709,7 +711,7 @@ static int mitsu70x_attach(void *vctx, struct libusb_device_handle *dev,
ctx->type = lookup_printer_type(&mitsu70x_backend,
desc.idVendor, desc.idProduct);
ctx->last_donor_l = ctx->last_donor_u = 65535;
ctx->last_l = ctx->last_u = 65535;
/* Attempt to open the library */
#if defined(WITH_DYNAMIC)
@ -788,7 +790,19 @@ static int mitsu70x_attach(void *vctx, struct libusb_device_handle *dev,
else
ctx->num_decks = 1;
// TODO: Update Marker
/* Set up markers */
ctx->marker[0].color = "#00FFFF#FF00FF#FFFF00";
ctx->marker[0].name = mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type);
ctx->marker[0].levelmax = be16_to_cpu(resp.lower.capacity);
ctx->marker[0].levelnow = be16_to_cpu(resp.lower.remain);
if (ctx->num_decks == 2) {
ctx->marker[1].color = "#00FFFF#FF00FF#FFFF00";
ctx->marker[1].name = mitsu70x_media_types(resp.upper.media_brand, resp.upper.media_type);
ctx->marker[1].levelmax = be16_to_cpu(resp.upper.capacity);
ctx->marker[1].levelnow = be16_to_cpu(resp.upper.remain);
}
return CUPS_BACKEND_OK;
}
@ -1528,23 +1542,6 @@ top:
if (ret)
return CUPS_BACKEND_FAILED;
if (ctx->num_decks == 2) {
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00,#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100,100\n");
ATTR("marker-low-levels=10,10\n");
ATTR("marker-names='\"%s\"','\"%s\"'\n",
mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type),
mitsu70x_media_types(resp.upper.media_brand, resp.upper.media_type));
ATTR("marker-types=ribbonWax,ribbonWax\n");
} else {
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
ATTR("marker-high-levels=100\n");
ATTR("marker-low-levels=10\n");
ATTR("marker-names='%s'\n",
mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type));
ATTR("marker-types=ribbonWax\n");
}
/* FW sanity checking */
if (ctx->type == P_KODAK_305) {
/* Known versions:
@ -1685,37 +1682,23 @@ skip_status:
INFO("Waiting for printer to acknowledge completion\n");
do {
uint16_t donor_u, donor_l;
sleep(1);
ret = mitsu70x_get_printerstatus(ctx, &resp);
if (ret)
return CUPS_BACKEND_FAILED;
donor_l = be16_to_cpu(resp.lower.remain) * 100 / be16_to_cpu(resp.lower.capacity);
ctx->marker[0].levelmax = be16_to_cpu(resp.lower.capacity);
ctx->marker[0].levelnow = be16_to_cpu(resp.lower.remain);
if (ctx->num_decks == 2) {
donor_u = be16_to_cpu(resp.upper.remain) * 100 / be16_to_cpu(resp.upper.capacity);
if (donor_l != ctx->last_donor_l ||
donor_u != ctx->last_donor_u) {
ctx->last_donor_l = donor_l;
ctx->last_donor_u = donor_u;
ATTR("marker-levels=%d,%d\n", donor_l, donor_u);
ATTR("marker-message='\"%d native prints remaining on %s media\"','\"%d native prints remaining on %s media\"'\n",
be16_to_cpu(resp.lower.remain),
mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type),
be16_to_cpu(resp.upper.remain),
mitsu70x_media_types(resp.upper.media_brand, resp.upper.media_type));
}
} else {
if (donor_l != ctx->last_donor_l) {
ctx->last_donor_l = donor_l;
ATTR("marker-levels=%d\n", donor_l);
ATTR("marker-message=\"%d native prints remaining on %s media\"\n",
be16_to_cpu(resp.lower.remain),
mitsu70x_media_types(resp.lower.media_brand, resp.lower.media_type));
}
ctx->marker[1].levelmax = be16_to_cpu(resp.upper.capacity);
ctx->marker[1].levelnow = be16_to_cpu(resp.upper.remain);
}
if (ctx->marker[0].levelnow != ctx->last_l ||
ctx->marker[1].levelnow != ctx->last_u) {
dump_markers(ctx->marker, ctx->num_decks, 0);
ctx->last_l = ctx->marker[0].levelnow;
ctx->last_u = ctx->marker[1].levelnow;
}
/* Query job status for our used jobid */
@ -1916,7 +1899,7 @@ static int mitsu70x_query_status(struct mitsu70x_ctx *ctx)
ret = mitsu70x_get_printerstatus(ctx, &resp);
if (!ret)
mitsu70x_dump_printerstatus(ctx, &resp);
return ret;
}
@ -1998,6 +1981,40 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
return 0;
}
static int mitsu70x_query_markers(void *vctx, struct marker **markers, int *count)
{
struct mitsu70x_ctx *ctx = vctx;
struct mitsu70x_printerstatus_resp resp;
int ret;
*markers = ctx->marker;
*count = ctx->num_decks;
/* Tell CUPS about the consumables we report */
ret = mitsu70x_get_printerstatus(ctx, &resp);
if (ret)
<