summaryrefslogtreecommitdiff
path: root/src/cups/backend_kodak6800.c
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2018-09-25 08:33:05 +0200
committerDidier Raboud <odyx@debian.org>2018-09-25 08:33:05 +0200
commite50542121e724e851fc5d6c68bb773f80c0bc12c (patch)
tree655c3f6331a6e8fd8b09ceb4da8f5896484ae16a /src/cups/backend_kodak6800.c
parent9dd97a029bf391c42b1dc76f2f7c5e386bb8f466 (diff)
New upstream version 5.3.1
Diffstat (limited to 'src/cups/backend_kodak6800.c')
-rw-r--r--src/cups/backend_kodak6800.c215
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}
}
};