all: Major updates to CUPS marker reporting
* use 'ribbonWax' instead of 'ink-ribbon' (as per RFC) * return media type as the 'marker' name, if known or inferrable * Selphy CP series gained support * Mitsu D70 family gained support for uppper and lower decks
This commit is contained in:
parent
d6b2ae3d3a
commit
b210c5a5c0
4
README
4
README
|
@ -114,6 +114,10 @@
|
|||
DEVICE_URI=someuri \
|
||||
gutenprint52+usb job-id user title num-copies options [ filename ]
|
||||
|
||||
The backend generates output for CUPS to parse, including logging
|
||||
print counts, and if the printer supports it, reporting media type and
|
||||
remaining media counts.
|
||||
|
||||
***************************************************************************
|
||||
Standalone usage:
|
||||
|
||||
|
|
|
@ -91,9 +91,22 @@ struct printer_data {
|
|||
int16_t paper_codes[256];
|
||||
int16_t pgcode_offset; /* Offset into printjob for paper type */
|
||||
int16_t paper_code_offset; /* Offset in readback for paper type */
|
||||
int (*error_detect)(uint8_t *rdbuf);
|
||||
int (*error_detect)(uint8_t *rdbuf);
|
||||
char *(*pgcode_names)(uint8_t pgcode);
|
||||
};
|
||||
|
||||
static char *generic_pgcode_names(uint8_t pgcode)
|
||||
{
|
||||
switch(pgcode & 0xf) {
|
||||
case 0x01: return "P";
|
||||
case 0x02: return "L";
|
||||
case 0x03: return "C";
|
||||
case 0x04: return "W";
|
||||
case 0x0f: return "None";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int es1_error_detect(uint8_t *rdbuf)
|
||||
{
|
||||
if (rdbuf[1] == 0x01) {
|
||||
|
@ -105,9 +118,11 @@ static int es1_error_detect(uint8_t *rdbuf)
|
|||
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;
|
||||
}
|
||||
|
@ -127,11 +142,13 @@ static int 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;
|
||||
}
|
||||
|
@ -145,6 +162,7 @@ static int es3_error_detect(uint8_t *rdbuf)
|
|||
if (rdbuf[10] == 0x0f) {
|
||||
ERROR("Communications Error\n");
|
||||
} else if (rdbuf[10] == 0x01) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("No media loaded!\n");
|
||||
} else {
|
||||
ERROR("Unknown error - %02x + %02x\n",
|
||||
|
@ -153,6 +171,7 @@ static int es3_error_detect(uint8_t *rdbuf)
|
|||
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 &&
|
||||
|
@ -182,10 +201,12 @@ static int es40_error_detect(uint8_t *rdbuf)
|
|||
|
||||
if (rdbuf[3] == 0x01)
|
||||
ERROR("Generic communication error\n");
|
||||
else if (rdbuf[3] == 0x32)
|
||||
else if (rdbuf[3] == 0x32) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("Cover open or media empty!\n");
|
||||
else
|
||||
} else
|
||||
ERROR("Unknown error - %02x\n", rdbuf[3]);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -200,15 +221,18 @@ static int 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
|
||||
if ((rdbuf[3] & 0xf) == 0x02) { // 0x12 0x22
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("No paper tray loaded!\n");
|
||||
else if ((rdbuf[3] & 0xf) == 0x03) // 0x13 0x23
|
||||
} else if ((rdbuf[3] & 0xf) == 0x03) { // 0x13 0x23
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
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)
|
||||
else if (rdbuf[3] == 0x21) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("Ribbon depleted!\n");
|
||||
else
|
||||
} else
|
||||
ERROR("Unknown error - %02x\n", rdbuf[3]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -216,19 +240,28 @@ static int cp790_error_detect(uint8_t *rdbuf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *cp10_pgcode_names(uint8_t pgcode)
|
||||
{
|
||||
switch (pgcode) {
|
||||
default: return "C";
|
||||
};
|
||||
}
|
||||
|
||||
static int cp10_error_detect(uint8_t *rdbuf)
|
||||
{
|
||||
if (!rdbuf[2])
|
||||
return 0;
|
||||
|
||||
if (rdbuf[2] == 0x80)
|
||||
if (rdbuf[2] == 0x80) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("No ribbon loaded\n");
|
||||
else if (rdbuf[2] == 0x08)
|
||||
} else if (rdbuf[2] == 0x08) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("Ribbon depleted!\n");
|
||||
else if (rdbuf[2] == 0x01)
|
||||
} else if (rdbuf[2] == 0x01) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("No paper loaded!\n");
|
||||
else
|
||||
} else
|
||||
ERROR("Unknown error - %02x\n", rdbuf[2]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -238,13 +271,15 @@ static int cpxxx_error_detect(uint8_t *rdbuf)
|
|||
if (!rdbuf[2])
|
||||
return 0;
|
||||
|
||||
if (rdbuf[2] == 0x01)
|
||||
if (rdbuf[2] == 0x01) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("Paper feed problem!\n");
|
||||
else if (rdbuf[2] == 0x04)
|
||||
} else if (rdbuf[2] == 0x04)
|
||||
ERROR("Ribbon problem!\n");
|
||||
else if (rdbuf[2] == 0x08)
|
||||
else if (rdbuf[2] == 0x08) {
|
||||
ATTR("marker-levels=%d\n", 0);
|
||||
ERROR("Ribbon depleted!\n");
|
||||
else
|
||||
} else
|
||||
ERROR("Unknown error - %02x\n", rdbuf[2]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -264,6 +299,7 @@ static struct printer_data selphy_printers[] = {
|
|||
.pgcode_offset = 3,
|
||||
.paper_code_offset = 6,
|
||||
.error_detect = es1_error_detect,
|
||||
.pgcode_names = generic_pgcode_names,
|
||||
},
|
||||
{ .type = P_ES2_20,
|
||||
.model = "SELPHY ES2/ES20",
|
||||
|
@ -279,6 +315,7 @@ static struct printer_data selphy_printers[] = {
|
|||
.pgcode_offset = 2,
|
||||
.paper_code_offset = 4,
|
||||
.error_detect = es2_error_detect,
|
||||
.pgcode_names = generic_pgcode_names,
|
||||
},
|
||||
{ .type = P_ES3_30,
|
||||
.model = "SELPHY ES3/ES30",
|
||||
|
@ -294,6 +331,7 @@ static struct printer_data selphy_printers[] = {
|
|||
.pgcode_offset = 2,
|
||||
.paper_code_offset = -1,
|
||||
.error_detect = es3_error_detect,
|
||||
.pgcode_names = NULL,
|
||||
},
|
||||
{ .type = P_ES40,
|
||||
.model = "SELPHY ES40",
|
||||
|
@ -309,6 +347,7 @@ static struct printer_data selphy_printers[] = {
|
|||
.pgcode_offset = 2,
|
||||
.paper_code_offset = 11,
|
||||
.error_detect = es40_error_detect,
|
||||
.pgcode_names = generic_pgcode_names,
|
||||
},
|
||||
{ .type = P_CP790,
|
||||
.model = "SELPHY CP790",
|
||||
|
@ -321,10 +360,10 @@ static struct printer_data selphy_printers[] = {
|
|||
.done_c_readback = { 0x00, 0x00, 0x10, 0x00, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
.clear_error_len = 12,
|
||||
// .paper_codes
|
||||
.pgcode_offset = 2,
|
||||
.paper_code_offset = -1, /* Uses a different technique */
|
||||
.error_detect = cp790_error_detect,
|
||||
.pgcode_names = generic_pgcode_names,
|
||||
},
|
||||
{ .type = P_CP_XXX,
|
||||
.model = "SELPHY CP Series (!CP-10/CP790)",
|
||||
|
@ -337,10 +376,10 @@ static struct printer_data selphy_printers[] = {
|
|||
.done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, -1 },
|
||||
.clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
.clear_error_len = 12,
|
||||
// .paper_codes
|
||||
.pgcode_offset = 3,
|
||||
.paper_code_offset = 6,
|
||||
.error_detect = cpxxx_error_detect,
|
||||
.pgcode_names = generic_pgcode_names,
|
||||
},
|
||||
{ .type = P_CP10,
|
||||
.model = "SELPHY CP-10",
|
||||
|
@ -353,10 +392,10 @@ static struct printer_data selphy_printers[] = {
|
|||
.done_c_readback = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
.clear_error = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
.clear_error_len = 12,
|
||||
// .paper_codes
|
||||
.pgcode_offset = -1,
|
||||
.pgcode_offset = 2,
|
||||
.paper_code_offset = -1,
|
||||
.error_detect = cp10_error_detect,
|
||||
.pgcode_names = cp10_pgcode_names,
|
||||
},
|
||||
{ .type = -1 },
|
||||
};
|
||||
|
@ -763,6 +802,13 @@ 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->paper_code_offset]) : "Unknown");
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
ATTR("marker-levels=%d\n", -3); /* ie Unknown but OK */
|
||||
|
||||
top:
|
||||
|
||||
if (state != last_state) {
|
||||
|
@ -983,7 +1029,7 @@ static int canonselphy_cmdline_arg(void *vctx, int argc, char **argv)
|
|||
|
||||
struct dyesub_backend canonselphy_backend = {
|
||||
.name = "Canon SELPHY CP/ES",
|
||||
.version = "0.90",
|
||||
.version = "0.91",
|
||||
.uri_prefix = "canonselphy",
|
||||
.cmdline_arg = canonselphy_cmdline_arg,
|
||||
.init = canonselphy_init,
|
||||
|
|
|
@ -1195,8 +1195,8 @@ static int dnpds40_main_loop(void *vctx, int copies) {
|
|||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
ATTR("marker-names='%s'\n", dnpds40_media_types(ctx->media));
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
}
|
||||
top:
|
||||
|
||||
|
|
|
@ -148,6 +148,20 @@ static char *bank_statuses(uint8_t v)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *kodak68xx_mediatypes(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case KODAK68x0_MEDIA_NONE:
|
||||
return "No media";
|
||||
case KODAK68x0_MEDIA_6R:
|
||||
case KODAK68x0_MEDIA_6TR2:
|
||||
return "Kodak 6R";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
#define CMDBUF_LEN 4
|
||||
|
||||
/* Private data stucture */
|
||||
|
@ -380,8 +394,8 @@ static int kodak605_main_loop(void *vctx, int copies) {
|
|||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type));
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
|
||||
INFO("Waiting for printer idle\n");
|
||||
|
||||
|
@ -506,7 +520,7 @@ static void kodak605_dump_status(struct kodak605_ctx *ctx, struct kodak605_statu
|
|||
INFO("\t Remaining : Unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INFO("Donor : %d%%\n", sts->donor);
|
||||
}
|
||||
|
||||
|
|
|
@ -240,6 +240,20 @@ struct kodak6800_ctx {
|
|||
uint8_t last_donor;
|
||||
};
|
||||
|
||||
static const char *kodak68xx_mediatypes(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case KODAK68x0_MEDIA_NONE:
|
||||
return "No media";
|
||||
case KODAK68x0_MEDIA_6R:
|
||||
case KODAK68x0_MEDIA_6TR2:
|
||||
return "Kodak 6R";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/* Baseline commands */
|
||||
static int kodak6800_do_cmd(struct kodak6800_ctx *ctx,
|
||||
void *cmd, int cmd_len,
|
||||
|
@ -262,6 +276,8 @@ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void kodak68x0_dump_mediainfo(struct kodak68x0_media_readback *media)
|
||||
{
|
||||
int i;
|
||||
|
@ -1124,8 +1140,8 @@ static int kodak6800_main_loop(void *vctx, int copies) {
|
|||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
ATTR("marker-names='%s'\n", kodak68xx_mediatypes(ctx->media->type));
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
|
||||
INFO("Waiting for printer idle\n");
|
||||
|
||||
|
|
|
@ -62,14 +62,19 @@ struct mitsu70x_ctx {
|
|||
|
||||
int matte;
|
||||
|
||||
uint16_t jobid;
|
||||
uint16_t jobid;
|
||||
uint16_t rows;
|
||||
uint16_t cols;
|
||||
|
||||
uint16_t last_donor_l;
|
||||
uint16_t last_donor_u;
|
||||
int num_decks;
|
||||
|
||||
#ifdef ENABLE_CORRTABLES
|
||||
struct mitsu70x_corrdata *corrdata;
|
||||
struct mitsu70x_corrdatalens *corrdatalens;
|
||||
char *laminatefname;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Printer data structures */
|
||||
|
@ -197,7 +202,7 @@ struct mitsu70x_status_deck {
|
|||
uint8_t temperature;
|
||||
uint8_t error_status[3];
|
||||
uint8_t rsvd_a[10];
|
||||
|
||||
|
||||
uint8_t media_brand;
|
||||
uint8_t media_type;
|
||||
uint8_t rsvd_b[2];
|
||||
|
@ -245,7 +250,7 @@ struct mitsu70x_hdr {
|
|||
uint8_t speed;
|
||||
uint8_t zero1[7];
|
||||
|
||||
uint8_t deck;
|
||||
uint8_t deck; /* 0 = default, 1 = lower, 2 = upper */
|
||||
uint8_t zero2[7];
|
||||
uint8_t laminate; /* 00 == on, 01 == off */
|
||||
uint8_t laminate_mode;
|
||||
|
@ -548,6 +553,20 @@ static char *mitsu70x_errors(uint8_t *err)
|
|||
return "Unknown error";
|
||||
}
|
||||
|
||||
static const char *mitsu70x_media_types(uint8_t brand, uint8_t type)
|
||||
{
|
||||
if (brand == 0xff && type == 0x02)
|
||||
return "CKD746 (4x6)";
|
||||
else if (brand == 0xff && type == 0x0f)
|
||||
return "CKD768 (6x8)";
|
||||
else if (brand == 0x61 && type == 0x8f)
|
||||
return "CKK76R (6x8)";
|
||||
else if (brand == 0x6c && type == 0x8f)
|
||||
return "CKK76R (6x8)";
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
#define CMDBUF_LEN 512
|
||||
#define READBACK_LEN 256
|
||||
|
||||
|
@ -583,7 +602,8 @@ static void 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;}
|
||||
|
||||
static void mitsu70x_teardown(void *vctx) {
|
||||
struct mitsu70x_ctx *ctx = vctx;
|
||||
|
@ -639,7 +659,7 @@ repeat:
|
|||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CORRTABLES
|
||||
#ifdef ENABLE_CORRTABLES
|
||||
/* Figure out the correction data table to use */
|
||||
if (ctx->type == P_MITSU_D70X) {
|
||||
struct mitsu70x_hdr *print = (struct mitsu70x_hdr *) &hdr[512];
|
||||
|
@ -774,7 +794,7 @@ static int mitsu70x_get_jobstatus(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs
|
|||
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp));
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -807,7 +827,7 @@ static int mitsu70x_get_jobs(struct mitsu70x_ctx *ctx, struct mitsu70x_jobs *res
|
|||
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*resp));
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -928,9 +948,10 @@ static int mitsu70x_set_sleeptime(struct mitsu70x_ctx *ctx, uint8_t time)
|
|||
static int mitsu70x_main_loop(void *vctx, int copies) {
|
||||
struct mitsu70x_ctx *ctx = vctx;
|
||||
struct mitsu70x_jobstatus jobstatus;
|
||||
struct mitsu70x_printerstatus_resp resp;
|
||||
struct mitsu70x_jobs jobs;
|
||||
struct mitsu70x_hdr *hdr = (struct mitsu70x_hdr*) (ctx->databuf + sizeof(struct mitsu70x_hdr));
|
||||
|
||||
|
||||
int ret;
|
||||
|
||||
if (!ctx)
|
||||
|
@ -938,28 +959,6 @@ static int mitsu70x_main_loop(void *vctx, int copies) {
|
|||
|
||||
INFO("Waiting for printer idle...\n");
|
||||
|
||||
ret = mitsu70x_get_jobs(ctx, &jobs);
|
||||
if (ret)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
#if 0
|
||||
/* Tell CUPS about the consumables we report */
|
||||
if (ctx->type == P_MITSU_D70X &&
|
||||
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=Ribbon,Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon,ribbon\n");
|
||||
} else {
|
||||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
top:
|
||||
/* Query job status for jobid 0 (global) */
|
||||
ret = mitsu70x_get_jobstatus(ctx, &jobstatus, 0x0000);
|
||||
|
@ -991,7 +990,7 @@ top:
|
|||
sleep(1);
|
||||
goto top;
|
||||
}
|
||||
|
||||
|
||||
/* See if we hit a printer error. */
|
||||
if (jobstatus.error_status[0]) {
|
||||
ERROR("%s/%s -> %s: %02x/%02x/%02x\n",
|
||||
|
@ -1004,11 +1003,43 @@ top:
|
|||
return CUPS_BACKEND_STOP;
|
||||
}
|
||||
|
||||
if (ctx->num_decks)
|
||||
goto skip_status;
|
||||
|
||||
/* Tell CUPS about the consumables we report */
|
||||
ret = mitsu70x_get_printerstatus(ctx, &resp);
|
||||
if (ret)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
if (resp.upper.mecha_status[0] != MECHA_STATUS_INIT)
|
||||
ctx->num_decks = 2;
|
||||
else
|
||||
ctx->num_decks = 1;
|
||||
|
||||
if (ctx->type == P_MITSU_D70X &&
|
||||
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");
|
||||
}
|
||||
|
||||
skip_status:
|
||||
/* Perform memory status query */
|
||||
{
|
||||
struct mitsu70x_memorystatus_resp memory;
|
||||
INFO("Checking Memory availability\n");
|
||||
|
||||
|
||||
ret = mitsu70x_get_memorystatus(ctx, &memory);
|
||||
if (ret)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
@ -1026,6 +1057,10 @@ top:
|
|||
}
|
||||
|
||||
/* Make sure we don't have any jobid collisions */
|
||||
ret = mitsu70x_get_jobs(ctx, &jobs);
|
||||
if (ret)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
while (ctx->jobid == be16_to_cpu(jobs.jobid_0) ||
|
||||
ctx->jobid == be16_to_cpu(jobs.jobid_1)) {
|
||||
ctx->jobid++;
|
||||
|
@ -1039,7 +1074,7 @@ top:
|
|||
/* Set deck */
|
||||
if (ctx->type == P_MITSU_D70X) {
|
||||
hdr->deck = 0; /* D70 use automatic deck selection */
|
||||
// XXX alternatively route it based on state and media? */
|
||||
/* XXX alternatively route it based on state and media? */
|
||||
} else {
|
||||
hdr->deck = 1; /* All others only have a "lower" deck. */
|
||||
}
|
||||
|
@ -1092,22 +1127,37 @@ top:
|
|||
INFO("Waiting for printer to acknowledge completion\n");
|
||||
|
||||
do {
|
||||
uint16_t donor_u, donor_l;
|
||||
|
||||
sleep(1);
|
||||
|
||||
#if 0
|
||||
// XXXX query printerstatus and dump deck remain/capacity..
|
||||
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);
|
||||
|
||||
if (ctx->type == P_MITSU_D70X &&
|
||||
ctx->num_decks == 2) {
|
||||
ATTR("marker-levels=XXX,YYY\n");
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
ATTR("marker-levels=XXX\n");
|
||||
if (donor_l != ctx->last_donor_l) {
|
||||
ctx->last_donor_l = donor_l;
|
||||
ATTR("marker-levels=%d\n", donor_l);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Query job status for our used jobid */
|
||||
ret = mitsu70x_get_jobstatus(ctx, &jobstatus, ctx->jobid);
|
||||
if (ret)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
|
||||
/* See if we hit a printer error. */
|
||||
if (jobstatus.error_status[0]) {
|
||||
ERROR("%s/%s -> %s: %02x/%02x/%02x\n",
|
||||
|
@ -1181,49 +1231,38 @@ static void mitsu70x_dump_printerstatus(struct mitsu70x_printerstatus_resp *resp
|
|||
buf[6] = 0;
|
||||
INFO("Component #%d ID: %s (checksum %04x)\n",
|
||||
i, buf, be16_to_cpu(resp->vers[i].checksum));
|
||||
}
|
||||
if (resp->upper.mecha_status[0] == MECHA_STATUS_INIT) { /* IOW, Not present */
|
||||
INFO("Mechanical Status: %s\n",
|
||||
mitsu70x_mechastatus(resp->lower.mecha_status));
|
||||
if (resp->lower.error_status[0]) {
|
||||
INFO("Error Status: %s/%s -> %s\n",
|
||||
mitsu70x_errorclass(resp->lower.error_status),
|
||||
mitsu70x_errors(resp->lower.error_status),
|
||||
mitsu70x_errorrecovery(resp->lower.error_status));
|
||||
}
|
||||
INFO("Media type: %02x/%02x\n",
|
||||
resp->lower.media_brand,
|
||||
resp->lower.media_type);
|
||||
INFO("Prints remaining: %03d/%03d\n",
|
||||
be16_to_cpu(resp->lower.remain),
|
||||
be16_to_cpu(resp->lower.capacity));
|
||||
} else {
|
||||
INFO("Mechanical Status: Upper: %s\n"
|
||||
" Lower: %s\n",
|
||||
mitsu70x_mechastatus(resp->upper.mecha_status),
|
||||
mitsu70x_mechastatus(resp->lower.mecha_status));
|
||||
}
|
||||
|
||||
INFO("Lower Mechanical Status: %s\n",
|
||||
mitsu70x_mechastatus(resp->lower.mecha_status));
|
||||
if (resp->lower.error_status[0]) {
|
||||
INFO("Lower Error Status: %s/%s -> %s\n",
|
||||
mitsu70x_errorclass(resp->lower.error_status),
|
||||
mitsu70x_errors(resp->lower.error_status),
|
||||
mitsu70x_errorrecovery(resp->lower.error_status));
|
||||
}
|
||||
INFO("Lower Media type: %s (%02x/%02x)\n",
|
||||
mitsu70x_media_types(resp->lower.media_brand, resp->lower.media_type),
|
||||
resp->lower.media_brand,
|
||||
resp->lower.media_type);
|
||||
INFO("Lower Prints remaining: %03d/%03d\n",
|
||||
be16_to_cpu(resp->lower.remain),
|
||||
be16_to_cpu(resp->lower.capacity));
|
||||
|
||||
if (resp->upper.mecha_status[0] != MECHA_STATUS_INIT) {
|
||||
INFO("Upper Mechanical Status: %s\n",
|
||||
mitsu70x_mechastatus(resp->upper.mecha_status));
|
||||
if (resp->upper.error_status[0]) {
|
||||
INFO("Upper Error Status: %s/%s -> %s\n",
|
||||
mitsu70x_errorclass(resp->upper.error_status),
|
||||
mitsu70x_errors(resp->upper.error_status),
|
||||
mitsu70x_errorrecovery(resp->upper.error_status));
|
||||
}
|
||||
if (resp->lower.error_status[0]) {
|
||||
INFO("Lower Error Status: %s/%s -> %s\n",
|
||||
mitsu70x_errorclass(resp->lower.error_status),
|
||||
mitsu70x_errors(resp->lower.error_status),
|
||||
mitsu70x_errorrecovery(resp->lower.error_status));
|
||||
}
|
||||
INFO("Media type: Lower: %02x/%02x\n"
|
||||
" Upper: %02x/%02x\n",
|
||||
resp->lower.media_brand,
|
||||
resp->lower.media_type,
|
||||
}
|
||||
INFO("Upper Media type: %s (%02x/%02x)\n",
|
||||
mitsu70x_media_types(resp->upper.media_brand, resp->upper.media_type),
|
||||
resp->upper.media_brand,
|
||||
resp->upper.media_type);
|
||||
INFO("Prints remaining: Lower: %03d/%03d\n"
|
||||
" Upper: %03d/%03d\n",
|
||||
be16_to_cpu(resp->lower.remain),
|
||||
be16_to_cpu(resp->lower.capacity),
|
||||
INFO("Upper Prints remaining: %03d/%03d\n",
|
||||
be16_to_cpu(resp->upper.remain),
|
||||
be16_to_cpu(resp->upper.capacity));
|
||||
}
|
||||
|
@ -1248,7 +1287,7 @@ static int mitsu70x_query_status(struct mitsu70x_ctx *ctx)
|
|||
INFO("JOB1 status : %s\n", mitsu70x_jobstatuses(jobs.job1_status));
|
||||
// XXX are there more?
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1267,12 +1306,12 @@ static int mitsu70x_query_serno(struct libusb_device_handle *dev, uint8_t endp_u
|
|||
|
||||
if (buf_len > 6) /* Will we ever have a buffer under 6 bytes? */
|
||||
buf_len = 6;
|
||||
|
||||
|
||||
for (i = 0 ; i < buf_len ; i++) {
|
||||
*buf++ = le16_to_cpu(resp.serno[i]) & 0x7f;
|
||||
}
|
||||
*buf = 0; /* Null-terminate the returned string */
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1318,7 +1357,7 @@ static int mitsu70x_cmdline_arg(void *vctx, int argc, char **argv)
|
|||
/* Exported */
|
||||
struct dyesub_backend mitsu70x_backend = {
|
||||
.name = "Mitsubishi CP-D70/D707/K60/D80",
|
||||
.version = "0.39WIP",
|
||||
.version = "0.40WIP",
|
||||
.uri_prefix = "mitsu70x",
|
||||
.cmdline_usage = mitsu70x_cmdline,
|
||||
.cmdline_arg = mitsu70x_cmdline_arg,
|
||||
|
|
|
@ -60,6 +60,7 @@ struct mitsu9550_ctx {
|
|||
|
||||
uint16_t last_donor;
|
||||
uint16_t last_remain;
|
||||
int marker_reported;
|
||||
};
|
||||
|
||||
/* Spool file structures */
|
||||
|
@ -155,6 +156,16 @@ struct mitsu9550_status2 {
|
|||
if (ret < 0) \
|
||||
return CUPS_BACKEND_FAILED; \
|
||||
\
|
||||
/* Tell CUPS about the consumables we report */ \
|
||||
if (!ctx->marker_reported) { \
|
||||
ctx->marker_reported = 1; \
|
||||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n"); \
|
||||
ATTR("marker-high-levels=100\n"); \
|
||||
ATTR("marker-low-levels=10\n"); \
|
||||
ATTR("marker-names='%s'\n", mitsu9550_media_types(media->type)); \
|
||||
ATTR("marker-types=ribbonWax\n"); \
|
||||
} \
|
||||
\
|
||||
/* Sanity-check media response */ \
|
||||
if (media->remain == 0 || media->max == 0) { \
|
||||
ERROR("Printer out of media!\n"); \
|
||||
|
@ -334,6 +345,27 @@ static int mitsu9550_get_status(struct mitsu9550_ctx *ctx, uint8_t *resp, int st
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *mitsu9550_media_types(uint8_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0x01:
|
||||
return "3.5x5";
|
||||
case 0x02:
|
||||
return "4x6";
|
||||
case 0x03:
|
||||
return "PC";
|
||||
case 0x04:
|
||||
return "5x7";
|
||||
case 0x05:
|
||||
return "6x9";
|
||||
case 0x06:
|
||||
return "V";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int validate_media(int type, int cols, int rows) {
|
||||
switch(type) {
|
||||
case 0x01: /* 3.5x5 */
|
||||
|
@ -375,7 +407,7 @@ static int mitsu9550_main_loop(void *vctx, int copies) {
|
|||
struct mitsu9550_cmd cmd;
|
||||
uint8_t rdbuf[READBACK_LEN];
|
||||
uint8_t *ptr;
|
||||
|
||||
|
||||
int ret;
|
||||
|
||||
if (!ctx)
|
||||
|
@ -387,17 +419,10 @@ static int mitsu9550_main_loop(void *vctx, int copies) {
|
|||
|
||||
ptr = ctx->databuf;
|
||||
|
||||
/* 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=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
|
||||
top:
|
||||
if (ctx->type == P_MITSU_9550S) {
|
||||
int num;
|
||||
|
||||
|
||||
/* Send "unknown 1" command */
|
||||
cmd.cmd[0] = 0x1b;
|
||||
cmd.cmd[1] = 0x53;
|
||||
|
@ -406,7 +431,7 @@ top:
|
|||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
(uint8_t*) &cmd, sizeof(cmd))))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
|
||||
/* Send "unknown 2" command */
|
||||
cmd.cmd[0] = 0x1b;
|
||||
cmd.cmd[1] = 0x4b;
|
||||
|
@ -415,7 +440,7 @@ top:
|
|||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
(uint8_t*) &cmd, sizeof(cmd))))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
|
||||
ret = read_data(ctx->dev, ctx->endp_up,
|
||||
rdbuf, READBACK_LEN, &num);
|
||||
if (ret < 0)
|
||||
|
@ -426,7 +451,7 @@ top:
|
|||
QUERY_STATUS();
|
||||
|
||||
/* Now it's time for the actual print job! */
|
||||
|
||||
|
||||
if (ctx->type == P_MITSU_9550S) {
|
||||
cmd.cmd[0] = 0x1b;
|
||||
cmd.cmd[1] = 0x44;
|
||||
|
@ -595,7 +620,7 @@ top:
|
|||
ret = mitsu9550_get_status(ctx, rdbuf, 0, 1, 0); // status2
|
||||
if (ret < 0)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
|
||||
ret = mitsu9550_get_status(ctx, rdbuf, 1, 0, 0); // status
|
||||
if (ret < 0)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
@ -617,33 +642,12 @@ top:
|
|||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
|
||||
INFO("Print complete\n");
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static char *mitsu9550_media_types(uint8_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0x01:
|
||||
return "3.5x5";
|
||||
case 0x02:
|
||||
return "4x6";
|
||||
case 0x03:
|
||||
return "PC";
|
||||
case 0x04:
|
||||
return "5x7";
|
||||
case 0x05:
|
||||
return "6x9";
|
||||
case 0x06:
|
||||
return "V";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void mitsu9550_dump_media(struct mitsu9550_media *resp)
|
||||
{
|
||||
INFO("Media type : %02x (%s)\n",
|
||||
|
@ -660,7 +664,6 @@ static void mitsu9550_dump_status(struct mitsu9550_status *resp)
|
|||
be16_to_cpu(resp->copies));
|
||||
INFO("Other status : %02x %02x %02x %02x %02x\n",
|
||||
resp->sts3, resp->sts4, resp->sts5, resp->sts6, resp->sts7);
|
||||
|
||||
}
|
||||
|
||||
static int mitsu9550_query_media(struct mitsu9550_ctx *ctx)
|
||||
|
|
|
@ -182,7 +182,7 @@ struct s2145_print_cmd {
|
|||
#define PRINT_MEDIA_6x8 0x06
|
||||
#define PRINT_MEDIA_2x6 0x07
|
||||
|
||||
static char *print_medias (uint8_t v) {
|
||||
static char *print_sizes (uint8_t v) {
|
||||
switch (v) {
|
||||
case PRINT_MEDIA_4x6:
|
||||
return "4x6";
|
||||
|
@ -909,7 +909,7 @@ static int get_fwinfo(struct shinkos2145_ctx *ctx)
|
|||
|
||||
if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_fwinfo_resp) - sizeof(struct s2145_status_hdr)))
|
||||
continue;
|
||||
|
||||
|
||||
INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
|
||||
resp->major, resp->minor);
|
||||
#if 0
|
||||
|
@ -940,7 +940,7 @@ static int get_errorlog(struct shinkos2145_ctx *ctx)
|
|||
ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_errorlog_resp) - sizeof(struct s2145_status_hdr)))
|
||||
return -2;
|
||||
|
||||
|
@ -948,13 +948,13 @@ static int get_errorlog(struct shinkos2145_ctx *ctx)
|
|||
for (i = 0 ; i < resp->count ; i++) {
|
||||
INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i,
|
||||
le32_to_cpu(resp->items[i].print_counter),
|
||||
resp->items[i].major, resp->items[i].minor,
|
||||
resp->items[i].major, resp->items[i].minor,
|
||||
error_codes(resp->items[i].major, resp->items[i].minor));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_mediainfo(struct shinkos2145_ctx *ctx)
|
||||
static int get_mediainfo(struct shinkos2145_ctx *ctx)
|
||||
{
|
||||
struct s2145_cmd_hdr cmd;
|
||||
struct s2145_mediainfo_resp *resp = (struct s2145_mediainfo_resp *) rdbuf;
|
||||
|
@ -971,23 +971,23 @@ static int get_mediainfo(struct shinkos2145_ctx *ctx)
|
|||
ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s2145_mediainfo_resp) - sizeof(struct s2145_status_hdr)))
|
||||
return -2;
|
||||
|
||||
INFO("Supported Media Information: %d entries:\n", resp->count);
|
||||
for (i = 0 ; i < resp->count ; i++) {
|
||||
INFO(" %02d: C 0x%02x (%s), %04dx%04d, M 0x%02x (%s), P 0x%02x (%s)\n", i,
|
||||
resp->items[i].code, print_medias(resp->items[i].code),
|
||||
resp->items[i].code, print_sizes(resp->items[i].code),
|
||||
le16_to_cpu(resp->items[i].columns),
|
||||
le16_to_cpu(resp->items[i].rows),
|
||||
le16_to_cpu(resp->items[i].rows),
|
||||
resp->items[i].media_type, media_types(resp->items[i].media_type),
|
||||
resp->items[i].print_type, print_methods(resp->items[i].print_type));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_user_string(struct shinkos2145_ctx *ctx)
|
||||
static int get_user_string(struct shinkos2145_ctx *ctx)
|
||||
{
|
||||
struct s2145_cmd_hdr cmd;
|
||||
struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf;
|
||||
|
@ -1540,8 +1540,8 @@ static int shinkos2145_main_loop(void *vctx, int copies) {
|
|||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
ATTR("marker-names='Color'\n");
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
|
||||
// XXX check copies against remaining media!
|
||||
|
||||
|
|
|
@ -275,15 +275,17 @@ struct shinkos6145_ctx {
|
|||
uint8_t *databuf;
|
||||
size_t datalen;
|
||||
|
||||
uint8_t ribbon_type;
|
||||
|
||||
uint16_t last_donor;
|
||||
uint16_t last_remain;
|
||||
|
||||
|
||||
uint8_t *eeprom;
|
||||
size_t eepromlen;
|
||||
|
||||
void *dl_handle;
|
||||
ImageProcessingFN ImageProcessing;
|
||||
ImageAvrCalcFN ImageAvrCalc;
|
||||
ImageAvrCalcFN ImageAvrCalc;
|
||||
|
||||
struct shinkos6145_correctionparam *corrdata;
|
||||
size_t corrdatalen;
|
||||
|
@ -869,13 +871,13 @@ struct s6145_status_resp {
|
|||
uint32_t count_head;
|
||||
uint32_t count_ribbon_left;
|
||||
uint32_t reserved;
|
||||
|
||||
|
||||
uint8_t bank1_printid;
|
||||
uint16_t bank1_remaining;
|
||||
uint16_t bank1_finished;
|
||||
uint16_t bank1_specified;
|
||||
uint8_t bank1_status;
|
||||
|
||||
|
||||
uint8_t bank2_printid;
|
||||
uint16_t bank2_remaining;
|
||||
uint16_t bank2_finished;
|
||||
|
@ -884,7 +886,7 @@ struct s6145_status_resp {
|
|||
|
||||
uint8_t reserved2[16];
|
||||
uint8_t tonecurve_status;
|
||||
uint8_t reserved3[6];
|
||||
uint8_t reserved3[6];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BANK_STATUS_FREE 0x00
|
||||
|
@ -953,7 +955,7 @@ struct s6145_mediainfo_item {
|
|||
#define MEDIA_2x6 0x07
|
||||
#define MEDIA_6x6 0x08
|
||||
|
||||
static char *print_medias (uint8_t v) {
|
||||
static char *print_sizes (uint8_t v) {
|
||||
switch (v) {
|
||||
case MEDIA_4x6:
|
||||
return "4x6";
|
||||
|
@ -981,7 +983,24 @@ static char *print_medias (uint8_t v) {
|
|||
#define RIBBON_6x8 0x04
|
||||
#define RIBBON_6x9 0x05
|
||||
|
||||
static char *print_ribbons (uint8_t v) {
|
||||
static int ribbon_sizes (uint8_t v) {
|
||||
switch (v) {
|
||||
case RIBBON_4x6:
|
||||
return 300;
|
||||
case RIBBON_3_5x5:
|
||||
return 340;
|
||||
case RIBBON_5x7:
|
||||
return 170;
|
||||
case RIBBON_6x8:
|
||||
return 150;
|
||||
case RIBBON_6x9:
|
||||
return 130; // XXX guessed
|
||||
default:
|
||||
return 300; // don't want 0.
|
||||
}
|
||||
}
|
||||
|
||||
static const char *print_ribbons (uint8_t v) {
|
||||
switch (v) {
|
||||
case RIBBON_NONE:
|
||||
return "None";
|
||||
|
@ -1330,7 +1349,7 @@ static int get_mediainfo(struct shinkos6145_ctx *ctx)
|
|||
ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6145_mediainfo_resp) - sizeof(struct s6145_status_hdr)))
|
||||
return -2;
|
||||
|
||||
|
@ -1338,9 +1357,9 @@ static int get_mediainfo(struct shinkos6145_ctx *ctx)
|
|||
INFO("Supported Print Sizes: %d entries:\n", resp->count);
|
||||
for (i = 0 ; i < resp->count ; i++) {
|
||||
INFO(" %02d: C 0x%02x (%s), %04dx%04d, P 0x%02x (%s)\n", i,
|
||||
resp->items[i].media_code, print_medias(resp->items[i].media_code),
|
||||
resp->items[i].media_code, print_sizes(resp->items[i].media_code),
|
||||
le16_to_cpu(resp->items[i].columns),
|
||||
le16_to_cpu(resp->items[i].rows),
|
||||
le16_to_cpu(resp->items[i].rows),
|
||||
resp->items[i].print_method, print_methods(resp->items[i].print_method));
|
||||
}
|
||||
return 0;
|
||||
|
@ -2055,7 +2074,7 @@ static int shinkos6145_read_parse(void *vctx, int data_fd) {
|
|||
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
|
||||
if (ctx->databuf) {
|
||||
free(ctx->databuf);
|
||||
ctx->databuf = NULL;
|
||||
|
@ -2131,7 +2150,7 @@ static int shinkos6145_main_loop(void *vctx, int copies) {
|
|||
ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd));
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if (le16_to_cpu(media->hdr.payload_len) != (sizeof(struct s6145_mediainfo_resp) - sizeof(struct s6145_status_hdr)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
|
@ -2153,9 +2172,10 @@ static int shinkos6145_main_loop(void *vctx, int copies) {
|
|||
ATTR("marker-colors=#00FFFF#FF00FF#FFFF00\n");
|
||||
ATTR("marker-high-levels=100\n");
|
||||
ATTR("marker-low-levels=10\n");
|
||||
ATTR("marker-names=Ribbon\n");
|
||||
ATTR("marker-types=ink-ribbon\n");
|
||||
|
||||
ATTR("marker-names='%s'\n", print_ribbons(media->ribbon));
|
||||
ATTR("marker-types=ribbonWax\n");
|
||||
ctx->ribbon_type = media->ribbon;
|
||||
|
||||
// XXX check copies against remaining media?
|
||||
|
||||
/* Query printer mode */
|
||||
|
@ -2164,7 +2184,7 @@ static int shinkos6145_main_loop(void *vctx, int copies) {
|
|||
ERROR("Failed to execute command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
top:
|
||||
if (state != last_state) {
|
||||
if (dyesub_debug)
|
||||
|
@ -2186,14 +2206,14 @@ top:
|
|||
|
||||
if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) {
|
||||
uint16_t donor, remain;
|
||||
|
||||
|
||||
memcpy(rdbuf2, rdbuf, READBACK_LEN);
|
||||
|
||||
INFO("Printer Status: 0x%02x (%s)\n",
|
||||
sts->hdr.status, status_str(sts->hdr.status));
|
||||
|
||||
/* Guessimate a percentage for the remaining media */
|
||||
donor = le32_to_cpu(sts->count_ribbon_left) * 100 / (le32_to_cpu(sts->count_ribbon_left)+le32_to_cpu(sts->count_paper));
|
||||
donor = le32_to_cpu(sts->count_ribbon_left) * 100 / ribbon_sizes(ctx->ribbon_type);
|
||||
if (donor != ctx->last_donor) {
|
||||
ctx->last_donor = donor;
|
||||
ATTR("marker-levels=%d\n", donor);
|
||||
|
@ -2207,14 +2227,14 @@ top:
|
|||
if (sts->hdr.result != RESULT_SUCCESS)
|
||||
goto printer_error;
|
||||
if (sts->hdr.status == ERROR_PRINTER)
|
||||
goto printer_error;
|
||||
goto printer_error;
|
||||
} else if (state == last_state) {
|
||||
sleep(1);
|
||||
goto top;
|
||||
}
|
||||
last_state = state;
|
||||
|
||||
fflush(stderr);
|
||||
fflush(stderr);
|
||||
|
||||
switch (state) {
|
||||
case S_IDLE:
|
||||
|
|
|
@ -106,6 +106,7 @@ struct shinkos6245_ctx {
|
|||
|
||||
uint16_t last_donor;
|
||||
uint16_t last_remain;
|
||||
uint8_t ribbon_code;
|
||||
};
|
||||
|
||||
/* Structs for printer */
|
||||
|
@ -520,7 +521,7 @@ static char *error_codes(uint8_t major, uint8_t minor)
|
|||
return "Paper Jam: Precut Print Position Off";
|
||||
case 0x20:
|
||||
return "Paper Jam: Precut Print Position On";
|
||||
|
||||
|
||||
case 0x29:
|
||||
return "Paper Jam: Printing Paper Top On";
|
||||
case 0x2A:
|
||||
|
@ -703,13 +704,13 @@ struct s6245_status_resp {
|
|||
uint32_t count_head;
|
||||
uint32_t count_ribbon_left;
|
||||
uint32_t reserved;
|
||||
|
||||
|
||||
uint8_t bank1_printid;
|
||||
uint16_t bank1_remaining;
|
||||
uint16_t bank1_finished;
|
||||
uint16_t bank1_specified;
|
||||
uint8_t bank1_status;
|
||||
|
||||
|
||||
uint8_t bank2_printid;
|
||||
uint16_t bank2_remaining;
|
||||
uint16_t bank2_finished;
|
||||
|
@ -718,7 +719,7 @@ struct s6245_status_resp {
|
|||
|
||||
uint8_t reserved2[16];
|
||||
uint8_t tonecurve_status;
|
||||
uint8_t reserved3[6];
|
||||
uint8_t reserved3[6];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BANK_STATUS_FREE 0x00
|
||||
|
@ -790,7 +791,7 @@ struct s6245_mediainfo_item {
|
|||
#define MEDIA_8x6_2 0x32
|
||||
#define MEDIA_8x4_3 0x40
|
||||
|
||||
static char *print_medias (uint8_t v) {
|
||||
static const char *print_sizes (uint8_t v) {
|
||||
switch (v) {
|
||||
case MEDIA_8x10:
|
||||
return "8x10";
|
||||
|
@ -819,10 +820,36 @@ static char *print_medias (uint8_t v) {
|
|||
|
||||
struct s6245_mediainfo_resp {
|
||||
struct s6245_status_hdr hdr;
|
||||
uint8_t count;
|
||||
uint8_t ribbon_code;
|
||||
uint8_t reserved;
|
||||
uint8_t count;
|
||||
struct s6245_mediainfo_item items[10]; /* Not all necessarily used */
|
||||
} __attribute__((packed));
|
||||
|
||||
static const char *ribbon_sizes (uint8_t v) {
|
||||
switch (v) {
|
||||
case 0x00:
|
||||
return "None";
|
||||
case 0x11:
|
||||
return "8x10";
|
||||
case 0x12:
|
||||
return "8x12";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int ribbon_counts (uint8_t v) {
|
||||
switch (v) {
|
||||
case 0x11:
|
||||
return 120;
|
||||
case 0x12:
|
||||
return 100;
|
||||
default:
|
||||
return 120;
|
||||
}
|
||||
}
|
||||
|
||||
struct s6245_errorlog_resp {
|
||||
struct s6245_status_hdr hdr;
|
||||
uint16_t error_count;
|
||||
|
@ -1113,14 +1140,15 @@ static int get_mediainfo(struct shinkos6245_ctx *ctx)
|
|||
ERROR("Failed to execute %s command\n", cmd_names(cmd.cmd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (le16_to_cpu(resp->hdr.payload_len) != (sizeof(struct s6245_mediainfo_resp) - sizeof(struct s6245_status_hdr)))
|
||||
return -2;
|
||||
|
||||
INFO("Loaded Media Type: %s\n", ribbon_sizes(resp->ribbon_code));
|
||||
INFO("Supported Media Information: %d entries:\n", resp->count);
|
||||
for (i = 0 ; i < resp->count ; i++) {
|
||||
INFO(" %02d: C 0x%02x (%s), %04dx%04d, P 0x%02x (%s)\n", i,
|
||||
resp->items[i].media_code, print_medias(resp->items[i].media_code),
|
||||
resp->items[i].media_code, print_sizes(resp->items[i].media_code),
|
||||
le16_to_cpu(resp->items[i].columns),
|
||||
le16_to_cpu(resp->items[i].rows),
|
||||
resp->items[i].print_method, print_methods(resp->items[i].print_method));
|
||||
|
@ -1473,10 +1501,10 @@ static void shinkos6245_attach(void *vctx, struct libusb_device_handle *dev,
|
|||