common: better split between parsing and printing.
parsing returns a self-contained job, which is then passed to printing code. No global state is modified. mitsu 70x: Still need to move the image processing code to the print side.
This commit is contained in:
parent
68701c746d
commit
fd9b38202e
|
@ -536,18 +536,9 @@ done:
|
|||
}
|
||||
|
||||
/* Private data structure */
|
||||
struct canonselphy_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
uint8_t endp_down;
|
||||
int type;
|
||||
|
||||
struct printer_data *printer;
|
||||
struct marker marker;
|
||||
|
||||
uint8_t bw_mode;
|
||||
|
||||
struct canonselphy_printjob {
|
||||
int16_t paper_code;
|
||||
uint8_t bw_mode;
|
||||
|
||||
uint32_t plane_len;
|
||||
|
||||
|
@ -557,7 +548,17 @@ struct canonselphy_ctx {
|
|||
uint8_t *plane_c;
|
||||
uint8_t *footer;
|
||||
|
||||
uint8_t *buffer;
|
||||
int copies;
|
||||
};
|
||||
|
||||
struct canonselphy_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
uint8_t endp_down;
|
||||
int type;
|
||||
|
||||
struct printer_data *printer;
|
||||
struct marker marker;
|
||||
|
||||
uint8_t cp900;
|
||||
};
|
||||
|
@ -611,13 +612,6 @@ static void *canonselphy_init(void)
|
|||
/* Static initialization */
|
||||
setup_paper_codes();
|
||||
|
||||
ctx->buffer = malloc(MAX_HEADER);
|
||||
if (!ctx->buffer) {
|
||||
ERROR("Memory Allocation Failure!\n");
|
||||
free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -679,42 +673,56 @@ static int canonselphy_attach(void *vctx, struct libusb_device_handle *dev, int
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void canonselphy_cleanup_job(const void *vjob) {
|
||||
const struct canonselphy_printjob *job = vjob;
|
||||
|
||||
if (job->header)
|
||||
free(job->header);
|
||||
if (job->plane_y)
|
||||
free(job->plane_y);
|
||||
if (job->plane_m)
|
||||
free(job->plane_m);
|
||||
if (job->plane_c)
|
||||
free(job->plane_c);
|
||||
if (job->footer)
|
||||
free(job->footer);
|
||||
|
||||
free((void*)job);
|
||||
}
|
||||
|
||||
static void canonselphy_teardown(void *vctx) {
|
||||
struct canonselphy_ctx *ctx = vctx;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->header)
|
||||
free(ctx->header);
|
||||
if (ctx->plane_y)
|
||||
free(ctx->plane_y);
|
||||
if (ctx->plane_m)
|
||||
free(ctx->plane_m);
|
||||
if (ctx->plane_c)
|
||||
free(ctx->plane_c);
|
||||
if (ctx->footer)
|
||||
free(ctx->footer);
|
||||
|
||||
if (ctx->buffer)
|
||||
free(ctx->buffer);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int canonselphy_read_parse(void *vctx, int data_fd)
|
||||
static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, int copies)
|
||||
{
|
||||
struct canonselphy_ctx *ctx = vctx;
|
||||
int i, remain;
|
||||
int printer_type;
|
||||
int offset = 0;
|
||||
uint8_t rdbuf[MAX_HEADER];
|
||||
|
||||
struct canonselphy_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies;
|
||||
|
||||
/* The CP900 job *may* have a 4-byte null footer after the
|
||||
job contents. Ignore it if it comes through here.. */
|
||||
i = read(data_fd, ctx->buffer, 4);
|
||||
i = read(data_fd, rdbuf, 4);
|
||||
if (i != 4) {
|
||||
if (i == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
|
@ -723,15 +731,15 @@ static int canonselphy_read_parse(void *vctx, int data_fd)
|
|||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
/* if it's not the null header.. don't ignore! */
|
||||
if (ctx->buffer[0] != 0 ||
|
||||
ctx->buffer[1] != 0 ||
|
||||
ctx->buffer[2] != 0 ||
|
||||
ctx->buffer[3] != 0) {
|
||||
if (rdbuf[0] != 0 ||
|
||||
rdbuf[1] != 0 ||
|
||||
rdbuf[2] != 0 ||
|
||||
rdbuf[3] != 0) {
|
||||
offset = 4;
|
||||
}
|
||||
|
||||
/* Read the rest of the header.. */
|
||||
i = read(data_fd, ctx->buffer + offset, MAX_HEADER - offset);
|
||||
i = read(data_fd, rdbuf + offset, MAX_HEADER - offset);
|
||||
if (i != MAX_HEADER - offset) {
|
||||
if (i == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
|
@ -742,7 +750,7 @@ static int canonselphy_read_parse(void *vctx, int data_fd)
|
|||
}
|
||||
|
||||
/* Figure out printer this file is intended for */
|
||||
printer_type = parse_printjob(ctx->buffer, &ctx->bw_mode, &ctx->plane_len);
|
||||
printer_type = parse_printjob(rdbuf, &job->bw_mode, &job->plane_len);
|
||||
/* Special cases for some models */
|
||||
if (printer_type == P_ES40_CP790) {
|
||||
if (ctx->type == P_CP790)
|
||||
|
@ -762,78 +770,56 @@ static int canonselphy_read_parse(void *vctx, int data_fd)
|
|||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
INFO("%sFile intended for a '%s' printer\n", ctx->bw_mode? "B/W " : "", ctx->printer->model);
|
||||
INFO("%sFile intended for a '%s' printer\n", job->bw_mode? "B/W " : "", ctx->printer->model);
|
||||
|
||||
/* Paper code setup */
|
||||
if (ctx->printer->pgcode_offset != -1)
|
||||
ctx->paper_code = ctx->printer->paper_codes[ctx->buffer[ctx->printer->pgcode_offset]];
|
||||
job->paper_code = ctx->printer->paper_codes[rdbuf[ctx->printer->pgcode_offset]];
|
||||
else
|
||||
ctx->paper_code = -1;
|
||||
job->paper_code = -1;
|
||||
|
||||
/* Add in plane header length! */
|
||||
ctx->plane_len += 12;
|
||||
|
||||
/* Now prep for the job */
|
||||
if (ctx->header) {
|
||||
free(ctx->header);
|
||||
ctx->header = NULL;
|
||||
}
|
||||
if (ctx->plane_y) {
|
||||
free(ctx->plane_y);
|
||||
ctx->plane_y = NULL;
|
||||
}
|
||||
if (ctx->plane_m) {
|
||||
free(ctx->plane_m);
|
||||
ctx->plane_m = NULL;
|
||||
}
|
||||
if (ctx->plane_c) {
|
||||
free(ctx->plane_c);
|
||||
ctx->plane_c = NULL;
|
||||
}
|
||||
if (ctx->footer) {
|
||||
free(ctx->footer);
|
||||
ctx->footer = NULL;
|
||||
}
|
||||
job->plane_len += 12;
|
||||
|
||||
/* Set up buffers */
|
||||
ctx->plane_y = malloc(ctx->plane_len);
|
||||
ctx->plane_m = malloc(ctx->plane_len);
|
||||
ctx->plane_c = malloc(ctx->plane_len);
|
||||
ctx->header = malloc(ctx->printer->init_length);
|
||||
ctx->footer = malloc(ctx->printer->foot_length);
|
||||
if (!ctx->plane_y || !ctx->plane_m || !ctx->plane_c || !ctx->header ||
|
||||
(ctx->printer->foot_length && !ctx->footer)) {
|
||||
job->plane_y = malloc(job->plane_len);
|
||||
job->plane_m = malloc(job->plane_len);
|
||||
job->plane_c = malloc(job->plane_len);
|
||||
job->header = malloc(ctx->printer->init_length);
|
||||
job->footer = malloc(ctx->printer->foot_length);
|
||||
if (!job->plane_y || !job->plane_m || !job->plane_c || !job->header ||
|
||||
(ctx->printer->foot_length && !job->footer)) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
/* Move over chunks already read in */
|
||||
memcpy(ctx->header, ctx->buffer, ctx->printer->init_length);
|
||||
memcpy(ctx->plane_y, ctx->buffer+ctx->printer->init_length,
|
||||
memcpy(job->header, rdbuf, ctx->printer->init_length);
|
||||
memcpy(job->plane_y, rdbuf+ctx->printer->init_length,
|
||||
MAX_HEADER-ctx->printer->init_length);
|
||||
|
||||
/* Read in YELLOW plane */
|
||||
remain = ctx->plane_len - (MAX_HEADER-ctx->printer->init_length);
|
||||
remain = job->plane_len - (MAX_HEADER-ctx->printer->init_length);
|
||||
while (remain > 0) {
|
||||
i = read(data_fd, ctx->plane_y + (ctx->plane_len - remain), remain);
|
||||
i = read(data_fd, job->plane_y + (job->plane_len - remain), remain);
|
||||
if (i < 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
remain -= i;
|
||||
}
|
||||
|
||||
/* Read in MAGENTA plane */
|
||||
remain = ctx->plane_len;
|
||||
remain = job->plane_len;
|
||||
while (remain > 0) {
|
||||
i = read(data_fd, ctx->plane_m + (ctx->plane_len - remain), remain);
|
||||
i = read(data_fd, job->plane_m + (job->plane_len - remain), remain);
|
||||
if (i < 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
remain -= i;
|
||||
}
|
||||
|
||||
/* Read in CYAN plane */
|
||||
remain = ctx->plane_len;
|
||||
remain = job->plane_len;
|
||||
while (remain > 0) {
|
||||
i = read(data_fd, ctx->plane_c + (ctx->plane_len - remain), remain);
|
||||
i = read(data_fd, job->plane_c + (job->plane_len - remain), remain);
|
||||
if (i < 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
remain -= i;
|
||||
|
@ -843,22 +829,34 @@ static int canonselphy_read_parse(void *vctx, int data_fd)
|
|||
if (ctx->printer->foot_length) {
|
||||
remain = ctx->printer->foot_length;
|
||||
while (remain > 0) {
|
||||
i = read(data_fd, ctx->footer + (ctx->printer->foot_length - remain), remain);
|
||||
i = read(data_fd, job->footer + (ctx->printer->foot_length - remain), remain);
|
||||
if (i < 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
remain -= i;
|
||||
}
|
||||
}
|
||||
|
||||
*vjob = job;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static int canonselphy_main_loop(void *vctx, int copies) {
|
||||
static int canonselphy_main_loop(void *vctx, const void *vjob) {
|
||||
struct canonselphy_ctx *ctx = vctx;
|
||||
|
||||
uint8_t rdbuf[READBACK_LEN], rdbuf2[READBACK_LEN];
|
||||
int last_state = -1, state = S_IDLE;
|
||||
int ret, num;
|
||||
int copies;
|
||||
|
||||
const struct canonselphy_printjob *job = vjob;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
if (!job)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
copies = job->copies;
|
||||
|
||||
/* Read in the printer status to clear last state */
|
||||
ret = read_data(ctx->dev, ctx->endp_up,
|
||||
|
@ -910,10 +908,10 @@ top:
|
|||
break;
|
||||
|
||||
/* Make sure paper/ribbon is correct */
|
||||
if (ctx->paper_code != -1) {
|
||||
if (job->paper_code != -1) {
|
||||
if (ctx->type == P_CP_XXX) {
|
||||
uint8_t pc = rdbuf[ctx->printer->paper_code_offset];
|
||||
if (((pc >> 4) & 0xf) != (ctx->paper_code & 0x0f)) {
|
||||
if (((pc >> 4) & 0xf) != (job->paper_code & 0x0f)) {
|
||||
|
||||
if (pc & 0xf0) {
|
||||
ERROR("Incorrect paper tray loaded, aborting job!\n");
|
||||
|
@ -923,7 +921,7 @@ top:
|
|||
return CUPS_BACKEND_STOP;
|
||||
}
|
||||
}
|
||||
if ((pc & 0xf) != (ctx->paper_code & 0xf)) {
|
||||
if ((pc & 0xf) != (job->paper_code & 0xf)) {
|
||||
if (pc & 0x0f) {
|
||||
ERROR("Incorrect ribbon loaded, aborting job!\n");
|
||||
return CUPS_BACKEND_HOLD;
|
||||
|
@ -935,9 +933,9 @@ top:
|
|||
}
|
||||
} else {
|
||||
if (rdbuf[ctx->printer->paper_code_offset] !=
|
||||
ctx->paper_code) {
|
||||
job->paper_code) {
|
||||
ERROR("Incorrect media/ribbon loaded (%02x vs %02x), aborting job!\n",
|
||||
ctx->paper_code,
|
||||
job->paper_code,
|
||||
rdbuf[ctx->printer->paper_code_offset]);
|
||||
return CUPS_BACKEND_HOLD; /* Hold this job, don't stop queue */
|
||||
}
|
||||
|
@ -949,14 +947,14 @@ top:
|
|||
if (ribbon == 0xf) {
|
||||
ERROR("No ribbon loaded, aborting!\n");
|
||||
return CUPS_BACKEND_STOP;
|
||||
} else if (ribbon != ctx->paper_code) {
|
||||
} else if (ribbon != job->paper_code) {
|
||||
ERROR("Incorrect ribbon loaded, aborting job!\n");
|
||||
return CUPS_BACKEND_HOLD;
|
||||
}
|
||||
if (paper == 0xf) {
|
||||
ERROR("No paper tray loaded, aborting!\n");
|
||||
return CUPS_BACKEND_STOP;
|
||||
} else if (paper != ctx->paper_code) {
|
||||
} else if (paper != job->paper_code) {
|
||||
ERROR("Incorrect paper loaded, aborting job!\n");
|
||||
return CUPS_BACKEND_HOLD;
|
||||
}
|
||||
|
@ -967,7 +965,7 @@ top:
|
|||
case S_PRINTER_READY:
|
||||
INFO("Printing started; Sending init sequence\n");
|
||||
/* Send printer init */
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->header, ctx->printer->init_length)))
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, job->header, ctx->printer->init_length)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
state = S_PRINTER_INIT_SENT;
|
||||
|
@ -978,19 +976,19 @@ top:
|
|||
}
|
||||
break;
|
||||
case S_PRINTER_READY_Y:
|
||||
if (ctx->bw_mode)
|
||||
if (job->bw_mode)
|
||||
INFO("Sending BLACK plane\n");
|
||||
else
|
||||
INFO("Sending YELLOW plane\n");
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->plane_y, ctx->plane_len)))
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_y, job->plane_len)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
state = S_PRINTER_Y_SENT;
|
||||
break;
|
||||
case S_PRINTER_Y_SENT:
|
||||
if (!fancy_memcmp(rdbuf, ctx->printer->ready_m_readback, READBACK_LEN)) {
|
||||
if (ctx->bw_mode)
|
||||
if (job->bw_mode)
|
||||
state = S_PRINTER_DONE;
|
||||
else
|
||||
state = S_PRINTER_READY_M;
|
||||
|
@ -999,7 +997,7 @@ top:
|
|||
case S_PRINTER_READY_M:
|
||||
INFO("Sending MAGENTA plane\n");
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->plane_m, ctx->plane_len)))
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_m, job->plane_len)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
state = S_PRINTER_M_SENT;
|
||||
|
@ -1012,7 +1010,7 @@ top:
|
|||
case S_PRINTER_READY_C:
|
||||
INFO("Sending CYAN plane\n");
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->plane_c, ctx->plane_len)))
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_c, job->plane_len)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
state = S_PRINTER_C_SENT;
|
||||
|
@ -1040,7 +1038,7 @@ top:
|
|||
if (ctx->printer->foot_length) {
|
||||
INFO("Cleaning up\n");
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->footer, ctx->printer->foot_length)))
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down, job->footer, ctx->printer->foot_length)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
}
|
||||
state = S_FINISHED;
|
||||
|
@ -1141,7 +1139,7 @@ static const char *canonselphy_prefixes[] = {
|
|||
|
||||
struct dyesub_backend canonselphy_backend = {
|
||||
.name = "Canon SELPHY CP/ES (legacy)",
|
||||
.version = "0.101",
|
||||
.version = "0.102",
|
||||
.uri_prefixes = canonselphy_prefixes,
|
||||
.cmdline_usage = canonselphy_cmdline,
|
||||
.cmdline_arg = canonselphy_cmdline_arg,
|
||||
|
@ -1149,6 +1147,7 @@ struct dyesub_backend canonselphy_backend = {
|
|||
.attach = canonselphy_attach,
|
||||
.teardown = canonselphy_teardown,
|
||||
.read_parse = canonselphy_read_parse,
|
||||
.cleanup_job = canonselphy_cleanup_job,
|
||||
.main_loop = canonselphy_main_loop,
|
||||
.query_markers = canonselphy_query_markers,
|
||||
.devices = {
|
||||
|
|
|
@ -62,15 +62,19 @@ struct selphyneo_readback {
|
|||
} __attribute((packed));
|
||||
|
||||
/* Private data structure */
|
||||
struct selphyneo_printjob {
|
||||
uint8_t *databuf;
|
||||
uint32_t datalen;
|
||||
|
||||
int copies;
|
||||
};
|
||||
|
||||
struct selphyneo_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
uint8_t endp_down;
|
||||
int type;
|
||||
|
||||
uint8_t *databuf;
|
||||
uint32_t datalen;
|
||||
|
||||
struct marker marker;
|
||||
};
|
||||
|
||||
|
@ -237,27 +241,43 @@ static int selphyneo_attach(void *vctx, struct libusb_device_handle *dev, int ty
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void selphyneo_cleanup_job(const void *vjob) {
|
||||
const struct selphyneo_printjob *job = vjob;
|
||||
|
||||
if (job->databuf)
|
||||
free(job->databuf);
|
||||
|
||||
free((void*)job);
|
||||
}
|
||||
|
||||
static void selphyneo_teardown(void *vctx) {
|
||||
struct selphyneo_ctx *ctx = vctx;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->databuf)
|
||||
free(ctx->databuf);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int selphyneo_read_parse(void *vctx, int data_fd)
|
||||
static int selphyneo_read_parse(void *vctx, const void **vjob, int data_fd, int copies)
|
||||
{
|
||||
struct selphyneo_ctx *ctx = vctx;
|
||||
struct selphyneo_hdr hdr;
|
||||
int i, remain;
|
||||
|
||||
struct selphyneo_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies;
|
||||
|
||||
/* Read the header.. */
|
||||
i = read(data_fd, &hdr, sizeof(hdr));
|
||||
if (i != sizeof(hdr)) {
|
||||
|
@ -283,34 +303,46 @@ static int selphyneo_read_parse(void *vctx, int data_fd)
|
|||
}
|
||||
|
||||
/* Allocate a buffer */
|
||||
ctx->datalen = 0;
|
||||
ctx->databuf = malloc(remain + sizeof(hdr));
|
||||
if (!ctx->databuf) {
|
||||
job->datalen = 0;
|
||||
job->databuf = malloc(remain + sizeof(hdr));
|
||||
if (!job->databuf) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
/* Store the read-in header */
|
||||
memcpy(ctx->databuf, &hdr, sizeof(hdr));
|
||||
ctx->datalen += sizeof(hdr);
|
||||
memcpy(job->databuf, &hdr, sizeof(hdr));
|
||||
job->datalen += sizeof(hdr);
|
||||
|
||||
/* Read in data */
|
||||
while (remain > 0) {
|
||||
i = read(data_fd, ctx->databuf + ctx->datalen, remain);
|
||||
i = read(data_fd, job->databuf + job->datalen, remain);
|
||||
if (i < 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
remain -= i;
|
||||
ctx->datalen += i;
|
||||
job->datalen += i;
|
||||
}
|
||||
|
||||
*vjob = job;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static int selphyneo_main_loop(void *vctx, int copies) {
|
||||
static int selphyneo_main_loop(void *vctx, const void *vjob) {
|
||||
struct selphyneo_ctx *ctx = vctx;
|
||||
struct selphyneo_readback rdback;
|
||||
|
||||
int ret, num;
|
||||
int copies;
|
||||
|
||||
const struct selphyneo_printjob *job = vjob;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
if (!job)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
copies = job->copies;
|
||||
|
||||
/* Read in the printer status to clear last state */
|
||||
ret = read_data(ctx->dev, ctx->endp_up,
|
||||
|
@ -361,10 +393,10 @@ top:
|
|||
int sent = 0;
|
||||
while (chunk > 0) {
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
ctx->databuf + sent, chunk)))
|
||||
job->databuf + sent, chunk)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
sent += chunk;
|
||||
chunk = ctx->datalen - sent;
|
||||
chunk = job->datalen - sent;
|
||||
if (chunk > 256*1024)
|
||||
chunk = 256*1024;
|
||||
}
|
||||
|
@ -496,12 +528,13 @@ static const char *canonselphyneo_prefixes[] = {
|
|||
|
||||
struct dyesub_backend canonselphyneo_backend = {
|
||||
.name = "Canon SELPHY CP (new)",
|
||||
.version = "0.17",
|
||||
.version = "0.18",
|
||||
.uri_prefixes = canonselphyneo_prefixes,
|
||||
.cmdline_usage = selphyneo_cmdline,
|
||||
.cmdline_arg = selphyneo_cmdline_arg,
|
||||
.init = selphyneo_init,
|
||||
.attach = selphyneo_attach,
|
||||
.cleanup_job = selphyneo_cleanup_job,
|
||||
.teardown = selphyneo_teardown,
|
||||
.read_parse = selphyneo_read_parse,
|
||||
.main_loop = selphyneo_main_loop,
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "backend_common.h"
|
||||
|
||||
#define BACKEND_VERSION "0.86"
|
||||
#define BACKEND_VERSION "0.87"
|
||||
#ifndef URI_PREFIX
|
||||
#error "Must Define URI_PREFIX"
|
||||
#endif
|
||||
|
@ -268,7 +268,7 @@ done:
|
|||
}
|
||||
|
||||
int send_data(struct libusb_device_handle *dev, uint8_t endp,
|
||||
uint8_t *buf, int len)
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
|
@ -279,7 +279,7 @@ int send_data(struct libusb_device_handle *dev, uint8_t endp,
|
|||
while (len) {
|
||||
int len2 = (len > max_xfer_size) ? max_xfer_size: len;
|
||||
int ret = libusb_bulk_transfer(dev, endp,
|
||||
buf, len2,
|
||||
(uint8_t*) buf, len2,
|
||||
&num, xfer_timeout);
|
||||
|
||||
if ((dyesub_debug > 1 && len < 4096) ||
|
||||
|
@ -942,6 +942,8 @@ int main (int argc, char **argv)
|
|||
|
||||
int data_fd = fileno(stdin);
|
||||
|
||||
const void *job = NULL;
|
||||
|
||||
int i;
|
||||
|
||||
int ret = CUPS_BACKEND_OK;
|
||||
|
@ -1235,7 +1237,7 @@ bypass:
|
|||
newpage:
|
||||
|
||||
/* Read in data */
|
||||
if ((ret = backend->read_parse(backend_ctx, data_fd))) {
|
||||
if ((ret = backend->read_parse(backend_ctx, &job, data_fd, copies))) {
|
||||
if (current_page)
|
||||
goto done_multiple;
|
||||
else
|
||||
|
@ -1252,7 +1254,9 @@ newpage:
|
|||
if (test_mode >= TEST_MODE_NOPRINT ) {
|
||||
WARNING("**** TEST MODE, bypassing printing!\n");
|
||||
} else {
|
||||
ret = backend->main_loop(backend_ctx, copies);
|
||||
ret = backend->main_loop(backend_ctx, job);
|
||||
if (backend->cleanup_job)
|
||||
backend->cleanup_job(job);
|
||||
if (ret)
|
||||
goto done_claimed;
|
||||
}
|
||||
|
|
|
@ -162,8 +162,9 @@ struct dyesub_backend {
|
|||
uint8_t endp_up, uint8_t endp_down, uint8_t jobid);
|
||||
void (*teardown)(void *ctx);
|
||||
int (*cmdline_arg)(void *ctx, int argc, char **argv);
|
||||
int (*read_parse)(void *ctx, int data_fd);
|
||||
int (*main_loop)(void *ctx, int copies);
|
||||
int (*read_parse)(void *ctx, const void **job, int data_fd, int copies);
|
||||
void (*cleanup_job)(const void *job);
|
||||
int (*main_loop)(void *ctx, const void *job);
|
||||
int (*query_serno)(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len); /* Optional */
|
||||
int (*query_markers)(void *ctx, struct marker **markers, int *count);
|
||||
const struct device_id devices[];
|
||||
|
@ -171,7 +172,7 @@ struct dyesub_backend {
|
|||
|
||||
/* Exported functions */
|
||||
int send_data(struct libusb_device_handle *dev, uint8_t endp,
|
||||
uint8_t *buf, int len);
|
||||
const uint8_t *buf, int len);
|
||||
int read_data(struct libusb_device_handle *dev, uint8_t endp,
|
||||
uint8_t *buf, int buflen, int *readlen);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -77,21 +77,26 @@ struct kodak1400_hdr {
|
|||
|
||||
|
||||
/* Private data structure */
|
||||
struct kodak1400_printjob {
|
||||
struct kodak1400_hdr hdr;
|
||||
uint8_t *plane_r;
|
||||
uint8_t *plane_g;
|
||||
uint8_t *plane_b;
|
||||
|
||||
int copies;
|
||||
};
|
||||
|
||||
struct kodak1400_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
uint8_t endp_down;
|
||||
int type;
|
||||
|
||||
struct kodak1400_hdr hdr;
|
||||
uint8_t *plane_r;
|
||||
uint8_t *plane_g;
|
||||
uint8_t *plane_b;
|
||||
|
||||
struct marker marker;
|
||||
};
|
||||
|
||||
static int send_plane(struct kodak1400_ctx *ctx,
|
||||
const struct kodak1400_printjob *job,
|
||||
uint8_t planeno, uint8_t *planedata,
|
||||
uint8_t *cmdbuf)
|
||||
{
|
||||
|
@ -117,9 +122,9 @@ static int send_plane(struct kodak1400_ctx *ctx,
|
|||
cmdbuf[3] = planeno;
|
||||
|
||||
if (planedata) {
|
||||
temp16 = htons(ctx->hdr.columns);
|
||||
temp16 = htons(job->hdr.columns);
|
||||
memcpy(cmdbuf+7, &temp16, 2);
|
||||
temp16 = htons(ctx->hdr.rows);
|
||||
temp16 = htons(job->hdr.rows);
|
||||
memcpy(cmdbuf+9, &temp16, 2);
|
||||
}
|
||||
|
||||
|
@ -129,10 +134,10 @@ static int send_plane(struct kodak1400_ctx *ctx,
|
|||
|
||||
if (planedata) {
|
||||
int i;
|
||||
for (i = 0 ; i < ctx->hdr.rows ; i++) {
|
||||
for (i = 0 ; i < job->hdr.rows ; i++) {
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
planedata + i * ctx->hdr.columns,
|
||||
ctx->hdr.columns)))
|
||||
planedata + i * job->hdr.columns,
|
||||
job->hdr.columns)))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -316,91 +321,96 @@ static int kodak1400_attach(void *vctx, struct libusb_device_handle *dev, int ty
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void kodak1400_cleanup_job(const void *vjob)
|
||||
{
|
||||
const struct kodak1400_printjob *job = vjob;
|
||||
|
||||
if (job->plane_r)
|
||||
free(job->plane_r);
|
||||
if (job->plane_g)
|
||||
free(job->plane_g);
|
||||
if (job->plane_b)
|
||||
free(job->plane_b);
|
||||
|
||||
free((void*)job);
|
||||
}
|
||||
|
||||
static void kodak1400_teardown(void *vctx) {
|
||||
struct kodak1400_ctx *ctx = vctx;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->plane_r)
|
||||
free(ctx->plane_r);
|
||||
if (ctx->plane_g)
|
||||
free(ctx->plane_g);
|
||||
if (ctx->plane_b)
|
||||
free(ctx->plane_b);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int kodak1400_read_parse(void *vctx, int data_fd) {
|
||||
static int kodak1400_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct kodak1400_ctx *ctx = vctx;
|
||||
int i, ret;
|
||||
|
||||
struct kodak1400_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
if (ctx->plane_r) {
|
||||
free(ctx->plane_r);
|
||||
ctx->plane_r = NULL;
|
||||
}
|
||||
if (ctx->plane_g) {
|
||||
free(ctx->plane_g);
|
||||
ctx->plane_g = NULL;
|
||||
}
|
||||
if (ctx->plane_b) {
|
||||
free(ctx->plane_b);
|
||||
ctx->plane_b = NULL;
|
||||
}
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &ctx->hdr, sizeof(ctx->hdr));
|
||||
if (ret < 0 || ret != sizeof(ctx->hdr)) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(ctx->hdr));
|
||||
perror("ERROR: Read failed");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
if (ctx->hdr.hdr[0] != 'P' ||
|
||||
ctx->hdr.hdr[1] != 'G' ||
|
||||
ctx->hdr.hdr[2] != 'H' ||
|
||||
ctx->hdr.hdr[3] != 'D') {
|
||||
ERROR("Unrecognized data format!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
ctx->hdr.planesize = le32_to_cpu(ctx->hdr.planesize);
|
||||
ctx->hdr.rows = le16_to_cpu(ctx->hdr.rows);
|
||||
ctx->hdr.columns = le16_to_cpu(ctx->hdr.columns);
|
||||
|
||||
/* Set up plane data */
|
||||
ctx->plane_r = malloc(ctx->hdr.planesize);
|
||||
ctx->plane_g = malloc(ctx->hdr.planesize);
|
||||
ctx->plane_b = malloc(ctx->hdr.planesize);
|
||||
if (!ctx->plane_r || !ctx->plane_g || !ctx->plane_b) {
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
for (i = 0 ; i < ctx->hdr.rows ; i++) {
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->copies = copies;
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(job->hdr));
|
||||
perror("ERROR: Read failed");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
if (job->hdr.hdr[0] != 'P' ||
|
||||
job->hdr.hdr[1] != 'G' ||
|
||||
job->hdr.hdr[2] != 'H' ||
|
||||
job->hdr.hdr[3] != 'D') {
|
||||
ERROR("Unrecognized data format!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
job->hdr.planesize = le32_to_cpu(job->hdr.planesize);
|
||||
job->hdr.rows = le16_to_cpu(job->hdr.rows);
|
||||
job->hdr.columns = le16_to_cpu(job->hdr.columns);
|
||||
|
||||
/* Set up plane data */
|
||||
job->plane_r = malloc(job->hdr.planesize);
|
||||
job->plane_g = malloc(job->hdr.planesize);
|
||||
job->plane_b = malloc(job->hdr.planesize);
|
||||
if (!job->plane_r || !job->plane_g || !job->plane_b) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
for (i = 0 ; i < job->hdr.rows ; i++) {
|
||||
int j;
|
||||
uint8_t *ptr;
|
||||
for (j = 0 ; j < 3 ; j++) {
|
||||
int remain;
|
||||
if (j == 0)
|
||||
ptr = ctx->plane_r + i * ctx->hdr.columns;
|
||||
ptr = job->plane_r + i * job->hdr.columns;
|
||||
else if (j == 1)
|
||||
ptr = ctx->plane_g + i * ctx->hdr.columns;
|
||||
ptr = job->plane_g + i * job->hdr.columns;
|
||||
else if (j == 2)
|
||||
ptr = ctx->plane_b + i * ctx->hdr.columns;
|
||||
ptr = job->plane_b + i * job->hdr.columns;
|
||||
else
|
||||
ptr = NULL;
|
||||
|
||||
remain = ctx->hdr.columns;
|
||||
remain = job->hdr.columns;
|
||||
do {
|
||||
ret = read(data_fd, ptr, remain);
|
||||
if (ret < 0) {
|
||||
ERROR("Read failed (%d/%d/%u) (%d/%u @ %d)\n",
|
||||
ret, remain, ctx->hdr.columns,
|
||||
i, ctx->hdr.rows, j);
|
||||
ret, remain, job->hdr.columns,
|
||||
i, job->hdr.rows, j);
|
||||
perror("ERROR: Read failed");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
@ -410,13 +420,15 @@ static int kodak1400_read_parse(void *vctx, int data_fd) {
|
|||
}
|
||||
}
|
||||
|
||||
*vjob = job;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static uint8_t idle_data[READBACK_LEN] = { 0xe4, 0x72, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static int kodak1400_main_loop(void *vctx, int copies) {
|
||||
static int kodak1400_main_loop(void *vctx, const void *vjob) {
|
||||
struct kodak1400_ctx *ctx = vctx;
|
||||
|
||||
uint8_t rdbuf[READBACK_LEN], rdbuf2[READBACK_LEN];
|
||||
|
@ -424,6 +436,16 @@ static int kodak1400_main_loop(void *vctx, int copies) {
|
|||
int last_state = -1, state = S_IDLE;
|
||||
int num, ret;
|
||||
uint16_t temp16;
|
||||
int copies;
|
||||
|
||||
const struct kodak1400_printjob *job = vjob;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
if (!job)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
copies = job->copies;
|
||||
|
||||
top:
|
||||
if (state != last_state) {
|
||||
|
@ -479,9 +501,9 @@ top:
|
|||
cmdbuf[0] = 0x1b;
|
||||
cmdbuf[1] = 0x5a;
|
||||
cmdbuf[2] = 0x53;
|
||||
temp16 = be16_to_cpu(ctx->hdr.columns);
|
||||
temp16 = be16_to_cpu(job->hdr.columns);
|
||||
memcpy(cmdbuf+3, &temp16, 2);
|
||||
temp16 = be16_to_cpu(ctx->hdr.rows);
|
||||
temp16 = be16_to_cpu(job->hdr.rows);
|
||||
memcpy(cmdbuf+5, &temp16, 2);
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
|
@ -492,7 +514,7 @@ top:
|
|||
memset(cmdbuf, 0, CMDBUF_LEN);
|
||||
cmdbuf[0] = 0x1b;
|
||||
cmdbuf[1] = 0x59;
|
||||
cmdbuf[2] = ctx->hdr.matte; // ???
|
||||
cmdbuf[2] = job->hdr.matte; // ???
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
cmdbuf, CMDBUF_LEN)))
|
||||
|
@ -502,7 +524,7 @@ top:
|
|||
memset(cmdbuf, 0, CMDBUF_LEN);
|
||||
cmdbuf[0] = 0x1b;
|
||||
cmdbuf[1] = 0x60;
|
||||
cmdbuf[2] = ctx->hdr.laminate;
|
||||
cmdbuf[2] = job->hdr.laminate;
|
||||
|
||||
if (send_data(ctx->dev, ctx->endp_down,
|
||||
cmdbuf, CMDBUF_LEN))
|
||||
|
@ -512,7 +534,7 @@ top:
|
|||
memset(cmdbuf, 0, CMDBUF_LEN);
|
||||
cmdbuf[0] = 0x1b;
|
||||
cmdbuf[1] = 0x62;
|
||||
cmdbuf[2] = ctx->hdr.lam_strength;
|
||||
cmdbuf[2] = job->hdr.lam_strength;
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
cmdbuf, CMDBUF_LEN)))
|
||||
|
@ -522,7 +544,7 @@ top:
|
|||
memset(cmdbuf, 0, CMDBUF_LEN);
|
||||
cmdbuf[0] = 0x1b;
|
||||
cmdbuf[1] = 0x61;
|
||||
cmdbuf[2] = ctx->hdr.unk1; // ???
|
||||
cmdbuf[2] = job->hdr.unk1; // ???
|
||||
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
cmdbuf, CMDBUF_LEN)))
|
||||
|
@ -532,7 +554,7 @@ top:
|
|||
break;
|
||||
case S_PRINTER_READY_Y:
|
||||
INFO("Sending YELLOW plane\n");
|
||||
if ((ret = send_plane(ctx, 1, ctx->plane_b, cmdbuf)))
|
||||
if ((ret = send_plane(ctx, job, 1, job->plane_b, cmdbuf)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
state = S_PRINTER_SENT_Y;
|
||||
break;
|
||||
|
@ -542,7 +564,7 @@ top:
|
|||
break;
|
||||
case S_PRINTER_READY_M:
|
||||
INFO("Sending MAGENTA plane\n");
|
||||
if ((ret = send_plane(ctx, 2, ctx->plane_g, cmdbuf)))
|
||||
if ((ret = send_plane(ctx, job, 2, job->plane_g, cmdbuf)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
state = S_PRINTER_SENT_M;
|
||||
break;
|
||||
|
@ -552,13 +574,13 @@ top:
|
|||
break;
|
||||
case S_PRINTER_READY_C:
|
||||
INFO("Sending CYAN plane\n");
|
||||
if ((ret = send_plane(ctx, 3, ctx->plane_r, cmdbuf)))
|
||||
if ((ret = send_plane(ctx, job, 3, job->plane_r, cmdbuf)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
state = S_PRINTER_SENT_C;
|
||||
break;
|
||||
case S_PRINTER_SENT_C:
|
||||
if (!memcmp(rdbuf, idle_data, READBACK_LEN)) {
|
||||
if (ctx->hdr.laminate)
|
||||
if (job->hdr.laminate)
|
||||
state = S_PRINTER_READY_L;
|
||||
else
|
||||
state = S_PRINTER_DONE;
|
||||
|
@ -566,7 +588,7 @@ top:
|
|||
break;
|
||||
case S_PRINTER_READY_L:
|
||||
INFO("Laminating page\n");
|
||||
if ((ret = send_plane(ctx, 4, NULL, cmdbuf)))
|
||||
if ((ret = send_plane(ctx, job, 4, NULL, cmdbuf)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
state = S_PRINTER_SENT_L;
|
||||
break;
|
||||
|
@ -635,13 +657,14 @@ static const char *kodak1400_prefixes[] = {
|
|||
|
||||
struct dyesub_backend kodak1400_backend = {
|
||||
.name = "Kodak 1400/805",
|
||||
.version = "0.37",
|
||||
.version = "0.38",
|
||||
.uri_prefixes = kodak1400_prefixes,
|
||||
.cmdline_usage = kodak1400_cmdline,
|
||||
.cmdline_arg = kodak1400_cmdline_arg,
|
||||
.init = kodak1400_init,
|
||||
.attach = kodak1400_attach,
|
||||
.teardown = kodak1400_teardown,
|
||||
.cleanup_job = kodak1400_cleanup_job,
|
||||
.read_parse = kodak1400_read_parse,
|
||||
.main_loop = kodak1400_main_loop,
|
||||
.query_markers = kodak1400_query_markers,
|
||||
|
|
|
@ -167,6 +167,12 @@ static const char *kodak68xx_mediatypes(int type)
|
|||
#define CMDBUF_LEN 4
|
||||
|
||||
/* Private data structure */
|
||||
struct kodak605_printjob {
|
||||
struct kodak605_hdr hdr;
|
||||
uint8_t *databuf;
|
||||
int datalen;
|
||||
};
|
||||
|
||||
struct kodak605_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
|
@ -174,14 +180,10 @@ struct kodak605_ctx {
|
|||
int type;
|
||||
uint8_t jobid;
|
||||
|
||||
struct kodak605_hdr hdr;
|
||||
|
||||
struct kodak605_media_list *media;
|
||||
|
||||
struct marker marker;
|
||||
|
||||
uint8_t *databuf;
|
||||
int datalen;
|
||||
};
|
||||
|
||||
static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_list *media)
|
||||
|
@ -299,63 +301,75 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev, int typ
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void kodak605_cleanup_job(const void *vjob)
|
||||
{
|
||||
const struct kodak605_printjob *job = vjob;
|
||||
|
||||
if (job->databuf)
|
||||
free(job->databuf);
|
||||
|
||||
free((void*)job);
|
||||
}
|
||||
|
||||
static void kodak605_teardown(void *vctx) {
|
||||
struct kodak605_ctx *ctx = vctx;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->databuf)
|
||||
free(ctx->databuf);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int kodak605_read_parse(void *vctx, int data_fd) {
|
||||
static int kodak605_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct kodak605_ctx *ctx = vctx;
|
||||
int ret;
|
||||
|
||||
struct kodak605_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
|
||||
if (ctx->databuf) {
|
||||
free(ctx->databuf);
|
||||
ctx->databuf = NULL;
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &ctx->hdr, sizeof(ctx->hdr));
|
||||
if (ret < 0 || ret != sizeof(ctx->hdr)) {
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, 0, (int)sizeof(ctx->hdr));
|
||||
ret, 0, (int)sizeof(job->hdr));
|
||||
perror("ERROR: Read failed");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
if (ctx->hdr.hdr[0] != 0x01 ||
|
||||
ctx->hdr.hdr[1] != 0x40 ||
|
||||
ctx->hdr.hdr[2] != 0x0a ||
|
||||
ctx->hdr.hdr[3] != 0x00) {
|
||||
if (job->hdr.hdr[0] != 0x01 ||
|
||||
job->hdr.hdr[1] != 0x40 ||
|
||||
job->hdr.hdr[2] != 0x0a ||
|
||||
job->hdr.hdr[3] != 0x00) {
|
||||
ERROR("Unrecognized data format!\n");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
||||
ctx->datalen = le16_to_cpu(ctx->hdr.rows) * le16_to_cpu(ctx->hdr.columns) * 3;
|
||||
ctx->databuf = malloc(ctx->datalen);
|
||||
if (!ctx->databuf) {
|
||||
job->datalen = le16_to_cpu(job->hdr.rows) * le16_to_cpu(job->hdr.columns) * 3;
|
||||
job->databuf = malloc(job->datalen);
|
||||
if (!job->databuf) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
|
||||
{
|
||||
int remain = ctx->datalen;
|
||||
uint8_t *ptr = ctx->databuf;
|
||||
int remain = job->datalen;
|
||||
uint8_t *ptr = job->databuf;
|
||||
do {
|
||||
ret = read(data_fd, ptr, remain);
|
||||
if (ret < 0) {
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||
ret, remain, ctx->datalen);
|
||||
ret, remain, job->datalen);
|
||||
perror("ERROR: Read failed");
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
|
@ -364,27 +378,36 @@ static int kodak605_read_parse(void *vctx, int data_fd) {
|
|||
} while (remain);
|
||||
}
|
||||
|
||||
/* Printer handles generating copies.. */
|
||||
if (le16_to_cpu(job->hdr.copies) < copies)
|
||||
job->hdr.copies = cpu_to_le16(copies);
|
||||
|
||||
*vjob = job;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static int kodak605_main_loop(void *vctx, int copies) {
|
||||
static int kodak605_main_loop(void *vctx, const void *vjob) {
|
||||
struct kodak605_ctx *ctx = vctx;
|
||||
|
||||
struct kodak605_status sts;
|
||||
|
||||
int num, ret;
|
||||
|
||||
const struct kodak605_printjob *job = vjob;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
if (!job)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
/* Printer handles generating copies.. */
|
||||
if (le16_to_cpu(ctx->hdr.copies) < copies)
|
||||
ctx->hdr.copies = cpu_to_le16(copies);
|
||||
struct kodak605_hdr hdr;
|
||||
memcpy(&hdr, &job->hdr, sizeof(hdr));
|
||||
|
||||
/* Validate against supported media list */
|
||||
for (num = 0 ; num < ctx->media->count; num++) {
|
||||
if (ctx->media->entries[num].rows == ctx->hdr.rows &&
|
||||
ctx->media->entries[num].cols == ctx->hdr.columns)
|
||||
if (ctx->media->entries[num].rows == hdr.rows &&
|
||||
ctx->media->entries[num].cols == hdr.columns)
|
||||
break;
|
||||
}
|
||||
if (num == ctx->media->count) {
|
||||
|
@ -425,12 +448,12 @@ static int kodak605_main_loop(void *vctx, int copies) {
|
|||
}
|
||||
|
||||
/* Use specified jobid */
|
||||
ctx->hdr.jobid = ctx->jobid;
|
||||
hdr.jobid = ctx->jobid;
|
||||
|
||||
{
|
||||
INFO("Sending image header (internal id %u)\n", ctx->jobid);
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
(uint8_t*)&ctx->hdr, sizeof(ctx->hdr))))
|
||||
(uint8_t*)&hdr, sizeof(hdr))))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
struct kodak605_sts_hdr resp;
|
||||
|
@ -448,7 +471,7 @@ static int kodak605_main_loop(void *vctx, int copies) {
|
|||
|
||||
INFO("Sending image data\n");
|
||||
if ((ret = send_data(ctx->dev, ctx->endp_down,
|
||||
ctx->databuf, ctx->datalen)))
|
||||
job->databuf, job->datalen)))
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
INFO("Image data sent\n");
|
||||
|
@ -690,13 +713,14 @@ static const char *kodak605_prefixes[] = {
|
|||
/* Exported */
|
||||
struct dyesub_backend kodak605_backend = {
|
||||
.name = "Kodak 605",
|
||||
.version = "0.30",
|
||||
.version = "0.31",
|
||||
.uri_prefixes = kodak605_prefixes,
|
||||
.cmdline_usage = kodak605_cmdline,
|
||||
.cmdline_arg = kodak605_cmdline_arg,
|
||||
.init = kodak605_init,
|
||||
.attach = kodak605_attach,
|
||||
.teardown = kodak605_teardown,
|
||||
.cleanup_job = kodak605_cleanup_job,
|
||||
.read_parse = kodak605_read_parse,
|
||||
.main_loop = kodak605_main_loop,
|
||||
.query_markers = kodak605_query_markers,
|
||||
|
|
|
@ -224,6 +224,13 @@ struct kodak68x0_media_readback {
|
|||
#define CMDBUF_LEN 17
|
||||
|
||||
/* Private data structure */
|
||||
struct kodak6800_printjob {
|
||||
struct kodak6800_hdr hdr;
|
||||
uint8_t *databuf;
|
||||
int datalen;
|
||||
int copies;
|
||||
};
|
||||
|
||||
struct kodak6800_ctx {
|
||||
struct libusb_device_handle *dev;
|
||||
uint8_t endp_up;
|
||||
|
@ -235,10 +242,6 @@ struct kodak6800_ctx {
|
|||
|
||||
struct kodak68x0_media_readback *media;
|
||||
|
||||
struct kodak6800_hdr hdr;
|
||||
uint8_t *databuf;
|
||||
int datalen;
|
||||
|
||||
struct marker marker;
|
||||
};
|
||||
|
||||
|
@ -1041,63 +1044,75 @@ static int kodak6800_attach(void *vctx, struct libusb_device_handle *dev, int ty
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void kodak6800_cleanup_job(const void *vjob)
|
||||
{
|
||||
const struct kodak6800_printjob *job = vjob;
|
||||
|
||||
if (job->databuf)
|
||||
free(job->databuf);
|
||||
|
||||
free((void*)job);
|
||||
}
|
||||
|
||||
static void kodak6800_teardown(void *vctx) {
|
||||
struct kodak6800_ctx *ctx = vctx;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->databuf)
|
||||
free(ctx->databuf);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int kodak6800_read_parse(void *vctx, int data_fd) {
|
||||
static int kodak6800_read_parse(void *vctx, const void **vjob, int data_fd, int copies) {
|
||||
struct kodak6800_ctx *ctx = vctx;
|
||||
int ret;
|
||||
|
||||
struct kodak6800_printjob *job = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return CUPS_BACKEND_FAILED;
|
||||
|
||||
if (ctx->databuf) {
|
||||
free(ctx->databuf);
|
||||
ctx->databuf = NULL;
|
||||
job = malloc(sizeof(*job));
|
||||
if (!job) {
|
||||
ERROR("Memory allocation failure!\n");
|
||||
return CUPS_BACKEND_RETRY_CURRENT;
|
||||
}
|
||||
memset(job, 0, sizeof(*job));
|
||||
|
||||
/* Read in then validate header */
|
||||
ret = read(data_fd, &ctx->hdr, sizeof(ctx->hdr));
|
||||
if (ret < 0 || ret != sizeof(ctx->hdr)) {
|
||||
ret = read(data_fd, &job->hdr, sizeof(job->hdr));
|
||||
if (ret < 0 || ret != sizeof(job->hdr)) {
|
||||
if (ret == 0)
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
ERROR("Read failed (%d/%d/%d)\n",
|
||||