#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include "defines.h" #include "config.h" #include "threading.h" #include "window.c" #include "colors.h" #include "interactions.h" unsigned int terminal_height; unsigned int terminal_width; unsigned int temp_heigth = 0; /*used for screen refresh*/ unsigned int temp_width = 0; unsigned int settings; unsigned int file_modifiers = 0; unsigned int status = (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY) & ~STATUS_UPDATE_SCREEN_RESIZE; char *start_path; char *global_path; time_t seed; WINDOW *win_t; WINDOW *win_b; WINDOW *win_l; WINDOW *win_m; WINDOW *win_r; extern pthread_mutex_t mutex_top; extern pthread_mutex_t mutex_btm; extern pthread_mutex_t mutex_lft; extern pthread_mutex_t mutex_mid; extern pthread_mutex_t mutex_rgt; char *input; /*used in user_interactions*/ char *terminal_width_empty_line; /* used in user_interactions */ void render_pass(); void init(); int main(){ init(); getmaxyx(stdscr, terminal_height, terminal_width); WINDOW *wint = newwin(1, terminal_width, 0, 0); WINDOW *winb = newwin(1, terminal_width, terminal_height-1, 0); WINDOW *winl = newwin(terminal_height-2, terminal_width/8, 1, 0); WINDOW *winm = newwin(terminal_height-2, terminal_width/3, 1, (terminal_width/8)); WINDOW *winr = newwin(terminal_height-2, terminal_width/3, 1, ((terminal_width/2))); win_t = wint; win_b = winb; win_r = winr; win_m = winm; win_l = winl; pthread_t thread_b; pthread_t thread_t; pthread_t thread_l; pthread_t thread_m; pthread_t thread_r; terminal_width_empty_line = malloc(terminal_width); #if SETTINGS_RELOAD_DIR_DELTA != 0 time_t t; time_t dt; time(&t); #endif pthread_create(&thread_t, NULL, thread_top, &status); /*top bar*/ pthread_create(&thread_l, NULL, thread_lft, &status); /*parent_content slash win_l*/ pthread_create(&thread_m, NULL, thread_mid, &status); /*current_content slash win_m*/ pthread_create(&thread_r, NULL, thread_rgt, &status); /*child_content slash win_r*/ pthread_create(&thread_b, NULL, thread_btm, &status); /*bottom bar*/ /* running through all once manually in order to get an as fast as possible first render on the screen */ pthread_cond_signal(&cond_mid); pthread_cond_signal(&cond_lft); render_pass(); timeout(SETTINGS_CURSES_TIMEOUT); while(!(status & STATUS_QUIT_PROGRAM)){ getmaxyx(stdscr, terminal_height, terminal_width); user_interactions(); if (status & STATUS_RUN_BACKEND) { free(global_path); global_path = getcwd(NULL, 0); pthread_cond_signal(&cond_mid); pthread_cond_signal(&cond_lft); status &= ~(STATUS_RUN_BACKEND); } else { status &= ~(STATUS_RELOAD_DIRECTORY | STATUS_DELTA_TIME); } if (!(terminal_height == temp_heigth) || !(terminal_width == temp_width)) { status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_RESIZE); temp_width = terminal_width; temp_heigth = terminal_height; } render_pass(); #if SETTINGS_RELOAD_DIR_DELTA != 0 time(&dt); if (dt - t >= SETTINGS_RELOAD_DIR_DELTA) { time(&t); status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY | STATUS_DELTA_TIME); } #endif } #if SETTINGS_UEBERZUG_IMAGE_PREVIEW != 0 ueberzug_close(); #endif threading_free(); free(start_path); delwin(win_l); delwin(win_m); delwin(win_r); delwin(win_t); delwin(win_b); noraw(); echo(); curs_set(1); endwin(); return 0; } void render_pass(){ if (status & STATUS_UPDATE_SCREEN_CLEAR) { clear(); status &= ~STATUS_UPDATE_SCREEN_CLEAR; } if (status & STATUS_UPDATE_SCREEN_RESIZE) { wresize(win_t, 1, terminal_width); wresize(win_l, terminal_height-2, terminal_width/8); wresize(win_m, terminal_height-2, (terminal_width/2)-(terminal_width/8)); wresize(win_r, terminal_height-2, terminal_width/2); wresize(win_b, 1, terminal_width); mvwin(win_t, 0, 0); mvwin(win_l, 1, 0); mvwin(win_m, 1, (terminal_width/8)); mvwin(win_r, 1, ((terminal_width/2))); mvwin(win_b, terminal_height-1, 0); } if (pthread_mutex_lock(&mutex_render) == 0 || status & STATUS_UPDATE_SCREEN_MASK) { doupdate(); status &= ~STATUS_UPDATE_SCREEN_MASK; pthread_mutex_unlock(&mutex_render); } } /*this function exists for things done at startup (initialization, reading config, etc)*/ void init() { setlocale(LC_ALL, ""); initscr(); /* start ncurses */ noecho(); /* hide keyboard input */ timeout(10); /* blocking timeout of getch(), using 10 rather than SETTINGS_CURSES_TIMEOUT to cause a faster first render regardless on SETTINGS_CURSES_TIMEOUT, 10 was taken arbitrary. if the blocking is too low, the first render happens delayed, however even this delay causes a quicker than (compute time of threads) + timeout */ curs_set(0); /*file_modifiers = (FILE_MODIFIERS_HIDDEN_FILES | FILE_MODIFIERS_SORT_BITMASK);*/ input = malloc(INPUT_BUFFER_SIZE); /* size of input buffer, out of bounds access will not be accounted for */ memset(input, 0, INPUT_BUFFER_SIZE); status = (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY); if (getuid() == 0) { status |= STATUS_USER_ROOT; } threading_init(); /* found in threading.c */ colors_init(); /* in colors.c */ dir_init(); /*in dir.c */ #if SETTINGS_UEBERZUG_IMAGE_PREVIEW != 0 ueberzug_init(); /* in file_previews.c */ #endif ESCDELAY = 10; global_path = getcwd(NULL, 0); char *start_path = getcwd(NULL, 0); setenv("START_PATH", start_path, 0); free(start_path); seed = time(NULL); }