hi, there! Attached patch implements cons.handler.c for FreeBSD console. Tested on both FreeBSD 4.x and 5.x.
/fjoe
--- 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 <[EMAIL PROTECTED]> @@ -393,10 +392,212 @@ } } -#endif /* SCO_FLAVOR */ +#elif defined(__FreeBSD__) +/* + * FreeBSD support copyright (C) 2003 Alexander Serkov <[EMAIL PROTECTED]>. + * Support for screenmaps by Max Khon <[EMAIL PROTECTED]> + */ + +#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__) */