diff --git a/.gitignore b/.gitignore index 96b79aa..37234fb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ sonyupdr150 kodak6800 kodak1400 gutenprint +shinkos2145 +canonselphy diff --git a/Makefile b/Makefile index 6e88be9..4e01f1c 100644 --- a/Makefile +++ b/Makefile @@ -3,20 +3,26 @@ LDFLAGS = -lusb-1.0 CUPS_BACKEND_DIR = /usr/lib/cups/backend 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) gcc -o $@ $(SOURCES) $(LDFLAGS) $(CFLAGS) -sonyupdr150: +sonyupdr150: gutenprint ln -s gutenprint $@ -kodak6800: +kodak6800: gutenprint ln -s gutenprint $@ -kodak1400: +kodak1400: gutenprint + ln -s gutenprint $@ + +shinkos2145: gutenprint + ln -s gutenprint $@ + +canonselphy: gutenprint ln -s gutenprint $@ diff --git a/backend_common.c b/backend_common.c index 77a98a5..bb1f03f 100644 --- a/backend_common.c +++ b/backend_common.c @@ -27,7 +27,7 @@ #include "backend_common.h" -#define BACKEND_VERSION "0.08" +#define BACKEND_VERSION "0.09" #ifndef URI_PREFIX #define URI_PREFIX "gutenprint+usb" #endif @@ -348,6 +348,7 @@ static struct dyesub_backend *backends[] = { &updr150_backend, &kodak6800_backend, &kodak1400_backend, + &shinkos2145_backend, NULL, }; @@ -393,6 +394,8 @@ int main (int argc, char **argv) int iface = 0; int found = -1; int copies = 1; + int jobid = 0; + char *uri = getenv("DEVICE_URI"); char *use_serno = NULL; int query_only = 0; @@ -450,6 +453,8 @@ int main (int argc, char **argv) /* 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? */ @@ -517,6 +522,9 @@ int main (int argc, char **argv) query_only = 1; } + srand(getpid()); + jobid = rand(); + /* Open Input File */ if (strcmp("-", argv[1])) { data_fd = open(argv[1], O_RDONLY); @@ -582,7 +590,7 @@ int main (int argc, char **argv) } /* Initialize backend */ - backend_ctx = backend->init(dev, endp_up, endp_down); + backend_ctx = backend->init(dev, endp_up, endp_down, jobid); if (query_only) { backend->cmdline_arg(backend_ctx, 1, argv[1], argv[2]); diff --git a/backend_common.h b/backend_common.h index 3e01e76..1ec1753 100644 --- a/backend_common.h +++ b/backend_common.h @@ -85,7 +85,7 @@ struct dyesub_backend { char *uri_prefix; void (*cmdline_usage)(char *caller); 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); int (*cmdline_arg)(void *ctx, int run, char *arg1, char *arg2); 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 kodak6800_backend; extern struct dyesub_backend kodak1400_backend; +extern struct dyesub_backend shinkos2145_backend; #endif /* __BACKEND_COMMON_H */ diff --git a/kodak1400_print.c b/kodak1400_print.c index 6f95e55..ab21f12 100644 --- a/kodak1400_print.c +++ b/kodak1400_print.c @@ -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, - 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)); if (!ctx) diff --git a/kodak6800_print.c b/kodak6800_print.c index 993cd84..8056957 100644 --- a/kodak6800_print.c +++ b/kodak6800_print.c @@ -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, - 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)); if (!ctx) diff --git a/shinko_s2145_print.c b/shinko_s2145_print.c index 90ff874..d9c5a55 100644 --- a/shinko_s2145_print.c +++ b/shinko_s2145_print.c @@ -39,10 +39,8 @@ #include #include -#define VERSION "0.16" -#define URI_PREFIX "shinkos2145://" +#include "backend_common.h" -#include "backend_common.c" enum { S_IDLE = 0, @@ -91,6 +89,19 @@ struct s2145_printjob_hdr { uint32_t unk21; } __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 */ struct s2145_cmd_hdr { uint16_t cmd; @@ -192,6 +203,7 @@ static char *print_medias (uint8_t v) { #define PRINT_MODE_STD_EGLOSSY 0x06 #define PRINT_MODE_FINE_EGLOSSY 0x07 +#if 0 static char *print_modes(uint8_t v) { switch (v) { case PRINT_MODE_DEFAULT: @@ -212,6 +224,7 @@ static char *print_modes(uint8_t v) { return "Unknown"; } } +#endif #define PRINT_METHOD_STD 0x00 #define PRINT_METHOD_4x6_2UP 0x02 @@ -620,8 +633,7 @@ static int s2145_do_cmd(libusb_device_handle *dev, return ret; } -static int get_status(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_status(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -670,8 +682,7 @@ static int get_status(libusb_device_handle *dev, return 0; } -static int get_fwinfo(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_fwinfo(struct shinkos2145_ctx *ctx) { struct s2145_fwinfo_cmd cmd; 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++) { 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), sizeof(*resp), &num)) < 0) { @@ -710,8 +721,7 @@ static int get_fwinfo(libusb_device_handle *dev, return 0; } -static int get_errorlog(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_errorlog(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -741,8 +751,7 @@ static int get_errorlog(libusb_device_handle *dev, return 0; } -static int get_mediainfo(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_mediainfo(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -775,8 +784,7 @@ static int get_mediainfo(libusb_device_handle *dev, return 0; } -static int get_user_string(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_user_string(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; 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.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), sizeof(*resp) - 1, &num)) < 0) { @@ -802,8 +810,7 @@ static int get_user_string(libusb_device_handle *dev, return 0; } -static int set_user_string(char *str, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int set_user_string(struct shinkos2145_ctx *ctx, char *str) { struct s2145_setunique_cmd cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -833,8 +840,7 @@ static int set_user_string(char *str, libusb_device_handle *dev, return 0; } -static int cancel_job(char *str, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int cancel_job(struct shinkos2145_ctx *ctx, char *str) { struct s2145_cancel_cmd cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -859,8 +865,7 @@ static int cancel_job(char *str, libusb_device_handle *dev, return 0; } -static int flash_led(libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int flash_led(struct shinkos2145_ctx *ctx) { struct s2145_cmd_hdr cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -880,8 +885,7 @@ static int flash_led(libusb_device_handle *dev, return 0; } -static int reset_curve(int target, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int reset_curve(struct shinkos2145_ctx *ctx, int target) { struct s2145_reset_cmd cmd; 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.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), sizeof(*resp), &num)) < 0) { @@ -903,8 +907,7 @@ static int reset_curve(int target, libusb_device_handle *dev, return 0; } -static int button_set(int enable, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int button_set(struct shinkos2145_ctx *ctx, int enable) { struct s2145_button_cmd cmd; 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; - 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), sizeof(*resp), &num)) < 0) { @@ -926,8 +929,7 @@ static int button_set(int enable, libusb_device_handle *dev, return 0; } -static int get_tonecurve(int type, char *fname, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname) { struct s2145_readtone_cmd cmd; 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); - 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), sizeof(*resp), &num)) < 0) { @@ -959,14 +961,14 @@ static int get_tonecurve(int type, char *fname, libusb_device_handle *dev, i = 0; while (i < resp->total_size) { - ret = libusb_bulk_transfer(dev, endp_up, + ret = libusb_bulk_transfer(ctx->dev, ctx->endp_up, data + i, resp->total_size * 2 - i, &num, 5000); 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; } i += num; @@ -997,8 +999,7 @@ static int get_tonecurve(int type, char *fname, libusb_device_handle *dev, return 0; } -static int set_tonecurve(int target, char *fname, libusb_device_handle *dev, - uint8_t endp_down, uint8_t endp_up) +static int set_tonecurve(struct shinkos2145_ctx *ctx, int target, char *fname) { struct s2145_update_cmd cmd; 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]); } - 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), sizeof(*resp), &num)) < 0) { @@ -1042,7 +1043,7 @@ static int set_tonecurve(int target, char *fname, libusb_device_handle *dev, } /* Sent transfer */ - if ((ret = send_data(dev, endp_down, + if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t *) data, UPDATE_SIZE))) { return ret; } @@ -1052,168 +1053,131 @@ static int set_tonecurve(int target, char *fname, libusb_device_handle *dev, return 0; } - -int main (int argc, char **argv) +static void shinkos2145_cmdline(char *caller) { - struct libusb_context *ctx; - struct libusb_device **list; - struct libusb_device_handle *dev; - struct libusb_config_descriptor *config; - - uint8_t endp_up = 0; - uint8_t endp_down = 0; - - int data_fd = fileno(stdin); - - int i, num; - int claimed; - - int query_only = 0; - 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; - struct s2145_cmd_hdr *cmd; - struct s2145_print_cmd *print; - struct s2145_status_resp *sts; - - uint8_t *planedata = NULL, *cmdbuf = NULL; - uint32_t datasize; + DEBUG("\t\t%s [ -qs | -qm | -qf | -qe | -qu ]\n", caller); + DEBUG("\t\t%s [ -qtu filename | -qtc filename ]\n", caller); + DEBUG("\t\t%s [ -su somestring | -stu filename | -stc filename ]\n", caller); + DEBUG("\t\t%s [ -pc id | -fl | -ru | -rp | -b1 | -b0 ]\n", caller); +} - uint8_t rdbuf2[READBACK_LEN]; - int last_state = -1, state = S_IDLE; +int shinkos2145_cmdline_arg(void *vctx, int run, char *arg1, char *arg2) +{ + struct shinkos2145_ctx *ctx = vctx; + + 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)); + + if (!strcmp("-qs", arg1)) + 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); + + return -1; +} - DEBUG("Shinko/Sinfonia CHC-S2145 CUPS backend version " VERSION "/" BACKEND_VERSION " \n"); +static void *shinkos2145_init(struct libusb_device_handle *dev, + uint8_t endp_up, uint8_t endp_down, uint8_t jobid) +{ + struct shinkos2145_ctx *ctx = malloc(sizeof(struct shinkos2145_ctx)); + if (!ctx) + return NULL; + memset(ctx, 0, sizeof(struct shinkos2145_ctx)); + + ctx->endp_up = endp_up; + ctx->endp_down = endp_down; - /* 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); - } + /* Ensure jobid is sane */ + ctx->jobid = (jobid & 0x7f) + 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); - } - } + return ctx; +} - /* 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; - } +static void shinkos2145_teardown(void *vctx) { + struct shinkos2145_ctx *ctx = vctx; - srand(getpid()); - jobid = rand(); + if (!ctx) + return; - /* 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); - } - } - } + free(ctx); +} - /* Ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); - signal(SIGTERM, sigterm_handler); +static int shinkos2145_read_parse(void *vctx, int data_fd) { + struct shinkos2145_ctx *ctx = vctx; + int ret; + uint8_t tmpbuf[4]; - /* Ensure jobid is sane */ - jobid = (jobid & 0x7f) + 1; + if (!ctx) + return 1; /* Read in then validate header */ - read(data_fd, &hdr, sizeof(hdr)); - if (le32_to_cpu(hdr.len1) != 0x10 || - le32_to_cpu(hdr.model) != 2145 || - le32_to_cpu(hdr.len2) != 0x64 || - le32_to_cpu(hdr.dpi) != 300) { + read(data_fd, &ctx->hdr, sizeof(ctx->hdr)); + if (le32_to_cpu(ctx->hdr.len1) != 0x10 || + le32_to_cpu(ctx->hdr.model) != 2145 || + le32_to_cpu(ctx->hdr.len2) != 0x64 || + le32_to_cpu(ctx->hdr.dpi) != 300) { ERROR("Unrecognized header data format!\n"); exit(1); } - /* Read in image data */ - cmdbuf = malloc(CMDBUF_LEN); - cmd = (struct s2145_cmd_hdr *) cmdbuf; - 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) { + ctx->datalen = le32_to_cpu(ctx->hdr.rows) * le32_to_cpu(ctx->hdr.columns) * 3; + ctx->databuf = malloc(ctx->datalen); + if (!ctx->databuf) { ERROR("Memory allocation failure!\n"); exit(1); } { - int remain; - uint8_t *ptr = planedata; - remain = datasize; + int remain = ctx->datalen; + uint8_t *ptr = ctx->databuf; do { ret = read(data_fd, ptr, remain); if (ret < 0) { ERROR("Read failed (%d/%d/%d)\n", - ret, remain, datasize); + ret, remain, ctx->datalen); perror("ERROR: Read failed"); exit(1); } @@ -1223,112 +1187,37 @@ int main (int argc, char **argv) } /* Make sure footer is sane too */ - ret = read(data_fd, cmdbuf, 4); + ret = read(data_fd, tmpbuf, 4); if (ret < 0 || ret != 4) { ERROR("Read failed (%d/%d/%d)\n", ret, 4, 4); perror("ERROR: Read failed"); exit(1); } - if (cmdbuf[0] != 0x04 || - cmdbuf[1] != 0x03 || - cmdbuf[2] != 0x02 || - cmdbuf[3] != 0x01) { + if (tmpbuf[0] != 0x04 || + tmpbuf[1] != 0x03 || + tmpbuf[2] != 0x02 || + tmpbuf[3] != 0x01) { ERROR("Unrecognized footer data format!\n"); exit(1); } - close(data_fd); /* We're done reading! */ - -skip_read: - /* Libusb setup */ - libusb_init(&ctx); - found = find_and_enumerate(ctx, &list, use_serno, P_SHINKO_S2145, 0); - - if (found == -1) { - ERROR("Printer open failure (No suitable printers found!)\n"); - ret = 3; - goto done; - } - - ret = libusb_open(list[found], &dev); - 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; - } - } + return 0; +} - ret = libusb_claim_interface(dev, iface); - if (ret) { - ERROR("Printer open failure (Could not claim printer interface)\n"); - ret = 4; - goto done_close; - } +static int shinkos2145_main_loop(void *vctx, int copies) { + struct shinkos2145_ctx *ctx = vctx; - 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; - } + int i, ret, num; + uint8_t cmdbuf[CMDBUF_LEN]; + uint8_t rdbuf2[READBACK_LEN]; - 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; - } - } + int last_state = -1, state = S_IDLE; - 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; - } + struct s2145_cmd_hdr *cmd = (struct s2145_cmd_hdr *) cmdbuf;; + struct s2145_print_cmd *print = (struct s2145_print_cmd *) cmdbuf; + struct s2145_status_resp *sts = (struct s2145_status_resp *) rdbuf; - /* Time for the main processing loop */ top: if (state != last_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->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), sizeof(struct s2145_status_hdr), &num)) < 0) { ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); - goto done_claimed; + return ret; } if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { @@ -1384,25 +1273,25 @@ top: break; 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); print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB); print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd)); - print->id = jobid; + print->id = ctx->jobid; print->count = cpu_to_le16(copies); - print->columns = cpu_to_le16(le32_to_cpu(hdr.columns)); - print->rows = cpu_to_le16(le32_to_cpu(hdr.rows)); - print->media = le32_to_cpu(hdr.media); - print->mode = le32_to_cpu(hdr.mode); - print->method = le32_to_cpu(hdr.method); + print->columns = cpu_to_le16(le32_to_cpu(ctx->hdr.columns)); + print->rows = cpu_to_le16(le32_to_cpu(ctx->hdr.rows)); + print->media = le32_to_cpu(ctx->hdr.media); + print->mode = le32_to_cpu(ctx->hdr.mode); + 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), sizeof(struct s2145_status_hdr), &num)) < 0) { ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd)); - goto done_claimed; + return ret; } if (sts->hdr.result != RESULT_SUCCESS) { @@ -1414,8 +1303,9 @@ top: } INFO("Sending image data to printer\n"); - if ((ret = send_data(dev, endp_down, planedata, datasize))) - goto done_claimed; + if ((ret = send_data(ctx->dev, ctx->endp_down, + ctx->databuf, ctx->datalen))) + return ret; INFO("Waiting for printer to acknowledge completion\n"); sleep(1); @@ -1449,10 +1339,7 @@ top: goto top; } - /* Done printing */ - INFO("All printing done\n"); - ret = 0; - goto done_claimed; + return 0; printer_error: ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x\n", @@ -1462,29 +1349,21 @@ printer_error: status_str(sts->hdr.status), sts->hdr.printer_major, sts->hdr.printer_minor); // XXX write this. - -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; + return 1; } - +/* 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 diff --git a/sony_updr150_print.c b/sony_updr150_print.c index 386a05b..1e7da1f 100644 --- a/sony_updr150_print.c +++ b/sony_updr150_print.c @@ -48,7 +48,7 @@ struct updr150_ctx { }; 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)); if (!ctx)