2019-06-12 20:08:54 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
2019-09-21 20:01:55 +02:00
|
|
|
#include <ctype.h>
|
2019-06-12 20:08:54 +02:00
|
|
|
#include <stdbool.h>
|
2019-06-13 21:23:52 +02:00
|
|
|
#include <locale.h>
|
2019-07-03 09:46:13 +02:00
|
|
|
#include <getopt.h>
|
2019-07-03 15:16:38 +02:00
|
|
|
#include <errno.h>
|
2019-06-12 20:08:54 +02:00
|
|
|
|
2019-07-29 20:13:26 +02:00
|
|
|
#include <sys/sysinfo.h>
|
2019-08-12 21:22:38 +02:00
|
|
|
|
2019-06-12 20:08:54 +02:00
|
|
|
#define LOG_MODULE "main"
|
2019-10-28 18:35:16 +01:00
|
|
|
#define LOG_ENABLE_DBG 0
|
2019-06-12 20:08:54 +02:00
|
|
|
#include "log.h"
|
2019-06-13 15:19:10 +02:00
|
|
|
|
2019-07-16 11:52:22 +02:00
|
|
|
#include "config.h"
|
2019-10-27 11:46:18 +01:00
|
|
|
#include "fdm.h"
|
2019-06-13 16:24:35 +02:00
|
|
|
#include "font.h"
|
2019-06-12 20:08:54 +02:00
|
|
|
#include "shm.h"
|
2019-06-15 22:22:44 +02:00
|
|
|
#include "terminal.h"
|
2019-10-19 22:09:52 +02:00
|
|
|
#include "version.h"
|
2019-06-19 14:17:43 +02:00
|
|
|
|
|
|
|
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
2019-06-26 19:33:39 +02:00
|
|
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
2019-06-12 20:08:54 +02:00
|
|
|
|
2019-08-11 16:03:29 +02:00
|
|
|
static void
|
|
|
|
|
print_usage(const char *prog_name)
|
|
|
|
|
{
|
|
|
|
|
printf("Usage: %s [OPTION]...\n", prog_name);
|
|
|
|
|
printf("\n");
|
|
|
|
|
printf("Options:\n");
|
2019-09-21 20:01:55 +02:00
|
|
|
printf(" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
|
2019-08-23 17:26:41 +02:00
|
|
|
" -t,--term=TERM value to set the environment variable TERM to (foot)\n"
|
|
|
|
|
" -g,--geometry=WIDTHxHEIGHT set initial width and height\n"
|
|
|
|
|
" -v,--version show the version number and quit\n");
|
2019-08-11 16:03:29 +02:00
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-12 20:08:54 +02:00
|
|
|
int
|
2019-07-03 09:46:13 +02:00
|
|
|
main(int argc, char *const *argv)
|
2019-06-12 20:08:54 +02:00
|
|
|
{
|
|
|
|
|
int ret = EXIT_FAILURE;
|
|
|
|
|
|
2019-09-26 18:41:39 +02:00
|
|
|
/* Startup notifications; we don't support it, but must ensure we
|
|
|
|
|
* don't pass this on to programs launched by us */
|
|
|
|
|
unsetenv("DESKTOP_STARTUP_ID");
|
|
|
|
|
|
2019-07-17 10:12:14 +02:00
|
|
|
struct config conf = {NULL};
|
|
|
|
|
if (!config_load(&conf))
|
|
|
|
|
return ret;
|
2019-07-16 11:52:22 +02:00
|
|
|
|
2019-08-11 16:03:29 +02:00
|
|
|
const char *const prog_name = argv[0];
|
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
static const struct option longopts[] = {
|
2019-08-23 17:26:41 +02:00
|
|
|
{"term", required_argument, 0, 't'},
|
|
|
|
|
{"font", required_argument, 0, 'f'},
|
|
|
|
|
{"geometry", required_argument, 0, 'g'},
|
|
|
|
|
{"version", no_argument, 0, 'v'},
|
|
|
|
|
{"help", no_argument, 0, 'h'},
|
|
|
|
|
{NULL, no_argument, 0, 0},
|
2019-07-03 09:46:13 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
while (true) {
|
2019-08-23 17:26:41 +02:00
|
|
|
int c = getopt_long(argc, argv, ":t:f:g:vh", longopts, NULL);
|
2019-07-03 09:46:13 +02:00
|
|
|
if (c == -1)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
switch (c) {
|
2019-07-18 14:34:45 +02:00
|
|
|
case 't':
|
|
|
|
|
free(conf.term);
|
|
|
|
|
conf.term = strdup(optarg);
|
|
|
|
|
break;
|
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
case 'f':
|
2019-07-30 18:04:28 +02:00
|
|
|
tll_free_and_free(conf.fonts, free);
|
2019-09-21 20:01:55 +02:00
|
|
|
for (char *font = strtok(optarg, ","); font != NULL; font = strtok(NULL, ",")) {
|
|
|
|
|
|
|
|
|
|
/* Strip leading spaces */
|
|
|
|
|
while (*font != '\0' && isspace(*font))
|
|
|
|
|
font++;
|
|
|
|
|
|
|
|
|
|
/* Strip trailing spaces */
|
|
|
|
|
char *end = font + strlen(font);
|
|
|
|
|
assert(*end == '\0');
|
|
|
|
|
end--;
|
|
|
|
|
while (end > font && isspace(*end))
|
|
|
|
|
*(end--) = '\0';
|
|
|
|
|
|
|
|
|
|
if (strlen(font) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
tll_push_back(conf.fonts, strdup(font));
|
|
|
|
|
}
|
2019-07-03 09:46:13 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-08-23 17:26:41 +02:00
|
|
|
case 'g': {
|
|
|
|
|
unsigned width, height;
|
|
|
|
|
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
|
|
|
|
|
fprintf(stderr, "error: invalid geometry: %s\n", optarg);
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conf.width = width;
|
|
|
|
|
conf.height = height;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-11 16:03:29 +02:00
|
|
|
case 'v':
|
|
|
|
|
printf("foot version %s\n", FOOT_VERSION);
|
2019-10-30 18:06:47 +01:00
|
|
|
config_free(conf);
|
2019-08-11 16:03:29 +02:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
case 'h':
|
2019-08-11 16:03:29 +02:00
|
|
|
print_usage(prog_name);
|
2019-10-30 18:06:47 +01:00
|
|
|
config_free(conf);
|
2019-08-11 16:03:29 +02:00
|
|
|
return EXIT_SUCCESS;
|
2019-07-03 09:46:13 +02:00
|
|
|
|
|
|
|
|
case ':':
|
|
|
|
|
fprintf(stderr, "error: -%c: missing required argument\n", optopt);
|
2019-10-30 18:06:47 +01:00
|
|
|
config_free(conf);
|
2019-07-03 09:46:13 +02:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
|
|
|
|
|
case '?':
|
|
|
|
|
fprintf(stderr, "error: -%c: invalid option\n", optopt);
|
2019-10-30 18:06:47 +01:00
|
|
|
config_free(conf);
|
2019-07-03 09:46:13 +02:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 09:55:36 +02:00
|
|
|
argc -= optind;
|
|
|
|
|
argv += optind;
|
|
|
|
|
|
2019-06-13 21:23:52 +02:00
|
|
|
setlocale(LC_ALL, "");
|
2019-07-18 14:29:40 +02:00
|
|
|
setenv("TERM", conf.term, 1);
|
2019-06-13 21:23:52 +02:00
|
|
|
|
2019-10-27 19:08:48 +01:00
|
|
|
struct fdm *fdm = NULL;
|
|
|
|
|
struct wayland *wayl = NULL;
|
2019-10-28 18:25:19 +01:00
|
|
|
struct terminal *term = NULL;
|
2019-10-27 19:08:48 +01:00
|
|
|
|
|
|
|
|
if ((fdm = fdm_init()) == NULL)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
if ((wayl = wayl_init(fdm)) == NULL)
|
|
|
|
|
goto out;
|
|
|
|
|
|
2019-10-28 18:25:19 +01:00
|
|
|
if ((term = term_init(&conf, fdm, wayl, argc, argv)) == NULL)
|
2019-06-12 20:08:54 +02:00
|
|
|
goto out;
|
2019-08-12 21:49:17 +02:00
|
|
|
|
2019-10-30 20:02:06 +01:00
|
|
|
while (tll_length(wayl->terms) > 0) {
|
2019-10-27 19:21:36 +01:00
|
|
|
|
2019-10-27 11:46:18 +01:00
|
|
|
if (!fdm_poll(fdm))
|
2019-06-12 20:08:54 +02:00
|
|
|
break;
|
2019-10-27 11:46:18 +01:00
|
|
|
}
|
2019-07-21 19:14:19 +02:00
|
|
|
|
2019-10-30 20:02:06 +01:00
|
|
|
ret = tll_length(wayl->terms) == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
2019-07-21 19:14:19 +02:00
|
|
|
|
2019-10-27 11:46:18 +01:00
|
|
|
out:
|
2019-06-12 20:08:54 +02:00
|
|
|
shm_fini();
|
2019-08-12 21:22:38 +02:00
|
|
|
|
2019-10-30 20:02:06 +01:00
|
|
|
tll_foreach(wayl->terms, it)
|
2019-10-30 20:26:08 +01:00
|
|
|
term_destroy(it->item);
|
|
|
|
|
|
|
|
|
|
int child_ret = wayl->last_exit_value;
|
2019-10-30 20:02:06 +01:00
|
|
|
|
2019-10-27 19:08:48 +01:00
|
|
|
wayl_destroy(wayl);
|
2019-10-27 11:46:18 +01:00
|
|
|
fdm_destroy(fdm);
|
2019-07-16 11:52:22 +02:00
|
|
|
config_free(conf);
|
2019-10-28 18:25:19 +01:00
|
|
|
|
|
|
|
|
return ret == EXIT_SUCCESS ? child_ret : ret;
|
2019-07-28 21:03:38 +02:00
|
|
|
|
2019-06-12 20:08:54 +02:00
|
|
|
}
|