/* * xcfg | simple xorg configuration tool * MatterLinux 2024 (https://matterlinux.xyz) * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "log.h" #define _(x) gettext(x) int ask(char* text, ITEM** items, int sz) { attron(COLOR_PAIR(1) | A_BOLD); mvprintw(1, 1, "%s", text); char line[strlen(text)+5]; for (int i = 0; i < strlen(text); i++){ line[i] = '#'; line[i+1] = '\0'; } mvprintw(2, 1, "%s", line); attroff(COLOR_PAIR(1) | A_BOLD); refresh(); WINDOW* swin = newwin(LINES-3, COLS-1, 3, 1); keypad(swin, TRUE); MENU* menu = new_menu(items); set_menu_win(menu, swin); set_menu_sub(menu, swin); set_menu_mark(menu, ">"); post_menu(menu); wrefresh(swin); bool done = false; int indx = 0, c = 0; while((c = wgetch(swin))){ switch(c){ case KEY_DOWN: if (indx != (sz+1)) indx++; menu_driver(menu, REQ_DOWN_ITEM); break; case KEY_UP: if (indx != 0) indx--; menu_driver(menu, REQ_UP_ITEM); break; case '\n': done = true; break; } wrefresh(swin); if(done) break; } free_menu(menu); return indx; } bool add_startx(){ bool ret = false; char* profile = ".bash_profile"; char* shellenv = getenv("SHELL"); if (NULL != shellenv && endswith(shellenv, "zsh")) profile = ".zshrc"; char profile_file[PATH_MAX]; if(!joinhome(profile_file, profile)){ error(_("Failed to get the home directory")); return ret; } FILE* pf = fopen(profile_file, "r"); if(NULL==pf){ error(_("Failed to open %s for reading"), profile_file); return ret; } char* line = NULL, *all = NULL; int indx = 0; size_t sz, len; while((sz = getline(&line, &len, pf)) != -1) { if(strcmp(line, "#auto-startx \n")==0){ ret = true; goto END; } if (NULL == all){ all = malloc(sz); for(int i = 0; i < sz; i++){ all[indx] = line[i]; indx++; } }else { all = realloc(all, indx+sz); for(int i = 0; i < sz; i++){ all[indx] = line[i]; indx++; } } } char* startx = AUTOSTARTX; all = realloc(all, indx+strlen(startx)+10); for(int i = 0; i < strlen(startx); i++){ all[indx] = startx[i]; indx++; } fclose(pf); pf = fopen(profile_file, "w"); if(NULL==pf){ error(_("Failed to open %s for writing"), profile_file); goto END; } all[indx] = '\0'; if(fwrite(all, 1, indx, pf)<=0) error(_("Failed to write to %s"), profile_file); ret = true; END: free(all); free(line); fclose(pf); return ret; } int main(int argc, char** argv, char** envp){ if(getuid()==0){ error(_("You should use this script as a regular user, not as root!")); return EXIT_FAILURE; } signal(SIGINT, SIG_IGN); setlocale(LC_ALL, ""); textdomain("xcfg"); struct Desktop desktops[] = { { .name="XFCE4", .desc=_("Lightweight desktop environment for UNIX-like operating systems"), .pkg="xfce4", .cmd="startxfce4\n", }, { .name="LXDE", .desc=_("Free desktop environment with comparatively low resource requirements"), .pkg="lxde", .cmd="startlxde\n", }, { .name="bspwm", .desc=_("Tiling window manager based on binary space partitioning"), .pkg="bspwm", .cmd="bspwm\n" } }; char* mpi_path = check_path("mp-install"); if(NULL==mpi_path){ error(_("mp is not installed!")); return EXIT_FAILURE; } free(mpi_path); char* doas_path = check_path("doas"); if(NULL==doas_path) { doas_path = check_path("sudo"); if(NULL==doas_path){ error(_("Install doas or sudo to use this script")); free(mpi_path); return EXIT_FAILURE; } } initscr(); cbreak(); noecho(); keypad(stdscr, TRUE); init_pair(1, COLOR_BLUE, COLOR_BLUE); int sz = sizeof(desktops)/sizeof(struct Desktop); ITEM** items = malloc(sizeof(ITEM *)*(sz+1)); for(int i = 0; i < sz; i++) items[i] = new_item(desktops[i].name, desktops[i].desc); items[sz] = NULL; int indx = ask(_("Choose a desktop enviroment"), items, sz+1); for (int i = 0; i < sz; i++) free_item(items[i]); free(items); clear(); char* yn[] = {_("Yes"), _("No"), NULL}; sz = sizeof(yn)/sizeof(char*); items = (ITEM **)malloc(sizeof(ITEM *)*(sz+1)); for(int i = 0; i < sz; i++) items[i] = new_item(yn[i], ""); bool autox = ask(_("Add auto-startx to shell configuration?"), items, sz) == 0; for (int i = 0; i < sz; i++) free_item(items[i]); free(items); clear(); clear(); endwin(); if(autox && !add_startx()) goto FAIL; char xinitrc[PATH_MAX]; if(!joinhome(xinitrc, ".xinitrc")){ error(_("Failed to get the home directory")); goto FAIL; } FILE* xf = fopen(xinitrc, "w"); if(fwrite(desktops[indx].cmd, 1, strlen(desktops[indx].cmd), xf)<0){ error(_("Failed to write to %s"), xinitrc); fclose(xf); goto FAIL; } fclose(xf); success(_("Configuration has been saved!")); info(_("Installing %s"), desktops[indx].name, mpi_path); char* args[] = { doas_path, "mp-install", desktops[indx].pkg, NULL }; if(execvp(doas_path, args) != 0) { error(_("Installation failed")); } FAIL: free(doas_path); return EXIT_FAILURE; }