parent
09061a5978
commit
51b1945744
8 changed files with 348 additions and 11 deletions
15
README.md
15
README.md
|
|
@ -53,6 +53,21 @@ Below is a summary of contributions upstreamed thus far.
|
|||
- [Automatic device discovery via libinput] (✅ merged)
|
||||
- [Make it possible to use multiple devices with the libinput and XKB drivers] (⏳ in review)
|
||||
|
||||
# Usage
|
||||
|
||||
For an overview of available command line options, run unl0kr with the `-h` or `--help` argument.
|
||||
|
||||
```
|
||||
$ unl0kr --help
|
||||
Usage: unl0kr [OPTION]
|
||||
|
||||
Mandatory arguments to long options are mandatory for short options too.
|
||||
-g, --geometry=NxM Force a display size of N horizontal times M vertical pixels
|
||||
-h, --help Print this message and exit
|
||||
-v, --verbose Enable more detailed logging output on STDERR
|
||||
-V, --version Print the unl0kr version and exit
|
||||
```
|
||||
|
||||
# Development
|
||||
|
||||
## Dependencies
|
||||
|
|
|
|||
108
command_line.c
Normal file
108
command_line.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* Copyright 2021 Johannes Marbach
|
||||
*
|
||||
* This file is part of unl0kr, 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "command_line.h"
|
||||
|
||||
#include "unl0kr.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/**
|
||||
* Static prototypes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise a command line options struct with default values.
|
||||
*
|
||||
* @param opts pointer to the options struct
|
||||
*/
|
||||
static void init_opts(ul_cli_opts *cli_opts);
|
||||
|
||||
/**
|
||||
* Output usage instructions.
|
||||
*/
|
||||
static void print_usage();
|
||||
|
||||
|
||||
/**
|
||||
* Static functions
|
||||
*/
|
||||
|
||||
static void init_opts(ul_cli_opts *cli_opts) {
|
||||
cli_opts->hor_res = -1;
|
||||
cli_opts->ver_res = -1;
|
||||
cli_opts->verbose = false;
|
||||
}
|
||||
|
||||
static void print_usage() {
|
||||
fprintf(stderr,
|
||||
"Usage: unl0kr [OPTION]\n"
|
||||
"\n"
|
||||
"Mandatory arguments to long options are mandatory for short options too.\n"
|
||||
" -g, --geometry=NxM Force a display size of N horizontal times M vertical pixels\n"
|
||||
" -h, --help Print this message and exit\n"
|
||||
" -v, --verbose Enable more detailed logging output on STDERR\n"
|
||||
" -V, --version Print the unl0kr version and exit\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *cli_opts) {
|
||||
init_opts(cli_opts);
|
||||
|
||||
struct option opts[] = {
|
||||
{ "geometry", required_argument, NULL, 'g' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
int opt, index = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "g:hvV", opts, &index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'g':
|
||||
if (sscanf(optarg, "%ix%i", &(cli_opts->hor_res), &(cli_opts->ver_res)) != 2) {
|
||||
fprintf(stderr, "Error: invalid geometry argument \"%s\"\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
cli_opts->verbose = true;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "unl0kr %s\n", UL_VERSION);
|
||||
exit(0);
|
||||
default:
|
||||
print_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
command_line.h
Normal file
47
command_line.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Copyright 2021 Johannes Marbach
|
||||
*
|
||||
* This file is part of unl0kr, 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UL_COMMAND_LINE_H
|
||||
#define UL_COMMAND_LINE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Options parsed from command line arguments
|
||||
*/
|
||||
typedef struct {
|
||||
/* Horizontal display resolution */
|
||||
int hor_res;
|
||||
/* Vertical display resolution */
|
||||
int ver_res;
|
||||
/* Verbose mode. If true, provide more detailed logging output on STDERR. */
|
||||
bool verbose;
|
||||
} ul_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 cli_opts pointer for writing the parsed options into
|
||||
*/
|
||||
void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *cli_opts);
|
||||
|
||||
#endif /* UL_COMMAND_LINE_H */
|
||||
54
log.c
Normal file
54
log.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Copyright 2021 Johannes Marbach
|
||||
*
|
||||
* This file is part of unl0kr, 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
/**
|
||||
* Static variables
|
||||
*/
|
||||
|
||||
static ul_log_level log_level = UL_LOG_LEVEL_ERROR;
|
||||
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
void ul_set_log_level(ul_log_level level) {
|
||||
log_level = level;
|
||||
}
|
||||
|
||||
void ul_log(ul_log_level level, const char *format, ...) {
|
||||
if (level > log_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ul_print_cb(const char *msg) {
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "%s\n", msg);
|
||||
}
|
||||
59
log.h
Normal file
59
log.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright 2021 Johannes Marbach
|
||||
*
|
||||
* This file is part of unl0kr, 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UL_LOG_H
|
||||
#define UL_LOG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* Log levels
|
||||
*/
|
||||
typedef enum {
|
||||
/* Errors only */
|
||||
UL_LOG_LEVEL_ERROR = 0,
|
||||
/* Include non-errors in log */
|
||||
UL_LOG_LEVEL_VERBOSE = 1
|
||||
} ul_log_level;
|
||||
|
||||
/**
|
||||
* Set the log level.
|
||||
*
|
||||
* @param level new log level value
|
||||
*/
|
||||
void ul_set_log_level(ul_log_level level);
|
||||
|
||||
/**
|
||||
* Log a message.
|
||||
*
|
||||
* @param level log level of the message
|
||||
* @param format message format string
|
||||
* @param ... parameters to fill into the format string
|
||||
*/
|
||||
void ul_log(ul_log_level level, const char *format, ...);
|
||||
|
||||
/**
|
||||
* Handle an LVGL log message.
|
||||
*
|
||||
* @param msg message to print
|
||||
*/
|
||||
void ul_print_cb(const char *msg);
|
||||
|
||||
#endif /* UL_LOG_H */
|
||||
40
main.c
40
main.c
|
|
@ -18,9 +18,12 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "command_line.h"
|
||||
#include "cursor.h"
|
||||
#include "libinput_multi.h"
|
||||
#include "libinput_xkb.h"
|
||||
#include "log.h"
|
||||
#include "unl0kr.h"
|
||||
|
||||
#include "lv_drivers/display/fbdev.h"
|
||||
#include "lv_drivers/indev/libinput_drv.h"
|
||||
|
|
@ -329,17 +332,36 @@ static void keyboard_ready_cb(lv_event_t *event) {
|
|||
* Main
|
||||
*/
|
||||
|
||||
int main(void) {
|
||||
/* Initialise lvgl and framebuffer driver */
|
||||
lv_init();
|
||||
fbdev_init();
|
||||
int main(int argc, char *argv[]) {
|
||||
/* Parse command line options */
|
||||
ul_cli_opts opts;
|
||||
ul_cli_parse_opts(argc, argv, &opts);
|
||||
|
||||
/* Query display size */
|
||||
/* Set up log level */
|
||||
if (opts.verbose) {
|
||||
ul_set_log_level(UL_LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
|
||||
/* Announce ourselves */
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "unl0kr %s", UL_VERSION);
|
||||
|
||||
/* Initialise LVGL and set up logging callback */
|
||||
lv_init();
|
||||
lv_log_register_print_cb(ul_print_cb);
|
||||
|
||||
/* Initialise framebuffer driver and query display size */
|
||||
fbdev_init();
|
||||
uint32_t hor_res;
|
||||
uint32_t ver_res;
|
||||
fbdev_get_sizes(&hor_res, &ver_res);
|
||||
|
||||
// hor_res = ver_res * 0.6; /* Simulate mobile screen */
|
||||
/* Override display size with command line options if necessary */
|
||||
if (opts.hor_res > 0) {
|
||||
hor_res = LV_MIN(hor_res, opts.hor_res);
|
||||
}
|
||||
if (opts.ver_res > 0) {
|
||||
ver_res = LV_MIN(ver_res, opts.ver_res);
|
||||
}
|
||||
|
||||
/* Prepare display buffer */
|
||||
const size_t buf_size = hor_res * ver_res / 10; /* At least 1/10 of the display size is recommended */
|
||||
|
|
@ -364,7 +386,7 @@ int main(void) {
|
|||
lv_indev_t *keyboard_indevs[MAX_KEYBOARDS] = { NULL, NULL, NULL };
|
||||
size_t num_keyboards = libinput_find_devs(LIBINPUT_CAPABILITY_KEYBOARD, keyboard_devices, MAX_KEYBOARDS, false);
|
||||
for (int i = 0; i < num_keyboards; ++i) {
|
||||
printf("found keyboard device %s\n", keyboard_devices[i]);
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting keyboard device %s\n", keyboard_devices[i]);
|
||||
lv_indev_drv_init(&keyboard_indev_drvs[i]);
|
||||
keyboard_indev_drvs[i].type = LV_INDEV_TYPE_KEYPAD;
|
||||
keyboard_indev_drvs[i].read_cb = libinput_multi_read;
|
||||
|
|
@ -385,7 +407,7 @@ int main(void) {
|
|||
lv_indev_t *pointer_indevs[MAX_POINTER_DEVICES] = { NULL, NULL, NULL, NULL };
|
||||
size_t num_pointer_devices = libinput_find_devs(LIBINPUT_CAPABILITY_POINTER, pointer_devices, MAX_POINTER_DEVICES, false);
|
||||
for (int i = 0; i < num_pointer_devices; ++i) {
|
||||
printf("found pointer device %s\n", pointer_devices[i]);
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting pointer device %s\n", pointer_devices[i]);
|
||||
lv_indev_drv_init(&pointer_indev_drvs[i]);
|
||||
pointer_indev_drvs[i].type = LV_INDEV_TYPE_POINTER;
|
||||
pointer_indev_drvs[i].read_cb = libinput_multi_read;
|
||||
|
|
@ -410,7 +432,7 @@ int main(void) {
|
|||
lv_indev_drv_t touchscreen_indev_drvs[MAX_TOUCHSCREENS];
|
||||
size_t num_touchscreens = libinput_find_devs(LIBINPUT_CAPABILITY_TOUCH, touchscreens, MAX_TOUCHSCREENS, false);
|
||||
for (int i = 0; i < num_touchscreens; ++i) {
|
||||
printf("found touchscreen %s\n", touchscreens[i]);
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting touchscreen device %s\n", touchscreens[i]);
|
||||
lv_indev_drv_init(&touchscreen_indev_drvs[i]);
|
||||
touchscreen_indev_drvs[i].type = LV_INDEV_TYPE_POINTER;
|
||||
touchscreen_indev_drvs[i].read_cb = libinput_multi_read;
|
||||
|
|
|
|||
|
|
@ -24,11 +24,15 @@ project(
|
|||
meson_version: '>=0.53.0'
|
||||
)
|
||||
|
||||
add_project_arguments('-DUL_VERSION="@0@"'.format(meson.project_version()), language: ['c'])
|
||||
|
||||
unl0kr_sources = [
|
||||
'command_line.c',
|
||||
'cursor.c',
|
||||
'main.c',
|
||||
'log.c',
|
||||
'libinput_multi.c',
|
||||
'libinput_xkb.c',
|
||||
'main.c',
|
||||
'montserrat_extended_32.c',
|
||||
'sq2lv_layouts.c',
|
||||
]
|
||||
|
|
|
|||
28
unl0kr.h
Normal file
28
unl0kr.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Copyright 2021 Johannes Marbach
|
||||
*
|
||||
* This file is part of unl0kr, 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UL_UNL0KR_H
|
||||
#define UL_UNL0KR_H
|
||||
|
||||
#ifndef UL_VERSION
|
||||
#define UL_VERSION "?" /* Just to silence IDE warning. Real version injected by meson during build. */
|
||||
#endif
|
||||
|
||||
#endif /* UL_UNL0KR_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue