cons.handler.c for FreeBSD
Max Khon
fjoe at iclub.nsu.ru
Wed Feb 26 17:00:49 UTC 2003
hi, there!
Attached patch implements cons.handler.c for FreeBSD console.
Tested on both FreeBSD 4.x and 5.x.
/fjoe
-------------- next part --------------
--- src/cons.handler.c.orig Mon Sep 23 13:43:23 2002
+++ src/cons.handler.c Wed Feb 26 22:09:57 2003
@@ -186,9 +186,8 @@
}
}
-#endif /* #ifdef linux */
+#elif defined(SCO_FLAVOR)
-#ifdef SCO_FLAVOR
/*
** SCO console save/restore handling routines
** Copyright (C) 1997 Alex Tkachenko <alex at bcs.zaporizhzhe.ua>
@@ -393,10 +392,212 @@
}
}
-#endif /* SCO_FLAVOR */
+#elif defined(__FreeBSD__)
+/*
+ * FreeBSD support copyright (C) 2003 Alexander Serkov <serkov at ukrpost.net>.
+ * Support for screenmaps by Max Khon <fjoe at FreeBSD.org>
+ */
+
+#include <sys/consio.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
-#if !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR)
+#include <stdarg.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <osreldate.h>
+
+#include "dialog.h"
+#include "wtools.h"
+
+#define FD_OUT 1
+
+static struct scrshot screen_shot;
+static struct vid_info screen_info;
+/*
+ * Color indexes returned by SCRSHOT differ from that ones VT220 accepts.
+ * color_map defines mapping from SCRSHOT colors to VT220.
+ */
+static int color_map[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+static void
+console_init(void)
+{
+ if (console_flag)
+ return;
+
+ screen_info.size = sizeof(screen_info);
+ if (ioctl(FD_OUT, CONS_GETINFO, &screen_info) == -1)
+ return;
+
+#if __FreeBSD_version >= 500000
+ screen_shot.x = 0;
+ screen_shot.y = 0;
+#endif
+ screen_shot.xsize = screen_info.mv_csz;
+ screen_shot.ysize = screen_info.mv_rsz;
+ if ((screen_shot.buf = malloc(
+ screen_info.mv_csz * screen_info.mv_rsz)) == NULL)
+ return;
+
+ console_flag = 1;
+}
+
+static void
+set_attr(unsigned attr)
+{
+ char cmd[17];
+ int bc, tc;
+
+ tc = attr & 0xF;
+ bc = (attr >> 4) & 0xF;
+
+ strcpy(cmd, "\x1B[");
+ strcat(cmd, (bc & 8) ? "5;" : "25;");
+ strcat(cmd, (tc & 8) ? "1;" : "22;");
+ strcat(cmd, "3%d;4%dm");
+ printf(cmd, color_map[tc & 7], color_map[bc & 7]);
+}
+
+#define cursor_to(x, y) do { \
+ printf("\x1B[%d;%df", (y) + 1, (x) + 1); \
+ fflush(stdout); \
+} while (0)
+
+static void
+console_restore(void)
+{
+ int i, last;
+
+ if (!console_flag)
+ return;
+
+ cursor_to(0, 0);
+
+ /* restoring all content up to cursor position */
+ last = screen_info.mv_row * screen_info.mv_csz + screen_info.mv_col;
+ for (i = 0; i < last; ++i) {
+ set_attr((screen_shot.buf[i] >> 8) & 0xFF);
+ putc(screen_shot.buf[i] & 0xFF, stdout);
+ }
+
+ /* restoring cursor color */
+ set_attr((screen_shot.buf[last] >> 8) & 0xFF);
+
+ fflush(stdout);
+}
+
+static void
+console_shutdown(void)
+{
+ if (!console_flag)
+ return;
+
+ free(screen_shot.buf);
+
+ console_flag = 0;
+}
+
+static void
+console_save(void)
+{
+ int i;
+ scrmap_t map;
+ scrmap_t revmap;
+
+ if (!console_flag)
+ return;
+
+ /* screen_info.size is already set in console_init() */
+ if (ioctl(FD_OUT, CONS_GETINFO, &screen_info) == -1) {
+ console_shutdown();
+ return;
+ }
+
+ /* handle console resize */
+ if (screen_info.mv_csz != screen_shot.xsize
+ || screen_info.mv_rsz != screen_shot.ysize) {
+ console_shutdown();
+ console_init();
+ }
+
+ if (ioctl(FD_OUT, CONS_SCRSHOT, &screen_shot) == -1) {
+ console_shutdown();
+ return;
+ }
+
+ if (ioctl(FD_OUT, GIO_SCRNMAP, &map) == -1) {
+ console_shutdown();
+ exit(1);
+ }
+
+ for (i = 0; i < 256; i++) {
+ char *p = memchr(map.scrmap, i, 256);
+ revmap.scrmap[i] = p ? p - map.scrmap : i;
+ }
+
+ for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++) {
+ screen_shot.buf[i] =
+ (screen_shot.buf[i] & 0xff00) |
+ (unsigned char) revmap.scrmap[screen_shot.buf[i] & 0xff];
+ }
+}
+
+void
+show_console_contents(int starty, unsigned char begin_line,
+ unsigned char end_line)
+{
+ int i, first, last;
+
+ if (look_for_rxvt_extensions()) {
+ show_rxvt_contents(starty, begin_line, end_line);
+ return;
+ }
+
+ if (!console_flag)
+ return;
+
+ cursor_to(0, starty);
+
+ first = starty * screen_info.mv_csz;
+ last = first + (end_line - begin_line + 1) * screen_info.mv_csz - 1;
+ for (i = first; i <= last; ++i) {
+ set_attr((screen_shot.buf[i] >> 8) & 0xFF);
+ putc(screen_shot.buf[i] & 0xFF, stdout);
+ }
+
+ fflush(stdout);
+}
+
+void
+handle_console(unsigned char action)
+{
+ if (look_for_rxvt_extensions())
+ return;
+
+ switch (action) {
+ case CONSOLE_INIT:
+ console_init();
+ break;
+
+ case CONSOLE_DONE:
+ console_shutdown();
+ break;
+
+ case CONSOLE_SAVE:
+ console_save();
+ break;
+
+ case CONSOLE_RESTORE:
+ console_restore();
+ break;
+ }
+}
+
+#else
#include "tty.h"
@@ -416,6 +617,4 @@
look_for_rxvt_extensions ();
}
-#endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) */
-
-
+#endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) && !defined(__FreeBSD__) */
More information about the mc-devel
mailing list