diff options
author | Alexey Gladkov <gladkov.alexey@gmail.com> | 2020-04-20 13:43:35 +0200 |
---|---|---|
committer | Alexey Gladkov <gladkov.alexey@gmail.com> | 2020-04-20 16:17:00 +0200 |
commit | 40ebac961647ea93ecdd99d4b252b26419b812fe (patch) | |
tree | 66dcd2b76162b97ec05d1d7f4afe2be3b4fc213f | |
parent | d8372df646ba9b7ff514c3cdc034146c83cdc51f (diff) | |
download | kbd-40ebac961647ea93ecdd99d4b252b26419b812fe.tar.gz |
Split different methods of getting a font into different functions
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
-rw-r--r-- | src/libkfont/kdfontop.c | 135 |
1 files changed, 92 insertions, 43 deletions
diff --git a/src/libkfont/kdfontop.c b/src/libkfont/kdfontop.c index cd93ce9d..5a496e45 100644 --- a/src/libkfont/kdfontop.c +++ b/src/libkfont/kdfontop.c @@ -10,6 +10,7 @@ #include <errno.h> #include <stdlib.h> /* free() */ #include <string.h> +#include <limits.h> #include <sys/ioctl.h> #include <linux/kd.h> @@ -45,75 +46,95 @@ nonzero: return h; } -/* - * May be called with buf==NULL if we only want info. - * May be called with width==NULL and height==NULL. - * Must not exit - we may have cleanup to do. - */ -int -kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned int *count, - unsigned int *width, unsigned int *height) +static int +get_font_kdfontop(struct kfont_context *ctx, int consolefd, + unsigned char *buf, + unsigned int *count, + unsigned int *width, + unsigned int *height) { - struct consolefontdesc cfd; struct console_font_op cfo; - int i; - /* First attempt: KDFONTOP */ cfo.op = KD_FONT_OP_GET; cfo.flags = 0; cfo.width = cfo.height = 32; cfo.charcount = *count; cfo.data = buf; - i = ioctl(fd, KDFONTOP, &cfo); - if (!i) { - *count = cfo.charcount; - if (height) - *height = cfo.height; - if (width) - *width = cfo.width; - return 0; + errno = 0; + + if (ioctl(consolefd, KDFONTOP, &cfo)) { + if (errno != ENOSYS && errno != EINVAL) { + KFONT_ERR(ctx, "ioctl(KDFONTOP): %m"); + return -1; + } + return 1; } - if (errno != ENOSYS && errno != EINVAL) { - KFONT_ERR(ctx, "ioctl(KDFONTOP): %m"); + *count = cfo.charcount; + if (height) + *height = cfo.height; + if (width) + *width = cfo.width; + return 0; +} + +static int +get_font_giofontx(struct kfont_context *ctx, int consolefd, + unsigned char *buf, + unsigned int *count, + unsigned int *width, + unsigned int *height) +{ + struct consolefontdesc cfd; + + if (*count > USHRT_MAX) { + KFONT_ERR(ctx, _("GIO_FONTX: the number of characters in the font cannot be more than %d"), USHRT_MAX); return -1; } - /* The other methods do not support width != 8 */ - if (width) - *width = 8; - /* Second attempt: GIO_FONTX */ - cfd.charcount = *count; + cfd.charcount = (unsigned short) *count; cfd.charheight = 0; cfd.chardata = (char *)buf; - i = ioctl(fd, GIO_FONTX, &cfd); - if (!i) { - *count = cfd.charcount; - if (height) - *height = cfd.charheight; - return 0; - } + errno = 0; - if (errno != ENOSYS && errno != EINVAL) { - KFONT_ERR(ctx, "ioctl(GIO_FONTX): %m"); - return -1; + if (ioctl(consolefd, GIO_FONTX, &cfd)) { + if (errno != ENOSYS && errno != EINVAL) { + KFONT_ERR(ctx, "ioctl(GIO_FONTX): %m"); + return -1; + } + return 1; } - /* Third attempt: GIO_FONT */ - if (*count < 256) { - KFONT_ERR(ctx, _("bug: getfont called with count<256")); + *count = cfd.charcount; + if (height) + *height = cfd.charheight; + if (width) + *width = 8; /* This method do not support width != 8 */ + return 0; +} + +static int +get_font_giofont(struct kfont_context *ctx, int consolefd, + unsigned char *buf, + unsigned int *count, + unsigned int *width, + unsigned int *height) +{ + if (*count != 256) { + KFONT_ERR(ctx, _("getfont called with count<256")); return -1; } if (!buf) { - KFONT_ERR(ctx, _("bug: getfont using GIO_FONT needs buf.")); + KFONT_ERR(ctx, _("getfont using GIO_FONT needs buf")); return -1; } - i = ioctl(fd, GIO_FONT, buf); - if (i) { + errno = 0; + + if (ioctl(consolefd, GIO_FONT, buf)) { KFONT_ERR(ctx, "ioctl(GIO_FONT): %m"); return -1; } @@ -121,10 +142,38 @@ kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, unsigned i *count = 256; if (height) *height = 0; /* undefined, at most 32 */ - + if (width) + *width = 8; /* This method do not support width != 8 */ return 0; } +/* + * May be called with buf==NULL if we only want info. + * May be called with width==NULL and height==NULL. + * Must not exit - we may have cleanup to do. + */ +int +kfont_get_font(struct kfont_context *ctx, int fd, unsigned char *buf, + unsigned int *count, + unsigned int *width, + unsigned int *height) +{ + int ret; + + /* First attempt: KDFONTOP */ + ret = get_font_kdfontop(ctx, fd, buf, count, width, height); + if (ret <= 0) + return ret; + + /* Second attempt: GIO_FONTX */ + ret = get_font_giofontx(ctx, fd, buf, count, width, height); + if (ret <= 0) + return ret; + + /* Third attempt: GIO_FONT */ + return get_font_giofont(ctx, fd, buf, count, width, height); +} + int unsigned kfont_get_fontsize(struct kfont_context *ctx, int fd) { |