mirror of
https://git.familie-radermacher.ch/linux/ptouch-print.git
synced 2026-09-29 11:42:09 +00:00
add --serial and --list-connected to pick one of several printers
When more than one printer is connected, ptouch-print used the first one it found. --serial <serial> now uses only the printer with that USB serial number, and --list-connected lists the connected printers with their serials. libptouch gets ptouch_open_serial() and ptouch_list_connected(); ptouch_open() keeps its signature and calls ptouch_open_serial() with NULL. The serial is checked before the P-Lite and unsupported-raster checks, so a different printer in the wrong mode no longer ends the search, and the "found on USB bus" line now shows the serial. The early error returns in the open loop now free the device list.
This commit is contained in:
committed by
Dominic Radermacher
parent
d05d31bb86
commit
7fa1e1ac46
@@ -107,6 +107,7 @@ struct _ptouch_dev {
|
||||
typedef struct _ptouch_dev *ptouch_dev;
|
||||
|
||||
int ptouch_open(ptouch_dev *ptdev);
|
||||
int ptouch_open_serial(ptouch_dev *ptdev, const char *serial);
|
||||
int ptouch_close(ptouch_dev ptdev);
|
||||
int ptouch_send(ptouch_dev ptdev, uint8_t *data, size_t len);
|
||||
int ptouch_init(ptouch_dev ptdev);
|
||||
@@ -130,6 +131,7 @@ int ptouch_rasterstart(ptouch_dev ptdev);
|
||||
int ptouch_sendraster(ptouch_dev ptdev, uint8_t *data, size_t len);
|
||||
void ptouch_rawstatus(uint8_t raw[32]);
|
||||
void ptouch_list_supported();
|
||||
int ptouch_list_connected();
|
||||
|
||||
const char* pt_mediatype(unsigned char media_type);
|
||||
const char* pt_tapecolor(unsigned char tape_color);
|
||||
|
||||
@@ -34,6 +34,10 @@ Set the seconds ptouch-print is waiting for finishing a previous ptouch-print co
|
||||
Default is 1 second. 0 (zero) means wait forever.
|
||||
Useful if ptouch-print is used in a script multiple times, and the device is waiting for the user
|
||||
to use the mechanical cutter.
|
||||
.TP
|
||||
.BR \-\-serial\ \fI<serial>
|
||||
Use the printer with this USB serial number, when more than one printer is connected.
|
||||
Use \-\-list\-connected to see the serial numbers.
|
||||
|
||||
.SS "Font selection options"
|
||||
.TP
|
||||
@@ -90,6 +94,9 @@ Show info about the tape detected (like printing width etc.) and exit.
|
||||
.TP
|
||||
.BR \-\-list-supported
|
||||
List all supported printers
|
||||
.TP
|
||||
.BR \-\-list-connected
|
||||
List all connected printers with their USB serial numbers, for use with \-\-serial
|
||||
|
||||
.SH DEFAULTS
|
||||
The default font used is 'DejaVuSans'.
|
||||
|
||||
+90
-7
@@ -112,6 +112,13 @@ struct _pt_dev_info ptdevs[] = {
|
||||
};
|
||||
|
||||
int ptouch_open(ptouch_dev *ptdev)
|
||||
{
|
||||
return ptouch_open_serial(ptdev, NULL);
|
||||
}
|
||||
|
||||
/* Like ptouch_open(), but when serial is not NULL only a printer whose
|
||||
USB serial number matches it is used. */
|
||||
int ptouch_open_serial(ptouch_dev *ptdev, const char *serial)
|
||||
{
|
||||
libusb_device **devs;
|
||||
libusb_device *dev;
|
||||
@@ -148,22 +155,43 @@ int ptouch_open(ptouch_dev *ptdev)
|
||||
}
|
||||
for (int k=0; ptdevs[k].vid > 0; ++k) {
|
||||
if ((desc.idVendor == ptdevs[k].vid) && (desc.idProduct == ptdevs[k].pid) && (ptdevs[k].flags >= 0)) {
|
||||
fprintf(stderr, _("%s found on USB bus %d, device %d\n"),
|
||||
unsigned char buf[64] = {0};
|
||||
if ((r=libusb_open(dev, &handle)) != 0) {
|
||||
fprintf(stderr, _("libusb_open error :%s\n"), libusb_error_name(r));
|
||||
if (serial) {
|
||||
/* can't read its serial, so it can't be the one we want */
|
||||
break;
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
return -1;
|
||||
}
|
||||
if (desc.iSerialNumber) {
|
||||
libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buf, sizeof(buf));
|
||||
}
|
||||
fprintf(stderr, _("%s found on USB bus %d, device %d, serial %s\n"),
|
||||
ptdevs[k].name,
|
||||
libusb_get_bus_number(dev),
|
||||
libusb_get_device_address(dev));
|
||||
libusb_get_device_address(dev),
|
||||
buf[0] ? (char *)buf : "-");
|
||||
/* check the serial before the P-Lite/unsupported checks, so
|
||||
a different printer in the wrong mode doesn't end the search */
|
||||
if (serial && (strcmp((char *)buf, serial) != 0)) {
|
||||
libusb_close(handle);
|
||||
handle = NULL;
|
||||
break; /* next device */
|
||||
}
|
||||
if (ptdevs[k].flags & FLAG_PLITE) {
|
||||
printf("Printer is in P-Lite Mode, which is unsupported\n\n");
|
||||
printf("Turn off P-Lite mode by changing switch from position EL to position E\n");
|
||||
printf("or by pressing the PLite button for ~ 2 seconds (or consult the manual)\n");
|
||||
libusb_close(handle);
|
||||
libusb_free_device_list(devs, 1);
|
||||
return -1;
|
||||
}
|
||||
if (ptdevs[k].flags & FLAG_UNSUP_RASTER) {
|
||||
printf("Unfortunately, that printer currently is unsupported (it has a different raster data transfer)\n");
|
||||
return -1;
|
||||
}
|
||||
if ((r=libusb_open(dev, &handle)) != 0) {
|
||||
fprintf(stderr, _("libusb_open error :%s\n"), libusb_error_name(r));
|
||||
libusb_close(handle);
|
||||
libusb_free_device_list(devs, 1);
|
||||
return -1;
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
@@ -186,7 +214,11 @@ int ptouch_open(ptouch_dev *ptdev)
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, _("No P-Touch printer found on USB (remember to put switch to position E)\n"));
|
||||
if (serial) {
|
||||
fprintf(stderr, _("No P-Touch printer with serial %s found\n"), serial);
|
||||
} else {
|
||||
fprintf(stderr, _("No P-Touch printer found on USB (remember to put switch to position E)\n"));
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
return -1;
|
||||
}
|
||||
@@ -555,6 +587,57 @@ void ptouch_list_supported()
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print every connected P-Touch printer with its USB serial number, which
|
||||
can then be passed to ptouch_open_serial(). Returns the number of
|
||||
printers found, or -1 on error. */
|
||||
int ptouch_list_connected()
|
||||
{
|
||||
libusb_device **devs;
|
||||
libusb_device *dev;
|
||||
libusb_device_handle *handle;
|
||||
struct libusb_device_descriptor desc;
|
||||
int r, i=0, found=0;
|
||||
|
||||
if ((libusb_init(NULL)) < 0) {
|
||||
fprintf(stderr, _("libusb_init() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
if (libusb_get_device_list(NULL, &devs) < 0) {
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
while ((dev=devs[i++]) != NULL) {
|
||||
if (libusb_get_device_descriptor(dev, &desc) < 0) {
|
||||
continue;
|
||||
}
|
||||
for (int k=0; ptdevs[k].vid > 0; ++k) {
|
||||
if ((desc.idVendor == ptdevs[k].vid) && (desc.idProduct == ptdevs[k].pid) && (ptdevs[k].flags >= 0)) {
|
||||
unsigned char buf[64] = {0};
|
||||
const char *serial = "-";
|
||||
if ((r=libusb_open(dev, &handle)) != 0) {
|
||||
serial = libusb_error_name(r);
|
||||
} else {
|
||||
if (desc.iSerialNumber && (libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buf, sizeof(buf)) > 0)) {
|
||||
serial = (char *)buf;
|
||||
}
|
||||
libusb_close(handle);
|
||||
}
|
||||
printf(_("%s\tserial %s\t(USB bus %d, device %d)%s\n"),
|
||||
ptdevs[k].name, serial,
|
||||
libusb_get_bus_number(dev),
|
||||
libusb_get_device_address(dev),
|
||||
(ptdevs[k].flags & FLAG_PLITE) ? _(" - in P-Lite mode, unsupported") :
|
||||
(ptdevs[k].flags & FLAG_UNSUP_RASTER) ? _(" - unsupported") : "");
|
||||
++found;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
libusb_exit(NULL);
|
||||
return found;
|
||||
}
|
||||
|
||||
const char* pt_mediatype(const uint8_t media_type)
|
||||
{
|
||||
switch (media_type) {
|
||||
|
||||
+16
-2
@@ -65,6 +65,7 @@ struct arguments {
|
||||
char *save_png;
|
||||
int verbose;
|
||||
int timeout;
|
||||
char *serial;
|
||||
};
|
||||
|
||||
typedef enum { JOB_CUTMARK, JOB_IMAGE, JOB_PAD, JOB_TEXT, JOB_UNDEFINED } job_type_t;
|
||||
@@ -109,6 +110,7 @@ static struct argp_option options[] = {
|
||||
{ "force-tape-width", 6, "<px>", 0, "Set tape width in pixels, use together with --writepng without a printer connected", 1},
|
||||
{ "copies", 7, "<number>", 0, "Sets the number of identical prints", 1},
|
||||
{ "timeout", 8, "<seconds>", 0, "Set timeout waiting for finishing previous job. Default:1, or a per-printer minimum where one is known. 0 means infinity", 1},
|
||||
{ "serial", 12, "<serial>", 0, "Use the printer with this USB serial number", 1 },
|
||||
|
||||
{ 0, 0, 0, 0, "print commands:", 2},
|
||||
{ "image", 'i', "<file>", 0, "Print the given image which must be a 2 color (black/white) png", 2},
|
||||
@@ -123,6 +125,7 @@ static struct argp_option options[] = {
|
||||
{ 0, 0, 0, 0, "other commands:", 3},
|
||||
{ "info", 20, 0, 0, "Show info about detected tape", 3},
|
||||
{ "list-supported", 21, 0, 0, "Show printers supported by this version", 3},
|
||||
{ "list-connected", 22, 0, 0, "Show connected printers and their USB serial numbers (for --serial)", 3},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -141,7 +144,8 @@ struct arguments arguments = {
|
||||
.forced_tape_width = 0,
|
||||
.save_png = NULL,
|
||||
.verbose = 0,
|
||||
.timeout = -1 /* -1 = not given; 0 is already "infinity" */
|
||||
.timeout = -1, /* -1 = not given; 0 is already "infinity" */
|
||||
.serial = NULL
|
||||
};
|
||||
|
||||
job_t *jobs = NULL;
|
||||
@@ -688,6 +692,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
case 11: // precut
|
||||
arguments->precut = true;
|
||||
break;
|
||||
case 12: // serial
|
||||
arguments->serial = arg;
|
||||
break;
|
||||
case 'a': // align
|
||||
if ((strcmp(arg, "c") == 0) || (strcmp(arg, "center") == 0)) {
|
||||
arguments->align = ALIGN_CENTER;
|
||||
@@ -709,6 +716,13 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
case 21: // list-supported
|
||||
ptouch_list_supported();
|
||||
exit(0);
|
||||
case 22: { // list-connected
|
||||
int n = ptouch_list_connected();
|
||||
if (n == 0) {
|
||||
fprintf(stderr, _("No P-Touch printer found on USB (remember to put switch to position E)\n"));
|
||||
}
|
||||
exit(n > 0 ? 0 : 5);
|
||||
}
|
||||
case ARGP_KEY_ARG:
|
||||
argp_failure(state, 1, E2BIG, _("No arguments supported"));
|
||||
break;
|
||||
@@ -745,7 +759,7 @@ int main(int argc, char *argv[])
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
if (!arguments.forced_tape_width) {
|
||||
if ((ptouch_open(&ptdev)) < 0) {
|
||||
if ((ptouch_open_serial(&ptdev, arguments.serial)) < 0) {
|
||||
return 5;
|
||||
}
|
||||
if (ptouch_init(ptdev) != 0) {
|
||||
|
||||
Reference in New Issue
Block a user