aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--fb-gui.c8
-rw-r--r--fbi.c110
-rw-r--r--fbtools.c63
-rw-r--r--vt.c178
-rw-r--r--vt.h7
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
diff --git a/fb-gui.c b/fb-gui.c
index 4f248ad..0080309 100644
--- a/fb-gui.c
+++ b/fb-gui.c
@@ -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;
diff --git a/fbi.c b/fbi.c
index 6281f6e..dd73858 100644
--- a/fbi.c
+++ b/fbi.c
@@ -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);
diff --git a/fbtools.c b/fbtools.c
index 08ac41f..c7d1cf1 100644
--- a/fbtools.c
+++ b/fbtools.c
@@ -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",
diff --git a/vt.c b/vt.c
new file mode 100644
index 0000000..75559fb
--- /dev/null
+++ b/vt.c
@@ -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");
+}
diff --git a/vt.h b/vt.h
new file mode 100644
index 0000000..bbba2be
--- /dev/null
+++ b/vt.h
@@ -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);