summaryrefslogtreecommitdiffstats
path: root/src/ql.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ql.c')
-rw-r--r--src/ql.c475
1 files changed, 233 insertions, 242 deletions
diff --git a/src/ql.c b/src/ql.c
index 25badaa..e759cb0 100644
--- a/src/ql.c
+++ b/src/ql.c
@@ -12,10 +12,9 @@
#include <stdlib.h>
#include <string.h>
-struct ql_ctx
-{
- char *printer;
- int fd;
+struct ql_ctx {
+ char *printer;
+ int fd;
};
#define ESC 0x1b
@@ -26,308 +25,300 @@ struct ql_ctx
ssize_t retry_write(int fd, const char *buf, size_t len)
{
- size_t written = 0;
- while (written != len)
- {
- ssize_t n = write(fd, buf + written, len - written);
- if (n == -1)
- {
- if (errno == EAGAIN || errno == EINTR)
- continue;
- else
- break;
- }
- else
- written += n;
- }
- return written;
+ size_t written = 0;
+ while (written != len) {
+ ssize_t n = write(fd, buf + written, len - written);
+ if (n == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ else
+ break;
+ } else
+ written += n;
+ }
+ return written;
}
-
ql_ctx_t ql_open(const char *printer)
{
- int fd = open(printer, O_RDWR);
- if (fd < 0)
- return NULL;
+ int fd = open(printer, O_RDWR);
+ if (fd < 0)
+ return NULL;
- ql_ctx_t ctx = malloc(sizeof(struct ql_ctx));
- if (!ctx)
- return NULL;
- ctx->printer = strdup(printer);
- ctx->fd = fd;
+ ql_ctx_t ctx = malloc(sizeof(struct ql_ctx));
+ if (!ctx)
+ return NULL;
+ ctx->printer = strdup(printer);
+ ctx->fd = fd;
- const char clear[200] = { 0, };
- (void)full_write(fd, clear); // recommended to clear old/errored jobs
+ const char clear[200] = { 0, };
+ (void)full_write(fd, clear); // recommended to clear old/errored jobs
- return ctx;
+ return ctx;
}
void ql_close(ql_ctx_t ctx)
{
- free(ctx->printer);
- close(ctx->fd);
- free(ctx);
+ free(ctx->printer);
+ close(ctx->fd);
+ free(ctx);
}
bool ql_init(ql_ctx_t ctx)
{
- const char init[] = { ESC, '@' };
- return full_write(ctx->fd, init);
+ const char init[] = { ESC, '@' };
+ return full_write(ctx->fd, init);
}
-
bool ql_request_status(ql_ctx_t ctx)
{
- const char status_req[] = { ESC, 'i', 'S' };
- return full_write(ctx->fd, status_req);
+ const char status_req[] = { ESC, 'i', 'S' };
+ return full_write(ctx->fd, status_req);
}
-
-bool ql_read_status(ql_ctx_t ctx, ql_status_t *status)
+bool ql_read_status(ql_ctx_t ctx, ql_status_t * status)
{
- for (int i = 0; i < NUM_STATUS_READ_RETRIES; ++i)
- {
- int ret = read(ctx->fd, status, sizeof(*status));
- if (ret == 32)
- return true;
- else if ( (ret == 0) // "no data yet, too bad we just eof'd your fd, sucker"
- || (ret == -1 && errno == EBADF)) // in case we messed up, somehow
- {
- close(ctx->fd);
- ctx->fd = open(ctx->printer, O_RDWR);
- if (ctx->fd < 0)
- return false;
- }
- else if (ret == -1 && (errno != EAGAIN || errno != EINTR))
- return false; // non-recoverable
- }
- errno = ETIME;
- return false;
+ for (int i = 0; i < NUM_STATUS_READ_RETRIES; ++i) {
+ int ret = read(ctx->fd, status, sizeof(*status));
+ if (ret == 32)
+ return true;
+ else if ((ret == 0) // "no data yet, too bad we just eof'd your fd, sucker"
+ || (ret == -1 && errno == EBADF)) // in case we messed up, somehow
+ {
+ close(ctx->fd);
+ ctx->fd = open(ctx->printer, O_RDWR);
+ if (ctx->fd < 0)
+ return false;
+ } else if (ret == -1 && (errno != EAGAIN || errno != EINTR))
+ return false; // non-recoverable
+ }
+ errno = ETIME;
+ return false;
}
-
bool ql_set_mode(ql_ctx_t ctx, unsigned mode)
{
- char cmd[] = { ESC, 'i', 'M', mode };
- return full_write(ctx->fd, cmd);
+ char cmd[] = { ESC, 'i', 'M', mode };
+ return full_write(ctx->fd, cmd);
}
-
bool ql_set_expanded_mode(ql_ctx_t ctx, unsigned mode)
{
- char cmd[] = { ESC, 'i', 'K', mode };
- return full_write(ctx->fd, cmd);
+ char cmd[] = { ESC, 'i', 'K', mode };
+ return full_write(ctx->fd, cmd);
}
-
bool ql_set_autocut_every_n(ql_ctx_t ctx, uint8_t n)
{
- char cmd[] = { ESC, 'i', 'A', n };
- return full_write(ctx->fd, cmd);
+ char cmd[] = { ESC, 'i', 'A', n };
+ return full_write(ctx->fd, cmd);
}
-
bool ql_set_margin(ql_ctx_t ctx, uint16_t dots)
{
- char cmd[] = { ESC, 'i', 'd', dots & 0xff, dots >> 8};
- return full_write(ctx->fd, cmd);
+ char cmd[] = { ESC, 'i', 'd', dots & 0xff, dots >> 8 };
+ return full_write(ctx->fd, cmd);
}
-
-bool ql_needs_mode_switch(const ql_status_t *status)
+bool ql_needs_mode_switch(const ql_status_t * status)
{
- switch(status->model_code)
- {
- case '3': case '4':
- case 'P': case 'Q':
- return true;
- default: break;
- }
- return false;
+ switch (status->model_code) {
+ case '3':
+ case '4':
+ case 'P':
+ case 'Q':
+ return true;
+ default:
+ break;
+ }
+ return false;
}
-
bool ql_switch_to_raster_mode(ql_ctx_t ctx)
{
- #define MODE_ESC_P 0
- #define MODE_RASTER 1
- #define MODE_P_TOUCH_TEMPLATE 3
- char cmd[] = { ESC, 'i', 'a', MODE_RASTER };
- return full_write(ctx->fd, cmd);
+#define MODE_ESC_P 0
+#define MODE_RASTER 1
+#define MODE_P_TOUCH_TEMPLATE 3
+ char cmd[] = { ESC, 'i', 'a', MODE_RASTER };
+ return full_write(ctx->fd, cmd);
}
-
-static void pack_column(uint8_t *out, uint16_t bytes, uint16_t colno, const ql_raster_image_t *img, uint8_t black_below_v)
+static void pack_column(uint8_t * out, uint16_t bytes, uint16_t colno,
+ const ql_raster_image_t * img, uint8_t black_below_v)
{
- for (unsigned n = 0; n < bytes; ++n, ++out)
- {
- *out = 0;
- for (unsigned i = 0; i < 8; ++i)
- {
- unsigned img_row = n * 8 + i;
- if (img_row < img->height)
- if (img->data[img_row * img->width + colno] < black_below_v)
- *out |= 1 << (7 - i);
- }
-//for(int i = 7; i >= 0; --i) fprintf(stderr, "%c", (*out & (1<<i)) ? '#' : '.');
- }
-//fprintf(stderr,"\n");
+ for (unsigned n = 0; n < bytes; ++n, ++out) {
+ *out = 0;
+ for (unsigned i = 0; i < 8; ++i) {
+ unsigned img_row = n * 8 + i;
+ if (img_row < img->height)
+ if (img->data[img_row * img->width + colno] < black_below_v)
+ *out |= 1 << (7 - i);
+ }
+ //for(int i = 7; i >= 0; --i) fprintf(stderr, "%c", (*out & (1<<i)) ? '#' : '.');
+ }
+ //fprintf(stderr,"\n");
}
-
-bool ql_print_raster_image(ql_ctx_t ctx, const ql_status_t *status, const ql_raster_image_t *img, const ql_print_cfg_t *cfg)
+bool ql_print_raster_image(ql_ctx_t ctx, const ql_status_t * status,
+ const ql_raster_image_t * img, const ql_print_cfg_t * cfg)
{
- unsigned dn = 90; // default raster transmission block size (720 pixels)
- if (status->model_code == 'P' || status->model_code == '4')
- dn = 162; // 1296 pixels
-
- if (img->height > dn * 8)
- return false; // image too wide for printer
-
- char print_info[] = { ESC, 'i', 'z',
- cfg->flags | 0x80,
- (cfg->flags & QL_PRINT_CFG_MEDIA_TYPE) ? cfg->media_type : 0,
- (cfg->flags & QL_PRINT_CFG_MEDIA_WIDTH) ? cfg->media_width : 0,
- (cfg->flags & QL_PRINT_CFG_MEDIA_LENGTH) ? cfg->media_length : 0,
- img->width & 0xff, img->width >> 8, 0, 0,
- cfg->first_page ? 0 : 1, 0 };
- if (!full_write(ctx->fd, print_info))
- return false;
-
- for (unsigned w = 0; w < img->width; ++w)
- {
- char block[dn + 3];
- block[0] = 'g'; block[1] = 0; block[2] = dn;
- pack_column((uint8_t *)block+3, dn, w, img, cfg->threshold);
- if (!full_write(ctx->fd, block))
- return false;
- }
-
- char done[] = { 0x1a }; // print with feeding
- return full_write(ctx->fd, done);
+ unsigned dn = 90; // default raster transmission block size (720 pixels)
+ if (status->model_code == 'P' || status->model_code == '4')
+ dn = 162; // 1296 pixels
+
+ if (img->height > dn * 8)
+ return false; // image too wide for printer
+
+ char print_info[] = { ESC, 'i', 'z',
+ cfg->flags | 0x80,
+ (cfg->flags & QL_PRINT_CFG_MEDIA_TYPE) ? cfg->media_type : 0,
+ (cfg->flags & QL_PRINT_CFG_MEDIA_WIDTH) ? cfg->media_width : 0,
+ (cfg->flags & QL_PRINT_CFG_MEDIA_LENGTH) ? cfg->media_length : 0,
+ img->width & 0xff, img->width >> 8, 0, 0,
+ cfg->first_page ? 0 : 1, 0
+ };
+ if (!full_write(ctx->fd, print_info))
+ return false;
+
+ for (unsigned w = 0; w < img->width; ++w) {
+ char block[dn + 3];
+ block[0] = 'g';
+ block[1] = 0;
+ block[2] = dn;
+ pack_column((uint8_t *) block + 3, dn, w, img, cfg->threshold);
+ if (!full_write(ctx->fd, block))
+ return false;
+ }
+
+ char done[] = { 0x1a }; // print with feeding
+ return full_write(ctx->fd, done);
}
-
-const char *ql_decode_model(const ql_status_t *status)
+const char *ql_decode_model(const ql_status_t * status)
{
- switch(status->model_code)
- {
- case '1': return "QL-560";
- case '2': return "QL-570";
- case '3': return "QL-580N";
- case '4': return "QL-1060N";
- case '5': return "QL-700";
- case '6': return "QL-710W";
- case '7': return "QL-720NW";
- case 'O': return "QL-500/550";
- case 'P': return "QL-1050";
- case 'Q': return "QL-650TD";
- default:
- {
- static char buf[] = "unrecognised (type code 0x$$)";
- char *q = strchr(buf, '$');
- sprintf(q, "%02hhx)", status->model_code);
- return buf;
- }
- }
+ switch (status->model_code) {
+ case '1':
+ return "QL-560";
+ case '2':
+ return "QL-570";
+ case '3':
+ return "QL-580N";
+ case '4':
+ return "QL-1060N";
+ case '5':
+ return "QL-700";
+ case '6':
+ return "QL-710W";
+ case '7':
+ return "QL-720NW";
+ case 'O':
+ return "QL-500/550";
+ case 'P':
+ return "QL-1050";
+ case 'Q':
+ return "QL-650TD";
+ default:
+ {
+ static char buf[] = "unrecognised (type code 0x$$)";
+ char *q = strchr(buf, '$');
+ sprintf(q, "%02hhx)", status->model_code);
+ return buf;
+ }
+ }
}
-const char *ql_decode_mode(const ql_status_t *status)
+const char *ql_decode_mode(const ql_status_t * status)
{
- if (status->mode & QL_MODE_AUTOCUT)
- return "auto-cut";
- else
- return "no-auto-cut";
+ if (status->mode & QL_MODE_AUTOCUT)
+ return "auto-cut";
+ else
+ return "no-auto-cut";
}
-const char *ql_decode_errors(const ql_status_t *status)
+const char *ql_decode_errors(const ql_status_t * status)
{
- typedef struct {
- uint16_t bit;
- const char *str;
- } strmap_t;
-
- #define ERR1(x) (x << 0)
- #define ERR2(x) (x << 8)
- const strmap_t strmap[] = {
- { ERR1(QL_ERR_1_NO_MEDIA), "no-media " },
- { ERR1(QL_ERR_1_END_OF_MEDIA), "end-of-media " },
- { ERR1(QL_ERR_1_CUTTER_JAM), "cutter-jam " },
- { ERR1(QL_ERR_1_PRINTER_IN_USE), "printer-in-use " },
- { ERR1(QL_ERR_1_PRINTER_TURNED_OFF), "printer-turned-off " },
- { ERR1(QL_ERR_1_HIGH_VOLTAGE_ADAPTER), "high-voltage-adapter " },
- { ERR1(QL_ERR_1_FAN_MOTOR_ERROR), "fan-motor-error " },
-
- { ERR2(QL_ERR_2_REPLACE_MEDIA), "replace-media " },
- { ERR2(QL_ERR_2_EXPANSION_BUFFER_FULL), "expansion-buffer-full " },
- { ERR2(QL_ERR_2_COMMUNICATION_ERROR), "communication-error " },
- { ERR2(QL_ERR_2_COMMUNICATION_BUFFER_FULL), "communication-buffer-full " },
- { ERR2(QL_ERR_2_COVER_OPEN), "cover-open " },
- { ERR2(QL_ERR_2_CANCEL_KEY), "cancel-key-pressed " },
- { ERR2(QL_ERR_2_MEDIA_CANNOT_BE_FED), "media-cannot-be-fed " },
- { ERR2(QL_ERR_2_SYSTEM_ERROR), "system-error " }
- };
-
- static char *buf = 0;
- if (!buf)
- {
- int len = 0;
- for (unsigned i = 0; i < (sizeof(strmap)/sizeof(strmap[0])); ++i)
- len += strlen(strmap[i].str);
- buf = malloc(len + 1);
- if (!buf)
- return "<host-out-of-memory>";
- }
-
- uint16_t errs = ERR1(status->err_info_1) | ERR2(status->err_info_2);
- buf[0] = 0;
- for (unsigned i = 0; i < (sizeof(strmap)/sizeof(strmap[0])); ++i)
- {
- if (errs & strmap[i].bit)
- strcat(buf, strmap[i].str);
- }
- return (buf[0] == 0) ? "none" : buf;
+ typedef struct {
+ uint16_t bit;
+ const char *str;
+ } strmap_t;
+
+#define ERR1(x) (x << 0)
+#define ERR2(x) (x << 8)
+ const strmap_t strmap[] = {
+ {ERR1(QL_ERR_1_NO_MEDIA), "no-media "},
+ {ERR1(QL_ERR_1_END_OF_MEDIA), "end-of-media "},
+ {ERR1(QL_ERR_1_CUTTER_JAM), "cutter-jam "},
+ {ERR1(QL_ERR_1_PRINTER_IN_USE), "printer-in-use "},
+ {ERR1(QL_ERR_1_PRINTER_TURNED_OFF), "printer-turned-off "},
+ {ERR1(QL_ERR_1_HIGH_VOLTAGE_ADAPTER), "high-voltage-adapter "},
+ {ERR1(QL_ERR_1_FAN_MOTOR_ERROR), "fan-motor-error "},
+
+ {ERR2(QL_ERR_2_REPLACE_MEDIA), "replace-media "},
+ {ERR2(QL_ERR_2_EXPANSION_BUFFER_FULL), "expansion-buffer-full "},
+ {ERR2(QL_ERR_2_COMMUNICATION_ERROR), "communication-error "},
+ {ERR2(QL_ERR_2_COMMUNICATION_BUFFER_FULL), "communication-buffer-full "},
+ {ERR2(QL_ERR_2_COVER_OPEN), "cover-open "},
+ {ERR2(QL_ERR_2_CANCEL_KEY), "cancel-key-pressed "},
+ {ERR2(QL_ERR_2_MEDIA_CANNOT_BE_FED), "media-cannot-be-fed "},
+ {ERR2(QL_ERR_2_SYSTEM_ERROR), "system-error "}
+ };
+
+ static char *buf = 0;
+ if (!buf) {
+ int len = 0;
+ for (unsigned i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i)
+ len += strlen(strmap[i].str);
+ buf = malloc(len + 1);
+ if (!buf)
+ return "<host-out-of-memory>";
+ }
+
+ uint16_t errs = ERR1(status->err_info_1) | ERR2(status->err_info_2);
+ buf[0] = 0;
+ for (unsigned i = 0; i < (sizeof(strmap) / sizeof(strmap[0])); ++i) {
+ if (errs & strmap[i].bit)
+ strcat(buf, strmap[i].str);
+ }
+ return (buf[0] == 0) ? "none" : buf;
}
-const char *ql_decode_media_type(const ql_status_t *status)
+const char *ql_decode_media_type(const ql_status_t * status)
{
- switch(status->media_type)
- {
- case QL_MEDIA_TYPE_NO_MEDIA: return "no-media";
- case QL_MEDIA_TYPE_CONTINUOUS:
- case QL_MEDIA_TYPE_CONTINUOUS_ALT:
- return "continuous-length-tape";
- case QL_MEDIA_TYPE_DIECUT_LABELS:
- case QL_MEDIA_TYPE_DIECUT_LABELS_ALT:
- return "die-cut-labels";
- default: {
- static char buf[] = "unknown (code 0x$$)";
- char *q = strchr(buf, '$');
- sprintf(q, "%02hhx)", status->media_type);
- return buf;
- }
- }
+ switch (status->media_type) {
+ case QL_MEDIA_TYPE_NO_MEDIA:
+ return "no-media";
+ case QL_MEDIA_TYPE_CONTINUOUS:
+ case QL_MEDIA_TYPE_CONTINUOUS_ALT:
+ return "continuous-length-tape";
+ case QL_MEDIA_TYPE_DIECUT_LABELS:
+ case QL_MEDIA_TYPE_DIECUT_LABELS_ALT:
+ return "die-cut-labels";
+ default:{
+ static char buf[] = "unknown (code 0x$$)";
+ char *q = strchr(buf, '$');
+ sprintf(q, "%02hhx)", status->media_type);
+ return buf;
+ }
+ }
}
-void ql_decode_print_status(FILE *f, const ql_status_t *status, unsigned flags)
+void ql_decode_print_status(FILE * f, const ql_status_t * status, unsigned flags)
{
- if (!status)
- return;
-
- const char *fmt_s = "%17s: %s\n";
- const char *fmt_u = "%17s: %u\n";
- if (flags & QL_DECODE_MODEL)
- fprintf(f, fmt_s, "Printer", ql_decode_model(status));
- if (flags & QL_DECODE_MODE)
- fprintf(f, fmt_s, "Mode", ql_decode_mode(status));
- if (flags & QL_DECODE_ERROR)
- fprintf(f, fmt_s, "Errors", ql_decode_errors(status));
- if (flags & QL_DECODE_MEDIA)
- {
- fprintf(f, fmt_s, "Media type", ql_decode_media_type(status));
- fprintf(f, fmt_u, "Media width (mm)", status->media_width_mm);
- if (status->media_type != QL_MEDIA_TYPE_CONTINUOUS)
- fprintf(f, fmt_u, "Media length (mm)", status->media_length_mm);
- }
+ if (!status)
+ return;
+
+ const char *fmt_s = "%17s: %s\n";
+ const char *fmt_u = "%17s: %u\n";
+ if (flags & QL_DECODE_MODEL)
+ fprintf(f, fmt_s, "Printer", ql_decode_model(status));
+ if (flags & QL_DECODE_MODE)
+ fprintf(f, fmt_s, "Mode", ql_decode_mode(status));
+ if (flags & QL_DECODE_ERROR)
+ fprintf(f, fmt_s, "Errors", ql_decode_errors(status));
+ if (flags & QL_DECODE_MEDIA) {
+ fprintf(f, fmt_s, "Media type", ql_decode_media_type(status));
+ fprintf(f, fmt_u, "Media width (mm)", status->media_width_mm);
+ if (status->media_type != QL_MEDIA_TYPE_CONTINUOUS)
+ fprintf(f, fmt_u, "Media length (mm)", status->media_length_mm);
+ }
}
-