From 50382e80f86a8302df7cfc20fbbb048adc74ad7d Mon Sep 17 00:00:00 2001 From: tmu Date: Sat, 6 May 2023 20:50:18 -0700 Subject: [PATCH 1/2] fix i915 freeze --- fb/linux.h | 130 +++++++++--------- yaft.c | 376 ++++++++++++++++++++++++++--------------------------- 2 files changed, 254 insertions(+), 252 deletions(-) diff --git a/fb/linux.h b/fb/linux.h index 5e572b6..e920090 100644 --- a/fb/linux.h +++ b/fb/linux.h @@ -6,99 +6,101 @@ typedef struct fb_cmap cmap_t; enum { - CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE, + CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE, }; /* os specific ioctl */ void alloc_cmap(cmap_t *cmap, int colors) { - cmap->start = 0; - cmap->len = colors; - cmap->red = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->green = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->blue = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->transp = NULL; + cmap->start = 0; + cmap->len = colors; + cmap->red = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->green = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->blue = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->transp = NULL; } int put_cmap(int fd, cmap_t *cmap) { - return ioctl(fd, FBIOPUTCMAP, cmap); + return ioctl(fd, FBIOPUTCMAP, cmap); } int get_cmap(int fd, cmap_t *cmap) { - return ioctl(fd, FBIOGETCMAP, cmap); + return ioctl(fd, FBIOGETCMAP, cmap); } /* initialize struct fb_info_t */ void set_bitfield(struct fb_var_screeninfo *vinfo, - struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue) + struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue) { - red->length = vinfo->red.length; - green->length = vinfo->green.length; - blue->length = vinfo->blue.length; + red->length = vinfo->red.length; + green->length = vinfo->green.length; + blue->length = vinfo->blue.length; - red->offset = vinfo->red.offset; - green->offset = vinfo->green.offset; - blue->offset = vinfo->blue.offset; + red->offset = vinfo->red.offset; + green->offset = vinfo->green.offset; + blue->offset = vinfo->blue.offset; } enum fb_type_t set_type(__u32 type) { - if (type == FB_TYPE_PACKED_PIXELS) - return YAFT_FB_TYPE_PACKED_PIXELS; - else if (type == FB_TYPE_PLANES) - return YAFT_FB_TYPE_PLANES; - else - return YAFT_FB_TYPE_UNKNOWN; + if (type == FB_TYPE_PACKED_PIXELS) + return YAFT_FB_TYPE_PACKED_PIXELS; + else if (type == FB_TYPE_PLANES) + return YAFT_FB_TYPE_PLANES; + else + return YAFT_FB_TYPE_UNKNOWN; } enum fb_visual_t set_visual(__u32 visual) { - if (visual == FB_VISUAL_TRUECOLOR) - return YAFT_FB_VISUAL_TRUECOLOR; - else if (visual == FB_VISUAL_DIRECTCOLOR) - return YAFT_FB_VISUAL_DIRECTCOLOR; - else if (visual == FB_VISUAL_PSEUDOCOLOR) - return YAFT_FB_VISUAL_PSEUDOCOLOR; - else - return YAFT_FB_VISUAL_UNKNOWN; + if (visual == FB_VISUAL_TRUECOLOR) + return YAFT_FB_VISUAL_TRUECOLOR; + else if (visual == FB_VISUAL_DIRECTCOLOR) + return YAFT_FB_VISUAL_DIRECTCOLOR; + else if (visual == FB_VISUAL_PSEUDOCOLOR) + return YAFT_FB_VISUAL_PSEUDOCOLOR; + else + return YAFT_FB_VISUAL_UNKNOWN; } bool set_fbinfo(int fd, struct fb_info_t *info) { - struct fb_fix_screeninfo finfo; - struct fb_var_screeninfo vinfo; - - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { - logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n"); - return false; - } - - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { - logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n"); - return false; - } - - set_bitfield(&vinfo, &info->red, &info->green, &info->blue); - - info->width = vinfo.xres; - info->height = vinfo.yres; - info->screen_size = finfo.smem_len; - info->line_length = finfo.line_length; - - info->bits_per_pixel = vinfo.bits_per_pixel; - info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE); - - info->type = set_type(finfo.type); - info->visual = set_visual(finfo.visual); - - /* check screen [xy]offset and initialize because linux console changes these values */ - if (vinfo.xoffset != 0 || vinfo.yoffset != 0) { - vinfo.xoffset = vinfo.yoffset = 0; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) - logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset); - } - - return true; + struct fb_fix_screeninfo finfo; + struct fb_var_screeninfo vinfo; + + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { + logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n"); + return false; + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { + logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n"); + return false; + } + + set_bitfield(&vinfo, &info->red, &info->green, &info->blue); + + info->width = vinfo.xres; + info->height = vinfo.yres; + info->screen_size = finfo.smem_len; + info->line_length = finfo.line_length; + + info->bits_per_pixel = vinfo.bits_per_pixel; + info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE); + + info->type = set_type(finfo.type); + info->visual = set_visual(finfo.visual); + + /* check screen [xy]offset and initialize because linux console changes these values */ + if (vinfo.xoffset != 0 || vinfo.yoffset != 0) { + vinfo.xoffset = vinfo.yoffset = 0; + if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) + logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset); + } + vinfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo); + + return true; } diff --git a/yaft.c b/yaft.c index 7b145aa..3e681c1 100644 --- a/yaft.c +++ b/yaft.c @@ -13,225 +13,225 @@ void sig_handler(int signo) { - sigset_t sigset; - /* global */ - extern volatile sig_atomic_t vt_active; - extern volatile sig_atomic_t child_alive; - extern volatile sig_atomic_t need_redraw; - - logging(DEBUG, "caught signal! no:%d\n", signo); - - if (signo == SIGCHLD) { - child_alive = false; - wait(NULL); - } else if (signo == SIGUSR1) { /* vt activate */ - vt_active = true; - need_redraw = true; - ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); - } else if (signo == SIGUSR2) { /* vt deactivate */ - vt_active = false; - ioctl(STDIN_FILENO, VT_RELDISP, 1); - - if (BACKGROUND_DRAW) { /* update passive cursor */ - need_redraw = true; - } else { /* sleep until next vt switching */ - sigfillset(&sigset); - sigdelset(&sigset, SIGUSR1); - sigsuspend(&sigset); - } - } + sigset_t sigset; + /* global */ + extern volatile sig_atomic_t vt_active; + extern volatile sig_atomic_t child_alive; + extern volatile sig_atomic_t need_redraw; + + logging(DEBUG, "caught signal! no:%d\n", signo); + + if (signo == SIGCHLD) { + child_alive = false; + wait(NULL); + } else if (signo == SIGUSR1) { /* vt activate */ + vt_active = true; + need_redraw = true; + ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); + } else if (signo == SIGUSR2) { /* vt deactivate */ + vt_active = false; + ioctl(STDIN_FILENO, VT_RELDISP, 1); + + if (BACKGROUND_DRAW) { /* update passive cursor */ + need_redraw = true; + } else { /* sleep until next vt switching */ + sigfillset(&sigset); + sigdelset(&sigset, SIGUSR1); + sigsuspend(&sigset); + } + } } void set_rawmode(int fd, struct termios *save_tm) { - struct termios tm; - - tm = *save_tm; - tm.c_iflag = tm.c_oflag = 0; - tm.c_cflag &= ~CSIZE; - tm.c_cflag |= CS8; - tm.c_lflag &= ~(ECHO | ISIG | ICANON); - tm.c_cc[VMIN] = 1; /* min data size (byte) */ - tm.c_cc[VTIME] = 0; /* time out */ - etcsetattr(fd, TCSAFLUSH, &tm); + struct termios tm; + + tm = *save_tm; + tm.c_iflag = tm.c_oflag = 0; + tm.c_cflag &= ~CSIZE; + tm.c_cflag |= CS8; + tm.c_lflag &= ~(ECHO | ISIG | ICANON); + tm.c_cc[VMIN] = 1; /* min data size (byte) */ + tm.c_cc[VTIME] = 0; /* time out */ + etcsetattr(fd, TCSAFLUSH, &tm); } bool tty_init(struct termios *termios_orig) { - struct sigaction sigact; - - memset(&sigact, 0, sizeof(struct sigaction)); - sigact.sa_handler = sig_handler; - sigact.sa_flags = SA_RESTART; - esigaction(SIGCHLD, &sigact, NULL); - - if (VT_CONTROL) { - esigaction(SIGUSR1, &sigact, NULL); - esigaction(SIGUSR2, &sigact, NULL); - - struct vt_mode vtm; - vtm.mode = VT_PROCESS; - vtm.waitv = 0; - vtm.acqsig = SIGUSR1; - vtm.relsig = SIGUSR2; - vtm.frsig = 0; - - if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm)) - logging(WARN, "ioctl: VT_SETMODE failed (maybe here is not console)\n"); - - if (FORCE_TEXT_MODE == false) { - if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS)) - logging(WARN, "ioctl: KDSETMODE failed (maybe here is not console)\n"); - } - } - - etcgetattr(STDIN_FILENO, termios_orig); - set_rawmode(STDIN_FILENO, termios_orig); - ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */ - - return true; + struct sigaction sigact; + + memset(&sigact, 0, sizeof(struct sigaction)); + sigact.sa_handler = sig_handler; + sigact.sa_flags = SA_RESTART; + esigaction(SIGCHLD, &sigact, NULL); + + if (VT_CONTROL) { + esigaction(SIGUSR1, &sigact, NULL); + esigaction(SIGUSR2, &sigact, NULL); + + struct vt_mode vtm; + vtm.mode = VT_PROCESS; + vtm.waitv = 0; + vtm.acqsig = SIGUSR1; + vtm.relsig = SIGUSR2; + vtm.frsig = 0; + + if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm)) + logging(WARN, "ioctl: VT_SETMODE failed (maybe here is not console)\n"); + + if (FORCE_TEXT_MODE == false) { + if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS)) + logging(WARN, "ioctl: KDSETMODE failed (maybe here is not console)\n"); + } + } + + etcgetattr(STDIN_FILENO, termios_orig); + set_rawmode(STDIN_FILENO, termios_orig); + ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */ + + return true; } void tty_die(struct termios *termios_orig) { - /* no error handling */ - struct sigaction sigact; - struct vt_mode vtm; + /* no error handling */ + struct sigaction sigact; + struct vt_mode vtm; - memset(&sigact, 0, sizeof(struct sigaction)); - sigact.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sigact, NULL); + memset(&sigact, 0, sizeof(struct sigaction)); + sigact.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sigact, NULL); - if (VT_CONTROL) { - sigaction(SIGUSR1, &sigact, NULL); - sigaction(SIGUSR2, &sigact, NULL); + if (VT_CONTROL) { + sigaction(SIGUSR1, &sigact, NULL); + sigaction(SIGUSR2, &sigact, NULL); - vtm.mode = VT_AUTO; - vtm.waitv = 0; - vtm.relsig = vtm.acqsig = vtm.frsig = 0; + vtm.mode = VT_AUTO; + vtm.waitv = 0; + vtm.relsig = vtm.acqsig = vtm.frsig = 0; - ioctl(STDIN_FILENO, VT_SETMODE, &vtm); + ioctl(STDIN_FILENO, VT_SETMODE, &vtm); - if (FORCE_TEXT_MODE == false) - ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); - } + if (FORCE_TEXT_MODE == false) + ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); + } - tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig); - fflush(stdout); - ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */ + tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig); + fflush(stdout); + ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */ } bool fork_and_exec(int *master, const char *cmd, char *const argv[], int lines, int cols) { - pid_t pid; - struct winsize ws = {.ws_row = lines, .ws_col = cols, - /* XXX: this variables are UNUSED (man tty_ioctl), - but useful for calculating terminal cell size */ - .ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols}; - - pid = eforkpty(master, NULL, NULL, &ws); - if (pid < 0) - return false; - else if (pid == 0) { /* child */ - esetenv("TERM", term_name, 1); - eexecvp(cmd, argv); - /* never reach here */ - exit(EXIT_FAILURE); - } - return true; + pid_t pid; + struct winsize ws = {.ws_row = lines, .ws_col = cols, + /* XXX: this variables are UNUSED (man tty_ioctl), + but useful for calculating terminal cell size */ + .ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols}; + + pid = eforkpty(master, NULL, NULL, &ws); + if (pid < 0) + return false; + else if (pid == 0) { /* child */ + esetenv("TERM", term_name, 1); + eexecvp(cmd, argv); + /* never reach here */ + exit(EXIT_FAILURE); + } + return true; } int check_fds(fd_set *fds, struct timeval *tv, int input, int master) { - FD_ZERO(fds); - FD_SET(input, fds); - FD_SET(master, fds); - tv->tv_sec = 0; - tv->tv_usec = SELECT_TIMEOUT; - return eselect(master + 1, fds, NULL, NULL, tv); + FD_ZERO(fds); + FD_SET(input, fds); + FD_SET(master, fds); + tv->tv_sec = 0; + tv->tv_usec = SELECT_TIMEOUT; + return eselect(master + 1, fds, NULL, NULL, tv); } int main(int argc, char *const argv[]) { - extern const char *shell_cmd; /* defined in conf.h */ - const char *cmd; - uint8_t buf[BUFSIZE]; - ssize_t size; - fd_set fds; - struct timeval tv; - struct framebuffer_t fb; - struct terminal_t term; - /* global */ - extern volatile sig_atomic_t need_redraw; - extern volatile sig_atomic_t child_alive; - extern struct termios termios_orig; - - /* init */ - if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ - logging(WARN, "setlocale falied\n"); - - if (!fb_init(&fb)) { - logging(FATAL, "framebuffer initialize failed\n"); - goto fb_init_failed; - } - - if (!term_init(&term, fb.info.width, fb.info.height)) { - logging(FATAL, "terminal initialize failed\n"); - goto term_init_failed; - } - - if (!tty_init(&termios_orig)) { - logging(FATAL, "tty initialize failed\n"); - goto tty_init_failed; - } - - /* fork and exec shell */ - cmd = (argc < 2) ? shell_cmd: argv[1]; - if (!fork_and_exec(&term.fd, cmd, argv + 1, term.lines, term.cols)) { - logging(FATAL, "forkpty failed\n"); - goto tty_init_failed; - } - child_alive = true; - - /* main loop */ - while (child_alive) { - if (need_redraw) { - need_redraw = false; - cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */ - redraw(&term); - refresh(&fb, &term); - } - - if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) - continue; - - if (FD_ISSET(STDIN_FILENO, &fds)) { - if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0) - ewrite(term.fd, buf, size); - } - if (FD_ISSET(term.fd, &fds)) { - if ((size = read(term.fd, buf, BUFSIZE)) > 0) { - if (VERBOSE) - ewrite(STDOUT_FILENO, buf, size); - parse(&term, buf, size); - if (LAZY_DRAW && size == BUFSIZE) - continue; /* maybe more data arrives soon */ - refresh(&fb, &term); - } - } - } - - /* normal exit */ - tty_die(&termios_orig); - term_die(&term); - fb_die(&fb); - return EXIT_SUCCESS; - - /* error exit */ + extern const char *shell_cmd; /* defined in conf.h */ + const char *cmd; + uint8_t buf[BUFSIZE]; + ssize_t size; + fd_set fds; + struct timeval tv; + struct framebuffer_t fb; + struct terminal_t term; + /* global */ + extern volatile sig_atomic_t need_redraw; + extern volatile sig_atomic_t child_alive; + extern struct termios termios_orig; + + /* init */ + if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ + logging(WARN, "setlocale falied\n"); + + if (!tty_init(&termios_orig)) { + logging(FATAL, "tty initialize failed\n"); + goto tty_init_failed; + } + + if (!fb_init(&fb)) { + logging(FATAL, "framebuffer initialize failed\n"); + goto fb_init_failed; + } + + if (!term_init(&term, fb.info.width, fb.info.height)) { + logging(FATAL, "terminal initialize failed\n"); + goto term_init_failed; + } + + /* fork and exec shell */ + cmd = (argc < 2) ? shell_cmd: argv[1]; + if (!fork_and_exec(&term.fd, cmd, argv + 1, term.lines, term.cols)) { + logging(FATAL, "forkpty failed\n"); + goto tty_init_failed; + } + child_alive = true; + + /* main loop */ + while (child_alive) { + if (need_redraw) { + need_redraw = false; + cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */ + redraw(&term); + refresh(&fb, &term); + } + + if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) + continue; + + if (FD_ISSET(STDIN_FILENO, &fds)) { + if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0) + ewrite(term.fd, buf, size); + } + if (FD_ISSET(term.fd, &fds)) { + if ((size = read(term.fd, buf, BUFSIZE)) > 0) { + if (VERBOSE) + ewrite(STDOUT_FILENO, buf, size); + parse(&term, buf, size); + if (LAZY_DRAW && size == BUFSIZE) + continue; /* maybe more data arrives soon */ + refresh(&fb, &term); + } + } + } + + /* normal exit */ + tty_die(&termios_orig); + term_die(&term); + fb_die(&fb); + return EXIT_SUCCESS; + + /* error exit */ tty_init_failed: - term_die(&term); + term_die(&term); term_init_failed: - fb_die(&fb); + fb_die(&fb); fb_init_failed: - return EXIT_FAILURE; + return EXIT_FAILURE; } From b199851bbd5d89f00bc6333080e7ecd0efa5634b Mon Sep 17 00:00:00 2001 From: tmu Date: Sat, 6 May 2023 20:52:29 -0700 Subject: [PATCH 2/2] turn the spaces back into tabs --- fb/linux.h | 132 +++++++++---------- yaft.c | 376 ++++++++++++++++++++++++++--------------------------- 2 files changed, 254 insertions(+), 254 deletions(-) diff --git a/fb/linux.h b/fb/linux.h index e920090..3981815 100644 --- a/fb/linux.h +++ b/fb/linux.h @@ -6,101 +6,101 @@ typedef struct fb_cmap cmap_t; enum { - CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE, + CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE, }; /* os specific ioctl */ void alloc_cmap(cmap_t *cmap, int colors) { - cmap->start = 0; - cmap->len = colors; - cmap->red = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->green = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->blue = (__u16 *) ecalloc(colors, sizeof(__u16)); - cmap->transp = NULL; + cmap->start = 0; + cmap->len = colors; + cmap->red = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->green = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->blue = (__u16 *) ecalloc(colors, sizeof(__u16)); + cmap->transp = NULL; } int put_cmap(int fd, cmap_t *cmap) { - return ioctl(fd, FBIOPUTCMAP, cmap); + return ioctl(fd, FBIOPUTCMAP, cmap); } int get_cmap(int fd, cmap_t *cmap) { - return ioctl(fd, FBIOGETCMAP, cmap); + return ioctl(fd, FBIOGETCMAP, cmap); } /* initialize struct fb_info_t */ void set_bitfield(struct fb_var_screeninfo *vinfo, - struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue) + struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue) { - red->length = vinfo->red.length; - green->length = vinfo->green.length; - blue->length = vinfo->blue.length; + red->length = vinfo->red.length; + green->length = vinfo->green.length; + blue->length = vinfo->blue.length; - red->offset = vinfo->red.offset; - green->offset = vinfo->green.offset; - blue->offset = vinfo->blue.offset; + red->offset = vinfo->red.offset; + green->offset = vinfo->green.offset; + blue->offset = vinfo->blue.offset; } enum fb_type_t set_type(__u32 type) { - if (type == FB_TYPE_PACKED_PIXELS) - return YAFT_FB_TYPE_PACKED_PIXELS; - else if (type == FB_TYPE_PLANES) - return YAFT_FB_TYPE_PLANES; - else - return YAFT_FB_TYPE_UNKNOWN; + if (type == FB_TYPE_PACKED_PIXELS) + return YAFT_FB_TYPE_PACKED_PIXELS; + else if (type == FB_TYPE_PLANES) + return YAFT_FB_TYPE_PLANES; + else + return YAFT_FB_TYPE_UNKNOWN; } enum fb_visual_t set_visual(__u32 visual) { - if (visual == FB_VISUAL_TRUECOLOR) - return YAFT_FB_VISUAL_TRUECOLOR; - else if (visual == FB_VISUAL_DIRECTCOLOR) - return YAFT_FB_VISUAL_DIRECTCOLOR; - else if (visual == FB_VISUAL_PSEUDOCOLOR) - return YAFT_FB_VISUAL_PSEUDOCOLOR; - else - return YAFT_FB_VISUAL_UNKNOWN; + if (visual == FB_VISUAL_TRUECOLOR) + return YAFT_FB_VISUAL_TRUECOLOR; + else if (visual == FB_VISUAL_DIRECTCOLOR) + return YAFT_FB_VISUAL_DIRECTCOLOR; + else if (visual == FB_VISUAL_PSEUDOCOLOR) + return YAFT_FB_VISUAL_PSEUDOCOLOR; + else + return YAFT_FB_VISUAL_UNKNOWN; } bool set_fbinfo(int fd, struct fb_info_t *info) { - struct fb_fix_screeninfo finfo; - struct fb_var_screeninfo vinfo; - - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { - logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n"); - return false; - } - - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { - logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n"); - return false; - } - - set_bitfield(&vinfo, &info->red, &info->green, &info->blue); - - info->width = vinfo.xres; - info->height = vinfo.yres; - info->screen_size = finfo.smem_len; - info->line_length = finfo.line_length; - - info->bits_per_pixel = vinfo.bits_per_pixel; - info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE); - - info->type = set_type(finfo.type); - info->visual = set_visual(finfo.visual); - - /* check screen [xy]offset and initialize because linux console changes these values */ - if (vinfo.xoffset != 0 || vinfo.yoffset != 0) { - vinfo.xoffset = vinfo.yoffset = 0; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) - logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset); - } - vinfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; - ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo); - - return true; + struct fb_fix_screeninfo finfo; + struct fb_var_screeninfo vinfo; + + if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) { + logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n"); + return false; + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) { + logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n"); + return false; + } + + set_bitfield(&vinfo, &info->red, &info->green, &info->blue); + + info->width = vinfo.xres; + info->height = vinfo.yres; + info->screen_size = finfo.smem_len; + info->line_length = finfo.line_length; + + info->bits_per_pixel = vinfo.bits_per_pixel; + info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE); + + info->type = set_type(finfo.type); + info->visual = set_visual(finfo.visual); + + /* check screen [xy]offset and initialize because linux console changes these values */ + if (vinfo.xoffset != 0 || vinfo.yoffset != 0) { + vinfo.xoffset = vinfo.yoffset = 0; + if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) + logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset); + } + vinfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo); + + return true; } diff --git a/yaft.c b/yaft.c index 3e681c1..d3039de 100644 --- a/yaft.c +++ b/yaft.c @@ -13,225 +13,225 @@ void sig_handler(int signo) { - sigset_t sigset; - /* global */ - extern volatile sig_atomic_t vt_active; - extern volatile sig_atomic_t child_alive; - extern volatile sig_atomic_t need_redraw; - - logging(DEBUG, "caught signal! no:%d\n", signo); - - if (signo == SIGCHLD) { - child_alive = false; - wait(NULL); - } else if (signo == SIGUSR1) { /* vt activate */ - vt_active = true; - need_redraw = true; - ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); - } else if (signo == SIGUSR2) { /* vt deactivate */ - vt_active = false; - ioctl(STDIN_FILENO, VT_RELDISP, 1); - - if (BACKGROUND_DRAW) { /* update passive cursor */ - need_redraw = true; - } else { /* sleep until next vt switching */ - sigfillset(&sigset); - sigdelset(&sigset, SIGUSR1); - sigsuspend(&sigset); - } - } + sigset_t sigset; + /* global */ + extern volatile sig_atomic_t vt_active; + extern volatile sig_atomic_t child_alive; + extern volatile sig_atomic_t need_redraw; + + logging(DEBUG, "caught signal! no:%d\n", signo); + + if (signo == SIGCHLD) { + child_alive = false; + wait(NULL); + } else if (signo == SIGUSR1) { /* vt activate */ + vt_active = true; + need_redraw = true; + ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); + } else if (signo == SIGUSR2) { /* vt deactivate */ + vt_active = false; + ioctl(STDIN_FILENO, VT_RELDISP, 1); + + if (BACKGROUND_DRAW) { /* update passive cursor */ + need_redraw = true; + } else { /* sleep until next vt switching */ + sigfillset(&sigset); + sigdelset(&sigset, SIGUSR1); + sigsuspend(&sigset); + } + } } void set_rawmode(int fd, struct termios *save_tm) { - struct termios tm; - - tm = *save_tm; - tm.c_iflag = tm.c_oflag = 0; - tm.c_cflag &= ~CSIZE; - tm.c_cflag |= CS8; - tm.c_lflag &= ~(ECHO | ISIG | ICANON); - tm.c_cc[VMIN] = 1; /* min data size (byte) */ - tm.c_cc[VTIME] = 0; /* time out */ - etcsetattr(fd, TCSAFLUSH, &tm); + struct termios tm; + + tm = *save_tm; + tm.c_iflag = tm.c_oflag = 0; + tm.c_cflag &= ~CSIZE; + tm.c_cflag |= CS8; + tm.c_lflag &= ~(ECHO | ISIG | ICANON); + tm.c_cc[VMIN] = 1; /* min data size (byte) */ + tm.c_cc[VTIME] = 0; /* time out */ + etcsetattr(fd, TCSAFLUSH, &tm); } bool tty_init(struct termios *termios_orig) { - struct sigaction sigact; - - memset(&sigact, 0, sizeof(struct sigaction)); - sigact.sa_handler = sig_handler; - sigact.sa_flags = SA_RESTART; - esigaction(SIGCHLD, &sigact, NULL); - - if (VT_CONTROL) { - esigaction(SIGUSR1, &sigact, NULL); - esigaction(SIGUSR2, &sigact, NULL); - - struct vt_mode vtm; - vtm.mode = VT_PROCESS; - vtm.waitv = 0; - vtm.acqsig = SIGUSR1; - vtm.relsig = SIGUSR2; - vtm.frsig = 0; - - if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm)) - logging(WARN, "ioctl: VT_SETMODE failed (maybe here is not console)\n"); - - if (FORCE_TEXT_MODE == false) { - if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS)) - logging(WARN, "ioctl: KDSETMODE failed (maybe here is not console)\n"); - } - } - - etcgetattr(STDIN_FILENO, termios_orig); - set_rawmode(STDIN_FILENO, termios_orig); - ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */ - - return true; + struct sigaction sigact; + + memset(&sigact, 0, sizeof(struct sigaction)); + sigact.sa_handler = sig_handler; + sigact.sa_flags = SA_RESTART; + esigaction(SIGCHLD, &sigact, NULL); + + if (VT_CONTROL) { + esigaction(SIGUSR1, &sigact, NULL); + esigaction(SIGUSR2, &sigact, NULL); + + struct vt_mode vtm; + vtm.mode = VT_PROCESS; + vtm.waitv = 0; + vtm.acqsig = SIGUSR1; + vtm.relsig = SIGUSR2; + vtm.frsig = 0; + + if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm)) + logging(WARN, "ioctl: VT_SETMODE failed (maybe here is not console)\n"); + + if (FORCE_TEXT_MODE == false) { + if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS)) + logging(WARN, "ioctl: KDSETMODE failed (maybe here is not console)\n"); + } + } + + etcgetattr(STDIN_FILENO, termios_orig); + set_rawmode(STDIN_FILENO, termios_orig); + ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */ + + return true; } void tty_die(struct termios *termios_orig) { - /* no error handling */ - struct sigaction sigact; - struct vt_mode vtm; + /* no error handling */ + struct sigaction sigact; + struct vt_mode vtm; - memset(&sigact, 0, sizeof(struct sigaction)); - sigact.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sigact, NULL); + memset(&sigact, 0, sizeof(struct sigaction)); + sigact.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sigact, NULL); - if (VT_CONTROL) { - sigaction(SIGUSR1, &sigact, NULL); - sigaction(SIGUSR2, &sigact, NULL); + if (VT_CONTROL) { + sigaction(SIGUSR1, &sigact, NULL); + sigaction(SIGUSR2, &sigact, NULL); - vtm.mode = VT_AUTO; - vtm.waitv = 0; - vtm.relsig = vtm.acqsig = vtm.frsig = 0; + vtm.mode = VT_AUTO; + vtm.waitv = 0; + vtm.relsig = vtm.acqsig = vtm.frsig = 0; - ioctl(STDIN_FILENO, VT_SETMODE, &vtm); + ioctl(STDIN_FILENO, VT_SETMODE, &vtm); - if (FORCE_TEXT_MODE == false) - ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); - } + if (FORCE_TEXT_MODE == false) + ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); + } - tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig); - fflush(stdout); - ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */ + tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig); + fflush(stdout); + ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */ } bool fork_and_exec(int *master, const char *cmd, char *const argv[], int lines, int cols) { - pid_t pid; - struct winsize ws = {.ws_row = lines, .ws_col = cols, - /* XXX: this variables are UNUSED (man tty_ioctl), - but useful for calculating terminal cell size */ - .ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols}; - - pid = eforkpty(master, NULL, NULL, &ws); - if (pid < 0) - return false; - else if (pid == 0) { /* child */ - esetenv("TERM", term_name, 1); - eexecvp(cmd, argv); - /* never reach here */ - exit(EXIT_FAILURE); - } - return true; + pid_t pid; + struct winsize ws = {.ws_row = lines, .ws_col = cols, + /* XXX: this variables are UNUSED (man tty_ioctl), + but useful for calculating terminal cell size */ + .ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols}; + + pid = eforkpty(master, NULL, NULL, &ws); + if (pid < 0) + return false; + else if (pid == 0) { /* child */ + esetenv("TERM", term_name, 1); + eexecvp(cmd, argv); + /* never reach here */ + exit(EXIT_FAILURE); + } + return true; } int check_fds(fd_set *fds, struct timeval *tv, int input, int master) { - FD_ZERO(fds); - FD_SET(input, fds); - FD_SET(master, fds); - tv->tv_sec = 0; - tv->tv_usec = SELECT_TIMEOUT; - return eselect(master + 1, fds, NULL, NULL, tv); + FD_ZERO(fds); + FD_SET(input, fds); + FD_SET(master, fds); + tv->tv_sec = 0; + tv->tv_usec = SELECT_TIMEOUT; + return eselect(master + 1, fds, NULL, NULL, tv); } int main(int argc, char *const argv[]) { - extern const char *shell_cmd; /* defined in conf.h */ - const char *cmd; - uint8_t buf[BUFSIZE]; - ssize_t size; - fd_set fds; - struct timeval tv; - struct framebuffer_t fb; - struct terminal_t term; - /* global */ - extern volatile sig_atomic_t need_redraw; - extern volatile sig_atomic_t child_alive; - extern struct termios termios_orig; - - /* init */ - if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ - logging(WARN, "setlocale falied\n"); - - if (!tty_init(&termios_orig)) { - logging(FATAL, "tty initialize failed\n"); - goto tty_init_failed; - } - - if (!fb_init(&fb)) { - logging(FATAL, "framebuffer initialize failed\n"); - goto fb_init_failed; - } - - if (!term_init(&term, fb.info.width, fb.info.height)) { - logging(FATAL, "terminal initialize failed\n"); - goto term_init_failed; - } - - /* fork and exec shell */ - cmd = (argc < 2) ? shell_cmd: argv[1]; - if (!fork_and_exec(&term.fd, cmd, argv + 1, term.lines, term.cols)) { - logging(FATAL, "forkpty failed\n"); - goto tty_init_failed; - } - child_alive = true; - - /* main loop */ - while (child_alive) { - if (need_redraw) { - need_redraw = false; - cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */ - redraw(&term); - refresh(&fb, &term); - } - - if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) - continue; - - if (FD_ISSET(STDIN_FILENO, &fds)) { - if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0) - ewrite(term.fd, buf, size); - } - if (FD_ISSET(term.fd, &fds)) { - if ((size = read(term.fd, buf, BUFSIZE)) > 0) { - if (VERBOSE) - ewrite(STDOUT_FILENO, buf, size); - parse(&term, buf, size); - if (LAZY_DRAW && size == BUFSIZE) - continue; /* maybe more data arrives soon */ - refresh(&fb, &term); - } - } - } - - /* normal exit */ - tty_die(&termios_orig); - term_die(&term); - fb_die(&fb); - return EXIT_SUCCESS; - - /* error exit */ + extern const char *shell_cmd; /* defined in conf.h */ + const char *cmd; + uint8_t buf[BUFSIZE]; + ssize_t size; + fd_set fds; + struct timeval tv; + struct framebuffer_t fb; + struct terminal_t term; + /* global */ + extern volatile sig_atomic_t need_redraw; + extern volatile sig_atomic_t child_alive; + extern struct termios termios_orig; + + /* init */ + if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ + logging(WARN, "setlocale falied\n"); + + if (!tty_init(&termios_orig)) { + logging(FATAL, "tty initialize failed\n"); + goto tty_init_failed; + } + + if (!fb_init(&fb)) { + logging(FATAL, "framebuffer initialize failed\n"); + goto fb_init_failed; + } + + if (!term_init(&term, fb.info.width, fb.info.height)) { + logging(FATAL, "terminal initialize failed\n"); + goto term_init_failed; + } + + /* fork and exec shell */ + cmd = (argc < 2) ? shell_cmd: argv[1]; + if (!fork_and_exec(&term.fd, cmd, argv + 1, term.lines, term.cols)) { + logging(FATAL, "forkpty failed\n"); + goto tty_init_failed; + } + child_alive = true; + + /* main loop */ + while (child_alive) { + if (need_redraw) { + need_redraw = false; + cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */ + redraw(&term); + refresh(&fb, &term); + } + + if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) + continue; + + if (FD_ISSET(STDIN_FILENO, &fds)) { + if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0) + ewrite(term.fd, buf, size); + } + if (FD_ISSET(term.fd, &fds)) { + if ((size = read(term.fd, buf, BUFSIZE)) > 0) { + if (VERBOSE) + ewrite(STDOUT_FILENO, buf, size); + parse(&term, buf, size); + if (LAZY_DRAW && size == BUFSIZE) + continue; /* maybe more data arrives soon */ + refresh(&fb, &term); + } + } + } + + /* normal exit */ + tty_die(&termios_orig); + term_die(&term); + fb_die(&fb); + return EXIT_SUCCESS; + + /* error exit */ tty_init_failed: - term_die(&term); + term_die(&term); term_init_failed: - fb_die(&fb); + fb_die(&fb); fb_init_failed: - return EXIT_FAILURE; + return EXIT_FAILURE; }