mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-12-24 21:58:59 +01:00
Add a CLI tool
For now it only prints the JSON representation of the information exposed by libdisplay-info. A JSON schema [1] and libjsonschema [2] are used to encode JSON. [1]: https://json-schema.org/ [2]: https://sr.ht/~emersion/libjsonschema/ Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
parent
fc9a605611
commit
f0e5199b50
4 changed files with 223 additions and 0 deletions
|
@ -85,4 +85,5 @@ di_dep = declare_dependency(
|
|||
meson.override_dependency('libdisplay-info', di_dep)
|
||||
|
||||
subdir('di-edid-decode')
|
||||
subdir('tool')
|
||||
subdir('test')
|
||||
|
|
129
tool/main.c
Normal file
129
tool/main.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libdisplay-info/edid.h>
|
||||
#include <libdisplay-info/info.h>
|
||||
|
||||
#include "schema.h"
|
||||
|
||||
static struct edid *
|
||||
get_edid(const struct di_edid *edid)
|
||||
{
|
||||
const struct di_edid_vendor_product *vendor_product;
|
||||
char manufacturer[4];
|
||||
struct edid *wire_edid;
|
||||
struct edid_vendor_product *wire_vendor_product;
|
||||
|
||||
vendor_product = di_edid_get_vendor_product(edid);
|
||||
|
||||
snprintf(manufacturer, sizeof(manufacturer), "%.3s", vendor_product->manufacturer);
|
||||
|
||||
wire_vendor_product = malloc(sizeof(*wire_vendor_product));
|
||||
*wire_vendor_product = (struct edid_vendor_product) {
|
||||
.manufacturer = strdup(manufacturer),
|
||||
.product = vendor_product->product,
|
||||
.serial = vendor_product->serial,
|
||||
.model_year = vendor_product->model_year,
|
||||
.manufacture_week = vendor_product->manufacture_week,
|
||||
.manufacture_year = vendor_product->manufacture_year,
|
||||
};
|
||||
|
||||
wire_edid = malloc(sizeof(*wire_edid));
|
||||
*wire_edid = (struct edid) {
|
||||
.version = di_edid_get_version(edid),
|
||||
.revision = di_edid_get_revision(edid),
|
||||
.vendor_product = wire_vendor_product,
|
||||
};
|
||||
|
||||
return wire_edid;
|
||||
}
|
||||
|
||||
static struct display_info *
|
||||
get_info(const struct di_info *info)
|
||||
{
|
||||
const struct di_edid *edid;
|
||||
struct edid *wire_edid = NULL;
|
||||
struct display_info *wire_info;
|
||||
|
||||
edid = di_info_get_edid(info);
|
||||
if (edid != NULL)
|
||||
wire_edid = get_edid(edid);
|
||||
|
||||
wire_info = malloc(sizeof(*wire_info));
|
||||
*wire_info = (struct display_info) {
|
||||
.edid = wire_edid,
|
||||
};
|
||||
|
||||
return wire_info;
|
||||
}
|
||||
|
||||
static const char usage[] =
|
||||
"usage: libdisplay-info <edid>\n";
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *in;
|
||||
static uint8_t raw[32 * 1024];
|
||||
size_t size = 0;
|
||||
struct di_info *info;
|
||||
int opt;
|
||||
struct jsch_encoder *enc;
|
||||
struct display_info *wire_info;
|
||||
|
||||
in = stdin;
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
opt = getopt_long(argc, argv, "h", long_options, &option_index);
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
fprintf(stderr, "%s", usage);
|
||||
return opt == 'h' ? 0 : 1;
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
in = fopen(argv[1], "r");
|
||||
if (!in) {
|
||||
perror("failed to open input file");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (!feof(in)) {
|
||||
size += fread(&raw[size], 1, sizeof(raw) - size, in);
|
||||
if (ferror(in)) {
|
||||
perror("fread failed");
|
||||
return 1;
|
||||
} else if (size >= sizeof(raw)) {
|
||||
fprintf(stderr, "input too large\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
info = di_info_parse_edid(raw, size);
|
||||
if (!info) {
|
||||
perror("di_edid_parse failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wire_info = get_info(info);
|
||||
|
||||
enc = jsch_encoder_create(stdout);
|
||||
display_info_encode(wire_info, enc);
|
||||
jsch_encoder_destroy(enc);
|
||||
printf("\n");
|
||||
|
||||
display_info_finish(wire_info);
|
||||
free(wire_info);
|
||||
di_info_destroy(info);
|
||||
return 0;
|
||||
}
|
40
tool/meson.build
Normal file
40
tool/meson.build
Normal file
|
@ -0,0 +1,40 @@
|
|||
libjsonschema = dependency('libjsonschema')
|
||||
libjsonschema_native = dependency('libjsonschema', native: true)
|
||||
libjsonschema_tool_path = libjsonschema_native.get_variable(pkgconfig: 'tool', internal: 'tool')
|
||||
libjsonschema_tool = find_program(libjsonschema_tool_path, native: true)
|
||||
|
||||
schema = files('schema.json')
|
||||
|
||||
schema_header = custom_target(
|
||||
'schema.h',
|
||||
command: [libjsonschema_tool, 'gen-header', '@INPUT@'],
|
||||
input: schema,
|
||||
output: 'schema.h',
|
||||
capture: true,
|
||||
)
|
||||
|
||||
schema_code = custom_target(
|
||||
'schema.c',
|
||||
command: [libjsonschema_tool, 'gen-code', '@INPUT@'],
|
||||
input: schema,
|
||||
output: 'schema.c',
|
||||
capture: true,
|
||||
)
|
||||
|
||||
schema_lib = static_library(
|
||||
'schema',
|
||||
schema_code,
|
||||
c_args: cc.get_supported_arguments(['-Wno-declaration-after-statement']),
|
||||
dependencies: libjsonschema,
|
||||
)
|
||||
|
||||
executable(
|
||||
'libdisplay-info',
|
||||
[
|
||||
'main.c',
|
||||
schema_header,
|
||||
],
|
||||
dependencies: [di_dep, libjsonschema],
|
||||
link_with: schema_lib,
|
||||
install: true,
|
||||
)
|
53
tool/schema.json
Normal file
53
tool/schema.json
Normal file
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$ref": "#/$defs/edid",
|
||||
"$defs": {
|
||||
"uint16": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 65535
|
||||
},
|
||||
"uint32": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"display_info": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"edid": { "$ref": "#/$defs/edid" }
|
||||
}
|
||||
},
|
||||
"edid": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"version": { "type": "integer" },
|
||||
"revision": { "type": "integer" },
|
||||
"vendor_product": { "$ref": "#/$defs/edid_vendor_product" }
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"revision",
|
||||
"vendor_product"
|
||||
]
|
||||
},
|
||||
"edid_vendor_product": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"manufacturer": { "type": "string" },
|
||||
"product": { "$ref": "#/$defs/uint16" },
|
||||
"serial": { "$ref": "#/$defs/uint32" },
|
||||
"model_year": { "type": "integer" },
|
||||
"manufacture_week": { "type": "integer" },
|
||||
"manufacture_year": { "type": "integer" }
|
||||
},
|
||||
"required": [
|
||||
"manufacturer",
|
||||
"product"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue