diff options
author | Didier Raboud <odyx@debian.org> | 2018-09-25 08:33:05 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2018-09-25 08:33:05 +0200 |
commit | e50542121e724e851fc5d6c68bb773f80c0bc12c (patch) | |
tree | 655c3f6331a6e8fd8b09ceb4da8f5896484ae16a /src/cups/backend_kodak6800.c | |
parent | 9dd97a029bf391c42b1dc76f2f7c5e386bb8f466 (diff) |
New upstream version 5.3.1
Diffstat (limited to 'src/cups/backend_kodak6800.c')
-rw-r--r-- | src/cups/backend_kodak6800.c | 215 |
1 files changed, 132 insertions, 83 deletions
diff --git a/src/cups/backend_kodak6800.c b/src/cups/backend_kodak6800.c index f535797..79d950b 100644 --- a/src/cups/backend_kodak6800.c +++ b/src/cups/backend_kodak6800.c @@ -1,7 +1,7 @@ /* * Kodak 6800/6850 Photo Printer CUPS backend -- libusb-1.0 version * - * (c) 2013-2017 Solomon Peachy <pizza@shaftnet.org> + * (c) 2013-2018 Solomon Peachy <pizza@shaftnet.org> * * Development of this backend was sponsored by: * @@ -22,11 +22,12 @@ * for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program. If not, see <https://www.gnu.org/licenses/>. * * [http://www.gnu.org/licenses/gpl-2.0.html] * + * SPDX-License-Identifier: GPL-2.0+ + * */ #include <stdio.h> @@ -222,6 +223,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; @@ -233,11 +241,7 @@ struct kodak6800_ctx { struct kodak68x0_media_readback *media; - struct kodak6800_hdr hdr; - uint8_t *databuf; - int datalen; - - uint8_t last_donor; + struct marker marker; }; static const char *kodak68xx_mediatypes(int type) @@ -276,8 +280,6 @@ static int kodak6800_do_cmd(struct kodak6800_ctx *ctx, return 0; } - - static void kodak68x0_dump_mediainfo(struct kodak68x0_media_readback *media) { int i; @@ -690,6 +692,7 @@ static int kodak6800_get_tonecurve(struct kodak6800_ctx *ctx, char *fname) cmdbuf[14] = 0x00; cmdbuf[15] = 0x00; + respbuf[0] = 0xff; /* Issue command and get response */ if ((ret = kodak6800_do_cmd(ctx, cmdbuf, sizeof(cmdbuf), respbuf, sizeof(respbuf), @@ -1004,40 +1007,54 @@ static void *kodak6800_init(void) ctx->media = malloc(MAX_MEDIA_LEN); - ctx->type = P_ANY; - return ctx; } -static void kodak6800_attach(void *vctx, struct libusb_device_handle *dev, - uint8_t endp_up, uint8_t endp_down, uint8_t jobid) +static int kodak6800_attach(void *vctx, struct libusb_device_handle *dev, int type, + uint8_t endp_up, uint8_t endp_down, uint8_t jobid) { struct kodak6800_ctx *ctx = vctx; - struct libusb_device *device; - struct libusb_device_descriptor desc; ctx->dev = dev; ctx->endp_up = endp_up; ctx->endp_down = endp_down; - - device = libusb_get_device(dev); - libusb_get_device_descriptor(device, &desc); - - ctx->type = lookup_printer_type(&kodak6800_backend, - desc.idVendor, desc.idProduct); + ctx->type = type; /* Ensure jobid is sane */ ctx->jobid = jobid & 0x7f; if (!ctx->jobid) ctx->jobid++; - /* Init */ - ctx->last_donor = 255; + if (test_mode < TEST_MODE_NOATTACH) { + /* Query media info */ + if (kodak6800_get_mediainfo(ctx, ctx->media)) { + ERROR("Can't query media\n"); + return CUPS_BACKEND_FAILED; + } + } else { + int media_code = KODAK68x0_MEDIA_6TR2; + if (getenv("MEDIA_CODE")) + media_code = atoi(getenv("MEDIA_CODE")); - /* Query media info */ - if (kodak6800_get_mediainfo(ctx, ctx->media)) { - ERROR("Can't query media\n"); + ctx->media->type = media_code; } + + ctx->marker.color = "#00FFFF#FF00FF#FFFF00"; + ctx->marker.name = kodak68xx_mediatypes(ctx->media->type); + ctx->marker.levelmax = 100; /* Ie percentage */ + ctx->marker.levelnow = -2; + + 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) { @@ -1046,57 +1063,59 @@ static void kodak6800_teardown(void *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", - 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] != 0x03 || - ctx->hdr.hdr[1] != 0x1b || - ctx->hdr.hdr[2] != 0x43 || - ctx->hdr.hdr[3] != 0x48 || - ctx->hdr.hdr[4] != 0x43) { + if (job->hdr.hdr[0] != 0x03 || + job->hdr.hdr[1] != 0x1b || + job->hdr.hdr[2] != 0x43 || + job->hdr.hdr[3] != 0x48 || + job->hdr.hdr[4] != 0x43) { ERROR("Unrecognized data format!\n"); return CUPS_BACKEND_CANCEL; } - ctx->datalen = be16_to_cpu(ctx->hdr.rows) * be16_to_cpu(ctx->hdr.columns) * 3; - ctx->databuf = malloc(ctx->datalen); - if (!ctx->databuf) { + job->datalen = be16_to_cpu(job->hdr.rows) * be16_to_cpu(job->hdr.columns) * 3; + job->databuf = malloc(job->datalen); + if (!job->databuf) { ERROR("Memory allocation failure!\n"); - return CUPS_BACKEND_FAILED; + 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; } @@ -1105,29 +1124,39 @@ static int kodak6800_read_parse(void *vctx, int data_fd) { } while (remain); } + /* Fix max print count. */ + if (copies > 9999) // XXX test against remaining media + copies = 9999; + + /* Printer handles generating copies.. */ + if (le16_to_cpu(job->hdr.copies) < copies) + job->hdr.copies = cpu_to_be16(uint16_to_packed_bcd(copies)); + + *vjob = job; + return CUPS_BACKEND_OK; } -static int kodak6800_main_loop(void *vctx, int copies) { +static int kodak6800_main_loop(void *vctx, const void *vjob) { struct kodak6800_ctx *ctx = vctx; struct kodak68x0_status_readback status; int num, ret; + const struct kodak6800_printjob *job = vjob; + if (!ctx) return CUPS_BACKEND_FAILED; + if (!job) + return CUPS_BACKEND_FAILED; - /* Fix max print count. */ - if (copies > 9999) // XXX test against remaining media - copies = 9999; - - /* Printer handles generating copies.. */ - ctx->hdr.copies = cpu_to_be16(uint16_to_packed_bcd(copies)); + struct kodak6800_hdr hdr; + memcpy(&hdr, &job->hdr, sizeof(hdr)); /* Validate against supported media list */ for (num = 0 ; num < ctx->media->count; num++) { - if (ctx->media->sizes[num].height == ctx->hdr.rows && - ctx->media->sizes[num].width == ctx->hdr.columns && + if (ctx->media->sizes[num].height == hdr.rows && + ctx->media->sizes[num].width == hdr.columns && ctx->media->sizes[num].code2 == 0x00) // XXX code2? break; } @@ -1136,22 +1165,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) { @@ -1189,20 +1211,20 @@ static int kodak6800_main_loop(void *vctx, int copies) { return ret; } - ctx->hdr.jobid = ctx->jobid; + hdr.jobid = ctx->jobid; #if 0 /* If we want to disable 4x6 rewind on 8x6 media.. */ // XXX not sure about this...? - if (ctx->hdr.size == 0x00 && + if (hdr.size == 0x00 && be16_to_cpu(ctx->media->sizes[0].width) == 0x0982) { - ctx->hdr.size = 0x06; - ctx->hdr.mode = 0x01; + hdr.size = 0x06; + hdr.mode = 0x01; } #endif INFO("Sending Print Job (internal id %u)\n", ctx->jobid); - if ((ret = kodak6800_do_cmd(ctx, (uint8_t*) &ctx->hdr, sizeof(ctx->hdr), + if ((ret = kodak6800_do_cmd(ctx, (uint8_t*) &hdr, sizeof(hdr), &status, sizeof(status), &num))) return ret; @@ -1215,7 +1237,7 @@ static int kodak6800_main_loop(void *vctx, int copies) { // sleep(1); // Appears to be necessary for reliability INFO("Sending image data\n"); if ((send_data(ctx->dev, ctx->endp_down, - ctx->databuf, ctx->datalen)) != 0) + job->databuf, job->datalen)) != 0) return CUPS_BACKEND_FAILED; INFO("Waiting for printer to acknowledge completion\n"); @@ -1224,9 +1246,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) { @@ -1237,9 +1259,9 @@ static int kodak6800_main_loop(void *vctx, int copies) { } /* If all prints are complete, we're done! */ - if (status.b1_jobid == ctx->hdr.jobid && status.b1_complete == status.b1_total) + if (status.b1_jobid == hdr.jobid && status.b1_complete == status.b1_total) break; - if (status.b2_jobid == ctx->hdr.jobid && status.b2_complete == status.b2_total) + if (status.b2_jobid == hdr.jobid && status.b2_complete == status.b2_total) break; if (fast_return) { @@ -1254,23 +1276,50 @@ 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", // Family driver, do not nuke. + "kodak-6800", "kodak-6850", + // Backwards-compatibility + "kodak6800", "kodak6850", + NULL +}; + /* Exported */ struct dyesub_backend kodak6800_backend = { .name = "Kodak 6800/6850", - .version = "0.58", - .uri_prefix = "kodak6800", + .version = "0.65", + .uri_prefixes = kodak6800_prefixes, .cmdline_usage = kodak6800_cmdline, .cmdline_arg = kodak6800_cmdline_arg, .init = kodak6800_init, .attach = kodak6800_attach, .teardown = kodak6800_teardown, + .cleanup_job = kodak6800_cleanup_job, .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"}, - { USB_VID_KODAK, USB_PID_KODAK_6850, P_KODAK_6850, "Kodak"}, - { 0, 0, 0, ""} + { USB_VID_KODAK, USB_PID_KODAK_6800, P_KODAK_6800, "Kodak", "kodak-6800"}, + { USB_VID_KODAK, USB_PID_KODAK_6850, P_KODAK_6850, "Kodak", "kodak-6850"}, + { 0, 0, 0, NULL, NULL} } }; |