s2145: Migrate to new unified backend.

UNTESTED.
This commit is contained in:
Solomon Peachy 2013-07-18 22:10:56 -04:00
parent bf1f12476b
commit 060b6763fb
8 changed files with 217 additions and 321 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ sonyupdr150
kodak6800 kodak6800
kodak1400 kodak1400
gutenprint gutenprint
shinkos2145
canonselphy

View File

@ -3,20 +3,26 @@ LDFLAGS = -lusb-1.0
CUPS_BACKEND_DIR = /usr/lib/cups/backend CUPS_BACKEND_DIR = /usr/lib/cups/backend
DEPS = backend_common.h DEPS = backend_common.h
SOURCES = sony_updr150_print.c kodak6800_print.c backend_common.c kodak1400_print.c SOURCES = sony_updr150_print.c kodak6800_print.c backend_common.c kodak1400_print.c shinko_s2145_print.c
all: gutenprint sonyupdr150 kodak6800 kodak1400 all: gutenprint sonyupdr150 kodak6800 kodak1400 shinkos2145 canonselphy
gutenprint: $(SOURCES) $(DEPS) gutenprint: $(SOURCES) $(DEPS)
gcc -o $@ $(SOURCES) $(LDFLAGS) $(CFLAGS) gcc -o $@ $(SOURCES) $(LDFLAGS) $(CFLAGS)
sonyupdr150: sonyupdr150: gutenprint
ln -s gutenprint $@ ln -s gutenprint $@
kodak6800: kodak6800: gutenprint
ln -s gutenprint $@ ln -s gutenprint $@
kodak1400: kodak1400: gutenprint
ln -s gutenprint $@
shinkos2145: gutenprint
ln -s gutenprint $@
canonselphy: gutenprint
ln -s gutenprint $@ ln -s gutenprint $@

View File

@ -27,7 +27,7 @@
#include "backend_common.h" #include "backend_common.h"
#define BACKEND_VERSION "0.08" #define BACKEND_VERSION "0.09"
#ifndef URI_PREFIX #ifndef URI_PREFIX
#define URI_PREFIX "gutenprint+usb" #define URI_PREFIX "gutenprint+usb"
#endif #endif
@ -348,6 +348,7 @@ static struct dyesub_backend *backends[] = {
&updr150_backend, &updr150_backend,
&kodak6800_backend, &kodak6800_backend,
&kodak1400_backend, &kodak1400_backend,
&shinkos2145_backend,
NULL, NULL,
}; };
@ -393,6 +394,8 @@ int main (int argc, char **argv)
int iface = 0; int iface = 0;
int found = -1; int found = -1;
int copies = 1; int copies = 1;
int jobid = 0;
char *uri = getenv("DEVICE_URI"); char *uri = getenv("DEVICE_URI");
char *use_serno = NULL; char *use_serno = NULL;
int query_only = 0; int query_only = 0;
@ -450,6 +453,8 @@ int main (int argc, char **argv)
/* Are we running as a CUPS backend? */ /* Are we running as a CUPS backend? */
if (uri) { if (uri) {
if (argv[1])
jobid = atoi(argv[1]);
if (argv[4]) if (argv[4])
copies = atoi(argv[4]); copies = atoi(argv[4]);
if (argv[6]) { /* IOW, is it specified? */ if (argv[6]) { /* IOW, is it specified? */
@ -517,6 +522,9 @@ int main (int argc, char **argv)
query_only = 1; query_only = 1;
} }
srand(getpid());
jobid = rand();
/* Open Input File */ /* Open Input File */
if (strcmp("-", argv[1])) { if (strcmp("-", argv[1])) {
data_fd = open(argv[1], O_RDONLY); data_fd = open(argv[1], O_RDONLY);
@ -582,7 +590,7 @@ int main (int argc, char **argv)
} }
/* Initialize backend */ /* Initialize backend */
backend_ctx = backend->init(dev, endp_up, endp_down); backend_ctx = backend->init(dev, endp_up, endp_down, jobid);
if (query_only) { if (query_only) {
backend->cmdline_arg(backend_ctx, 1, argv[1], argv[2]); backend->cmdline_arg(backend_ctx, 1, argv[1], argv[2]);

View File

@ -85,7 +85,7 @@ struct dyesub_backend {
char *uri_prefix; char *uri_prefix;
void (*cmdline_usage)(char *caller); void (*cmdline_usage)(char *caller);
void *(*init)(struct libusb_device_handle *dev, void *(*init)(struct libusb_device_handle *dev,
uint8_t endp_up, uint8_t endp_down); uint8_t endp_up, uint8_t endp_down, uint8_t jobid);
void (*teardown)(void *ctx); void (*teardown)(void *ctx);
int (*cmdline_arg)(void *ctx, int run, char *arg1, char *arg2); int (*cmdline_arg)(void *ctx, int run, char *arg1, char *arg2);
int (*read_parse)(void *ctx, int data_fd); int (*read_parse)(void *ctx, int data_fd);
@ -126,5 +126,6 @@ extern int terminate;
extern struct dyesub_backend updr150_backend; extern struct dyesub_backend updr150_backend;
extern struct dyesub_backend kodak6800_backend; extern struct dyesub_backend kodak6800_backend;
extern struct dyesub_backend kodak1400_backend; extern struct dyesub_backend kodak1400_backend;
extern struct dyesub_backend shinkos2145_backend;
#endif /* __BACKEND_COMMON_H */ #endif /* __BACKEND_COMMON_H */

View File

@ -255,7 +255,7 @@ int kodak1400_cmdline_arg(void *vctx, int run, char *arg1, char *arg2)
} }
static void *kodak1400_init(struct libusb_device_handle *dev, static void *kodak1400_init(struct libusb_device_handle *dev,
uint8_t endp_up, uint8_t endp_down) uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{ {
struct kodak1400_ctx *ctx = malloc(sizeof(struct kodak1400_ctx)); struct kodak1400_ctx *ctx = malloc(sizeof(struct kodak1400_ctx));
if (!ctx) if (!ctx)

View File

@ -292,7 +292,7 @@ int kodak6800_cmdline_arg(void *vctx, int run, char *arg1, char *arg2)
static void *kodak6800_init(struct libusb_device_handle *dev, static void *kodak6800_init(struct libusb_device_handle *dev,
uint8_t endp_up, uint8_t endp_down) uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{ {
struct kodak6800_ctx *ctx = malloc(sizeof(struct kodak6800_ctx)); struct kodak6800_ctx *ctx = malloc(sizeof(struct kodak6800_ctx));
if (!ctx) if (!ctx)

View File

@ -39,10 +39,8 @@
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#define VERSION "0.16" #include "backend_common.h"
#define URI_PREFIX "shinkos2145://"
#include "backend_common.c"
enum { enum {
S_IDLE = 0, S_IDLE = 0,
@ -91,6 +89,19 @@ struct s2145_printjob_hdr {
uint32_t unk21; uint32_t unk21;
} __attribute__((packed)); } __attribute__((packed));
/* Private data stucture */
struct shinkos2145_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
uint8_t jobid;
struct s2145_printjob_hdr hdr;
uint8_t *databuf;
int datalen;
};
/* Structs for printer */ /* Structs for printer */
struct s2145_cmd_hdr { struct s2145_cmd_hdr {
uint16_t cmd; uint16_t cmd;
@ -192,6 +203,7 @@ static char *print_medias (uint8_t v) {
#define PRINT_MODE_STD_EGLOSSY 0x06 #define PRINT_MODE_STD_EGLOSSY 0x06
#define PRINT_MODE_FINE_EGLOSSY 0x07 #define PRINT_MODE_FINE_EGLOSSY 0x07
#if 0
static char *print_modes(uint8_t v) { static char *print_modes(uint8_t v) {
switch (v) { switch (v) {
case PRINT_MODE_DEFAULT: case PRINT_MODE_DEFAULT:
@ -212,6 +224,7 @@ static char *print_modes(uint8_t v) {
return "Unknown"; return "Unknown";
} }
} }
#endif
#define PRINT_METHOD_STD 0x00 #define PRINT_METHOD_STD 0x00
#define PRINT_METHOD_4x6_2UP 0x02 #define PRINT_METHOD_4x6_2UP 0x02
@ -620,8 +633,7 @@ static int s2145_do_cmd(libusb_device_handle *dev,
return ret; return ret;
} }
static int get_status(libusb_device_handle *dev, static int get_status(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cmd_hdr cmd; struct s2145_cmd_hdr cmd;
struct s2145_status_resp *resp = (struct s2145_status_resp *) rdbuf; struct s2145_status_resp *resp = (struct s2145_status_resp *) rdbuf;
@ -630,7 +642,7 @@ static int get_status(libusb_device_handle *dev,
cmd.cmd = cpu_to_le16(S2145_CMD_STATUS); cmd.cmd = cpu_to_le16(S2145_CMD_STATUS);
cmd.len = cpu_to_le16(0); cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -670,8 +682,7 @@ static int get_status(libusb_device_handle *dev,
return 0; return 0;
} }
static int get_fwinfo(libusb_device_handle *dev, static int get_fwinfo(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_fwinfo_cmd cmd; struct s2145_fwinfo_cmd cmd;
struct s2145_fwinfo_resp *resp = (struct s2145_fwinfo_resp *)rdbuf; struct s2145_fwinfo_resp *resp = (struct s2145_fwinfo_resp *)rdbuf;
@ -686,7 +697,7 @@ static int get_fwinfo(libusb_device_handle *dev,
for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_TABLES ; i++) { for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_TABLES ; i++) {
cmd.target = i; cmd.target = i;
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -710,8 +721,7 @@ static int get_fwinfo(libusb_device_handle *dev,
return 0; return 0;
} }
static int get_errorlog(libusb_device_handle *dev, static int get_errorlog(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cmd_hdr cmd; struct s2145_cmd_hdr cmd;
struct s2145_errorlog_resp *resp = (struct s2145_errorlog_resp *) rdbuf; struct s2145_errorlog_resp *resp = (struct s2145_errorlog_resp *) rdbuf;
@ -721,7 +731,7 @@ static int get_errorlog(libusb_device_handle *dev,
cmd.cmd = cpu_to_le16(S2145_CMD_ERRORLOG); cmd.cmd = cpu_to_le16(S2145_CMD_ERRORLOG);
cmd.len = cpu_to_le16(0); cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -741,8 +751,7 @@ static int get_errorlog(libusb_device_handle *dev,
return 0; return 0;
} }
static int get_mediainfo(libusb_device_handle *dev, static int get_mediainfo(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cmd_hdr cmd; struct s2145_cmd_hdr cmd;
struct s2145_mediainfo_resp *resp = (struct s2145_mediainfo_resp *) rdbuf; struct s2145_mediainfo_resp *resp = (struct s2145_mediainfo_resp *) rdbuf;
@ -752,7 +761,7 @@ static int get_mediainfo(libusb_device_handle *dev,
cmd.cmd = cpu_to_le16(S2145_CMD_MEDIAINFO); cmd.cmd = cpu_to_le16(S2145_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0); cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -775,8 +784,7 @@ static int get_mediainfo(libusb_device_handle *dev,
return 0; return 0;
} }
static int get_user_string(libusb_device_handle *dev, static int get_user_string(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cmd_hdr cmd; struct s2145_cmd_hdr cmd;
struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf; struct s2145_getunique_resp *resp = (struct s2145_getunique_resp*) rdbuf;
@ -785,7 +793,7 @@ static int get_user_string(libusb_device_handle *dev,
cmd.cmd = cpu_to_le16(S2145_CMD_GETUNIQUE); cmd.cmd = cpu_to_le16(S2145_CMD_GETUNIQUE);
cmd.len = cpu_to_le16(0); cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp) - 1, sizeof(*resp) - 1,
&num)) < 0) { &num)) < 0) {
@ -802,8 +810,7 @@ static int get_user_string(libusb_device_handle *dev,
return 0; return 0;
} }
static int set_user_string(char *str, libusb_device_handle *dev, static int set_user_string(struct shinkos2145_ctx *ctx, char *str)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_setunique_cmd cmd; struct s2145_setunique_cmd cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -822,7 +829,7 @@ static int set_user_string(char *str, libusb_device_handle *dev,
cmd.hdr.cmd = cpu_to_le16(S2145_CMD_SETUNIQUE); cmd.hdr.cmd = cpu_to_le16(S2145_CMD_SETUNIQUE);
cmd.hdr.len = cpu_to_le16(cmd.len + 1); cmd.hdr.len = cpu_to_le16(cmd.len + 1);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, cmd.len + 1 + sizeof(cmd.hdr), (uint8_t*)&cmd, cmd.len + 1 + sizeof(cmd.hdr),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -833,8 +840,7 @@ static int set_user_string(char *str, libusb_device_handle *dev,
return 0; return 0;
} }
static int cancel_job(char *str, libusb_device_handle *dev, static int cancel_job(struct shinkos2145_ctx *ctx, char *str)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cancel_cmd cmd; struct s2145_cancel_cmd cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -848,7 +854,7 @@ static int cancel_job(char *str, libusb_device_handle *dev,
cmd.hdr.cmd = cpu_to_le16(S2145_CMD_CANCELJOB); cmd.hdr.cmd = cpu_to_le16(S2145_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1); cmd.hdr.len = cpu_to_le16(1);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -859,8 +865,7 @@ static int cancel_job(char *str, libusb_device_handle *dev,
return 0; return 0;
} }
static int flash_led(libusb_device_handle *dev, static int flash_led(struct shinkos2145_ctx *ctx)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_cmd_hdr cmd; struct s2145_cmd_hdr cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -869,7 +874,7 @@ static int flash_led(libusb_device_handle *dev,
cmd.cmd = cpu_to_le16(S2145_CMD_FLASHLED); cmd.cmd = cpu_to_le16(S2145_CMD_FLASHLED);
cmd.len = cpu_to_le16(0); cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -880,8 +885,7 @@ static int flash_led(libusb_device_handle *dev,
return 0; return 0;
} }
static int reset_curve(int target, libusb_device_handle *dev, static int reset_curve(struct shinkos2145_ctx *ctx, int target)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_reset_cmd cmd; struct s2145_reset_cmd cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -892,7 +896,7 @@ static int reset_curve(int target, libusb_device_handle *dev,
cmd.hdr.cmd = cpu_to_le16(S2145_CMD_RESET); cmd.hdr.cmd = cpu_to_le16(S2145_CMD_RESET);
cmd.hdr.len = cpu_to_le16(1); cmd.hdr.len = cpu_to_le16(1);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -903,8 +907,7 @@ static int reset_curve(int target, libusb_device_handle *dev,
return 0; return 0;
} }
static int button_set(int enable, libusb_device_handle *dev, static int button_set(struct shinkos2145_ctx *ctx, int enable)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_button_cmd cmd; struct s2145_button_cmd cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -915,7 +918,7 @@ static int button_set(int enable, libusb_device_handle *dev,
cmd.enabled = enable; cmd.enabled = enable;
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -926,8 +929,7 @@ static int button_set(int enable, libusb_device_handle *dev,
return 0; return 0;
} }
static int get_tonecurve(int type, char *fname, libusb_device_handle *dev, static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_readtone_cmd cmd; struct s2145_readtone_cmd cmd;
struct s2145_readtone_resp *resp = (struct s2145_readtone_resp *) rdbuf; struct s2145_readtone_resp *resp = (struct s2145_readtone_resp *) rdbuf;
@ -945,7 +947,7 @@ static int get_tonecurve(int type, char *fname, libusb_device_handle *dev,
INFO("Dump %s Tone Curve to '%s'\n", tonecurve_statuses(type), fname); INFO("Dump %s Tone Curve to '%s'\n", tonecurve_statuses(type), fname);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -959,14 +961,14 @@ static int get_tonecurve(int type, char *fname, libusb_device_handle *dev,
i = 0; i = 0;
while (i < resp->total_size) { while (i < resp->total_size) {
ret = libusb_bulk_transfer(dev, endp_up, ret = libusb_bulk_transfer(ctx->dev, ctx->endp_up,
data + i, data + i,
resp->total_size * 2 - i, resp->total_size * 2 - i,
&num, &num,
5000); 5000);
if (ret < 0) { if (ret < 0) {
ERROR("Failure to receive data from printer (libusb error %d: (%d/%d from 0x%02x))\n", ret, num + i, (int)resp->total_size, endp_up); ERROR("Failure to receive data from printer (libusb error %d: (%d/%d from 0x%02x))\n", ret, num + i, (int)resp->total_size, ctx->endp_up);
return ret; return ret;
} }
i += num; i += num;
@ -997,8 +999,7 @@ static int get_tonecurve(int type, char *fname, libusb_device_handle *dev,
return 0; return 0;
} }
static int set_tonecurve(int target, char *fname, libusb_device_handle *dev, static int set_tonecurve(struct shinkos2145_ctx *ctx, int target, char *fname)
uint8_t endp_down, uint8_t endp_up)
{ {
struct s2145_update_cmd cmd; struct s2145_update_cmd cmd;
struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf;
@ -1033,7 +1034,7 @@ static int set_tonecurve(int target, char *fname, libusb_device_handle *dev,
data[ret] = cpu_to_le16(data[ret]); data[ret] = cpu_to_le16(data[ret]);
} }
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd), (uint8_t*)&cmd, sizeof(cmd),
sizeof(*resp), sizeof(*resp),
&num)) < 0) { &num)) < 0) {
@ -1042,7 +1043,7 @@ static int set_tonecurve(int target, char *fname, libusb_device_handle *dev,
} }
/* Sent transfer */ /* Sent transfer */
if ((ret = send_data(dev, endp_down, if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t *) data, UPDATE_SIZE))) { (uint8_t *) data, UPDATE_SIZE))) {
return ret; return ret;
} }
@ -1052,168 +1053,131 @@ static int set_tonecurve(int target, char *fname, libusb_device_handle *dev,
return 0; return 0;
} }
static void shinkos2145_cmdline(char *caller)
int main (int argc, char **argv)
{ {
struct libusb_context *ctx; DEBUG("\t\t%s [ -qs | -qm | -qf | -qe | -qu ]\n", caller);
struct libusb_device **list; DEBUG("\t\t%s [ -qtu filename | -qtc filename ]\n", caller);
struct libusb_device_handle *dev; DEBUG("\t\t%s [ -su somestring | -stu filename | -stc filename ]\n", caller);
struct libusb_config_descriptor *config; DEBUG("\t\t%s [ -pc id | -fl | -ru | -rp | -b1 | -b0 ]\n", caller);
}
uint8_t endp_up = 0; int shinkos2145_cmdline_arg(void *vctx, int run, char *arg1, char *arg2)
uint8_t endp_down = 0; {
struct shinkos2145_ctx *ctx = vctx;
int data_fd = fileno(stdin); if (!run || !ctx)
return (!strcmp("-qs", arg1) ||
!strcmp("-qf", arg1) ||
!strcmp("-qe", arg1) ||
!strcmp("-qm", arg1) ||
!strcmp("-qu", arg1) ||
!strcmp("-qtc", arg1) ||
!strcmp("-qtu", arg1) ||
!strcmp("-pc", arg1) ||
!strcmp("-fl", arg1) ||
!strcmp("-ru", arg1) ||
!strcmp("-rp", arg1) ||
!strcmp("-b1", arg1) ||
!strcmp("-b0", arg1) ||
!strcmp("-stc", arg1) ||
!strcmp("-stu", arg1) ||
!strcmp("-su", arg1));
int i, num; if (!strcmp("-qs", arg1))
int claimed; get_status(ctx);
else if (!strcmp("-qf", arg1))
get_fwinfo(ctx);
else if (!strcmp("-qe", arg1))
get_errorlog(ctx);
else if (!strcmp("-qm", arg1))
get_mediainfo(ctx);
else if (!strcmp("-qu", arg1))
get_user_string(ctx);
else if (!strcmp("-qtu", arg1))
get_tonecurve(ctx, TONECURVE_USER, arg2);
else if (!strcmp("-qtc", arg1))
get_tonecurve(ctx, TONECURVE_CURRENT, arg2);
else if (!strcmp("-su", arg1))
set_user_string(ctx, arg2);
else if (!strcmp("-stu", arg1))
set_tonecurve(ctx, UPDATE_TARGET_USER, arg2);
else if (!strcmp("-stc", arg1))
set_tonecurve(ctx, UPDATE_TARGET_CURRENT, arg2);
else if (!strcmp("-pc", arg1))
cancel_job(ctx, arg2);
else if (!strcmp("-fl", arg1))
flash_led(ctx);
else if (!strcmp("-ru", arg1))
reset_curve(ctx, RESET_USER_CURVE);
else if (!strcmp("-rp", arg1))
reset_curve(ctx, RESET_PRINTER);
else if (!strcmp("-b1", arg1))
button_set(ctx, BUTTON_ENABLED);
else if (!strcmp("-b0", arg1))
button_set(ctx, BUTTON_DISABLED);
int query_only = 0; return -1;
int ret = 0; }
int iface = 0;
int found = -1;
int copies = 1;
int jobid = 0;
char *uri = getenv("DEVICE_URI");;
char *use_serno = NULL;
struct s2145_printjob_hdr hdr; static void *shinkos2145_init(struct libusb_device_handle *dev,
struct s2145_cmd_hdr *cmd; uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
struct s2145_print_cmd *print; {
struct s2145_status_resp *sts; struct shinkos2145_ctx *ctx = malloc(sizeof(struct shinkos2145_ctx));
if (!ctx)
uint8_t *planedata = NULL, *cmdbuf = NULL; return NULL;
uint32_t datasize; memset(ctx, 0, sizeof(struct shinkos2145_ctx));
uint8_t rdbuf2[READBACK_LEN]; ctx->endp_up = endp_up;
int last_state = -1, state = S_IDLE; ctx->endp_down = endp_down;
DEBUG("Shinko/Sinfonia CHC-S2145 CUPS backend version " VERSION "/" BACKEND_VERSION " \n");
/* Cmdline help */
if (argc < 2) {
DEBUG("Usage:\n\t%s [ infile | - ]\n\t%s job user title num-copies options [ filename ]\n\t%s [ -qs | -qm | -qf | -qe | -qu | -qtu filename | -qtc filename ]\n\t%s [ -su somestring | -stu filename | -stc filename ]\n\t%s [ -pc id | -fl | -ru | -rp | -b1 | -b0 ]\n\n",
argv[0], argv[0], argv[0], argv[0], argv[0]);
libusb_init(&ctx);
find_and_enumerate(ctx, &list, NULL, P_SHINKO_S2145, 1);
libusb_free_device_list(list, 1);
libusb_exit(ctx);
exit(1);
}
/* Are we running as a CUPS backend? */
if (uri) {
if (argv[1])
jobid = atoi(argv[1]);
if (argv[4])
copies = atoi(argv[4]);
if (argv[6]) { /* IOW, is it specified? */
data_fd = open(argv[6], O_RDONLY);
if (data_fd < 0) {
perror("ERROR:Can't open input file");
exit(1);
}
}
/* Ensure we're using BLOCKING I/O */
i = fcntl(data_fd, F_GETFL, 0);
if (i < 0) {
perror("ERROR:Can't open input");
exit(1);
}
i &= ~O_NONBLOCK;
i = fcntl(data_fd, F_SETFL, 0);
if (i < 0) {
perror("ERROR:Can't open input");
exit(1);
}
/* Start parsing URI 'selphy://PID/SERIAL' */
if (strncmp(URI_PREFIX, uri, strlen(URI_PREFIX))) {
ERROR("Invalid URI prefix (%s)\n", uri);
exit(1);
}
use_serno = strchr(uri, '=');
if (!use_serno || !*(use_serno+1)) {
ERROR("Invalid URI (%s)\n", uri);
exit(1);
}
use_serno++;
} else {
use_serno = getenv("DEVICE");
if (!strcmp("-qs", argv[1]) ||
!strcmp("-qf", argv[1]) ||
!strcmp("-qe", argv[1]) ||
!strcmp("-qm", argv[1]) ||
!strcmp("-qu", argv[1]) ||
!strcmp("-qtc", argv[1]) ||
!strcmp("-qtu", argv[1]) ||
!strcmp("-pc", argv[1]) ||
!strcmp("-fl", argv[1]) ||
!strcmp("-ru", argv[1]) ||
!strcmp("-rp", argv[1]) ||
!strcmp("-b1", argv[1]) ||
!strcmp("-b0", argv[1]) ||
!strcmp("-stc", argv[1]) ||
!strcmp("-stu", argv[1]) ||
!strcmp("-su", argv[1])) {
query_only = 1;
goto skip_read;
}
srand(getpid());
jobid = rand();
/* Open Input File */
if (strcmp("-", argv[1])) {
data_fd = open(argv[1], O_RDONLY);
if (data_fd < 0) {
perror("ERROR:Can't open input file");
exit(1);
}
}
}
/* Ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
signal(SIGTERM, sigterm_handler);
/* Ensure jobid is sane */ /* Ensure jobid is sane */
jobid = (jobid & 0x7f) + 1; ctx->jobid = (jobid & 0x7f) + 1;
return ctx;
}
static void shinkos2145_teardown(void *vctx) {
struct shinkos2145_ctx *ctx = vctx;
if (!ctx)
return;
free(ctx);
}
static int shinkos2145_read_parse(void *vctx, int data_fd) {
struct shinkos2145_ctx *ctx = vctx;
int ret;
uint8_t tmpbuf[4];
if (!ctx)
return 1;
/* Read in then validate header */ /* Read in then validate header */
read(data_fd, &hdr, sizeof(hdr)); read(data_fd, &ctx->hdr, sizeof(ctx->hdr));
if (le32_to_cpu(hdr.len1) != 0x10 || if (le32_to_cpu(ctx->hdr.len1) != 0x10 ||
le32_to_cpu(hdr.model) != 2145 || le32_to_cpu(ctx->hdr.model) != 2145 ||
le32_to_cpu(hdr.len2) != 0x64 || le32_to_cpu(ctx->hdr.len2) != 0x64 ||
le32_to_cpu(hdr.dpi) != 300) { le32_to_cpu(ctx->hdr.dpi) != 300) {
ERROR("Unrecognized header data format!\n"); ERROR("Unrecognized header data format!\n");
exit(1); exit(1);
} }
/* Read in image data */ ctx->datalen = le32_to_cpu(ctx->hdr.rows) * le32_to_cpu(ctx->hdr.columns) * 3;
cmdbuf = malloc(CMDBUF_LEN); ctx->databuf = malloc(ctx->datalen);
cmd = (struct s2145_cmd_hdr *) cmdbuf; if (!ctx->databuf) {
print = (struct s2145_print_cmd *) cmdbuf;
sts = (struct s2145_status_resp *) rdbuf;
datasize = le32_to_cpu(hdr.rows) * le32_to_cpu(hdr.columns) * 3;
planedata = malloc(datasize);
if (!cmdbuf || !planedata) {
ERROR("Memory allocation failure!\n"); ERROR("Memory allocation failure!\n");
exit(1); exit(1);
} }
{ {
int remain; int remain = ctx->datalen;
uint8_t *ptr = planedata; uint8_t *ptr = ctx->databuf;
remain = datasize;
do { do {
ret = read(data_fd, ptr, remain); ret = read(data_fd, ptr, remain);
if (ret < 0) { if (ret < 0) {
ERROR("Read failed (%d/%d/%d)\n", ERROR("Read failed (%d/%d/%d)\n",
ret, remain, datasize); ret, remain, ctx->datalen);
perror("ERROR: Read failed"); perror("ERROR: Read failed");
exit(1); exit(1);
} }
@ -1223,112 +1187,37 @@ int main (int argc, char **argv)
} }
/* Make sure footer is sane too */ /* Make sure footer is sane too */
ret = read(data_fd, cmdbuf, 4); ret = read(data_fd, tmpbuf, 4);
if (ret < 0 || ret != 4) { if (ret < 0 || ret != 4) {
ERROR("Read failed (%d/%d/%d)\n", ERROR("Read failed (%d/%d/%d)\n",
ret, 4, 4); ret, 4, 4);
perror("ERROR: Read failed"); perror("ERROR: Read failed");
exit(1); exit(1);
} }
if (cmdbuf[0] != 0x04 || if (tmpbuf[0] != 0x04 ||
cmdbuf[1] != 0x03 || tmpbuf[1] != 0x03 ||
cmdbuf[2] != 0x02 || tmpbuf[2] != 0x02 ||
cmdbuf[3] != 0x01) { tmpbuf[3] != 0x01) {
ERROR("Unrecognized footer data format!\n"); ERROR("Unrecognized footer data format!\n");
exit(1); exit(1);
} }
close(data_fd); /* We're done reading! */ return 0;
}
skip_read: static int shinkos2145_main_loop(void *vctx, int copies) {
/* Libusb setup */ struct shinkos2145_ctx *ctx = vctx;
libusb_init(&ctx);
found = find_and_enumerate(ctx, &list, use_serno, P_SHINKO_S2145, 0);
if (found == -1) { int i, ret, num;
ERROR("Printer open failure (No suitable printers found!)\n"); uint8_t cmdbuf[CMDBUF_LEN];
ret = 3; uint8_t rdbuf2[READBACK_LEN];
goto done;
}
ret = libusb_open(list[found], &dev); int last_state = -1, state = S_IDLE;
if (ret) {
ERROR("Printer open failure (Need to be root?) (%d)\n", ret);
ret = 4;
goto done;
}
claimed = libusb_kernel_driver_active(dev, iface);
if (claimed) {
ret = libusb_detach_kernel_driver(dev, iface);
if (ret) {
ERROR("Printer open failure (Could not detach printer from kernel)\n");
ret = 4;
goto done_close;
}
}
ret = libusb_claim_interface(dev, iface); struct s2145_cmd_hdr *cmd = (struct s2145_cmd_hdr *) cmdbuf;;
if (ret) { struct s2145_print_cmd *print = (struct s2145_print_cmd *) cmdbuf;
ERROR("Printer open failure (Could not claim printer interface)\n"); struct s2145_status_resp *sts = (struct s2145_status_resp *) rdbuf;
ret = 4;
goto done_close;
}
ret = libusb_get_active_config_descriptor(list[found], &config);
if (ret) {
ERROR("Printer open failure (Could not fetch config descriptor)\n");
ret = 4;
goto done_close;
}
for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) {
if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_BULK) {
if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN)
endp_up = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress;
else
endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress;
}
}
if (query_only) {
if (!strcmp("-qs", argv[1]))
get_status(dev, endp_down, endp_up);
else if (!strcmp("-qf", argv[1]))
get_fwinfo(dev, endp_down, endp_up);
else if (!strcmp("-qe", argv[1]))
get_errorlog(dev, endp_down, endp_up);
else if (!strcmp("-qm", argv[1]))
get_mediainfo(dev, endp_down, endp_up);
else if (!strcmp("-qu", argv[1]))
get_user_string(dev, endp_down, endp_up);
else if (!strcmp("-qtu", argv[1]))
get_tonecurve(TONECURVE_USER, argv[2], dev, endp_down, endp_up);
else if (!strcmp("-qtc", argv[1]))
get_tonecurve(TONECURVE_CURRENT, argv[2], dev, endp_down, endp_up);
else if (!strcmp("-su", argv[1]))
set_user_string(argv[2], dev, endp_down, endp_up);
else if (!strcmp("-stu", argv[1]))
set_tonecurve(UPDATE_TARGET_USER, argv[2], dev, endp_down, endp_up);
else if (!strcmp("-stc", argv[1]))
set_tonecurve(UPDATE_TARGET_CURRENT, argv[2], dev, endp_down, endp_up);
else if (!strcmp("-pc", argv[1]))
cancel_job(argv[2], dev, endp_down, endp_up);
else if (!strcmp("-fl", argv[1]))
flash_led(dev, endp_down, endp_up);
else if (!strcmp("-ru", argv[1]))
reset_curve(RESET_USER_CURVE, dev, endp_down, endp_up);
else if (!strcmp("-rp", argv[1]))
reset_curve(RESET_PRINTER, dev, endp_down, endp_up);
else if (!strcmp("-b1", argv[1]))
button_set(BUTTON_ENABLED, dev, endp_down, endp_up);
else if (!strcmp("-b0", argv[1]))
button_set(BUTTON_DISABLED, dev, endp_down, endp_up);
goto done_claimed;
}
/* Time for the main processing loop */
top: top:
if (state != last_state) { if (state != last_state) {
DEBUG("last_state %d new %d\n", last_state, state); DEBUG("last_state %d new %d\n", last_state, state);
@ -1339,12 +1228,12 @@ top:
cmd->cmd = cpu_to_le16(S2145_CMD_STATUS); cmd->cmd = cpu_to_le16(S2145_CMD_STATUS);
cmd->len = cpu_to_le16(0); cmd->len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
cmdbuf, sizeof(*cmd), cmdbuf, sizeof(*cmd),
sizeof(struct s2145_status_hdr), sizeof(struct s2145_status_hdr),
&num)) < 0) { &num)) < 0) {
ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd));
goto done_claimed; return ret;
} }
if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) {
@ -1384,25 +1273,25 @@ top:
break; break;
case S_PRINTER_READY_CMD: case S_PRINTER_READY_CMD:
INFO("Initiating print job (internal id %d)\n", jobid); INFO("Initiating print job (internal id %d)\n", ctx->jobid);
memset(cmdbuf, 0, CMDBUF_LEN); memset(cmdbuf, 0, CMDBUF_LEN);
print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB); print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB);
print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd)); print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd));
print->id = jobid; print->id = ctx->jobid;
print->count = cpu_to_le16(copies); print->count = cpu_to_le16(copies);
print->columns = cpu_to_le16(le32_to_cpu(hdr.columns)); print->columns = cpu_to_le16(le32_to_cpu(ctx->hdr.columns));
print->rows = cpu_to_le16(le32_to_cpu(hdr.rows)); print->rows = cpu_to_le16(le32_to_cpu(ctx->hdr.rows));
print->media = le32_to_cpu(hdr.media); print->media = le32_to_cpu(ctx->hdr.media);
print->mode = le32_to_cpu(hdr.mode); print->mode = le32_to_cpu(ctx->hdr.mode);
print->method = le32_to_cpu(hdr.method); print->method = le32_to_cpu(ctx->hdr.method);
if ((ret = s2145_do_cmd(dev, endp_up, endp_down, if ((ret = s2145_do_cmd(ctx->dev, ctx->endp_up, ctx->endp_down,
cmdbuf, sizeof(*print), cmdbuf, sizeof(*print),
sizeof(struct s2145_status_hdr), sizeof(struct s2145_status_hdr),
&num)) < 0) { &num)) < 0) {
ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd)); ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd));
goto done_claimed; return ret;
} }
if (sts->hdr.result != RESULT_SUCCESS) { if (sts->hdr.result != RESULT_SUCCESS) {
@ -1414,8 +1303,9 @@ top:
} }
INFO("Sending image data to printer\n"); INFO("Sending image data to printer\n");
if ((ret = send_data(dev, endp_down, planedata, datasize))) if ((ret = send_data(ctx->dev, ctx->endp_down,
goto done_claimed; ctx->databuf, ctx->datalen)))
return ret;
INFO("Waiting for printer to acknowledge completion\n"); INFO("Waiting for printer to acknowledge completion\n");
sleep(1); sleep(1);
@ -1449,10 +1339,7 @@ top:
goto top; goto top;
} }
/* Done printing */ return 0;
INFO("All printing done\n");
ret = 0;
goto done_claimed;
printer_error: printer_error:
ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x\n", ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x\n",
@ -1462,29 +1349,21 @@ printer_error:
status_str(sts->hdr.status), status_str(sts->hdr.status),
sts->hdr.printer_major, sts->hdr.printer_minor); sts->hdr.printer_major, sts->hdr.printer_minor);
// XXX write this. // XXX write this.
return 1;
done_claimed:
libusb_release_interface(dev, iface);
done_close:
#if 0
if (claimed)
libusb_attach_kernel_driver(dev, iface);
#endif
libusb_close(dev);
done:
if (planedata)
free(planedata);
if (cmdbuf)
free(cmdbuf);
libusb_free_device_list(list, 1);
libusb_exit(ctx);
return ret;
} }
/* Exported */
struct dyesub_backend shinkos2145_backend = {
.name = "Shinko/Sinfonia CHC-S2145",
.version = "0.17",
.uri_prefix = "shinkos2145",
.cmdline_usage = shinkos2145_cmdline,
.cmdline_arg = shinkos2145_cmdline_arg,
.init = shinkos2145_init,
.teardown = shinkos2145_teardown,
.read_parse = shinkos2145_read_parse,
.main_loop = shinkos2145_main_loop,
};
/* CHC-S2145 data format /* CHC-S2145 data format

View File

@ -48,7 +48,7 @@ struct updr150_ctx {
}; };
static void* updr150_init(struct libusb_device_handle *dev, static void* updr150_init(struct libusb_device_handle *dev,
uint8_t endp_up, uint8_t endp_down) uint8_t endp_up, uint8_t endp_down, uint8_t jobid)
{ {
struct updr150_ctx *ctx = malloc(sizeof(struct updr150_ctx)); struct updr150_ctx *ctx = malloc(sizeof(struct updr150_ctx));
if (!ctx) if (!ctx)