#include "app.h" #include "config.h" #include "font.h" #include "media.h" #include "render.h" #include #include #include #define WINDOW_WIDTH 1000 #define WINDOW_HEIGHT 700 static void print_usage(const char *argv0) { fprintf(stderr, "usage:\n"); fprintf(stderr, " %s [--config path/to/ecexrc.c] [--font path/to/font.ttf]\n", argv0); fprintf(stderr, "\n"); fprintf(stderr, "keys:\n"); fprintf(stderr, " F1 opens M-x\n"); fprintf(stderr, " Tab completes M-x command names\n"); fprintf(stderr, " Alt+x opens M-x when the OS/window-manager allows it\n"); fprintf(stderr, " C-x is reserved for prefix maps\n"); fprintf(stderr, "\n"); fprintf(stderr, "env:\n"); fprintf(stderr, " ECEX_FONT=/path/to/font.ttf\n"); fprintf(stderr, " ECEX_INCLUDE=/path/to/ecex/include\n"); } static int parse_args(int argc, char **argv, const char **config_path, const char **font_path_arg) { *config_path = NULL; *font_path_arg = NULL; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--config") == 0) { if (i + 1 >= argc) { print_usage(argv[0]); return -1; } *config_path = argv[++i]; } else if (strcmp(argv[i], "--font") == 0) { if (i + 1 >= argc) { print_usage(argv[0]); return -1; } *font_path_arg = argv[++i]; } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { print_usage(argv[0]); return 1; } else { *font_path_arg = argv[i]; } } return 0; } static const char *select_font_path(ecex_t *ed, const char *font_path_arg) { if (font_path_arg) return font_path_arg; if (ed && ed->theme.font_path) return ed->theme.font_path; return font_choose_path(NULL); } int main(int argc, char **argv) { const char *config_path = NULL; const char *font_path_arg = NULL; int args_result = parse_args(argc, argv, &config_path, &font_path_arg); if (args_result != 0) { return args_result < 0 ? 1 : 0; } ecex_t *ed = ecex_new(); if (!ed) { fprintf(stderr, "failed to create editor\n"); return 1; } if (config_path) { if (ecex_load_c_config(ed, config_path) != 0) { fprintf(stderr, "ecex: continuing without config\n"); } } if (!glfwInit()) { fprintf(stderr, "failed to initialize GLFW\n"); ecex_free(ed); return 1; } GLFWwindow *window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "ecex", NULL, NULL ); if (!window) { fprintf(stderr, "failed to create GLFW window\n"); glfwTerminate(); ecex_free(ed); return 1; } glfwMakeContextCurrent(window); glfwSwapInterval(1); app_t app; app_init(&app, ed); app_set_window(&app, window); const char *font_path = select_font_path(ed, font_path_arg); if (!font_path) { fprintf(stderr, "ecex: could not find a font automatically\n"); fprintf(stderr, "try:\n"); fprintf(stderr, " export ECEX_FONT=/path/to/font.ttf\n"); fprintf(stderr, " %s --font /path/to/font.ttf\n", argv[0]); glfwDestroyWindow(window); glfwTerminate(); ecex_free(ed); return 1; } if (font_load(&app.font, font_path, ed->theme.font_size) != 0) { fprintf(stderr, "ecex: could not load font\n"); fprintf(stderr, "try an explicit font path:\n"); fprintf(stderr, " %s --font /path/to/font.ttf\n", argv[0]); glfwDestroyWindow(window); glfwTerminate(); ecex_free(ed); return 1; } snprintf(app.font_path, sizeof(app.font_path), "%s", font_path); app_install_callbacks(&app); app_message(&app, "F1 for M-x. Tab completes commands."); while (!glfwWindowShouldClose(window) && !ed->should_quit) { double now = glfwGetTime(); if (ecex_media_tick(ed, now) || ecex_tick_animations(ed, now)) { app.dirty = 1; } if (app.dirty) { render(&app); glfwSwapBuffers(window); app.dirty = 0; } glfwWaitEventsTimeout(1.0 / 60.0); } font_free(&app.font); glfwDestroyWindow(window); glfwTerminate(); ecex_free(ed); return 0; }