From be94ac3fffe2d41a545dfe8264ef2780325eea9b Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Wed, 17 Jul 2013 23:39:31 -0400 Subject: [PATCH] all: Unify find_and_enumerate function. Also means pushing device IDs etc into a table. This is all *UNTESTED* --- backend_common.c | 163 ++++++++++++++++++++++++++++++++++++++++++- kodak1400_print.c | 49 +------------ kodak6800_print.c | 45 +----------- selphy_print.c | 136 ------------------------------------ shinko_s2145_print.c | 45 +----------- sony_updr150_print.c | 45 +----------- 6 files changed, 169 insertions(+), 314 deletions(-) diff --git a/backend_common.c b/backend_common.c index 63c78d4..9a3b27f 100644 --- a/backend_common.c +++ b/backend_common.c @@ -28,7 +28,7 @@ #include #include -#define BACKEND_VERSION "0.5" +#define BACKEND_VERSION "0.6" #define STR_LEN_MAX 64 #define DEBUG( ... ) fprintf(stderr, "DEBUG: " __VA_ARGS__ ) @@ -67,10 +67,114 @@ #define cpu_to_be16 be16_to_cpu #define cpu_to_be32 be32_to_cpu +/* To enumerate supported devices */ +struct device_id { + uint16_t vid; + uint16_t pid; + int type; + char *manuf_str; +}; + +enum { + P_ES1 = 0, + P_ES2_20, + P_ES3_30, + P_ES40_CP790, + P_CP_XXX, + P_CP10, + P_KODAK_6800, + P_KODAK_1400_805, + P_SHINKO_S2145, + P_SONY_UPDR150, + P_END, +}; + +#define USB_VID_CANON 0x04a9 +#define USB_PID_CANON_CP10 0x304A +#define USB_PID_CANON_CP100 0x3063 +#define USB_PID_CANON_CP200 0x307C +#define USB_PID_CANON_CP220 0x30BD +#define USB_PID_CANON_CP300 0x307D +#define USB_PID_CANON_CP330 0x30BE +#define USB_PID_CANON_CP400 0x30F6 +#define USB_PID_CANON_CP500 0x30F5 +#define USB_PID_CANON_CP510 0x3128 +#define USB_PID_CANON_CP520 520 // XXX 316f? 3172? (related to cp740/cp750) +#define USB_PID_CANON_CP530 0x31b1 +#define USB_PID_CANON_CP600 0x310B +#define USB_PID_CANON_CP710 0x3127 +#define USB_PID_CANON_CP720 0x3143 +#define USB_PID_CANON_CP730 0x3142 +#define USB_PID_CANON_CP740 0x3171 +#define USB_PID_CANON_CP750 0x3170 +#define USB_PID_CANON_CP760 0x31AB +#define USB_PID_CANON_CP770 0x31AA +#define USB_PID_CANON_CP780 0x31DD +#define USB_PID_CANON_CP790 790 // XXX 31ed? 31ef? (related to es40) +#define USB_PID_CANON_CP800 0x3214 +#define USB_PID_CANON_CP810 0x3256 +#define USB_PID_CANON_CP900 0x3255 +#define USB_PID_CANON_ES1 0x3141 +#define USB_PID_CANON_ES2 0x3185 +#define USB_PID_CANON_ES20 0x3186 +#define USB_PID_CANON_ES3 0x31AF +#define USB_PID_CANON_ES30 0x31B0 +#define USB_PID_CANON_ES40 0x31EE +#define USB_VID_SONY 0x054C +#define USB_PID_SONY_UPDR150 0x01E8 +#define USB_VID_KODAK 0x040A +#define USB_PID_KODAK_6800 0x4021 +#define USB_PID_KODAK_1400 0x4022 +#define USB_PID_KODAK_805 0x4034 +#define USB_VID_SHINKO 0x10CE +#define USB_PID_SHINKO_S2145 0x000E + +static struct device_id devices[] = { + { USB_VID_CANON, USB_PID_CANON_CP10, P_CP10, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP100, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP200, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP220, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP300, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP330, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP400, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP500, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP510, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP520, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP530, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP600, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP710, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP720, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP730, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP740, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP750, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP760, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP770, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP780, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP790, P_ES40_CP790, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP800, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP810, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_CP900, P_CP_XXX, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES1, P_ES1, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES2, P_ES2_20, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES20, P_ES2_20, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES3, P_ES3_30, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES30, P_ES3_30, "Canon"}, + { USB_VID_CANON, USB_PID_CANON_ES40, P_ES40_CP790, "Canon"}, + + { USB_VID_KODAK, USB_PID_KODAK_6800, P_KODAK_6800, "Kodak"}, + { USB_VID_KODAK, USB_PID_KODAK_1400, P_KODAK_1400_805, "Kodak"}, + { USB_VID_KODAK, USB_PID_KODAK_805, P_KODAK_1400_805, "Kodak"}, + + { USB_VID_SHINKO, USB_PID_SHINKO_S2145, P_SHINKO_S2145, ""}, + { USB_VID_SONY, USB_PID_SONY_UPDR150, P_SONY_UPDR150, ""}, +}; + +/* Support Functions */ + #define ID_BUF_SIZE 2048 static char *get_device_id(struct libusb_device_handle *dev) { - int length; + int length; int claimed = 0; int iface = 0; char *buf = malloc(ID_BUF_SIZE + 1); @@ -121,6 +225,7 @@ done: return buf; } + static int send_data(struct libusb_device_handle *dev, uint8_t endp, uint8_t *buf, int len) { @@ -240,3 +345,57 @@ static int print_scan_output(struct libusb_device *device, abort: return found; } + +static int find_and_enumerate(struct libusb_context *ctx, + struct libusb_device ***list, + char *match_serno, + int printer_type, + int scan_only) +{ + int num; + int i, j; + int found = -1; + + /* Enumerate and find suitable device */ + num = libusb_get_device_list(ctx, list); + + for (i = 0 ; i < num ; i++) { + struct libusb_device_descriptor desc; + int match = 0; + libusb_get_device_descriptor((*list)[i], &desc); + + for (j = 0 ; j < sizeof(devices)/sizeof(struct device_id) ; j++) { + if (desc.idVendor == devices[j].vid && + desc.idProduct == devices[j].pid) { + match = 1; + if (printer_type == devices[j].type) + found = i; + break; + } + } + + if (!match) { + if (getenv("EXTRA_PID") && getenv("EXTRA_TYPE") && getenv("EXTRA_VID")) { + int pid = strtol(getenv("EXTRA_PID"), NULL, 16); + int vid = strtol(getenv("EXTRA_VID"), NULL, 16); + int type = atoi(getenv("EXTRA_TYPE")); + if (vid == desc.idVendor && + pid == desc.idProduct) { + match = 1; + if (printer_type == type) + found = i; + } + } + } + + if (!match) + continue; + + found = print_scan_output((*list)[i], &desc, + URI_PREFIX, devices[j].manuf_str, + found, (found == i), + scan_only, match_serno); + } + + return found; +} diff --git a/kodak1400_print.c b/kodak1400_print.c index b76c931..51951ea 100644 --- a/kodak1400_print.c +++ b/kodak1400_print.c @@ -40,11 +40,6 @@ #include "backend_common.c" -/* USB Identifiers */ -#define USB_VID_KODAK 0x040A -#define USB_PID_KODAK_1400 0x4022 -#define USB_PID_KODAK_805 0x4034 - /* Program states */ enum { S_IDLE = 0, @@ -81,46 +76,6 @@ struct kodak1400_hdr { static uint8_t idle_data[READBACK_LEN] = { 0xe4, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static int find_and_enumerate(struct libusb_context *ctx, - struct libusb_device ***list, - char *match_serno, - int scan_only) -{ - int num; - int i; - int found = -1; - - /* Enumerate and find suitable device */ - num = libusb_get_device_list(ctx, list); - - for (i = 0 ; i < num ; i++) { - struct libusb_device_descriptor desc; - - libusb_get_device_descriptor((*list)[i], &desc); - - if (desc.idVendor != USB_VID_KODAK) - continue; - - switch(desc.idProduct) { - case USB_PID_KODAK_1400: - found = i; - break; - case USB_PID_KODAK_805: - found = i; - break; - default: - continue; - } - - found = print_scan_output((*list)[i], &desc, - URI_PREFIX, "Kodak", - found, (found == i), - scan_only, match_serno); - } - - return found; -} - static int send_plane(struct libusb_device_handle *dev, uint8_t endp, uint8_t planeno, uint8_t *planedata, struct kodak1400_hdr *hdr, uint8_t *cmdbuf) @@ -309,7 +264,7 @@ int main (int argc, char **argv) DEBUG("Usage:\n\t%s [ infile | - ]\n\t%s job user title num-copies options [ filename ]\n\t%s [ -stc filename ] \n\n", argv[0], argv[0], argv[0]); libusb_init(&ctx); - find_and_enumerate(ctx, &list, NULL, 1); + find_and_enumerate(ctx, &list, NULL, P_KODAK_1400_805, 1); libusb_free_device_list(list, 1); libusb_exit(ctx); exit(1); @@ -426,7 +381,7 @@ int main (int argc, char **argv) skip_read: /* Libusb setup */ libusb_init(&ctx); - found = find_and_enumerate(ctx, &list, use_serno, 0); + found = find_and_enumerate(ctx, &list, use_serno, P_KODAK_1400_805, 0); if (found == -1) { ERROR("Printer open failure (No suitable printers found!)\n"); diff --git a/kodak6800_print.c b/kodak6800_print.c index c78ac30..4e4a661 100644 --- a/kodak6800_print.c +++ b/kodak6800_print.c @@ -41,10 +41,6 @@ #include "backend_common.c" -/* USB Identifiers */ -#define USB_VID_KODAK 0x040A -#define USB_PID_KODAK_6800 0x4021 - /* Program states */ enum { S_IDLE = 0, @@ -68,43 +64,6 @@ struct kodak6800_hdr { #define CMDBUF_LEN 17 #define READBACK_LEN 58 -static int find_and_enumerate(struct libusb_context *ctx, - struct libusb_device ***list, - char *match_serno, - int scan_only) -{ - int num; - int i; - int found = -1; - - /* Enumerate and find suitable device */ - num = libusb_get_device_list(ctx, list); - - for (i = 0 ; i < num ; i++) { - struct libusb_device_descriptor desc; - - libusb_get_device_descriptor((*list)[i], &desc); - - if (desc.idVendor != USB_VID_KODAK) - continue; - - switch(desc.idProduct) { - case USB_PID_KODAK_6800: - found = i; - break; - default: - continue; - } - - found = print_scan_output((*list)[i], &desc, - URI_PREFIX, "Kodak", - found, (found == i), - scan_only, match_serno); - } - - return found; -} - #define UPDATE_SIZE 1536 static int get_tonecurve(char *fname, libusb_device_handle *dev, uint8_t endp_down, uint8_t endp_up) @@ -332,7 +291,7 @@ int main (int argc, char **argv) DEBUG("Usage:\n\t%s [ infile | - ]\n\t%s job user title num-copies options [ filename ]\n\t%s [ -qtc filename | -stc filename ] \n\n", argv[0], argv[0], argv[0]); libusb_init(&ctx); - find_and_enumerate(ctx, &list, NULL, 1); + find_and_enumerate(ctx, &list, NULL, P_KODAK_6800, 1); libusb_free_device_list(list, 1); libusb_exit(ctx); exit(1); @@ -437,7 +396,7 @@ int main (int argc, char **argv) skip_read: /* Libusb setup */ libusb_init(&ctx); - found = find_and_enumerate(ctx, &list, use_serno, 0); + found = find_and_enumerate(ctx, &list, use_serno, P_KODAK_6800, 0); if (found == -1) { ERROR("Printer open failure (No suitable printers found!)\n"); diff --git a/selphy_print.c b/selphy_print.c index eeabd7f..e6e20b4 100644 --- a/selphy_print.c +++ b/selphy_print.c @@ -40,39 +40,6 @@ #include "backend_common.c" -/* USB Identifiers */ -#define USB_VID_CANON 0x04a9 -#define USB_PID_CANON_ES1 0x3141 -#define USB_PID_CANON_ES2 0x3185 -#define USB_PID_CANON_ES20 0x3186 -#define USB_PID_CANON_ES3 0x31AF -#define USB_PID_CANON_ES30 0x31B0 -#define USB_PID_CANON_ES40 0x31EE -#define USB_PID_CANON_CP10 0x304A -#define USB_PID_CANON_CP100 0x3063 -#define USB_PID_CANON_CP200 0x307C -#define USB_PID_CANON_CP220 0x30BD -#define USB_PID_CANON_CP300 0x307D -#define USB_PID_CANON_CP330 0x30BE -#define USB_PID_CANON_CP400 0x30F6 -#define USB_PID_CANON_CP500 0x30F5 -#define USB_PID_CANON_CP510 0x3128 -#define USB_PID_CANON_CP520 520 // XXX 316f? 3172? (related to cp740/cp750) -#define USB_PID_CANON_CP530 0x31b1 -#define USB_PID_CANON_CP600 0x310B -#define USB_PID_CANON_CP710 0x3127 -#define USB_PID_CANON_CP720 0x3143 -#define USB_PID_CANON_CP730 0x3142 -#define USB_PID_CANON_CP740 0x3171 -#define USB_PID_CANON_CP750 0x3170 -#define USB_PID_CANON_CP760 0x31AB -#define USB_PID_CANON_CP770 0x31AA -#define USB_PID_CANON_CP780 0x31DD -#define USB_PID_CANON_CP790 790 // XXX 31ed? 31ef? (related to es40) -#define USB_PID_CANON_CP800 0x3214 -#define USB_PID_CANON_CP810 0x3256 -#define USB_PID_CANON_CP900 0x3255 - #define READBACK_LEN 12 struct printer_data { @@ -92,17 +59,6 @@ struct printer_data { int16_t error_offset; }; -/* printer types */ -enum { - P_ES1 = 0, - P_ES2_20, - P_ES3_30, - P_ES40_CP790, - P_CP_XXX, - P_CP10, - P_END -}; - struct printer_data printers[P_END] = { { .type = P_ES1, .model = "SELPHY ES1", @@ -353,98 +309,6 @@ static int read_data(int remaining, int present, int data_fd, uint8_t *target, return wrote; } -static int find_and_enumerate(struct libusb_context *ctx, - struct libusb_device ***list, - char *match_serno, - int printer_type, - int scan_only) -{ - int num; - int i; - int found = -1; - - /* Enumerate and find suitable device */ - num = libusb_get_device_list(ctx, list); - - for (i = 0 ; i < num ; i++) { - struct libusb_device_descriptor desc; - libusb_get_device_descriptor((*list)[i], &desc); - - if (desc.idVendor != USB_VID_CANON) - continue; - - switch(desc.idProduct) { - case USB_PID_CANON_ES1: // "Canon SELPHY ES1" - if (printer_type == P_ES1) - found = i; - break; - case USB_PID_CANON_ES2: // "Canon SELPHY ES2" - case USB_PID_CANON_ES20: // "Canon SELPHY ES20" - if (printer_type == P_ES2_20) - found = i; - break; - case USB_PID_CANON_ES3: // "Canon SELPHY ES3" - case USB_PID_CANON_ES30: // "Canon SELPHY ES30" - if (printer_type == P_ES3_30) - found = i; - break; - case USB_PID_CANON_ES40: // "Canon SELPHY ES40" - case USB_PID_CANON_CP790: - if (printer_type == P_ES40_CP790) - found = i; - break; - case USB_PID_CANON_CP10: // "Canon CP-10" - if (printer_type == P_CP10) - found = i; - break; - case USB_PID_CANON_CP100: // "Canon CP-100" - case USB_PID_CANON_CP200: // "Canon CP-200" - case USB_PID_CANON_CP220: // "Canon CP-220" - case USB_PID_CANON_CP300: // "Canon CP-300" - case USB_PID_CANON_CP330: // "Canon CP-330" - case USB_PID_CANON_CP400: // "Canon SELPHY CP400" - case USB_PID_CANON_CP500: // "Canon SELPHY CP500" - case USB_PID_CANON_CP510: // "Canon SELPHY CP510" - case USB_PID_CANON_CP520: // "Canon SELPHY CP520" - case USB_PID_CANON_CP530: // "Canon SELPHY CP530" - case USB_PID_CANON_CP600: // "Canon SELPHY CP600" - case USB_PID_CANON_CP710: // "Canon SELPHY CP710" - case USB_PID_CANON_CP720: // "Canon SELPHY CP720" - case USB_PID_CANON_CP730: // "Canon SELPHY CP730" - case USB_PID_CANON_CP740: // "Canon SELPHY CP740" - case USB_PID_CANON_CP750: // "Canon SELPHY CP750" - case USB_PID_CANON_CP760: // "Canon SELPHY CP760" - case USB_PID_CANON_CP770: // "Canon SELPHY CP770" - case USB_PID_CANON_CP780: // "Canon SELPHY CP780" - case USB_PID_CANON_CP800: // "Canon SELPHY CP800" - case USB_PID_CANON_CP810: // "Canon SELPHY CP810" - case USB_PID_CANON_CP900: // "Canon SELPHY CP900" - if (printer_type == P_CP_XXX) - found = i; - break; - default: - /* Hook for testing unknown PIDs */ - if (getenv("SELPHY_PID") && getenv("SELPHY_TYPE")) { - int pid = strtol(getenv("SELPHY_PID"), NULL, 16); - int type = atoi(getenv("SELPHY_TYPE")); - if (pid == desc.idProduct) { - if (printer_type == type) - found = i; - break; - } - } - continue; - } - - found = print_scan_output((*list)[i], &desc, - URI_PREFIX, "Canon", - found, (found == i), - scan_only, match_serno); - } - - return found; -} - int main (int argc, char **argv) { struct libusb_context *ctx; diff --git a/shinko_s2145_print.c b/shinko_s2145_print.c index ee99c6f..90ff874 100644 --- a/shinko_s2145_print.c +++ b/shinko_s2145_print.c @@ -44,10 +44,6 @@ #include "backend_common.c" -/* USB Identifiers */ -#define USB_VID_SHINKO 0x10CE -#define USB_PID_SHINKO_S2145 0x000E - enum { S_IDLE = 0, S_PRINTER_READY_CMD, @@ -590,43 +586,6 @@ struct s2145_getunique_resp { uint8_t rdbuf[READBACK_LEN]; -static int find_and_enumerate(struct libusb_context *ctx, - struct libusb_device ***list, - char *match_serno, - int scan_only) -{ - int num; - int i; - int found = -1; - - /* Enumerate and find suitable device */ - num = libusb_get_device_list(ctx, list); - - for (i = 0 ; i < num ; i++) { - struct libusb_device_descriptor desc; - - libusb_get_device_descriptor((*list)[i], &desc); - - if (desc.idVendor != USB_VID_SHINKO) - continue; - - switch(desc.idProduct) { - case USB_PID_SHINKO_S2145: - found = i; - break; - default: - continue; - } - - found = print_scan_output((*list)[i], &desc, - URI_PREFIX, "", - found, (found == i), - scan_only, match_serno); - } - - return found; -} - static int s2145_do_cmd(libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, uint8_t *cmd, int cmdlen, int minlen, int *num) @@ -1136,7 +1095,7 @@ int main (int argc, char **argv) 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, 1); + find_and_enumerate(ctx, &list, NULL, P_SHINKO_S2145, 1); libusb_free_device_list(list, 1); libusb_exit(ctx); exit(1); @@ -1284,7 +1243,7 @@ int main (int argc, char **argv) skip_read: /* Libusb setup */ libusb_init(&ctx); - found = find_and_enumerate(ctx, &list, use_serno, 0); + found = find_and_enumerate(ctx, &list, use_serno, P_SHINKO_S2145, 0); if (found == -1) { ERROR("Printer open failure (No suitable printers found!)\n"); diff --git a/sony_updr150_print.c b/sony_updr150_print.c index 1e37d15..8ef242a 100644 --- a/sony_updr150_print.c +++ b/sony_updr150_print.c @@ -41,49 +41,8 @@ #include "backend_common.c" -/* USB Identifiers */ -#define USB_VID_SONY 0x054C -#define USB_PID_UP_DR150 0x01E8 - #define MAX_PRINTJOB_LEN 16736455 -static int find_and_enumerate(struct libusb_context *ctx, - struct libusb_device ***list, - char *match_serno, - int scan_only) -{ - int num; - int i; - int found = -1; - - /* Enumerate and find suitable device */ - num = libusb_get_device_list(ctx, list); - - for (i = 0 ; i < num ; i++) { - struct libusb_device_descriptor desc; - - libusb_get_device_descriptor((*list)[i], &desc); - - if (desc.idVendor != USB_VID_SONY) - continue; - - switch(desc.idProduct) { - case USB_PID_UP_DR150: - found = i; - break; - default: - continue; - } - - found = print_scan_output((*list)[i], &desc, - URI_PREFIX, "", - found, (found == i), - scan_only, match_serno); - } - - return found; -} - int main (int argc, char **argv) { struct libusb_context *ctx; @@ -115,7 +74,7 @@ int main (int argc, char **argv) DEBUG("Usage:\n\t%s [ infile | - ]\n\t%s job user title num-copies options [ filename ]\n\n", argv[0], argv[0]); libusb_init(&ctx); - find_and_enumerate(ctx, &list, NULL, 1); + find_and_enumerate(ctx, &list, NULL, P_SONY_UPDR150, 1); libusb_free_device_list(list, 1); libusb_exit(ctx); exit(1); @@ -188,7 +147,7 @@ int main (int argc, char **argv) /* Libusb setup */ libusb_init(&ctx); - found = find_and_enumerate(ctx, &list, use_serno, 0); + found = find_and_enumerate(ctx, &list, use_serno, P_SONY_UPDR150, 0); if (found == -1) { ERROR("Printer open failure (No suitable printers found!)\n");