diff options
-rw-r--r-- | GNUmakefile | 2 | ||||
-rw-r--r-- | fb-gui.c | 8 | ||||
-rw-r--r-- | fbi.c | 110 | ||||
-rw-r--r-- | fbtools.c | 63 | ||||
-rw-r--r-- | vt.c | 178 | ||||
-rw-r--r-- | vt.h | 7 |
6 files changed, 203 insertions, 165 deletions
diff --git a/GNUmakefile b/GNUmakefile index 2d18ab4..82bf42d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -172,7 +172,7 @@ ida.o: Ida.ad.h logo.h # object files OBJS_FBI := \ - fbi.o fbtools.o fb-gui.o desktop.o \ + fbi.o vt.o fbtools.o fb-gui.o desktop.o \ parseconfig.o fbiconfig.o \ jpegtools.o jpeg/$(JPEG_VER)/transupp.o \ dither.o filter.o op.o @@ -11,13 +11,11 @@ #include <fontconfig/fontconfig.h> #include <fontconfig/fcfreetype.h> +#include "vt.h" #include "fbtools.h" #include "dither.h" #include "fb-gui.h" -/* public */ -int visible = 1; - static int ys = 3; static int xs = 10; @@ -95,7 +93,7 @@ void shadow_render(gfxstate *gfx) unsigned int offset = 0; int i; - if (!visible) + if (!console_visible) return; for (i = 0; i < sheight; i++, offset += gfx->stride) { if (0 == sdirty[i]) @@ -465,7 +463,7 @@ void shadow_draw_text_box(FT_Face face, int x, int y, int percent, wchar_t *line { unsigned int i,len,max, x1, x2, y1, y2; - if (!visible) + if (!console_visible) return; max = 0; @@ -36,6 +36,7 @@ #endif #include "readers.h" +#include "vt.h" #include "fbtools.h" #include "fb-gui.h" #include "filter.h" @@ -198,101 +199,6 @@ usage(char *name) "\n"); } -/* -------------------------------------------------------------------- */ - -#define CONSOLE_ACTIVE 0 -#define CONSOLE_REL_REQ 1 -#define CONSOLE_INACTIVE 2 -#define CONSOLE_ACQ_REQ 3 - -static int switch_last; -static int console_switch_state = CONSOLE_ACTIVE; -static struct vt_mode vt_mode; - -static void console_switch_signal(int signal) -{ - if (signal == SIGUSR1) { - /* release */ - console_switch_state = CONSOLE_REL_REQ; - if (debug) - write(2,"vt: SIGUSR1\n",12); - } - if (signal == SIGUSR2) { - /* acquisition */ - console_switch_state = CONSOLE_ACQ_REQ; - if (debug) - write(2,"vt: SIGUSR2\n",12); - } -} - -static void console_switch_release(void) -{ - ioctl(gfx->tty_fd, VT_RELDISP, 1); - console_switch_state = CONSOLE_INACTIVE; - if (debug) - write(2,"vt: release\n",12); -} - -static void console_switch_acquire(void) -{ - ioctl(gfx->tty_fd, VT_RELDISP, VT_ACKACQ); - console_switch_state = CONSOLE_ACTIVE; - if (debug) - write(2,"vt: acquire\n",12); -} - -static int console_switch_init(void) -{ - struct sigaction act,old; - - memset(&act,0,sizeof(act)); - act.sa_handler = console_switch_signal; - sigemptyset(&act.sa_mask); - sigaction(SIGUSR1,&act,&old); - sigaction(SIGUSR2,&act,&old); - - if (-1 == ioctl(gfx->tty_fd, VT_GETMODE, &vt_mode)) { - perror("ioctl VT_GETMODE"); - exit(1); - } - vt_mode.mode = VT_PROCESS; - vt_mode.waitv = 0; - vt_mode.relsig = SIGUSR1; - vt_mode.acqsig = SIGUSR2; - - if (-1 == ioctl(gfx->tty_fd, VT_SETMODE, &vt_mode)) { - perror("ioctl VT_SETMODE"); - exit(1); - } - return 0; -} - -static int check_console_switch(void) -{ - if (switch_last == console_switch_state) - return 0; - - switch (console_switch_state) { - case CONSOLE_REL_REQ: - console_switch_release(); - case CONSOLE_INACTIVE: - visible = 0; - break; - case CONSOLE_ACQ_REQ: - console_switch_acquire(); - case CONSOLE_ACTIVE: - visible = 1; - gfx->restore_display(); - shadow_set_dirty(); - shadow_render(gfx); - break; - default: - break; - } - switch_last = console_switch_state; - return 1; -} - /* ---------------------------------------------------------------------- */ static int flist_add(char *filename) @@ -563,7 +469,7 @@ static void show_exif(struct flist *f) char *value[ARRAY_SIZE(tags)]; wchar_t *linebuffer[ARRAY_SIZE(tags)]; - if (!visible) + if (!console_visible) return; ed = exif_data_new_from_file(f->name); @@ -1513,8 +1419,14 @@ static void cleanup_and_exit(int code) exit(code); } -int -main(int argc, char *argv[]) +static void console_switch_redraw(void) +{ + gfx->restore_display(); + shadow_set_dirty(); + shadow_render(gfx); +} + +int main(int argc, char *argv[]) { int once; int i, arg, key; @@ -1600,7 +1512,7 @@ main(int argc, char *argv[]) cfg_get_str(O_VIDEO_MODE), GET_VT()); exit_signals_init(); - console_switch_init(); + console_switch_init(gfx->tty_fd, console_switch_redraw); shadow_init(gfx); signal(SIGTSTP,SIG_IGN); @@ -22,6 +22,7 @@ #include <linux/vt.h> #include <linux/fb.h> +#include "vt.h" #include "fbtools.h" #ifndef HAVE_STRSIGNAL @@ -41,8 +42,6 @@ static int fb_mem_offset = 0; static int fb,tty; -static int orig_vt_no = 0; - static int kd_mode; static struct vt_mode vt_omode; static struct termios term; @@ -204,59 +203,6 @@ fb_setmode(char *name) return -1; } -static void -fb_setvt(int vtno) -{ - struct vt_stat vts; - char vtname[12]; - - if (vtno < 0) { - if (-1 == ioctl(tty,VT_OPENQRY, &vtno) || vtno == -1) { - perror("ioctl VT_OPENQRY"); - exit(1); - } - } - - vtno &= 0xff; - sprintf(vtname, "/dev/tty%d", vtno); - chown(vtname, getuid(), getgid()); - if (-1 == access(vtname, R_OK | W_OK)) { - fprintf(stderr,"access %s: %s\n",vtname,strerror(errno)); - exit(1); - } - switch (fork()) { - case 0: - break; - case -1: - perror("fork"); - exit(1); - default: - exit(0); - } - close(tty); - close(0); - close(1); - close(2); - setsid(); - open(vtname,O_RDWR); - dup(0); - dup(0); - - if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { - perror("ioctl VT_GETSTATE"); - exit(1); - } - orig_vt_no = vts.v_active; - if (-1 == ioctl(tty,VT_ACTIVATE, vtno)) { - perror("ioctl VT_ACTIVATE"); - exit(1); - } - if (-1 == ioctl(tty,VT_WAITACTIVE, vtno)) { - perror("ioctl VT_WAITACTIVE"); - exit(1); - } -} - /* Hmm. radeonfb needs this. matroxfb doesn't. */ static int fb_activate_current(int tty) { @@ -301,10 +247,7 @@ static void fb_cleanup_display(void) if (-1 == ioctl(tty,VT_SETMODE, &vt_omode)) perror("ioctl VT_SETMODE"); - if (orig_vt_no && -1 == ioctl(tty, VT_ACTIVATE, orig_vt_no)) - perror("ioctl VT_ACTIVATE"); - if (orig_vt_no && -1 == ioctl(tty, VT_WAITACTIVE, orig_vt_no)) - perror("ioctl VT_WAITACTIVE"); + console_restore_vt(); tcsetattr(tty, TCSANOW, &term); close(tty); } @@ -320,7 +263,7 @@ gfxstate* fb_init(char *device, char *mode, int vt) tty = 0; if (vt != 0) - fb_setvt(vt); + console_set_vt(vt); if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { fprintf(stderr,"ioctl VT_GETSTATE: %s (not a linux console?)\n", @@ -0,0 +1,178 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <signal.h> +#include <sys/ioctl.h> + +#include <linux/kd.h> +#include <linux/vt.h> + +#include "vt.h" + +/* -------------------------------------------------------------------- */ + +#define CONSOLE_ACTIVE 0 +#define CONSOLE_REL_REQ 1 +#define CONSOLE_INACTIVE 2 +#define CONSOLE_ACQ_REQ 3 + +int console_visible = 1; + +extern int debug; + +static int switch_last, tty; +static int console_switch_state = CONSOLE_ACTIVE; +static struct vt_mode vt_mode; +static int orig_vt_no = 0; +static void (*console_redraw)(void); + +static void console_switch_signal(int signal) +{ + if (signal == SIGUSR1) { + /* release */ + console_switch_state = CONSOLE_REL_REQ; + if (debug) + write(2,"vt: SIGUSR1\n",12); + } + if (signal == SIGUSR2) { + /* acquisition */ + console_switch_state = CONSOLE_ACQ_REQ; + if (debug) + write(2,"vt: SIGUSR2\n",12); + } +} + +static void console_switch_release(void) +{ + ioctl(tty, VT_RELDISP, 1); + console_switch_state = CONSOLE_INACTIVE; + if (debug) + write(2,"vt: release\n",12); +} + +static void console_switch_acquire(void) +{ + ioctl(tty, VT_RELDISP, VT_ACKACQ); + console_switch_state = CONSOLE_ACTIVE; + if (debug) + write(2,"vt: acquire\n",12); +} + +int console_switch_init(int tty_fd, void (*redraw)(void)) +{ + struct sigaction act,old; + + tty = tty_fd; + console_redraw = redraw; + + memset(&act,0,sizeof(act)); + act.sa_handler = console_switch_signal; + sigemptyset(&act.sa_mask); + sigaction(SIGUSR1,&act,&old); + sigaction(SIGUSR2,&act,&old); + + if (-1 == ioctl(tty, VT_GETMODE, &vt_mode)) { + perror("ioctl VT_GETMODE"); + exit(1); + } + vt_mode.mode = VT_PROCESS; + vt_mode.waitv = 0; + vt_mode.relsig = SIGUSR1; + vt_mode.acqsig = SIGUSR2; + + if (-1 == ioctl(tty, VT_SETMODE, &vt_mode)) { + perror("ioctl VT_SETMODE"); + exit(1); + } + return 0; +} + +int check_console_switch(void) +{ + if (switch_last == console_switch_state) + return 0; + + switch (console_switch_state) { + case CONSOLE_REL_REQ: + console_switch_release(); + case CONSOLE_INACTIVE: + console_visible = 0; + break; + case CONSOLE_ACQ_REQ: + console_switch_acquire(); + case CONSOLE_ACTIVE: + console_visible = 1; + console_redraw(); + break; + default: + break; + } + switch_last = console_switch_state; + return 1; +} + +void console_set_vt(int vtno) +{ + struct vt_stat vts; + char vtname[12]; + + if (vtno < 0) { + if (-1 == ioctl(tty,VT_OPENQRY, &vtno) || vtno == -1) { + perror("ioctl VT_OPENQRY"); + exit(1); + } + } + + vtno &= 0xff; + sprintf(vtname, "/dev/tty%d", vtno); + chown(vtname, getuid(), getgid()); + if (-1 == access(vtname, R_OK | W_OK)) { + fprintf(stderr,"access %s: %s\n",vtname,strerror(errno)); + exit(1); + } + switch (fork()) { + case 0: + break; + case -1: + perror("fork"); + exit(1); + default: + exit(0); + } + close(tty); + close(0); + close(1); + close(2); + setsid(); + open(vtname,O_RDWR); + dup(0); + dup(0); + + if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { + perror("ioctl VT_GETSTATE"); + exit(1); + } + orig_vt_no = vts.v_active; + if (-1 == ioctl(tty,VT_ACTIVATE, vtno)) { + perror("ioctl VT_ACTIVATE"); + exit(1); + } + if (-1 == ioctl(tty,VT_WAITACTIVE, vtno)) { + perror("ioctl VT_WAITACTIVE"); + exit(1); + } +} + +void console_restore_vt(void) +{ + if (!orig_vt_no) + return; + + if (ioctl(tty, VT_ACTIVATE, orig_vt_no) < 0) + perror("ioctl VT_ACTIVATE"); + if (ioctl(tty, VT_WAITACTIVE, orig_vt_no) < 0) + perror("ioctl VT_WAITACTIVE"); +} @@ -0,0 +1,7 @@ +extern int console_visible; + +int console_switch_init(int fd, void (*redraw)(void)); +int check_console_switch(void); + +void console_set_vt(int vtno); +void console_restore_vt(void); |