int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "[gwmserver] no launcher specified\n"); return 1; }; char dispdev[1024]; uint64_t requestRes; char linebuf[1024]; if (geteuid() != 0) { fprintf(stderr, "[gwmserver] you need to be root to start the window manager\n"); return 1; }; int sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (sockfd == -1) { fprintf(stderr, "[gwmserver] cannot create socket: %s\n", strerror(errno)); return 1; }; struct sockaddr_un srvaddr; srvaddr.sun_family = AF_UNIX; strcpy(srvaddr.sun_path, "/run/gwmserver"); if (bind(sockfd, (struct sockaddr*) &srvaddr, sizeof(struct sockaddr_un)) != 0) { fprintf(stderr, "[gwmserver] cannot bind to /run/gwmserver: %s\n", strerror(errno)); return 1; }; if (listen(sockfd, 5) != 0) { fprintf(stderr, "[gwmserver] cannot listen: %s\n", strerror(errno)); return 1; }; // make sure the clipboard and shared surface directories actually exist mkdir("/run/clipboard", 0777); mkdir("/run/shsurf", 01777); mkdir("/run/gwmserver-wd", 0777); mkdir("/var", 0755); mkdir("/var/log", 0755); chdir("/run/gwmserver-wd"); FILE *fp = fopen("/etc/gwm.conf", "r"); if (fp == NULL) { fprintf(stderr, "could not open /etc/gwm.conf: %s\n", strerror(errno)); return 1; }; requestRes = DDI_RES_AUTO; dispdev[0] = 0; char *line; int lineno = 0; char logdest[PATH_MAX]; strcpy(logdest, "/var/log/gwmserver.log"); while ((line = fgets(linebuf, 1024, fp)) != NULL) { lineno++; char *endline = strchr(line, '\n'); if (endline != NULL) { *endline = 0; }; if (strlen(line) >= 1023) { fprintf(stderr, "/etc/gwm.conf:%d: buffer overflow\n", lineno); return 1; }; if ((line[0] == 0) || (line[0] == '#')) { continue; } else { char *cmd = strtok(line, " \t"); if (cmd == NULL) { continue; }; if (strcmp(cmd, "display") == 0) { char *name = strtok(NULL, " \t"); if (name == NULL) { fprintf(stderr, "/etc/gwm.conf:%d: 'display' needs a parameter\n", lineno); return 1; }; strcpy(dispdev, name); } else if (strcmp(cmd, "resolution") == 0) { char *res = strtok(NULL, " \t"); if (res == NULL) { fprintf(stderr, "/etc/gwm.conf:%d: 'resolution' needs a parameter\n", lineno); return 1; }; uint64_t reqWidth, reqHeight; if (strcmp(res, "auto") == 0) { requestRes = DDI_RES_AUTO; } else if (strcmp(res, "safe") == 0) { requestRes = DDI_RES_SAFE; } else if (sscanf(res, "%lux%lu", &reqWidth, &reqHeight) == 2) { requestRes = DDI_RES_SPECIFIC(reqWidth, reqHeight); } else { fprintf(stderr, "/etc/gwm.conf:%d: invalid resolution: %s\n", lineno, res); return 1; }; } else if (strcmp(cmd, "log") == 0) { char *path = strtok(NULL, " \t"); if (path == NULL) { fprintf(stderr, "/etc/gwm.conf:%d: 'log' needs a parameter\n", lineno); return 1; }; if (strlen(path) >= PATH_MAX) { fprintf(stderr, "/etc/gwm.conf:%d: log path too long\n", lineno); return 1; }; strcpy(logdest, path); } else { fprintf(stderr, "/etc/gwm.conf:%d: invalid directive: %s\n", lineno, cmd); return 1; }; }; }; fclose(fp); int logfd = open(logdest, O_WRONLY | O_CREAT | O_APPEND, 0644); if (logfd == -1) { fprintf(stderr, "[gwmserver] could not open log file %s: %s\n", logdest, strerror(errno)); return 1; }; dup2(logfd, 1); dup2(logfd, 2); close(logfd); if (dispdev[0] == 0) { fprintf(stderr, "/etc/gwm.conf: no display device specified!\n"); return 1; }; if (ddiInit(dispdev, O_RDWR) != 0) { fprintf(stderr, "ddiInit: %s: %s\n", dispdev, strerror(errno)); return 1; }; if (symlink(dispdev, "/run/gwmdisp") != 0) { fprintf(stderr, "symlink /run/gwmdisp: %s\n", strerror(errno)); return 1; }; frontBuffer = ddiSetVideoMode(requestRes); screen = ddiCreateSurface(&frontBuffer->format, frontBuffer->width, frontBuffer->height, NULL, 0); // GWM information int fd = open("/run/gwminfo", O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd == -1) { fprintf(stderr, "Failed to open /run/gwminfo! %s\n", strerror(errno)); return 1; }; DDIColor backgroundColor = {0, 0, 0x77, 0xFF}; desktopBackground = ddiCreateSurface(&screen->format, screen->width, screen->height, NULL, DDI_SHARED); ddiFillRect(desktopBackground, 0, 0, screen->width, screen->height, &backgroundColor); ddiFillRect(screen, 0, 0, screen->width, screen->height, &backgroundColor); ddiFillRect(frontBuffer, 0, 0, screen->width, screen->height, &backgroundColor); ftruncate(fd, sizeof(GWMInfo)); gwminfo = (GWMInfo*) mmap(NULL, sizeof(GWMInfo), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); gwminfo->backgroundID = desktopBackground->id; printf("[gwmserver] initialize theme info\n"); gwmGlobalThemeInit(&frontBuffer->format); imgWincap = ddiOpenSurface(gwminfo->imgWinCap); imgWinbut = ddiOpenSurface(gwminfo->imgWinButtons); if (fork() == 0) { execv(argv[1], &argv[1]); perror("exec launcher"); _exit(1); }; // now that we won't be starting any processes, we can set core dumps signal(SIGSEGV, SIG_CORE); signal(SIGILL, SIG_CORE); signal(SIGBUS, SIG_CORE); signal(SIGABRT, SIG_CORE); signal(SIGALRM, SIG_CORE); kblSet("/usr/share/kblayout/en_US/int", stderr); wndInit(); ptrInit(); inputInit(); runServer(sockfd); return 0; };
void *Init() { wndInit(); return NULL; }