diff --git a/command_line.c b/command_line.c new file mode 100644 index 0000000..068f168 --- /dev/null +++ b/command_line.c @@ -0,0 +1,123 @@ +/** + * Copyright 2021 Johannes Marbach + * + * This file is part of buffyboard, hereafter referred to as the program. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "command_line.h" + +#include +#include +#include + + +/** + * Static prototypes + */ + +/** + * Initialise a command line options struct with default values and exit on failure. + * + * @param opts pointer to the options struct + */ +static void init_opts(bb_cli_opts *opts); + +/** + * Output usage instructions. + */ +static void print_usage(); + + +/** + * Static functions + */ + +static void init_opts(bb_cli_opts *opts) { + opts->rotation = LV_DISP_ROT_NONE; +} + +static void print_usage() { + fprintf(stderr, + /*-------------------------------- 78 CHARS --------------------------------*/ + "Usage: buffyboard [OPTION]\n" + "\n" + "Mandatory arguments to long options are mandatory for short options too.\n" + " -r, --rotate=[0-3] Rotate the UI to the given orientation.\n" + " 0 - normal orientation (0 degree)\n" + " 1 - clockwise orientation (90 degrees)\n" + " 2 - upside down orientation (180 degrees)\n" + " 3 - counterclockwise orientation (270 degrees)\n" + " The values match the ones provided by the kernel in\n" + " /sys/class/graphics/fbcon/rotate.\n" + " -h, --help Print this message and exit\n" + " -V, --version Print the buffyboard version and exit\n"); + /*-------------------------------- 78 CHARS --------------------------------*/ +} + + +/** + * Public functions + */ + +void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) { + init_opts(opts); + + struct option long_opts[] = { + { "rotate", required_argument, NULL, 'r' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } + }; + + int opt, index = 0; + + while ((opt = getopt_long(argc, argv, "r:hV", long_opts, &index)) != -1) { + switch (opt) { + case 'r': { + int orientation; + if (sscanf(optarg, "%i", &orientation) != 1 || orientation < 0 || orientation > 3) { + fprintf(stderr, "Invalid orientation argument \"%s\"\n", optarg); + exit(EXIT_FAILURE); + } + switch (orientation) { + case 0: + opts->rotation = LV_DISP_ROT_NONE; + break; + case 1: + opts->rotation = LV_DISP_ROT_270; + break; + case 2: + opts->rotation = LV_DISP_ROT_180; + break; + case 3: + opts->rotation = LV_DISP_ROT_90; + break; + } + break; + } + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + case 'V': + fprintf(stderr, "buffyboard %s\n", BB_VERSION); + exit(0); + default: + print_usage(); + exit(EXIT_FAILURE); + } + } +} diff --git a/command_line.h b/command_line.h new file mode 100644 index 0000000..d80ee70 --- /dev/null +++ b/command_line.h @@ -0,0 +1,43 @@ +/** + * Copyright 2021 Johannes Marbach + * + * This file is part of buffyboard, hereafter referred to as the program. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef BB_COMMAND_LINE_H +#define BB_COMMAND_LINE_H + +#include "lvgl/lvgl.h" + +/** + * Options parsed from command line arguments + */ +typedef struct { + /* Display rotation */ + lv_disp_rot_t rotation; +} bb_cli_opts; + +/** + * Parse command line arguments and exit on failure. + * + * @param argc number of provided command line arguments + * @param argv arguments as an array of strings + * @param opts pointer for writing the parsed options into + */ +void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts); + +#endif /* BB_COMMAND_LINE_H */ diff --git a/main.c b/main.c index de7c535..a4d8bf9 100644 --- a/main.c +++ b/main.c @@ -18,6 +18,7 @@ */ +#include "command_line.h" #include "indev.h" #include "sq2lv_layouts.h" #include "terminal.h" @@ -50,6 +51,8 @@ LV_FONT_DECLARE(font_32); * Static variables */ +bb_cli_opts cli_opts; + static bool resize_terminals = false; static lv_obj_t *keyboard = NULL; static lv_style_t style_text_normal; @@ -243,7 +246,10 @@ static void pop_checked_modifier_keys(void) { * Main */ -int main(void) { +int main(int argc, char *argv[]) { + /* Parse command line options */ + bb_cli_parse_opts(argc, argv, &cli_opts); + /* Prepare for terminal resizing and reset */ resize_terminals = bb_terminal_init(2.0f / 3.0f); if (resize_terminals) { @@ -276,18 +282,18 @@ int main(void) { static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = fbdev_flush; - disp_drv.rotated = LV_DISP_ROT_NONE; + disp_drv.rotated = cli_opts.rotation; disp_drv.sw_rotate = true; disp_drv.physical_hor_res = hor_res_phys; disp_drv.physical_ver_res = ver_res_phys; - switch (disp_drv.rotated) { + switch (cli_opts.rotation) { case LV_DISP_ROT_NONE: case LV_DISP_ROT_180: { lv_coord_t denom = keyboard_height_denominator(hor_res_phys, ver_res_phys); disp_drv.hor_res = hor_res_phys; disp_drv.ver_res = ver_res_phys / denom; disp_drv.offset_x = 0; - disp_drv.offset_y = (disp_drv.rotated == LV_DISP_ROT_NONE) ? (denom - 1) * ver_res_phys / denom : 0; + disp_drv.offset_y = (cli_opts.rotation == LV_DISP_ROT_NONE) ? (denom - 1) * ver_res_phys / denom : 0; break; } case LV_DISP_ROT_90: @@ -295,7 +301,7 @@ int main(void) { lv_coord_t denom = keyboard_height_denominator(ver_res_phys, hor_res_phys); disp_drv.hor_res = hor_res_phys / denom; disp_drv.ver_res = ver_res_phys; - disp_drv.offset_x = (disp_drv.rotated == LV_DISP_ROT_90) ? (denom - 1) * hor_res_phys / denom : 0; + disp_drv.offset_x = (cli_opts.rotation == LV_DISP_ROT_90) ? (denom - 1) * hor_res_phys / denom : 0; disp_drv.offset_y = 0; break; } diff --git a/meson.build b/meson.build index 2cd3ac9..d9093f9 100644 --- a/meson.build +++ b/meson.build @@ -19,12 +19,15 @@ project( 'buffyboard', 'c', - version: '0.0.0', + version: '0.1.0', default_options: 'warning_level=1', meson_version: '>=0.53.0' ) +add_project_arguments('-DBB_VERSION="@0@"'.format(meson.project_version()), language: ['c']) + buffyboard_sources = [ + 'command_line.c', 'cursor.c', 'font_32.c', 'indev.c',