diff --git a/.gitignore b/.gitignore index 1fff046..f489934 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -li +lidm dist/ .cache/ diff --git a/Makefile b/Makefile index e734e2d..6336bcf 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,10 @@ CFLAGS=-O3 -I$(IDIR) LIBS=-lm -lpam -lpam_misc -_DEPS = util.h ui.h auth.h efield.h keys.h users.h sessions.h +_DEPS = util.h ui.h config.h auth.h efield.h keys.h users.h sessions.h DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) -_OBJ = main.o util.o ui.o auth.o efield.o users.o sessions.o +_OBJ = main.o util.o ui.o config.o auth.o efield.o users.o sessions.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: $(CDIR)/%.c $(DEPS) diff --git a/README.md b/README.md index a28d038..051a9b3 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Lidm is a really light display manager made in C, highly customizable and held t ![demo image](assets/lidm.png) > *this is shown as in a terminal emulator, actual linux console doesn't support as much color and decorations* +> *but all colors and strings are fully suctomizable* + > *I'm open if anybody wants to contact me to record a proper demo of the program, my laptop can't handle it and idk how to config obs for hyprland* ## Features @@ -14,6 +16,7 @@ Lidm is a really light display manager made in C, highly customizable and held t * Automatically detects xorg and wayland sessions, plus allowing to launch the default user shell (if enabled in config) ## WIP +* desktop's file `TryExec` key * Save last selection * Show/hide passwd switch * Config parsing, it's fully customizable, but everything hardcoded for now :) @@ -21,7 +24,7 @@ Lidm is a really light display manager made in C, highly customizable and held t ## Forget it * Any kind of arguments -* UTF characters, I'm using `strlen()` and treating characters as per byte basis, UTF-8 chars might work or not +* UTF characters, I'm using `strlen()` and treating characters as per byte basis, UTF-8 chars might work or not actually, might fix it by replacing some `strlen()` with a utflen one. > [!CAUTION] > (they should add `> [!DISCLAIMER]` fr) I wrote this readme with the same quality as the code, behing this keyboard there's half a brainrotcell left writing what it remembers of this program, so don't take this to seriously, I'm typing as I think without filter lol, but the program works, or should. Also, about any "TODO" in this readme (or the code), I didn't forget finishing it, I actually don't care. And, references to ~~code~~ **anything** are likely to be outdated, check the commit history to know what I was refering to exactly if you care. @@ -65,7 +68,7 @@ make # 👍 ``` # Configuring -Ugh, config will be a straigh copy of config defaults to `/etc` I think, there's no config yet :P and you need to enable the service, just do what ly does (I'm doing this on dinit, all init systems should be supported). +Copy `config.ini` (if I haven't moved it) to `/etc/lidm.ini` and configure it to your liking. Also, don't place empty lines (for now). Also configurable colors are just gonna be put inside `\x1b[...m`, ofc you can add an m to break this and this can f* up really bad or even make some nice UI effect possible, but please don't, you should also be able to embed the `\x1b` byte in the config as I won't parse escape codes, I think that the parser is just gonna grab anything in the config file from the space after the `=` (yes, I'ma enforce that space, get good taste if you don't like it) until the newline, you can put any abomination in there. diff --git a/compile_commands.json b/compile_commands.json index 6766123..4d6b6a7 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -7,6 +7,7 @@ "-o", "dist/main.o", "src/main.c", + "-O3", "-Iinclude" ], "file": "src/main.c" @@ -19,6 +20,7 @@ "-o", "dist/util.o", "src/util.c", + "-O3", "-Iinclude" ], "file": "src/util.c" @@ -31,6 +33,7 @@ "-o", "dist/ui.o", "src/ui.c", + "-O3", "-Iinclude" ], "file": "src/ui.c" @@ -43,6 +46,7 @@ "-o", "dist/users.o", "src/users.c", + "-O3", "-Iinclude" ], "file": "src/users.c" @@ -55,6 +59,7 @@ "-o", "dist/sessions.o", "src/sessions.c", + "-O3", "-Iinclude" ], "file": "src/sessions.c" @@ -67,6 +72,7 @@ "-o", "dist/efield.o", "src/efield.c", + "-O3", "-Iinclude" ], "file": "src/efield.c" @@ -79,8 +85,22 @@ "-o", "dist/auth.o", "src/auth.c", + "-O3", "-Iinclude" ], "file": "src/auth.c" + }, + { + "directory": "/home/javalsai/coding/lidm", + "arguments": [ + "gcc", + "-c", + "-o", + "dist/config.o", + "src/config.c", + "-O3", + "-Iinclude" + ], + "file": "src/config.c" } ] diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..453f9a1 --- /dev/null +++ b/config.ini @@ -0,0 +1,33 @@ +colors.bg = 48;2;38;28;28 +colors.fg = 22;24;38;2;245;245;245 +colors.err = 1;31 +colors.s_wl = 38;2;255;174;66 +colors.s_xorg = 38;2;37;175;255 +colors.s_shell = 38;2;34;140;34 +colors.f_other = 38;2;255;64;64 +colors.e_hostname = 38;2;255;64;64 +colors.e_date = 38;2;144;144;144 +colors.e_box = 38;2;122;122;122 +colors.e_header = 4;38;2;0;255;0 +colors.e_user = 36 +colors.e_passwd = 4;38;2;245;245;205 +colors.e_badpasswd = 3;4;31 +colors.e_key = 38;2;255;174;66 +chars.hb = ─ +chars.vb = │ +chars.ctl = ┌ +chars.ctr = ┐ +chars.cbl = └ +chars.cbr = ┘ +functions.poweroff = F1 +functions.reboot = F2 +functions.refresh = F5 +strings.f_poweroff = powewoff +strings.f_reboot = rewoot +strings.f_refresh = rewresh +strings.e_user = wuser +strings.e_passwd = passwd +strings.s_xorg = xworg +strings.s_wayland = waywand +strings.s_shell = swell +behavior.include_defshell = true diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..d6e086f --- /dev/null +++ b/include/config.h @@ -0,0 +1,83 @@ +#ifndef _CONFIGH_ +#define _CONFIGH_ + +#include +#include + +#include +#include +#include + +// should be ansi escape codes under \x1b[...m +// if not prepared accordingly, it might break +struct theme_colors { + char *bg; + char *fg; + char *err; + char *s_wl; + char *s_xorg; + char *s_shell; + char *f_other; + char *e_hostname; + char *e_date; + char *e_box; + char *e_header; + char *e_user; + char *e_passwd; + char *e_badpasswd; + char *e_key; +}; + +// even if they're multiple bytes long +// they should only take up 1 char size on display +struct theme_chars { + char *hb; + char *vb; + + char *ctl; + char *ctr; + char *cbl; + char *cbr; +}; + +struct theme { + struct theme_colors colors; + struct theme_chars chars; +}; + +struct functions { + enum keys poweroff; + enum keys reboot; + enum keys refresh; +}; + +struct strings { + char *f_poweroff; + char *f_reboot; + char *f_refresh; + char *e_user; + char *e_passwd; + char *s_xorg; + char *s_wayland; + char *s_shell; +}; + +struct behavior { + bool include_defshell; +}; + +struct config { + struct theme theme; + struct functions functions; + struct strings strings; + struct behavior behavior; +}; + +bool line_parser( + FILE* fd, + ssize_t* blksize, + u_char (*cb)(char *key, + char *value)); // might use this for parsing .desktop files too +struct config *parse_config(char *path); + +#endif diff --git a/include/ui.h b/include/ui.h index 9d6d576..56ddaaf 100644 --- a/include/ui.h +++ b/include/ui.h @@ -1,76 +1,7 @@ #ifndef _UIH_ #define _UIH_ -#include - -#include -#include -#include - -// should be ansi escape codes under \x1b[...m -// if not prepared accordingly, it might break -struct theme_colors { - char *bg; - char *fg; - char *err; - char *s_wl; - char *s_xorg; - char *s_shell; - char *f_other; - char *e_hostname; - char *e_date; - char *e_box; - char *e_header; - char *e_user; - char *e_passwd; - char *e_badpasswd; - char *e_key; -}; - -// even if they're multiple bytes long -// they should only take up 1 char size on display -struct theme_chars { - char *hb; - char *vb; - - char *ctl; - char *ctr; - char *cbl; - char *cbr; -}; - -struct theme { - struct theme_colors colors; - struct theme_chars chars; -}; - -struct functions { - enum keys poweroff; - enum keys reboot; - enum keys refresh; -}; - -struct strings { - char* f_poweroff; - char* f_reboot; - char* f_refresh; - char* e_user; - char* e_passwd; - char* s_xorg; - char* s_wayland; - char* s_shell; -}; - -struct behavior { - bool include_defshell; -}; - -struct config { - struct theme theme; - struct functions functions; - struct strings strings; - struct behavior behavior; -}; +#include void setup(struct config); int load(struct users_list*, struct sessions_list*); diff --git a/include/util.h b/include/util.h index fbfb026..4759221 100644 --- a/include/util.h +++ b/include/util.h @@ -5,6 +5,7 @@ #include #include +enum keys find_keyname(char*); enum keys find_ansi(char*); void read_press(u_char*, char*); void strcln(char **dest, const char *source); diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..b622866 --- /dev/null +++ b/src/config.c @@ -0,0 +1,138 @@ +#include "util.h" +#include +#include + +#include + +bool line_parser(FILE *fd, ssize_t *blksize, + u_char (*cb)(char *key, char *value)) { + size_t opt_size = 4096; + if (blksize != NULL) + opt_size = *blksize; + + while (true) { + size_t alloc_size = opt_size; + char *buf = malloc(alloc_size); + if (buf == NULL) + return false; + ssize_t read_size = getline(&buf, &alloc_size, fd); + if (read_size == -1) { + free(buf); + break; + } + + uint read; + char *key = malloc(read_size); + if (key == NULL) { + free(buf); + return false; + } + if ((read = sscanf(buf, "%[^ ] = %[^\n]\n", key, buf)) != 0) { + u_char ret = cb(key, buf); + if (ret & 0b0100) + free(key); + if (ret & 0b0010) + free(buf); + if (ret & 0b1000) + return false; + if (ret & 0b0001) + break; + } + } + + return true; +} + +struct config *__config; +u_char config_line_handler(char *k, char *v) { + if(strcmp(k, "colors.bg") == 0) + __config->theme.colors.bg = v; + else if(strcmp(k, "colors.fg") == 0) + __config->theme.colors.fg = v; + else if(strcmp(k, "colors.err") == 0) + __config->theme.colors.err = v; + else if(strcmp(k, "colors.s_wl") == 0) + __config->theme.colors.s_wl = v; + else if(strcmp(k, "colors.s_xorg") == 0) + __config->theme.colors.s_xorg = v; + else if(strcmp(k, "colors.s_shell") == 0) + __config->theme.colors.s_shell = v; + else if(strcmp(k, "colors.f_other") == 0) + __config->theme.colors.f_other = v; + else if(strcmp(k, "colors.e_hostname") == 0) + __config->theme.colors.e_hostname = v; + else if(strcmp(k, "colors.e_date") == 0) + __config->theme.colors.e_date = v; + else if(strcmp(k, "colors.e_box") == 0) + __config->theme.colors.e_box = v; + else if(strcmp(k, "colors.e_header") == 0) + __config->theme.colors.e_header = v; + else if(strcmp(k, "colors.e_user") == 0) + __config->theme.colors.e_user = v; + else if(strcmp(k, "colors.e_passwd") == 0) + __config->theme.colors.e_passwd = v; + else if(strcmp(k, "colors.e_badpasswd") == 0) + __config->theme.colors.e_badpasswd = v; + else if(strcmp(k, "colors.e_key") == 0) + __config->theme.colors.e_key = v; + else if(strcmp(k, "chars.hb") == 0) + __config->theme.chars.hb = v; + else if(strcmp(k, "chars.vb") == 0) + __config->theme.chars.vb = v; + else if(strcmp(k, "chars.ctl") == 0) + __config->theme.chars.ctl = v; + else if(strcmp(k, "chars.ctr") == 0) + __config->theme.chars.ctr = v; + else if(strcmp(k, "chars.cbl") == 0) + __config->theme.chars.cbl = v; + else if(strcmp(k, "chars.cbr") == 0) + __config->theme.chars.cbr = v; + else if(strcmp(k, "functions.poweroff") == 0) + __config->functions.poweroff = find_keyname(v); + else if(strcmp(k, "functions.reboot") == 0) + __config->functions.reboot = find_keyname(v); + else if(strcmp(k, "functions.refresh") == 0) + __config->functions.refresh = find_keyname(v); + else if(strcmp(k, "strings.f_poweroff") == 0) + __config->strings.f_poweroff= v; + else if(strcmp(k, "strings.f_reboot") == 0) + __config->strings.f_reboot= v; + else if(strcmp(k, "strings.f_refresh") == 0) + __config->strings.f_refresh= v; + else if(strcmp(k, "strings.e_user") == 0) + __config->strings.e_user= v; + else if(strcmp(k, "strings.e_passwd") == 0) + __config->strings.e_passwd= v; + else if(strcmp(k, "strings.s_xorg") == 0) + __config->strings.s_xorg= v; + else if(strcmp(k, "strings.s_wayland") == 0) + __config->strings.s_wayland= v; + else if(strcmp(k, "strings.s_shell") == 0) + __config->strings.s_shell= v; + else if(strcmp(k, "behavior.include_defshell") == 0) + __config->behavior.include_defshell= strcmp(v, "true") == 0; + else + return 0b1111; + + return 0b100; +} + +struct config *parse_config(char *path) { + struct stat sb; + FILE *fd = fopen(path, "r"); + if (fd == NULL || (stat(path, &sb) == -1)) { + perror("fopen"); + return NULL; + } + + __config = malloc(sizeof(struct config)); + if (__config == NULL) + return NULL; + bool ret = line_parser(fd, &sb.st_blksize, config_line_handler); + if (!ret) { + free(__config); + return NULL; + } + + return __config; +} diff --git a/src/main.c b/src/main.c index 60145c2..1dfe107 100644 --- a/src/main.c +++ b/src/main.c @@ -4,71 +4,18 @@ #include #include +#include #include #include #include -static const struct config default_config() { - struct theme_colors __colors; - __colors.bg = "48;2;38;28;28"; - __colors.fg = "22;24;38;2;245;245;245"; - __colors.err = "1;31"; - __colors.s_wl = "38;2;255;174;66"; - __colors.s_xorg = "38;2;37;175;255"; - __colors.s_shell = "38;2;34;140;34"; - __colors.f_other = "38;2;255;64;64"; - __colors.e_hostname = "38;2;255;64;64"; - __colors.e_date = "38;2;144;144;144"; - __colors.e_box = "38;2;122;122;122"; - __colors.e_header = "4;38;2;0;255;0"; - __colors.e_user = "36"; - __colors.e_passwd = "4;38;2;245;245;205"; - __colors.e_badpasswd = "3;4;31"; - __colors.e_key = "38;2;255;174;66"; - - struct theme_chars __chars; - __chars.hb = "─"; - __chars.vb = "│"; - __chars.ctl = "┌"; - __chars.ctr = "┐"; - __chars.cbl = "└"; - __chars.cbr = "┘"; - - struct theme __theme; - __theme.colors = __colors; - __theme.chars = __chars; - - struct functions __functions; - __functions.poweroff = F1; - __functions.reboot = F2; - __functions.refresh = F5; - - struct strings __strings; - __strings.f_poweroff = "powewoff"; - __strings.f_reboot = "rewoot"; - __strings.f_refresh = "rewresh"; - __strings.e_user = "wuser"; - __strings.e_passwd = "passwd"; - __strings.s_xorg = "xworg"; - __strings.s_wayland = "waywand"; - __strings.s_shell = "swell"; - - struct behavior __behavior; - __behavior.include_defshell = true; - - struct config __config; - __config.theme = __theme; - __config.functions = __functions; - __config.strings = __strings; - __config.behavior = __behavior; - - return __config; -} - -#include -#include int main(int argc, char *argv[]) { - setup(default_config()); + struct config* config = parse_config("/etc/lidm.ini"); + if(config == NULL) { + fprintf(stderr, "error parsing config\n"); + return 1; + } + setup(*config); struct users_list *users = get_human_users(); struct sessions_list *sessions = get_avaliable_sessions(); diff --git a/src/sessions.c b/src/sessions.c index 1d63101..eb2437c 100644 --- a/src/sessions.c +++ b/src/sessions.c @@ -92,6 +92,8 @@ static int fn(const char *fpath, const struct stat *sb, int typeflag) { break; } + fclose(fd); + // just add this to the list if (name_buf != NULL && exec_buf != NULL) { if (used_size >= alloc_size) { diff --git a/src/util.c b/src/util.c index 29132f2..a7e95b8 100644 --- a/src/util.c +++ b/src/util.c @@ -15,6 +15,16 @@ void strcln(char **dest, const char *source) { strcpy(*dest, source); } +enum keys find_keyname(char* name) { + for (size_t i = 0; i < sizeof(key_mappings) / sizeof(key_mappings[0]); i++) { + if(strcmp(key_names[i], name) == 0) + return (enum keys)i; + } + + perror("key not found"); + exit(1); +} + enum keys find_ansi(char *seq) { for (size_t i = 0; i < sizeof(key_mappings) / sizeof(key_mappings[0]); i++) { struct key_mapping mapping = key_mappings[i];