aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.alpha4
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/dev/syscons/daemon/daemon_saver.c2
-rw-r--r--sys/dev/syscons/scgfbrndr.c23
-rw-r--r--sys/dev/syscons/schistory.c8
-rw-r--r--sys/dev/syscons/scmouse.c216
-rw-r--r--sys/dev/syscons/scterm-dumb.c156
-rw-r--r--sys/dev/syscons/scterm-sc.c729
-rw-r--r--sys/dev/syscons/scterm.c128
-rw-r--r--sys/dev/syscons/sctermvar.h437
-rw-r--r--sys/dev/syscons/scvgarndr.c23
-rw-r--r--sys/dev/syscons/scvidctl.c105
-rw-r--r--sys/dev/syscons/scvtb.c1
-rw-r--r--sys/dev/syscons/snake/snake_saver.c2
-rw-r--r--sys/dev/syscons/star/star_saver.c2
-rw-r--r--sys/dev/syscons/syscons.c1199
-rw-r--r--sys/dev/syscons/syscons.h224
-rw-r--r--sys/dev/syscons/sysmouse.c344
-rw-r--r--sys/modules/syscons/daemon/daemon_saver.c2
-rw-r--r--sys/modules/syscons/snake/snake_saver.c2
-rw-r--r--sys/modules/syscons/star/star_saver.c2
-rw-r--r--sys/sys/consio.h15
22 files changed, 2378 insertions, 1250 deletions
diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha
index b7434e44699f..ecb411ee37c4 100644
--- a/sys/conf/files.alpha
+++ b/sys/conf/files.alpha
@@ -181,10 +181,14 @@ dev/sound/isa/sb.c optional pcm isa
dev/sound/isa/sbc.c optional sbc
dev/syscons/schistory.c optional sc
dev/syscons/scmouse.c optional sc
+dev/syscons/scterm.c optional sc
+dev/syscons/scterm-dumb.c optional sc
+dev/syscons/scterm-sc.c optional sc
dev/syscons/scvgarndr.c optional sc
dev/syscons/scvidctl.c optional sc
dev/syscons/scvtb.c optional sc
dev/syscons/syscons.c optional sc
+dev/syscons/sysmouse.c optional sc
isa/atkbd_isa.c optional atkbd
isa/atkbdc_isa.c optional atkbdc
isa/fd.c optional fd
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 813aa93002f6..e9bbc68f467a 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -92,11 +92,15 @@ dev/sound/isa/sb.c optional pcm isa
dev/sound/isa/sbc.c optional sbc
dev/syscons/schistory.c optional sc
dev/syscons/scmouse.c optional sc
+dev/syscons/scterm.c optional sc
+dev/syscons/scterm-dumb.c optional sc
+dev/syscons/scterm-sc.c optional sc
dev/syscons/scvesactl.c optional sc
dev/syscons/scvgarndr.c optional sc
dev/syscons/scvidctl.c optional sc
dev/syscons/scvtb.c optional sc
dev/syscons/syscons.c optional sc
+dev/syscons/sysmouse.c optional sc
gnu/i386/fpemul/div_small.s optional gpl_math_emulate
gnu/i386/fpemul/errors.c optional gpl_math_emulate
gnu/i386/fpemul/fpu_arith.c optional gpl_math_emulate
diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c
index bc03f6446401..b056b486a039 100644
--- a/sys/dev/syscons/daemon/daemon_saver.c
+++ b/sys/dev/syscons/daemon/daemon_saver.c
@@ -240,7 +240,7 @@ daemon_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
xlen = ylen = tlen = 0;
}
if (blanked++ < 2)
diff --git a/sys/dev/syscons/scgfbrndr.c b/sys/dev/syscons/scgfbrndr.c
index 7290558f8159..afdd073627a8 100644
--- a/sys/dev/syscons/scgfbrndr.c
+++ b/sys/dev/syscons/scgfbrndr.c
@@ -38,7 +38,6 @@
#include <sys/kernel.h>
#include <machine/console.h>
-#include <machine/md_var.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/vgareg.h>
@@ -83,6 +82,8 @@ static vr_draw_border_t vga_grborder;
static void vga_nop(scr_stat *scp, ...);
+static struct linker_set vga_set;
+
static sc_rndr_sw_t txtrndrsw = {
vga_txtclear,
vga_txtborder,
@@ -93,10 +94,10 @@ static sc_rndr_sw_t txtrndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_txtmouse,
};
-RENDERER(mda, 0, txtrndrsw);
-RENDERER(cga, 0, txtrndrsw);
-RENDERER(ega, 0, txtrndrsw);
-RENDERER(vga, 0, txtrndrsw);
+RENDERER(mda, 0, txtrndrsw, vga_set);
+RENDERER(cga, 0, txtrndrsw, vga_set);
+RENDERER(ega, 0, txtrndrsw, vga_set);
+RENDERER(vga, 0, txtrndrsw, vga_set);
#ifdef SC_PIXEL_MODE
static sc_rndr_sw_t egarndrsw = {
@@ -109,7 +110,7 @@ static sc_rndr_sw_t egarndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_pxlmouse,
};
-RENDERER(ega, PIXEL_MODE, egarndrsw);
+RENDERER(ega, PIXEL_MODE, egarndrsw, vga_set);
static sc_rndr_sw_t vgarndrsw = {
vga_pxlclear,
@@ -121,7 +122,7 @@ static sc_rndr_sw_t vgarndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_pxlmouse,
};
-RENDERER(vga, PIXEL_MODE, vgarndrsw);
+RENDERER(vga, PIXEL_MODE, vgarndrsw, vga_set);
#endif /* SC_PIXEL_MODE */
#ifndef SC_NO_MODE_CHANGE
@@ -135,11 +136,13 @@ static sc_rndr_sw_t grrndrsw = {
(vr_set_mouse_t *)vga_nop,
(vr_draw_mouse_t *)vga_nop,
};
-RENDERER(cga, GRAPHICS_MODE, grrndrsw);
-RENDERER(ega, GRAPHICS_MODE, grrndrsw);
-RENDERER(vga, GRAPHICS_MODE, grrndrsw);
+RENDERER(cga, GRAPHICS_MODE, grrndrsw, vga_set);
+RENDERER(ega, GRAPHICS_MODE, grrndrsw, vga_set);
+RENDERER(vga, GRAPHICS_MODE, grrndrsw, vga_set);
#endif /* SC_NO_MODE_CHANGE */
+RENDERER_MODULE(vga, vga_set);
+
#ifndef SC_NO_CUTPASTE
static u_short mouse_and_mask[16] = {
0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c
index aa7de06ca64b..49fc6eae8c09 100644
--- a/sys/dev/syscons/schistory.c
+++ b/sys/dev/syscons/schistory.c
@@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <machine/console.h>
+#include <machine/pc/display.h>
#include <dev/syscons/syscons.h>
@@ -120,10 +121,12 @@ sc_alloc_history_buffer(scr_stat *scp, int lines, int prev_ysize, int wait)
if (history != NULL) {
if (lines > min_lines)
extra_history_size -= lines - min_lines;
+ /* XXX error check? */
sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines,
NULL, wait);
+ /* FIXME: XXX no good? */
sc_vtb_clear(history, scp->sc->scr_map[0x20],
- scp->term.cur_color);
+ SC_NORM_ATTR << 8);
if (prev_history != NULL)
copy_history(prev_history, history);
scp->history_pos = sc_vtb_tail(history);
@@ -182,7 +185,8 @@ sc_free_history_buffer(scr_stat *scp, int prev_ysize)
cur_lines = sc_vtb_rows(history);
min_lines = imax(SC_HISTORY_SIZE, prev_ysize);
- extra_history_size += (cur_lines > min_lines) ? cur_lines - min_lines : 0;
+ extra_history_size += (cur_lines > min_lines) ?
+ cur_lines - min_lines : 0;
sc_vtb_destroy(history);
free(history, M_DEVBUF);
diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c
index b0663a005f02..e55946c0211d 100644
--- a/sys/dev/syscons/scmouse.c
+++ b/sys/dev/syscons/scmouse.c
@@ -38,7 +38,6 @@
#include <sys/signalvar.h>
#include <sys/proc.h>
#include <sys/tty.h>
-#include <sys/kernel.h>
#include <sys/malloc.h>
#include <machine/console.h>
@@ -73,16 +72,13 @@ typedef struct old_mouse_info {
} u;
} old_mouse_info_t;
-/* local variables */
#ifndef SC_NO_SYSMOUSE
-static int mouse_level; /* sysmouse protocol level */
-static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
+
+/* local variables */
static int cut_buffer_size;
static u_char *cut_buffer;
-#endif /* SC_NO_SYSMOUE */
/* local functions */
-#ifndef SC_NO_SYSMOUSE
static void set_mouse_pos(scr_stat *scp);
#ifndef SC_NO_CUTPASTE
static int skip_spc_right(scr_stat *scp, int p);
@@ -95,7 +91,6 @@ static void mouse_cut_line(scr_stat *scp);
static void mouse_cut_extend(scr_stat *scp);
static void mouse_paste(scr_stat *scp);
#endif /* SC_NO_CUTPASTE */
-#endif /* SC_NO_SYSMOUE */
#ifndef SC_NO_CUTPASTE
/* allocate a cut buffer */
@@ -120,15 +115,6 @@ sc_alloc_cut_buffer(scr_stat *scp, int wait)
}
#endif /* SC_NO_CUTPASTE */
-#ifndef SC_NO_SYSMOUSE
-
-/* modify the sysmouse software level */
-void
-sc_mouse_set_level(int level)
-{
- mouse_level = level;
-}
-
/* move mouse */
void
sc_mouse_move(scr_stat *scp, int x, int y)
@@ -612,39 +598,21 @@ int
sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
struct proc *p)
{
-
+ mouse_info_t *mouse;
+ mouse_info_t buf;
+ scr_stat *cur_scp;
scr_stat *scp;
int s;
- int i;
+ int f;
- /* scp == NULL, if tp == sc_get_mouse_tty() (/dev/sysmouse) */
scp = SC_STAT(tp->t_dev);
switch (cmd) {
case CONS_MOUSECTL: /* control mouse arrow */
case OLD_CONS_MOUSECTL:
- {
- /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
- static int butmap[8] = {
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON1UP,
- 0,
- };
- mouse_info_t *mouse = (mouse_info_t*)data;
- mouse_info_t buf;
- scr_stat *cur_scp;
- struct tty *mtty;
- int f;
-
- if (scp == NULL)
- return ENOTTY;
+ mouse = (mouse_info_t*)data;
if (cmd == OLD_CONS_MOUSECTL) {
static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
@@ -767,45 +735,9 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
}
splx(s);
- mouse_status.dx += mouse->u.data.x;
- mouse_status.dy += mouse->u.data.y;
- mouse_status.dz += mouse->u.data.z;
- if (mouse->operation == MOUSE_ACTION)
- mouse_status.button = mouse->u.data.buttons;
- mouse_status.flags |=
- ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ?
- MOUSE_POSCHANGED : 0)
- | (mouse_status.obutton ^ mouse_status.button);
- if (mouse_status.flags == 0)
+ if (sysmouse_event(mouse) == 0)
return 0;
- mtty = sc_get_mouse_tty();
- if (mtty->t_state & TS_ISOPEN) {
- u_char buf[MOUSE_SYS_PACKETSIZE];
-
- /* the first five bytes are compatible with MouseSystems' */
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- i = imax(imin(mouse->u.data.x, 255), -256);
- buf[1] = i >> 1;
- buf[3] = i - buf[1];
- i = -imax(imin(mouse->u.data.y, 255), -256);
- buf[2] = i >> 1;
- buf[4] = i - buf[2];
- for (i = 0; i < MOUSE_MSC_PACKETSIZE; i++)
- (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
- if (mouse_level >= 1) { /* extended part */
- i = imax(imin(mouse->u.data.z, 127), -128);
- buf[5] = (i >> 1) & 0x7f;
- buf[6] = (i - (i >> 1)) & 0x7f;
- /* buttons 4-10 */
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- for (i = MOUSE_MSC_PACKETSIZE;
- i < MOUSE_SYS_PACKETSIZE; i++)
- (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
- }
- }
-
/*
* If any buttons are down or the mouse has moved a lot,
* stop the screen saver.
@@ -862,30 +794,13 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
return ENOTTY;
#endif
- if (mouse->u.event.value > 0) {
+ if (mouse->u.event.value > 0)
cur_scp->mouse_buttons |= mouse->u.event.id;
- mouse_status.button |= mouse->u.event.id;
- } else {
+ else
cur_scp->mouse_buttons &= ~mouse->u.event.id;
- mouse_status.button &= ~mouse->u.event.id;
- }
- mouse_status.flags |= mouse_status.obutton ^ mouse_status.button;
- if (mouse_status.flags == 0)
- return 0;
- mtty = sc_get_mouse_tty();
- if (mtty->t_state & TS_ISOPEN) {
- u_char buf[MOUSE_SYS_PACKETSIZE];
-
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
- for (i = 0;
- i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE
- : MOUSE_MSC_PACKETSIZE); i++)
- (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
- }
+ if (sysmouse_event(mouse) == 0)
+ return 0;
/* if a button is held down, stop the screen saver */
if (mouse->u.event.value > 0)
@@ -961,11 +876,12 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
} else {
if (mouse->u.mouse_char >= UCHAR_MAX - 4)
return EINVAL;
- s = spltty();
+ s = spltty();
sc_remove_all_mouse(scp->sc);
#ifndef SC_NO_FONT_LOADING
if (ISTEXTSC(cur_scp) && (cur_scp->font_size != FONT_NONE))
- copy_font(cur_scp, LOAD, cur_scp->font_size, cur_scp->font);
+ sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
+ cur_scp->sc->mouse_char, 4);
#endif
scp->sc->mouse_char = mouse->u.mouse_char;
splx(s);
@@ -979,108 +895,6 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
return 0;
}
- /* MOUSE_XXX: /dev/sysmouse ioctls */
- case MOUSE_GETHWINFO: /* get device information */
- {
- mousehw_t *hw = (mousehw_t *)data;
-
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- hw->buttons = 10; /* XXX unknown */
- hw->iftype = MOUSE_IF_SYSMOUSE;
- hw->type = MOUSE_MOUSE;
- hw->model = MOUSE_MODEL_GENERIC;
- hw->hwid = 0;
- return 0;
- }
-
- case MOUSE_GETMODE: /* get protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- mode->level = mouse_level;
- switch (mode->level) {
- case 0:
- /* at this level, sysmouse emulates MouseSystems protocol */
- mode->protocol = MOUSE_PROTO_MSC;
- mode->rate = -1; /* unknown */
- mode->resolution = -1; /* unknown */
- mode->accelfactor = 0; /* disabled */
- mode->packetsize = MOUSE_MSC_PACKETSIZE;
- mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
- mode->syncmask[1] = MOUSE_MSC_SYNC;
- break;
-
- case 1:
- /* at this level, sysmouse uses its own protocol */
- mode->protocol = MOUSE_PROTO_SYSMOUSE;
- mode->rate = -1;
- mode->resolution = -1;
- mode->accelfactor = 0;
- mode->packetsize = MOUSE_SYS_PACKETSIZE;
- mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
- mode->syncmask[1] = MOUSE_SYS_SYNC;
- break;
- }
- return 0;
- }
-
- case MOUSE_SETMODE: /* set protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- if ((mode->level < 0) || (mode->level > 1))
- return EINVAL;
- sc_mouse_set_level(mode->level);
- return 0;
- }
-
- case MOUSE_GETLEVEL: /* get operation level */
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- *(int *)data = mouse_level;
- return 0;
-
- case MOUSE_SETLEVEL: /* set operation level */
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- if ((*(int *)data < 0) || (*(int *)data > 1))
- return EINVAL;
- sc_mouse_set_level(*(int *)data);
- return 0;
-
- case MOUSE_GETSTATUS: /* get accumulated mouse events */
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- s = spltty();
- *(mousestatus_t *)data = mouse_status;
- mouse_status.flags = 0;
- mouse_status.obutton = mouse_status.button;
- mouse_status.dx = 0;
- mouse_status.dy = 0;
- mouse_status.dz = 0;
- splx(s);
- return 0;
-
-#if notyet
- case MOUSE_GETVARS: /* get internal mouse variables */
- case MOUSE_SETVARS: /* set internal mouse variables */
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- return ENODEV;
-#endif
-
- case MOUSE_READSTATE: /* read status from the device */
- case MOUSE_READDATA: /* read data from the device */
- if (tp != sc_get_mouse_tty())
- return ENOTTY;
- return ENODEV;
- }
-
return ENOIOCTL;
}
diff --git a/sys/dev/syscons/scterm-dumb.c b/sys/dev/syscons/scterm-dumb.c
new file mode 100644
index 000000000000..19e421d594a1
--- /dev/null
+++ b/sys/dev/syscons/scterm-dumb.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/consio.h>
+
+#include <machine/pc/display.h>
+
+#include <dev/syscons/syscons.h>
+#include <dev/syscons/sctermvar.h>
+
+#ifdef SC_DUMB_TERMINAL
+
+/* dumb terminal emulator */
+
+static sc_term_init_t dumb_init;
+static sc_term_term_t dumb_term;
+static sc_term_puts_t dumb_puts;
+static sc_term_ioctl_t dumb_ioctl;
+static sc_term_clear_t dumb_clear;
+static sc_term_input_t dumb_input;
+static void dumb_nop(void);
+
+static sc_term_sw_t sc_term_dumb = {
+ { NULL, NULL },
+ "dumb", /* emulator name */
+ "dumb terminal", /* description */
+ "*", /* matching renderer */
+ 0, /* softc size */
+ 0,
+ dumb_init,
+ dumb_term,
+ dumb_puts,
+ dumb_ioctl,
+ (sc_term_reset_t *)dumb_nop,
+ (sc_term_default_attr_t *)dumb_nop,
+ dumb_clear,
+ (sc_term_notify_t *)dumb_nop,
+ dumb_input,
+};
+
+SCTERM_MODULE(dumb, sc_term_dumb);
+
+static int
+dumb_init(scr_stat *scp, void **softc, int code)
+{
+ switch (code) {
+ case SC_TE_COLD_INIT:
+ ++sc_term_dumb.te_refcount;
+ break;
+ case SC_TE_WARM_INIT:
+ break;
+ }
+ return 0;
+}
+
+static int
+dumb_term(scr_stat *scp, void **softc)
+{
+ --sc_term_dumb.te_refcount;
+ return 0;
+}
+
+static void
+dumb_puts(scr_stat *scp, u_char *buf, int len)
+{
+ while (len > 0) {
+ ++scp->sc->write_in_progress;
+ sc_term_gen_print(scp, &buf, &len, SC_NORM_ATTR << 8);
+ sc_term_gen_scroll(scp, scp->sc->scr_map[0x20],
+ SC_NORM_ATTR << 8);
+ --scp->sc->write_in_progress;
+ }
+}
+
+static int
+dumb_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
+ int flag, struct proc *p)
+{
+ vid_info_t *vi;
+
+ switch (cmd) {
+ case GIO_ATTR: /* get current attributes */
+ *(int*)data = SC_NORM_ATTR;
+ return 0;
+ case CONS_GETINFO: /* get current (virtual) console info */
+ vi = (vid_info_t *)data;
+ if (vi->size != sizeof(struct vid_info))
+ return EINVAL;
+ vi->mv_norm.fore = SC_NORM_ATTR & 0x0f;
+ vi->mv_norm.back = (SC_NORM_ATTR >> 4) & 0x0f;
+ vi->mv_rev.fore = SC_NORM_ATTR & 0x0f;
+ vi->mv_rev.back = (SC_NORM_ATTR >> 4) & 0x0f;
+ /*
+ * The other fields are filled by the upper routine. XXX
+ */
+ return ENOIOCTL;
+ }
+ return ENOIOCTL;
+}
+
+static void
+dumb_clear(scr_stat *scp)
+{
+ sc_move_cursor(scp, 0, 0);
+ sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8);
+ mark_all(scp);
+}
+
+static int
+dumb_input(scr_stat *scp, int c, struct tty *tp)
+{
+ return FALSE;
+}
+
+static void
+dumb_nop(void)
+{
+ /* nothing */
+}
+
+#endif /* SC_DUMB_TERMINAL */
+
+#endif /* NSC > 1 */
diff --git a/sys/dev/syscons/scterm-sc.c b/sys/dev/syscons/scterm-sc.c
new file mode 100644
index 000000000000..317f7da5bcec
--- /dev/null
+++ b/sys/dev/syscons/scterm-sc.c
@@ -0,0 +1,729 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * Copyright (c) 1992-1998 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/consio.h>
+
+#include <machine/pc/display.h>
+
+#include <dev/syscons/syscons.h>
+#include <dev/syscons/sctermvar.h>
+
+#ifndef SC_DUMB_TERMINAL
+
+#define MAX_ESC_PAR 5
+
+/* attribute flags */
+typedef struct {
+ u_short fg; /* foreground color */
+ u_short bg; /* background color */
+} color_t;
+
+typedef struct {
+ int flags;
+#define SCTERM_BUSY (1 << 0)
+ int esc;
+ int num_param;
+ int last_param;
+ int param[MAX_ESC_PAR];
+ int saved_xpos;
+ int saved_ypos;
+ int attr_mask; /* current logical attr mask */
+#define NORMAL_ATTR 0x00
+#define BLINK_ATTR 0x01
+#define BOLD_ATTR 0x02
+#define UNDERLINE_ATTR 0x04
+#define REVERSE_ATTR 0x08
+#define FG_CHANGED 0x10
+#define BG_CHANGED 0x20
+ int cur_attr; /* current hardware attr word */
+ color_t cur_color; /* current hardware color */
+ color_t std_color; /* normal hardware color */
+ color_t rev_color; /* reverse hardware color */
+ color_t dflt_std_color; /* default normal color */
+ color_t dflt_rev_color; /* default reverse color */
+} term_stat;
+
+static sc_term_init_t scterm_init;
+static sc_term_term_t scterm_term;
+static sc_term_puts_t scterm_puts;
+static sc_term_ioctl_t scterm_ioctl;
+static sc_term_reset_t scterm_reset;
+static sc_term_default_attr_t scterm_default_attr;
+static sc_term_clear_t scterm_clear;
+static sc_term_notify_t scterm_notify;
+static sc_term_input_t scterm_input;
+
+static sc_term_sw_t sc_term_sc = {
+ { NULL, NULL },
+ "sc", /* emulator name */
+ "syscons terminal", /* description */
+ "*", /* matching renderer, any :-) */
+ sizeof(term_stat), /* softc size */
+ 0,
+ scterm_init,
+ scterm_term,
+ scterm_puts,
+ scterm_ioctl,
+ scterm_reset,
+ scterm_default_attr,
+ scterm_clear,
+ scterm_notify,
+ scterm_input,
+};
+
+SCTERM_MODULE(sc, sc_term_sc);
+
+static term_stat reserved_term_stat;
+static void scterm_scan_esc(scr_stat *scp, term_stat *tcp,
+ u_char c);
+static int mask2attr(term_stat *tcp);
+
+static int
+scterm_init(scr_stat *scp, void **softc, int code)
+{
+ term_stat *tcp;
+
+ if (*softc == NULL) {
+ if (reserved_term_stat.flags & SCTERM_BUSY)
+ return EINVAL;
+ *softc = &reserved_term_stat;
+ }
+ tcp = *softc;
+
+ switch (code) {
+ case SC_TE_COLD_INIT:
+ bzero(tcp, sizeof(*tcp));
+ tcp->flags = SCTERM_BUSY;
+ tcp->esc = 0;
+ tcp->saved_xpos = -1;
+ tcp->saved_ypos = -1;
+ tcp->attr_mask = NORMAL_ATTR;
+ /* XXX */
+ tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f;
+ tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f;
+ tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f;
+ tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f;
+ tcp->std_color = tcp->dflt_std_color;
+ tcp->rev_color = tcp->dflt_rev_color;
+ tcp->cur_color = tcp->std_color;
+ tcp->cur_attr = mask2attr(tcp);
+ ++sc_term_sc.te_refcount;
+ break;
+
+ case SC_TE_WARM_INIT:
+ tcp->esc = 0;
+ tcp->saved_xpos = -1;
+ tcp->saved_ypos = -1;
+ tcp->std_color = tcp->dflt_std_color;
+ tcp->rev_color = tcp->dflt_rev_color;
+ tcp->cur_color = tcp->std_color;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+scterm_term(scr_stat *scp, void **softc)
+{
+ if (*softc == &reserved_term_stat) {
+ *softc = NULL;
+ bzero(&reserved_term_stat, sizeof(reserved_term_stat));
+ }
+ --sc_term_sc.te_refcount;
+ return 0;
+}
+
+static void
+scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c)
+{
+ static u_char ansi_col[16] = {
+ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
+ FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
+ FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
+ FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE
+ };
+ sc_softc_t *sc;
+ int i, n;
+
+ i = n = 0;
+ sc = scp->sc;
+ if (tcp->esc == 1) { /* seen ESC */
+ switch (c) {
+
+ case '7': /* Save cursor position */
+ tcp->saved_xpos = scp->xpos;
+ tcp->saved_ypos = scp->ypos;
+ break;
+
+ case '8': /* Restore saved cursor position */
+ if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
+ sc_move_cursor(scp, tcp->saved_xpos, tcp->saved_ypos);
+ break;
+
+ case '[': /* Start ESC [ sequence */
+ tcp->esc = 2;
+ tcp->last_param = -1;
+ for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
+ tcp->param[i] = 1;
+ tcp->num_param = 0;
+ return;
+
+ case 'M': /* Move cursor up 1 line, scroll if at top */
+ sc_term_up_scroll(scp, 1, sc->scr_map[0x20], tcp->cur_attr, 0, 0);
+ break;
+#if notyet
+ case 'Q':
+ tcp->esc = 4;
+ return;
+#endif
+ case 'c': /* Clear screen & home */
+ sc_clear_screen(scp);
+ break;
+
+ case '(': /* iso-2022: designate 94 character set to G0 */
+ tcp->esc = 5;
+ return;
+ }
+ }
+ else if (tcp->esc == 2) { /* seen ESC [ */
+ if (c >= '0' && c <= '9') {
+ if (tcp->num_param < MAX_ESC_PAR) {
+ if (tcp->last_param != tcp->num_param) {
+ tcp->last_param = tcp->num_param;
+ tcp->param[tcp->num_param] = 0;
+ } else {
+ tcp->param[tcp->num_param] *= 10;
+ }
+ tcp->param[tcp->num_param] += c - '0';
+ return;
+ }
+ }
+ tcp->num_param = tcp->last_param + 1;
+ switch (c) {
+
+ case ';':
+ if (tcp->num_param < MAX_ESC_PAR)
+ return;
+ break;
+
+ case '=':
+ tcp->esc = 3;
+ tcp->last_param = -1;
+ for (i = tcp->num_param; i < MAX_ESC_PAR; i++)
+ tcp->param[i] = 1;
+ tcp->num_param = 0;
+ return;
+
+ case 'A': /* up n rows */
+ sc_term_up(scp, tcp->param[0], 0);
+ break;
+
+ case 'B': /* down n rows */
+ sc_term_down(scp, tcp->param[0], 0);
+ break;
+
+ case 'C': /* right n columns */
+ sc_term_right(scp, tcp->param[0]);
+ break;
+
+ case 'D': /* left n columns */
+ sc_term_left(scp, tcp->param[0]);
+ break;
+
+ case 'E': /* cursor to start of line n lines down */
+ n = tcp->param[0]; if (n < 1) n = 1;
+ sc_move_cursor(scp, 0, scp->ypos + n);
+ break;
+
+ case 'F': /* cursor to start of line n lines up */
+ n = tcp->param[0]; if (n < 1) n = 1;
+ sc_move_cursor(scp, 0, scp->ypos - n);
+ break;
+
+ case 'f': /* Cursor move */
+ case 'H':
+ if (tcp->num_param == 0)
+ sc_move_cursor(scp, 0, 0);
+ else if (tcp->num_param == 2)
+ sc_move_cursor(scp, tcp->param[1] - 1, tcp->param[0] - 1);
+ break;
+
+ case 'J': /* Clear all or part of display */
+ if (tcp->num_param == 0)
+ n = 0;
+ else
+ n = tcp->param[0];
+ sc_term_clr_eos(scp, n, sc->scr_map[0x20], tcp->cur_attr);
+ break;
+
+ case 'K': /* Clear all or part of line */
+ if (tcp->num_param == 0)
+ n = 0;
+ else
+ n = tcp->param[0];
+ sc_term_clr_eol(scp, n, sc->scr_map[0x20], tcp->cur_attr);
+ break;
+
+ case 'L': /* Insert n lines */
+ sc_term_ins_line(scp, scp->ypos, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr, 0);
+ break;
+
+ case 'M': /* Delete n lines */
+ sc_term_del_line(scp, scp->ypos, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr, 0);
+ break;
+
+ case 'P': /* Delete n chars */
+ sc_term_del_char(scp, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr);
+ break;
+
+ case '@': /* Insert n chars */
+ sc_term_ins_char(scp, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr);
+ break;
+
+ case 'S': /* scroll up n lines */
+ sc_term_del_line(scp, 0, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr, 0);
+ break;
+
+ case 'T': /* scroll down n lines */
+ sc_term_ins_line(scp, 0, tcp->param[0],
+ sc->scr_map[0x20], tcp->cur_attr, 0);
+ break;
+
+ case 'X': /* erase n characters in line */
+ n = tcp->param[0]; if (n < 1) n = 1;
+ if (n > scp->xsize - scp->xpos)
+ n = scp->xsize - scp->xpos;
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], tcp->cur_attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n - 1);
+ break;
+
+ case 'Z': /* move n tabs backwards */
+ sc_term_backtab(scp, tcp->param[0]);
+ break;
+
+ case '`': /* move cursor to column n */
+ sc_term_col(scp, tcp->param[0]);
+ break;
+
+ case 'a': /* move cursor n columns to the right */
+ sc_term_right(scp, tcp->param[0]);
+ break;
+
+ case 'd': /* move cursor to row n */
+ sc_term_row(scp, tcp->param[0]);
+ break;
+
+ case 'e': /* move cursor n rows down */
+ sc_term_down(scp, tcp->param[0], 0);
+ break;
+
+ case 'm': /* change attribute */
+ if (tcp->num_param == 0) {
+ tcp->attr_mask = NORMAL_ATTR;
+ tcp->cur_color = tcp->std_color;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ }
+ for (i = 0; i < tcp->num_param; i++) {
+ switch (n = tcp->param[i]) {
+ case 0: /* back to normal */
+ tcp->attr_mask = NORMAL_ATTR;
+ tcp->cur_color = tcp->std_color;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 1: /* bold */
+ tcp->attr_mask |= BOLD_ATTR;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 4: /* underline */
+ tcp->attr_mask |= UNDERLINE_ATTR;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 5: /* blink */
+ tcp->attr_mask |= BLINK_ATTR;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 7: /* reverse video */
+ tcp->attr_mask |= REVERSE_ATTR;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 30: case 31: /* set fg color */
+ case 32: case 33: case 34:
+ case 35: case 36: case 37:
+ tcp->attr_mask |= FG_CHANGED;
+ tcp->cur_color.fg = ansi_col[n - 30];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 40: case 41: /* set bg color */
+ case 42: case 43: case 44:
+ case 45: case 46: case 47:
+ tcp->attr_mask |= BG_CHANGED;
+ tcp->cur_color.bg = ansi_col[n - 40];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ }
+ }
+ break;
+
+ case 's': /* Save cursor position */
+ tcp->saved_xpos = scp->xpos;
+ tcp->saved_ypos = scp->ypos;
+ break;
+
+ case 'u': /* Restore saved cursor position */
+ if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0)
+ sc_move_cursor(scp, tcp->saved_xpos, tcp->saved_ypos);
+ break;
+
+ case 'x':
+ if (tcp->num_param == 0)
+ n = 0;
+ else
+ n = tcp->param[0];
+ switch (n) {
+ case 0: /* reset attributes */
+ tcp->attr_mask = NORMAL_ATTR;
+ tcp->cur_color = tcp->std_color = tcp->dflt_std_color;
+ tcp->rev_color = tcp->dflt_rev_color;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 1: /* set ansi background */
+ tcp->attr_mask &= ~BG_CHANGED;
+ tcp->cur_color.bg = tcp->std_color.bg =
+ ansi_col[tcp->param[1] & 0x0f];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 2: /* set ansi foreground */
+ tcp->attr_mask &= ~FG_CHANGED;
+ tcp->cur_color.fg = tcp->std_color.fg =
+ ansi_col[tcp->param[1] & 0x0f];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 3: /* set ansi attribute directly */
+ tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED);
+ tcp->cur_color.fg = tcp->std_color.fg =
+ tcp->param[1] & 0x0f;
+ tcp->cur_color.bg = tcp->std_color.bg =
+ (tcp->param[1] >> 4) & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 5: /* set ansi reverse video background */
+ tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 6: /* set ansi reverse video foreground */
+ tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f];
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ case 7: /* set ansi reverse video directly */
+ tcp->rev_color.fg = tcp->param[1] & 0x0f;
+ tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ break;
+ }
+ break;
+
+ case 'z': /* switch to (virtual) console n */
+ if (tcp->num_param == 1)
+ sc_switch_scr(sc, tcp->param[0]);
+ break;
+ }
+ }
+ else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */
+ if (c >= '0' && c <= '9') {
+ if (tcp->num_param < MAX_ESC_PAR) {
+ if (tcp->last_param != tcp->num_param) {
+ tcp->last_param = tcp->num_param;
+ tcp->param[tcp->num_param] = 0;
+ } else {
+ tcp->param[tcp->num_param] *= 10;
+ }
+ tcp->param[tcp->num_param] += c - '0';
+ return;
+ }
+ }
+ tcp->num_param = tcp->last_param + 1;
+ switch (c) {
+
+ case ';':
+ if (tcp->num_param < MAX_ESC_PAR)
+ return;
+ break;
+
+ case 'A': /* set display border color */
+ if (tcp->num_param == 1) {
+ scp->border=tcp->param[0] & 0xff;
+ if (scp == sc->cur_scp)
+ sc_set_border(scp, scp->border);
+ }
+ break;
+
+ case 'B': /* set bell pitch and duration */
+ if (tcp->num_param == 2) {
+ scp->bell_pitch = tcp->param[0];
+ scp->bell_duration = tcp->param[1];
+ }
+ break;
+
+ case 'C': /* set cursor type & shape */
+ if (!ISGRAPHSC(sc->cur_scp))
+ sc_remove_cursor_image(sc->cur_scp);
+ if (tcp->num_param == 1) {
+ if (tcp->param[0] & 0x01)
+ sc->flags |= SC_BLINK_CURSOR;
+ else
+ sc->flags &= ~SC_BLINK_CURSOR;
+ if (tcp->param[0] & 0x02)
+ sc->flags |= SC_CHAR_CURSOR;
+ else
+ sc->flags &= ~SC_CHAR_CURSOR;
+ } else if (tcp->num_param == 2) {
+ sc->cursor_base = scp->font_size
+ - (tcp->param[1] & 0x1F) - 1;
+ sc->cursor_height = (tcp->param[1] & 0x1F)
+ - (tcp->param[0] & 0x1F) + 1;
+ }
+ /*
+ * The cursor shape is global property; all virtual consoles
+ * are affected. Update the cursor in the current console...
+ */
+ if (!ISGRAPHSC(sc->cur_scp)) {
+ i = spltty();
+ sc_set_cursor_image(sc->cur_scp);
+ sc_draw_cursor_image(sc->cur_scp);
+ splx(i);
+ }
+ break;
+
+ case 'F': /* set ansi foreground */
+ if (tcp->num_param == 1) {
+ tcp->attr_mask &= ~FG_CHANGED;
+ tcp->cur_color.fg = tcp->std_color.fg = tcp->param[0] & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ }
+ break;
+
+ case 'G': /* set ansi background */
+ if (tcp->num_param == 1) {
+ tcp->attr_mask &= ~BG_CHANGED;
+ tcp->cur_color.bg = tcp->std_color.bg = tcp->param[0] & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ }
+ break;
+
+ case 'H': /* set ansi reverse video foreground */
+ if (tcp->num_param == 1) {
+ tcp->rev_color.fg = tcp->param[0] & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ }
+ break;
+
+ case 'I': /* set ansi reverse video background */
+ if (tcp->num_param == 1) {
+ tcp->rev_color.bg = tcp->param[0] & 0x0f;
+ tcp->cur_attr = mask2attr(tcp);
+ }
+ break;
+ }
+
+#if notyet
+ } else if (tcp->esc == 4) { /* seen ESC Q */
+ /* to be filled */
+#endif
+ } else if (tcp->esc == 5) { /* seen ESC ( */
+ switch (c) {
+ case 'B': /* iso-2022: desginate ASCII into G0 */
+ break;
+ /* other items to be filled */
+ default:
+ break;
+ }
+ }
+ tcp->esc = 0;
+}
+
+static void
+scterm_puts(scr_stat *scp, u_char *buf, int len)
+{
+ term_stat *tcp;
+
+ tcp = scp->ts;
+outloop:
+ scp->sc->write_in_progress++;
+
+ if (tcp->esc) {
+ scterm_scan_esc(scp, tcp, *buf);
+ buf++;
+ len--;
+ } else {
+ switch (*buf) {
+ case 0x1b:
+ tcp->esc = 1;
+ tcp->num_param = 0;
+ buf++;
+ len--;
+ break;
+ default:
+ sc_term_gen_print(scp, &buf, &len, tcp->cur_attr);
+ break;
+ }
+ }
+
+ sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr);
+
+ scp->sc->write_in_progress--;
+ if (len)
+ goto outloop;
+}
+
+static int
+scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
+ int flag, struct proc *p)
+{
+ term_stat *tcp = scp->ts;
+ vid_info_t *vi;
+
+ switch (cmd) {
+ case GIO_ATTR: /* get current attributes */
+ /* FIXME: */
+ *(int*)data = (tcp->cur_attr >> 8) & 0xff;
+ return 0;
+ case CONS_GETINFO: /* get current (virtual) console info */
+ vi = (vid_info_t *)data;
+ if (vi->size != sizeof(struct vid_info))
+ return EINVAL;
+ vi->mv_norm.fore = tcp->std_color.fg;
+ vi->mv_norm.back = tcp->std_color.bg;
+ vi->mv_rev.fore = tcp->rev_color.fg;
+ vi->mv_rev.back = tcp->rev_color.bg;
+ /*
+ * The other fields are filled by the upper routine. XXX
+ */
+ return ENOIOCTL;
+ }
+ return ENOIOCTL;
+}
+
+static int
+scterm_reset(scr_stat *scp, int code)
+{
+ /* FIXME */
+ return 0;
+}
+
+static void
+scterm_default_attr(scr_stat *scp, int color, int rev_color)
+{
+ term_stat *tcp = scp->ts;
+
+ tcp->dflt_std_color.fg = color & 0x0f;
+ tcp->dflt_std_color.bg = (color >> 4) & 0x0f;
+ tcp->dflt_rev_color.fg = rev_color & 0x0f;
+ tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f;
+ tcp->std_color = tcp->dflt_std_color;
+ tcp->rev_color = tcp->dflt_rev_color;
+ tcp->cur_color = tcp->std_color;
+ tcp->cur_attr = mask2attr(tcp);
+}
+
+static void
+scterm_clear(scr_stat *scp)
+{
+ term_stat *tcp = scp->ts;
+
+ sc_move_cursor(scp, 0, 0);
+ sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr);
+ mark_all(scp);
+}
+
+static void
+scterm_notify(scr_stat *scp, int event)
+{
+ switch (event) {
+ case SC_TE_NOTIFY_VTSWITCH_IN:
+ break;
+ case SC_TE_NOTIFY_VTSWITCH_OUT:
+ break;
+ }
+}
+
+static int
+scterm_input(scr_stat *scp, int c, struct tty *tp)
+{
+ return FALSE;
+}
+
+/*
+ * Calculate hardware attributes word using logical attributes mask and
+ * hardware colors
+ */
+
+/* FIXME */
+static int
+mask2attr(term_stat *tcp)
+{
+ int attr, mask = tcp->attr_mask;
+
+ if (mask & REVERSE_ATTR) {
+ attr = ((mask & FG_CHANGED) ?
+ tcp->cur_color.bg : tcp->rev_color.fg) |
+ (((mask & BG_CHANGED) ?
+ tcp->cur_color.fg : tcp->rev_color.bg) << 4);
+ } else
+ attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4);
+
+ /* XXX: underline mapping for Hercules adapter can be better */
+ if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
+ attr ^= 0x08;
+ if (mask & BLINK_ATTR)
+ attr ^= 0x80;
+
+ return (attr << 8);
+}
+
+#endif /* SC_DUMB_TERMINAL */
+
+#endif /* NSC > 0 */
diff --git a/sys/dev/syscons/scterm.c b/sys/dev/syscons/scterm.c
new file mode 100644
index 000000000000..c6359930dad8
--- /dev/null
+++ b/sys/dev/syscons/scterm.c
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/consio.h>
+
+#include <dev/syscons/syscons.h>
+#include <dev/syscons/sctermvar.h>
+
+/* exported subroutines */
+
+void
+sc_move_cursor(scr_stat *scp, int x, int y)
+{
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ if (x >= scp->xsize)
+ x = scp->xsize - 1;
+ if (y >= scp->ysize)
+ y = scp->ysize - 1;
+ scp->xpos = x;
+ scp->ypos = y;
+ scp->cursor_pos = scp->ypos*scp->xsize + scp->xpos;
+}
+
+void
+sc_clear_screen(scr_stat *scp)
+{
+ (*scp->tsw->te_clear)(scp);
+ scp->cursor_oldpos = scp->cursor_pos;
+ sc_remove_cutmarking(scp);
+}
+
+/* terminal emulator manager routines */
+
+static LIST_HEAD(, sc_term_sw) sc_term_list =
+ LIST_HEAD_INITIALIZER(sc_term_list);
+
+int
+sc_term_add(sc_term_sw_t *sw)
+{
+ LIST_INSERT_HEAD(&sc_term_list, sw, link);
+ return 0;
+}
+
+int
+sc_term_remove(sc_term_sw_t *sw)
+{
+ LIST_REMOVE(sw, link);
+ return 0;
+}
+
+sc_term_sw_t
+*sc_term_match(char *name)
+{
+ sc_term_sw_t **list;
+ sc_term_sw_t *p;
+
+ if (!LIST_EMPTY(&sc_term_list)) {
+ LIST_FOREACH(p, &sc_term_list, link) {
+ if ((strcmp(name, p->te_name) == 0)
+ || (strcmp(name, "*") == 0)) {
+ return p;
+ }
+ }
+ } else {
+ list = (sc_term_sw_t **)scterm_set.ls_items;
+ while ((p = *list++) != NULL) {
+ if ((strcmp(name, p->te_name) == 0)
+ || (strcmp(name, "*") == 0)) {
+ return p;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+sc_term_sw_t
+*sc_term_match_by_number(int index)
+{
+ sc_term_sw_t *p;
+
+ if (index <= 0)
+ return NULL;
+ LIST_FOREACH(p, &sc_term_list, link) {
+ if (--index <= 0)
+ return p;
+ }
+
+ return NULL;
+}
+
+#endif /* NSC > 0 */
diff --git a/sys/dev/syscons/sctermvar.h b/sys/dev/syscons/sctermvar.h
new file mode 100644
index 000000000000..2ef75f069157
--- /dev/null
+++ b/sys/dev/syscons/sctermvar.h
@@ -0,0 +1,437 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_SYSCONS_SCTERMVAR_H_
+#define _DEV_SYSCONS_SCTERMVAR_H_
+
+/*
+ * building blocks for terminal emulator modules.
+ */
+
+static __inline void sc_term_ins_line(scr_stat *scp, int y, int n, int ch,
+ int attr, int tail);
+static __inline void sc_term_del_line(scr_stat *scp, int y, int n, int ch,
+ int attr, int tail);
+static __inline void sc_term_ins_char(scr_stat *scp, int n, int ch,
+ int attr);
+static __inline void sc_term_del_char(scr_stat *scp, int n, int ch,
+ int attr);
+static __inline void sc_term_col(scr_stat *scp, int n);
+static __inline void sc_term_row(scr_stat *scp, int n);
+static __inline void sc_term_up(scr_stat *scp, int n, int head);
+static __inline void sc_term_down(scr_stat *scp, int n, int tail);
+static __inline void sc_term_left(scr_stat *scp, int n);
+static __inline void sc_term_right(scr_stat *scp, int n);
+static __inline void sc_term_up_scroll(scr_stat *scp, int n, int ch,
+ int attr, int head, int tail);
+static __inline void sc_term_down_scroll(scr_stat *scp, int n, int ch,
+ int attr, int head, int tail);
+static __inline void sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr);
+static __inline void sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr);
+static __inline void sc_term_tab(scr_stat *scp, int n);
+static __inline void sc_term_backtab(scr_stat *scp, int n);
+static __inline void sc_term_respond(scr_stat *scp, u_char *s);
+static __inline void sc_term_gen_print(scr_stat *scp, u_char **buf, int *len,
+ int attr);
+static __inline void sc_term_gen_scroll(scr_stat *scp, int ch, int attr);
+
+static __inline void
+sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
+{
+ if (tail <= 0)
+ tail = scp->ysize;
+ if (n < 1)
+ n = 1;
+ if (n > tail - y)
+ n = tail - y;
+ sc_vtb_ins(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
+ mark_for_update(scp, y*scp->xsize);
+ mark_for_update(scp, scp->xsize*tail - 1);
+}
+
+static __inline void
+sc_term_del_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
+{
+ if (tail <= 0)
+ tail = scp->ysize;
+ if (n < 1)
+ n = 1;
+ if (n > tail - y)
+ n = tail - y;
+ sc_vtb_delete(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
+ mark_for_update(scp, y*scp->xsize);
+ mark_for_update(scp, scp->xsize*tail - 1);
+}
+
+static __inline void
+sc_term_ins_char(scr_stat *scp, int n, int ch, int attr)
+{
+ int count;
+
+ if (n < 1)
+ n = 1;
+ if (n > scp->xsize - scp->xpos)
+ n = scp->xsize - scp->xpos;
+ count = scp->xsize - (scp->xpos + n);
+ sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
+}
+
+static __inline void
+sc_term_del_char(scr_stat *scp, int n, int ch, int attr)
+{
+ int count;
+
+ if (n < 1)
+ n = 1;
+ if (n > scp->xsize - scp->xpos)
+ n = scp->xsize - scp->xpos;
+ count = scp->xsize - (scp->xpos + n);
+ sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n, ch, attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
+}
+
+static __inline void
+sc_term_col(scr_stat *scp, int n)
+{
+ if (n < 1)
+ n = 1;
+ sc_move_cursor(scp, n - 1, scp->ypos);
+}
+
+static __inline void
+sc_term_row(scr_stat *scp, int n)
+{
+ if (n < 1)
+ n = 1;
+ sc_move_cursor(scp, scp->xpos, n - 1);
+}
+
+static __inline void
+sc_term_up(scr_stat *scp, int n, int head)
+{
+ if (n < 1)
+ n = 1;
+ n = imin(n, scp->ypos - head);
+ if (n <= 0)
+ return;
+ sc_move_cursor(scp, scp->xpos, scp->ypos - n);
+}
+
+static __inline void
+sc_term_down(scr_stat *scp, int n, int tail)
+{
+ if (tail <= 0)
+ tail = scp->ysize;
+ if (n < 1)
+ n = 1;
+ n = imin(n, tail - scp->ypos - 1);
+ if (n <= 0)
+ return;
+ sc_move_cursor(scp, scp->xpos, scp->ypos + n);
+}
+
+static __inline void
+sc_term_left(scr_stat *scp, int n)
+{
+ if (n < 1)
+ n = 1;
+ sc_move_cursor(scp, scp->xpos - n, scp->ypos);
+}
+
+static __inline void
+sc_term_right(scr_stat *scp, int n)
+{
+ if (n < 1)
+ n = 1;
+ sc_move_cursor(scp, scp->xpos + n, scp->ypos);
+}
+
+static __inline void
+sc_term_up_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
+{
+ if (tail <= 0)
+ tail = scp->ysize;
+ if (n < 1)
+ n = 1;
+ if (n <= scp->ypos - head) {
+ sc_move_cursor(scp, scp->xpos, scp->ypos - n);
+ } else {
+ sc_term_ins_line(scp, head, n - (scp->ypos - head),
+ ch, attr, tail);
+ sc_move_cursor(scp, scp->xpos, head);
+ }
+}
+
+static __inline void
+sc_term_down_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
+{
+ if (tail <= 0)
+ tail = scp->ysize;
+ if (n < 1)
+ n = 1;
+ if (n < tail - scp->ypos) {
+ sc_move_cursor(scp, scp->xpos, scp->ypos + n);
+ } else {
+ sc_term_del_line(scp, head, n - (tail - scp->ypos) + 1,
+ ch, attr, tail);
+ sc_move_cursor(scp, scp->xpos, tail - 1);
+ }
+}
+
+static __inline void
+sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr)
+{
+ switch (n) {
+ case 0: /* clear form cursor to end of display */
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize*scp->ysize - scp->cursor_pos,
+ ch, attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->xsize*scp->ysize - 1);
+ sc_remove_cutmarking(scp);
+ break;
+ case 1: /* clear from beginning of display to cursor */
+ sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos, ch, attr);
+ mark_for_update(scp, 0);
+ mark_for_update(scp, scp->cursor_pos);
+ sc_remove_cutmarking(scp);
+ break;
+ case 2: /* clear entire display */
+ sc_vtb_erase(&scp->vtb, 0, scp->xsize*scp->ysize, ch, attr);
+ mark_for_update(scp, 0);
+ mark_for_update(scp, scp->xsize*scp->ysize - 1);
+ sc_remove_cutmarking(scp);
+ break;
+ }
+}
+
+static __inline void
+sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr)
+{
+ switch (n) {
+ case 0: /* clear form cursor to end of line */
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize - scp->xpos, ch, attr);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos +
+ scp->xsize - 1 - scp->xpos);
+ break;
+ case 1: /* clear from beginning of line to cursor */
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xpos + 1, ch, attr);
+ mark_for_update(scp, scp->ypos*scp->xsize);
+ mark_for_update(scp, scp->cursor_pos);
+ break;
+ case 2: /* clear entire line */
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xsize, ch, attr);
+ mark_for_update(scp, scp->ypos*scp->xsize);
+ mark_for_update(scp, (scp->ypos + 1)*scp->xsize - 1);
+ break;
+ }
+}
+
+static __inline void
+sc_term_tab(scr_stat *scp, int n)
+{
+ int i;
+
+ if (n < 1)
+ n = 1;
+ i = (scp->xpos & ~7) + 8*n;
+ if (i >= scp->xsize)
+ sc_move_cursor(scp, 0, scp->ypos + 1);
+ else
+ sc_move_cursor(scp, i, scp->ypos);
+}
+
+static __inline void
+sc_term_backtab(scr_stat *scp, int n)
+{
+ int i;
+
+ if (n < 1)
+ n = 1;
+ if ((i = scp->xpos & ~7) == scp->xpos)
+ i -= 8*n;
+ else
+ i -= 8*(n - 1);
+ if (i < 0)
+ i = 0;
+ sc_move_cursor(scp, i, scp->ypos);
+}
+
+static __inline void
+sc_term_respond(scr_stat *scp, u_char *s)
+{
+ sc_paste(scp, s, strlen(s)); /* XXX: not correct, don't use rmap */
+}
+
+static __inline void
+sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, int attr)
+{
+ vm_offset_t p;
+ u_char *ptr;
+ u_char *map;
+ int cnt;
+ int l;
+ int i;
+
+ ptr = *buf;
+ l = *len;
+
+ if (PRINTABLE(*ptr)) {
+ p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
+ map = scp->sc->scr_map;
+
+ cnt = imin(l, scp->xsize - scp->xpos);
+ i = cnt;
+ do {
+ /*
+ * gcc-2.6.3 generates poor (un)sign extension code.
+ * Casting the pointers in the following to volatile
+ * should have no effect, but in fact speeds up this
+ * inner loop from 26 to 18 cycles (+ cache misses)
+ * on i486's.
+ * XXX: out of date?
+ */
+#define UCVP(ucp) ((u_char volatile *)(ucp))
+ p = sc_vtb_putchar(&scp->vtb, p,
+ UCVP(map)[*UCVP(ptr)], attr);
+ ++ptr;
+ --i;
+ } while ((i > 0) && PRINTABLE(*ptr));
+
+ l -= cnt - i;
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos += cnt - i;
+ mark_for_update(scp, scp->cursor_pos - 1);
+ scp->xpos += cnt - i;
+
+ if (scp->xpos >= scp->xsize) {
+ scp->xpos = 0;
+ scp->ypos++;
+ /* we may have to scroll the screen */
+ }
+ } else {
+ switch(*ptr) {
+ case 0x07:
+ sc_bell(scp, scp->bell_pitch, scp->bell_duration);
+ break;
+
+ case 0x08: /* non-destructive backspace */
+ /* XXX */
+ if (scp->cursor_pos > 0) {
+#if 0
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos--;
+ mark_for_update(scp, scp->cursor_pos);
+#else
+ scp->cursor_pos--;
+#endif
+ if (scp->xpos > 0) {
+ scp->xpos--;
+ } else {
+ scp->xpos += scp->xsize - 1;
+ scp->ypos--;
+ }
+ }
+ break;
+
+ case 0x09: /* non-destructive tab */
+ sc_term_tab(scp, 1);
+ /* we may have to scroll the screen */
+#if 0
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos += (8 - scp->xpos % 8u);
+ mark_for_update(scp, scp->cursor_pos);
+ scp->xpos += (8 - scp->xpos % 8u);
+ if (scp->xpos >= scp->xsize) {
+ scp->xpos = 0;
+ scp->ypos++;
+ }
+#endif
+ break;
+
+ case 0x0a: /* newline, same pos */
+#if 0
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos += scp->xsize;
+ mark_for_update(scp, scp->cursor_pos);
+#else
+ scp->cursor_pos += scp->xsize;
+ /* we may have to scroll the screen */
+#endif
+ scp->ypos++;
+ break;
+
+ case 0x0c: /* form feed, clears screen */
+ sc_clear_screen(scp);
+ break;
+
+ case 0x0d: /* return, return to pos 0 */
+#if 0
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos -= scp->xpos;
+ mark_for_update(scp, scp->cursor_pos);
+#else
+ scp->cursor_pos -= scp->xpos;
+#endif
+ scp->xpos = 0;
+ break;
+ }
+ ptr++; l--;
+ }
+
+ *buf = ptr;
+ *len = l;
+}
+
+static __inline void
+sc_term_gen_scroll(scr_stat *scp, int ch, int attr)
+{
+ /* do we have to scroll ?? */
+ if (scp->cursor_pos >= scp->ysize*scp->xsize) {
+ sc_remove_cutmarking(scp); /* XXX */
+#ifndef SC_NO_HISTORY
+ if (scp->history != NULL)
+ sc_hist_save_one_line(scp, 0); /* XXX */
+#endif
+ sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr);
+ scp->cursor_pos -= scp->xsize;
+ scp->ypos--;
+ mark_all(scp);
+ }
+}
+
+#endif /* _DEV_SYSCONS_SCTERMVAR_H_ */
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
index 7290558f8159..afdd073627a8 100644
--- a/sys/dev/syscons/scvgarndr.c
+++ b/sys/dev/syscons/scvgarndr.c
@@ -38,7 +38,6 @@
#include <sys/kernel.h>
#include <machine/console.h>
-#include <machine/md_var.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/vgareg.h>
@@ -83,6 +82,8 @@ static vr_draw_border_t vga_grborder;
static void vga_nop(scr_stat *scp, ...);
+static struct linker_set vga_set;
+
static sc_rndr_sw_t txtrndrsw = {
vga_txtclear,
vga_txtborder,
@@ -93,10 +94,10 @@ static sc_rndr_sw_t txtrndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_txtmouse,
};
-RENDERER(mda, 0, txtrndrsw);
-RENDERER(cga, 0, txtrndrsw);
-RENDERER(ega, 0, txtrndrsw);
-RENDERER(vga, 0, txtrndrsw);
+RENDERER(mda, 0, txtrndrsw, vga_set);
+RENDERER(cga, 0, txtrndrsw, vga_set);
+RENDERER(ega, 0, txtrndrsw, vga_set);
+RENDERER(vga, 0, txtrndrsw, vga_set);
#ifdef SC_PIXEL_MODE
static sc_rndr_sw_t egarndrsw = {
@@ -109,7 +110,7 @@ static sc_rndr_sw_t egarndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_pxlmouse,
};
-RENDERER(ega, PIXEL_MODE, egarndrsw);
+RENDERER(ega, PIXEL_MODE, egarndrsw, vga_set);
static sc_rndr_sw_t vgarndrsw = {
vga_pxlclear,
@@ -121,7 +122,7 @@ static sc_rndr_sw_t vgarndrsw = {
(vr_set_mouse_t *)vga_nop,
vga_pxlmouse,
};
-RENDERER(vga, PIXEL_MODE, vgarndrsw);
+RENDERER(vga, PIXEL_MODE, vgarndrsw, vga_set);
#endif /* SC_PIXEL_MODE */
#ifndef SC_NO_MODE_CHANGE
@@ -135,11 +136,13 @@ static sc_rndr_sw_t grrndrsw = {
(vr_set_mouse_t *)vga_nop,
(vr_draw_mouse_t *)vga_nop,
};
-RENDERER(cga, GRAPHICS_MODE, grrndrsw);
-RENDERER(ega, GRAPHICS_MODE, grrndrsw);
-RENDERER(vga, GRAPHICS_MODE, grrndrsw);
+RENDERER(cga, GRAPHICS_MODE, grrndrsw, vga_set);
+RENDERER(ega, GRAPHICS_MODE, grrndrsw, vga_set);
+RENDERER(vga, GRAPHICS_MODE, grrndrsw, vga_set);
#endif /* SC_NO_MODE_CHANGE */
+RENDERER_MODULE(vga, vga_set);
+
#ifndef SC_NO_CUTPASTE
static u_short mouse_and_mask[16] = {
0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index 0923a7be4ec1..3c03ee573f86 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -38,9 +38,6 @@
#include <sys/tty.h>
#include <sys/kernel.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
#include <machine/console.h>
#include <dev/fb/fbreg.h>
@@ -131,7 +128,6 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
int fontsize)
{
video_info_t info;
- sc_rndr_sw_t *rndr;
u_char *font;
int prev_ysize;
int error;
@@ -183,8 +179,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
return error;
}
- rndr = sc_render_match(scp, scp->sc->adp, 0);
- if (rndr == NULL) {
+ if (sc_render_match(scp, scp->sc->adp->va_name, 0) == NULL) {
splx(s);
return ENODEV;
}
@@ -213,13 +208,13 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ sc_init_emulator(scp, NULL);
#ifndef SC_NO_CUTPASTE
sc_alloc_cut_buffer(scp, FALSE);
#endif
#ifndef SC_NO_HISTORY
sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
#endif
- scp->rndr = rndr;
splx(s);
if (scp == scp->sc->cur_scp)
@@ -247,7 +242,6 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
return ENODEV;
#else
video_info_t info;
- sc_rndr_sw_t *rndr;
int error;
int s;
@@ -261,8 +255,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
return error;
}
- rndr = sc_render_match(scp, scp->sc->adp, GRAPHICS_MODE);
- if (rndr == NULL) {
+ if (sc_render_match(scp, scp->sc->adp->va_name, GRAPHICS_MODE) == NULL) {
splx(s);
return ENODEV;
}
@@ -285,7 +278,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
/* move the mouse cursor at the center of the screen */
sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
#endif
- scp->rndr = rndr;
+ sc_init_emulator(scp, NULL);
splx(s);
if (scp == scp->sc->cur_scp)
@@ -314,7 +307,6 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
return ENODEV;
#else
video_info_t info;
- sc_rndr_sw_t *rndr;
u_char *font;
int prev_ysize;
int error;
@@ -381,12 +373,18 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
return error;
}
- rndr = sc_render_match(scp, scp->sc->adp, PIXEL_MODE);
- if (rndr == NULL) {
+ if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) {
splx(s);
return ENODEV;
}
+#if 0
+ if (scp->tsw)
+ (*scp->tsw->te_term)(scp, scp->ts);
+ scp->tsw = NULL;
+ scp->ts = NULL;
+#endif
+
/* set up scp */
#ifndef SC_NO_HISTORY
if (scp->history != NULL)
@@ -404,17 +402,17 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ sc_init_emulator(scp, NULL);
#ifndef SC_NO_CUTPASTE
sc_alloc_cut_buffer(scp, FALSE);
#endif
#ifndef SC_NO_HISTORY
sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
#endif
- scp->rndr = rndr;
splx(s);
if (scp == scp->sc->cur_scp) {
- set_border(scp, scp->border);
+ sc_set_border(scp, scp->border);
sc_set_cursor_image(scp);
}
@@ -433,24 +431,6 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
#endif /* SC_PIXEL_MODE */
}
-sc_rndr_sw_t
-*sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode)
-{
- const sc_renderer_t **list;
- const sc_renderer_t *p;
-
- list = (const sc_renderer_t **)scrndr_set.ls_items;
- while ((p = *list++) != NULL) {
- if ((strcmp(p->name, adp->va_name) == 0)
- && (mode == p->mode)) {
- scp->status &= ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
- return p->rndrsw;
- }
- }
-
- return NULL;
-}
-
#define fb_ioctl(a, c, d) \
(((a) == NULL) ? ENODEV : \
(*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d)))
@@ -666,11 +646,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
* Don't load fonts for now... XXX
*/
if (scp->sc->fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, scp->sc->font_8);
+ sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256);
if (scp->sc->fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, scp->sc->font_14);
+ sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256);
if (scp->sc->fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, scp->sc->font_16);
+ sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256);
}
#endif /* SC_NO_FONT_LOADING */
#endif
@@ -779,11 +759,60 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case KDSBORDER: /* set border color of this (virtual) console */
scp->border = *data;
if (scp == scp->sc->cur_scp)
- set_border(scp, scp->border);
+ sc_set_border(scp, scp->border);
return 0;
}
return ENOIOCTL;
}
+static LIST_HEAD(, sc_renderer) sc_rndr_list =
+ LIST_HEAD_INITIALIZER(sc_rndr_list);
+
+int
+sc_render_add(sc_renderer_t *rndr)
+{
+ LIST_INSERT_HEAD(&sc_rndr_list, rndr, link);
+ return 0;
+}
+
+int
+sc_render_remove(sc_renderer_t *rndr)
+{
+ /*
+ LIST_REMOVE(rndr, link);
+ */
+ return EBUSY; /* XXX */
+}
+
+sc_rndr_sw_t
+*sc_render_match(scr_stat *scp, char *name, int mode)
+{
+ const sc_renderer_t **list;
+ const sc_renderer_t *p;
+
+ if (!LIST_EMPTY(&sc_rndr_list)) {
+ LIST_FOREACH(p, &sc_rndr_list, link) {
+ if ((strcmp(p->name, name) == 0)
+ && (mode == p->mode)) {
+ scp->status &=
+ ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
+ return p->rndrsw;
+ }
+ }
+ } else {
+ list = (const sc_renderer_t **)scrndr_set.ls_items;
+ while ((p = *list++) != NULL) {
+ if ((strcmp(p->name, name) == 0)
+ && (mode == p->mode)) {
+ scp->status &=
+ ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
+ return p->rndrsw;
+ }
+ }
+ }
+
+ return NULL;
+}
+
#endif /* NSC > 0 */
diff --git a/sys/dev/syscons/scvtb.c b/sys/dev/syscons/scvtb.c
index eebeb23182de..aac9024814b5 100644
--- a/sys/dev/syscons/scvtb.c
+++ b/sys/dev/syscons/scvtb.c
@@ -33,7 +33,6 @@
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
#include <sys/malloc.h>
#include <machine/console.h>
diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c
index 093e564bef13..e4277e3beee2 100644
--- a/sys/dev/syscons/snake/snake_saver.c
+++ b/sys/dev/syscons/snake/snake_saver.c
@@ -79,7 +79,7 @@ snake_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
diff --git a/sys/dev/syscons/star/star_saver.c b/sys/dev/syscons/star/star_saver.c
index 645e4fd3c354..27e992133ee7 100644
--- a/sys/dev/syscons/star/star_saver.c
+++ b/sys/dev/syscons/star/star_saver.c
@@ -85,7 +85,7 @@ star_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
blanked = TRUE;
for(i=0; i<NUM_STARS; i++) {
stars[i][0] =
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 64ecd738535f..6d46128a4efb 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -73,24 +73,25 @@
#define KEYCODE_BS 0x0e /* "<-- Backspace" key, XXX */
+typedef struct default_attr {
+ int std_color; /* normal hardware color */
+ int rev_color; /* reverse hardware color */
+} default_attr;
+
static default_attr user_default = {
- SC_NORM_ATTR << 8,
- SC_NORM_REV_ATTR << 8,
+ SC_NORM_ATTR,
+ SC_NORM_REV_ATTR,
};
static default_attr kernel_default = {
- SC_KERNEL_CONS_ATTR << 8,
- SC_KERNEL_CONS_REV_ATTR << 8,
+ SC_KERNEL_CONS_ATTR,
+ SC_KERNEL_CONS_REV_ATTR,
};
static int sc_console_unit = -1;
static scr_stat *sc_console;
static struct tty *sc_console_tty;
-#ifndef SC_NO_SYSMOUSE
-static struct tty *sc_mouse_tty;
-#endif
-static term_stat kernel_console;
-static default_attr *current_default;
+static void *kernel_console_ts;
static char init_done = COLD;
static char shutdown_in_progress = FALSE;
@@ -119,7 +120,6 @@ static int enable_panic_key;
SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key,
0, "");
-#define SC_MOUSE 128
#define SC_CONSOLECTL 255
#define VIRTUAL_TTY(sc, x) (SC_DEV((sc), (x))->si_tty)
@@ -134,7 +134,6 @@ static int scdevtounit(dev_t dev);
static kbd_callback_func_t sckbdevent;
static int scparam(struct tty *tp, struct termios *t);
static void scstart(struct tty *tp);
-static void scmousestart(struct tty *tp);
static void scinit(int unit, int flags);
#if __i386__
static void scterm(int unit, int flags);
@@ -165,23 +164,15 @@ static int wait_scrn_saver_stop(sc_softc_t *sc);
#define scsplash_stick(stick)
#endif /* NSPLASH */
-static int switch_scr(sc_softc_t *sc, u_int next_scr);
static int do_switch_scr(sc_softc_t *sc, int s);
static int vt_proc_alive(scr_stat *scp);
static int signal_vt_rel(scr_stat *scp);
static int signal_vt_acq(scr_stat *scp);
static void exchange_scr(sc_softc_t *sc);
-static void scan_esc(scr_stat *scp, u_char c);
-static void ansi_put(scr_stat *scp, u_char *buf, int len);
-static void draw_cursor_image(scr_stat *scp);
-static void remove_cursor_image(scr_stat *scp);
static void update_cursor_image(scr_stat *scp);
-static void move_crsr(scr_stat *scp, int x, int y);
-static int mask2attr(struct term_stat *term);
static int save_kbd_state(scr_stat *scp);
static int update_kbd_state(scr_stat *scp, int state, int mask);
static int update_kbd_leds(scr_stat *scp, int which);
-static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#define CDEV_MAJOR 12
@@ -300,12 +291,33 @@ sc_attach_unit(int unit, int flags)
int vc;
dev_t dev;
- scmeminit(NULL); /* XXX */
-
flags &= ~SC_KERNEL_CONSOLE;
- if (sc_console_unit == unit)
+
+ if (sc_console_unit == unit) {
+ /*
+ * If this unit is being used as the system console, we need to
+ * adjust some variables and buffers before and after scinit().
+ */
+ /* assert(sc_console != NULL) */
flags |= SC_KERNEL_CONSOLE;
- scinit(unit, flags);
+ scmeminit(NULL);
+
+ scinit(unit, flags);
+
+ if (sc_console->tsw->te_size > 0) {
+ /* assert(sc_console->ts != NULL); */
+ kernel_console_ts = sc_console->ts;
+ sc_console->ts = malloc(sc_console->tsw->te_size,
+ M_DEVBUF, M_WAITOK);
+ bcopy(kernel_console_ts, sc_console->ts, sc_console->tsw->te_size);
+ (*sc_console->tsw->te_default_attr)(sc_console,
+ user_default.std_color,
+ user_default.rev_color);
+ }
+ } else {
+ scinit(unit, flags);
+ }
+
sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
sc->config = flags;
scp = SC_STAT(sc->dev[0]);
@@ -348,7 +360,10 @@ sc_attach_unit(int unit, int flags)
if (sc->adapter >= 0)
printf(" fb%d", sc->adapter);
if (sc->keyboard >= 0)
- printf(" kbd%d", sc->keyboard);
+ printf(", kbd%d", sc->keyboard);
+ if (scp->tsw)
+ printf(", terminal emulator: %s (%s)",
+ scp->tsw->te_name, scp->tsw->te_desc);
printf("\n");
}
@@ -368,12 +383,6 @@ sc_attach_unit(int unit, int flags)
*/
}
-#ifndef SC_NO_SYSMOUSE
- dev = make_dev(&sc_cdevsw, SC_MOUSE,
- UID_ROOT, GID_WHEEL, 0600, "sysmouse");
- dev->si_tty = sc_mouse_tty = ttymalloc(sc_mouse_tty);
- /* sysmouse doesn't have scr_stat */
-#endif /* SC_NO_SYSMOUSE */
dev = make_dev(&sc_cdevsw, SC_CONSOLECTL,
UID_ROOT, GID_WHEEL, 0600, "consolectl");
dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty);
@@ -394,7 +403,7 @@ scmeminit(void *arg)
* various buffers for the kernel console.
*/
- if (sc_console_unit < 0)
+ if (sc_console_unit < 0) /* sc_console == NULL */
return;
/* copy the temporary buffer to the final buffer */
@@ -434,8 +443,6 @@ scdevtounit(dev_t dev)
if (vty == SC_CONSOLECTL)
return ((sc_console != NULL) ? sc_console->sc->unit : -1);
- else if (vty == SC_MOUSE)
- return -1;
else if ((vty < 0) || (vty >= MAXCONS*sc_max_unit()))
return -1;
else
@@ -455,17 +462,12 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
DPRINTF(5, ("scopen: dev:%d,%d, unit:%d, vty:%d\n",
major(dev), minor(dev), unit, SC_VTY(dev)));
- /* sc == NULL, if SC_VTY(dev) == SC_MOUSE */
sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
-#ifndef SC_NO_SYSMOUSE
- if ((SC_VTY(dev) != SC_MOUSE) && (sc == NULL))
-#else
if (sc == NULL)
-#endif
return ENXIO;
tp = dev->si_tty = ttymalloc(dev->si_tty);
- tp->t_oproc = (SC_VTY(dev) == SC_MOUSE) ? scmousestart : scstart;
+ tp->t_oproc = scstart;
tp->t_param = scparam;
tp->t_stop = nottystop;
tp->t_dev = dev;
@@ -485,10 +487,6 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
scparam(tp, &tp->t_termios);
(*linesw[tp->t_line].l_modem)(tp, 1);
-#ifndef SC_NO_SYSMOUSE
- if (SC_VTY(dev) == SC_MOUSE)
- sc_mouse_set_level(0); /* XXX */
-#endif
}
else
if (tp->t_state & TS_XCLUDE && suser(p))
@@ -496,19 +494,17 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
error = (*linesw[tp->t_line].l_open)(dev, tp);
- if (SC_VTY(dev) != SC_MOUSE) {
- /* assert(sc != NULL) */
- scp = SC_STAT(dev);
- if (scp == NULL) {
- scp = SC_STAT(dev) = alloc_scp(sc, SC_VTY(dev));
- if (ISGRAPHSC(scp))
- sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
- }
- if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
- tp->t_winsize.ws_col = scp->xsize;
- tp->t_winsize.ws_row = scp->ysize;
- }
+ scp = SC_STAT(dev);
+ if (scp == NULL) {
+ scp = SC_STAT(dev) = alloc_scp(sc, SC_VTY(dev));
+ if (ISGRAPHSC(scp))
+ sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
+ }
+ if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
}
+
return error;
}
@@ -516,10 +512,10 @@ int
scclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = dev->si_tty;
- struct scr_stat *scp;
+ scr_stat *scp;
int s;
- if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) {
+ if (SC_VTY(dev) != SC_CONSOLECTL) {
scp = SC_STAT(tp->t_dev);
/* were we in the middle of the VT switching process? */
DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit));
@@ -548,6 +544,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
sc_vtb_destroy(&scp->vtb);
sc_vtb_destroy(&scp->scr);
sc_free_history_buffer(scp, scp->ysize);
+ SC_STAT(dev) = NULL;
free(scp, M_DEVBUF);
}
#else
@@ -570,9 +567,8 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
int
scread(dev_t dev, struct uio *uio, int flag)
{
-
sc_touch_scrn_saver();
- return(ttyread(dev, uio, flag));
+ return ttyread(dev, uio, flag);
}
static int
@@ -613,6 +609,9 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
|| !(cur_tty->t_state & TS_ISOPEN))
continue;
+ if ((*sc->cur_scp->tsw->te_input)(sc->cur_scp, c, cur_tty))
+ continue;
+
switch (KEYFLAGS(c)) {
case 0x0000: /* normal key */
(*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
@@ -688,15 +687,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
error = sc_mouse_ioctl(tp, cmd, data, flag, p);
if (error != ENOIOCTL)
return error;
- if (SC_VTY(dev) == SC_MOUSE) {
- error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
- if (error != ENOIOCTL)
- return error;
- error = ttioctl(tp, cmd, data, flag);
- if (error != ENOIOCTL)
- return error;
- return ENOTTY;
- }
#endif
scp = SC_STAT(tp->t_dev);
@@ -704,11 +694,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
/* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */
sc = scp->sc;
+ if (scp->tsw) {
+ error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ }
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
- *(int*)data = (scp->term.cur_attr >> 8) & 0xFF;
- return 0;
+ /* this ioctl is not processed here, but in the terminal emulator */
+ return ENOTTY;
case GIO_COLOR: /* is this a color console ? */
*(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
@@ -725,7 +721,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
if (!ISGRAPHSC(sc->cur_scp))
- remove_cursor_image(sc->cur_scp);
+ sc_remove_cursor_image(sc->cur_scp);
if ((*(int*)data) & 0x01)
sc->flags |= SC_BLINK_CURSOR;
else
@@ -741,7 +737,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (!ISGRAPHSC(sc->cur_scp)) {
s = spltty();
sc_set_cursor_image(sc->cur_scp);
- draw_cursor_image(sc->cur_scp);
+ sc_draw_cursor_image(sc->cur_scp);
splx(s);
}
return 0;
@@ -766,10 +762,14 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
ptr->mv_row = scp->ypos;
ptr->mv_csz = scp->xsize;
ptr->mv_rsz = scp->ysize;
- ptr->mv_norm.fore = (scp->term.std_color & 0x0f00)>>8;
- ptr->mv_norm.back = (scp->term.std_color & 0xf000)>>12;
- ptr->mv_rev.fore = (scp->term.rev_color & 0x0f00)>>8;
- ptr->mv_rev.back = (scp->term.rev_color & 0xf000)>>12;
+ /*
+ * The following fields are filled by the terminal emulator. XXX
+ *
+ * ptr->mv_norm.fore
+ * ptr->mv_norm.back
+ * ptr->mv_rev.fore
+ * ptr->mv_rev.back
+ */
ptr->mv_grfc.fore = 0; /* not supported */
ptr->mv_grfc.back = 0; /* not supported */
ptr->mv_ovscan = scp->border;
@@ -962,7 +962,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
s = spltty();
sc_clean_up(sc->cur_scp);
splx(s);
- return switch_scr(sc, *(int *)data - 1);
+ return sc_switch_scr(sc, *(int *)data - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
if ((*(int *)data >= sc->first_vty + sc->vtys)
@@ -1062,10 +1062,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case KDMKTONE: /* sound the bell */
if (*(int*)data)
- do_bell(scp, (*(int*)data)&0xffff,
+ sc_bell(scp, (*(int*)data)&0xffff,
(((*(int*)data)>>16)&0xffff)*hz/1000);
else
- do_bell(scp, scp->bell_pitch, scp->bell_duration);
+ sc_bell(scp, scp->bell_pitch, scp->bell_duration);
return 0;
case KIOCSOUND: /* make tone (*data) hz */
@@ -1148,6 +1148,37 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return error;
+ case CONS_GETTERM: /* get the current terminal emulator info */
+ {
+ sc_term_sw_t *sw;
+
+ if (((term_info_t *)data)->ti_index == 0) {
+ sw = scp->tsw;
+ } else {
+ sw = sc_term_match_by_number(((term_info_t *)data)->ti_index);
+ }
+ if (sw != NULL) {
+ strncpy(((term_info_t *)data)->ti_name, sw->te_name,
+ sizeof(((term_info_t *)data)->ti_name));
+ strncpy(((term_info_t *)data)->ti_desc, sw->te_desc,
+ sizeof(((term_info_t *)data)->ti_desc));
+ ((term_info_t *)data)->ti_flags = 0;
+ return 0;
+ } else {
+ ((term_info_t *)data)->ti_name[0] = '\0';
+ ((term_info_t *)data)->ti_desc[0] = '\0';
+ ((term_info_t *)data)->ti_flags = 0;
+ return EINVAL;
+ }
+ }
+
+ case CONS_SETTERM: /* set the current terminal emulator */
+ s = spltty();
+ error = sc_init_emulator(scp, ((term_info_t *)data)->ti_name);
+ /* FIXME: what if scp == sc_console! XXX */
+ splx(s);
+ return error;
+
case GIO_SCRNMAP: /* get output translation table */
bcopy(&sc->scr_map, data, sizeof(sc->scr_map));
return 0;
@@ -1183,7 +1214,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Don't load if the current font size is not 8x8.
*/
if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size < 14))
- copy_font(sc->cur_scp, LOAD, 8, sc->font_8);
+ sc_load_font(sc->cur_scp, 0, 8, sc->font_8, 0, 256);
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
@@ -1209,7 +1240,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (ISTEXTSC(sc->cur_scp)
&& (sc->cur_scp->font_size >= 14)
&& (sc->cur_scp->font_size < 16))
- copy_font(sc->cur_scp, LOAD, 14, sc->font_14);
+ sc_load_font(sc->cur_scp, 0, 14, sc->font_14, 0, 256);
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
@@ -1233,7 +1264,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Don't load if the current font size is not 8x16.
*/
if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 16))
- copy_font(sc->cur_scp, LOAD, 16, sc->font_16);
+ sc_load_font(sc->cur_scp, 0, 16, sc->font_16, 0, 256);
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
@@ -1278,7 +1309,7 @@ scstart(struct tty *tp)
while (rbp->c_cc) {
len = q_to_b(rbp, buf, PCBURST);
splx(s);
- ansi_put(scp, buf, len);
+ sc_puts(scp, buf, len);
s = spltty();
}
tp->t_state &= ~TS_BUSY;
@@ -1288,26 +1319,6 @@ scstart(struct tty *tp)
}
static void
-scmousestart(struct tty *tp)
-{
- struct clist *rbp;
- int s;
- u_char buf[PCBURST];
-
- s = spltty();
- if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
- tp->t_state |= TS_BUSY;
- rbp = &tp->t_outq;
- while (rbp->c_cc) {
- q_to_b(rbp, buf, PCBURST);
- }
- tp->t_state &= ~TS_BUSY;
- ttwwakeup(tp);
- }
- splx(s);
-}
-
-static void
sccnprobe(struct consdev *cp)
{
#if __i386__
@@ -1418,7 +1429,7 @@ sccnputc(dev_t dev, int c)
{
u_char buf[1];
scr_stat *scp = sc_console;
- term_stat save = scp->term;
+ void *save;
#ifndef SC_NO_HISTORY
struct tty *tp;
#endif /* !SC_NO_HISTORY */
@@ -1435,7 +1446,7 @@ sccnputc(dev_t dev, int c)
sc_remove_cutmarking(scp);
scp->status &= ~BUFFER_SAVED;
scp->status |= CURSOR_ENABLED;
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
}
tp = VIRTUAL_TTY(scp->sc, scp->index);
if (tp->t_state & TS_ISOPEN)
@@ -1443,13 +1454,12 @@ sccnputc(dev_t dev, int c)
}
#endif /* !SC_NO_HISTORY */
- scp->term = kernel_console;
- current_default = &kernel_default;
+ save = scp->ts;
+ if (kernel_console_ts != NULL)
+ scp->ts = kernel_console_ts;
buf[0] = c;
- ansi_put(scp, buf, 1);
- kernel_console = scp->term;
- current_default = &user_default;
- scp->term = save;
+ sc_puts(scp, buf, 1);
+ scp->ts = save;
s = spltty(); /* block sckbdevent and scrn_timer */
sccnupdate(scp);
@@ -1482,7 +1492,7 @@ sccndbctl(dev_t dev, int on)
if (!cold
&& sc_console->sc->cur_scp->smode.mode == VT_AUTO
&& sc_console->smode.mode == VT_AUTO)
- switch_scr(sc_console->sc, sc_console->index);
+ sc_switch_scr(sc_console->sc, sc_console->index);
}
if (on)
++debugger;
@@ -1781,15 +1791,15 @@ scrn_update(scr_stat *scp, int show_cursor)
/* do we need to remove old cursor image ? */
if (scp->cursor_oldpos < scp->start ||
scp->cursor_oldpos > scp->end) {
- remove_cursor_image(scp);
+ sc_remove_cursor_image(scp);
}
scp->cursor_oldpos = scp->cursor_pos;
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
}
else {
/* cursor didn't move, has it been overwritten ? */
if (scp->cursor_pos >= scp->start && scp->cursor_pos <= scp->end) {
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
} else {
/* if its a blinking cursor, we may have to update it */
if (scp->sc->flags & SC_BLINK_CURSOR)
@@ -1957,7 +1967,7 @@ set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
/* assert(scp == scp->sc->cur_scp) */
s = spltty();
if (!ISGRAPHSC(scp))
- remove_cursor_image(scp);
+ sc_remove_cursor_image(scp);
scp->splash_save_mode = scp->mode;
scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
@@ -1975,7 +1985,7 @@ set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
if (pal != NULL)
load_palette(scp->sc->adp, pal);
#endif
- set_border(scp, border);
+ sc_set_border(scp, border);
return 0;
} else {
s = spltty();
@@ -2004,7 +2014,7 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
scp->sc->flags &= ~SC_SCRN_BLANKED;
if (!changemode) {
if (!ISGRAPHSC(scp))
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
--scrn_blanked;
splx(s);
return 0;
@@ -2035,7 +2045,7 @@ stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int))
mark_all(sc->cur_scp);
if (sc->delayed_next_scr)
- switch_scr(sc, sc->delayed_next_scr - 1);
+ sc_switch_scr(sc, sc->delayed_next_scr - 1);
wakeup((caddr_t)&scrn_blanked);
}
@@ -2066,23 +2076,13 @@ sc_touch_scrn_saver(void)
run_scrn_saver = FALSE;
}
-void
-sc_clear_screen(scr_stat *scp)
-{
- move_crsr(scp, 0, 0);
- scp->cursor_oldpos = scp->cursor_pos;
- sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], scp->term.cur_color);
- mark_all(scp);
- sc_remove_cutmarking(scp);
-}
-
-static int
-switch_scr(sc_softc_t *sc, u_int next_scr)
+int
+sc_switch_scr(sc_softc_t *sc, u_int next_scr)
{
struct tty *tp;
int s;
- DPRINTF(5, ("sc0: switch_scr() %d ", next_scr + 1));
+ DPRINTF(5, ("sc0: sc_switch_scr() %d ", next_scr + 1));
/* delay switch if the screen is blanked or being updated */
if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress
@@ -2190,7 +2190,7 @@ switch_scr(sc_softc_t *sc, u_int next_scr)
if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys)
|| sc->switch_in_progress) {
splx(s);
- do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error 1\n"));
return EINVAL;
}
@@ -2206,7 +2206,7 @@ switch_scr(sc_softc_t *sc, u_int next_scr)
&& (sc->cur_scp->smode.mode == VT_AUTO)
&& ISGRAPHSC(sc->cur_scp)) {
splx(s);
- do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error, graphics mode\n"));
return EINVAL;
}
@@ -2220,7 +2220,7 @@ switch_scr(sc_softc_t *sc, u_int next_scr)
tp = VIRTUAL_TTY(sc, next_scr);
if ((tp == NULL) || !(tp->t_state & TS_ISOPEN)) {
splx(s);
- do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error 2, requested vty isn't open!\n"));
return EINVAL;
}
@@ -2336,7 +2336,7 @@ exchange_scr(sc_softc_t *sc)
scr_stat *scp;
/* save the current state of video and keyboard */
- move_crsr(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
+ sc_move_cursor(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
if (sc->old_scp->kbd_mode == K_XLATE)
save_kbd_state(sc->old_scp);
@@ -2347,14 +2347,14 @@ exchange_scr(sc_softc_t *sc)
else
sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
(void *)sc->adp->va_window, FALSE);
- move_crsr(scp, scp->xpos, scp->ypos);
+ sc_move_cursor(scp, scp->xpos, scp->ypos);
if (!ISGRAPHSC(scp))
sc_set_cursor_image(scp);
#ifndef SC_NO_PALETTE_LOADING
if (ISGRAPHSC(sc->old_scp))
load_palette(sc->adp, sc->palette);
#endif
- set_border(scp, scp->border);
+ sc_set_border(scp, scp->border);
/* set up the keyboard for the new screen */
if (sc->old_scp->kbd_mode != scp->kbd_mode)
@@ -2364,665 +2364,24 @@ exchange_scr(sc_softc_t *sc)
mark_all(scp);
}
-static void
-scan_esc(scr_stat *scp, u_char c)
-{
- static u_char ansi_col[16] =
- {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
- sc_softc_t *sc;
- int i, n;
- int count;
-
- i = n = 0;
- sc = scp->sc;
- if (scp->term.esc == 1) { /* seen ESC */
- switch (c) {
-
- case '7': /* Save cursor position */
- scp->saved_xpos = scp->xpos;
- scp->saved_ypos = scp->ypos;
- break;
-
- case '8': /* Restore saved cursor position */
- if (scp->saved_xpos >= 0 && scp->saved_ypos >= 0)
- move_crsr(scp, scp->saved_xpos, scp->saved_ypos);
- break;
-
- case '[': /* Start ESC [ sequence */
- scp->term.esc = 2;
- scp->term.last_param = -1;
- for (i = scp->term.num_param; i < MAX_ESC_PAR; i++)
- scp->term.param[i] = 1;
- scp->term.num_param = 0;
- return;
-
- case 'M': /* Move cursor up 1 line, scroll if at top */
- if (scp->ypos > 0)
- move_crsr(scp, scp->xpos, scp->ypos - 1);
- else {
- sc_vtb_ins(&scp->vtb, 0, scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_all(scp);
- }
- break;
-#if notyet
- case 'Q':
- scp->term.esc = 4;
- return;
-#endif
- case 'c': /* Clear screen & home */
- sc_clear_screen(scp);
- break;
-
- case '(': /* iso-2022: designate 94 character set to G0 */
- scp->term.esc = 5;
- return;
- }
- }
- else if (scp->term.esc == 2) { /* seen ESC [ */
- if (c >= '0' && c <= '9') {
- if (scp->term.num_param < MAX_ESC_PAR) {
- if (scp->term.last_param != scp->term.num_param) {
- scp->term.last_param = scp->term.num_param;
- scp->term.param[scp->term.num_param] = 0;
- }
- else
- scp->term.param[scp->term.num_param] *= 10;
- scp->term.param[scp->term.num_param] += c - '0';
- return;
- }
- }
- scp->term.num_param = scp->term.last_param + 1;
- switch (c) {
-
- case ';':
- if (scp->term.num_param < MAX_ESC_PAR)
- return;
- break;
-
- case '=':
- scp->term.esc = 3;
- scp->term.last_param = -1;
- for (i = scp->term.num_param; i < MAX_ESC_PAR; i++)
- scp->term.param[i] = 1;
- scp->term.num_param = 0;
- return;
-
- case 'A': /* up n rows */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos, scp->ypos - n);
- break;
-
- case 'B': /* down n rows */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos, scp->ypos + n);
- break;
-
- case 'C': /* right n columns */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos + n, scp->ypos);
- break;
-
- case 'D': /* left n columns */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos - n, scp->ypos);
- break;
-
- case 'E': /* cursor to start of line n lines down */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, 0, scp->ypos + n);
- break;
-
- case 'F': /* cursor to start of line n lines up */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, 0, scp->ypos - n);
- break;
-
- case 'f': /* Cursor move */
- case 'H':
- if (scp->term.num_param == 0)
- move_crsr(scp, 0, 0);
- else if (scp->term.num_param == 2)
- move_crsr(scp, scp->term.param[1] - 1, scp->term.param[0] - 1);
- break;
-
- case 'J': /* Clear all or part of display */
- if (scp->term.num_param == 0)
- n = 0;
- else
- n = scp->term.param[0];
- switch (n) {
- case 0: /* clear form cursor to end of display */
- sc_vtb_erase(&scp->vtb, scp->cursor_pos,
- scp->xsize * scp->ysize - scp->cursor_pos,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
- sc_remove_cutmarking(scp);
- break;
- case 1: /* clear from beginning of display to cursor */
- sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, 0);
- mark_for_update(scp, scp->cursor_pos);
- sc_remove_cutmarking(scp);
- break;
- case 2: /* clear entire display */
- sc_vtb_clear(&scp->vtb, sc->scr_map[0x20], scp->term.cur_color);
- mark_all(scp);
- sc_remove_cutmarking(scp);
- break;
- }
- break;
-
- case 'K': /* Clear all or part of line */
- if (scp->term.num_param == 0)
- n = 0;
- else
- n = scp->term.param[0];
- switch (n) {
- case 0: /* clear form cursor to end of line */
- sc_vtb_erase(&scp->vtb, scp->cursor_pos,
- scp->xsize - scp->xpos,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos +
- scp->xsize - 1 - scp->xpos);
- break;
- case 1: /* clear from beginning of line to cursor */
- sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
- scp->xpos + 1,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->cursor_pos);
- break;
- case 2: /* clear entire line */
- sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
- scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
- break;
- }
- break;
-
- case 'L': /* Insert n lines */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->ysize - scp->ypos)
- n = scp->ysize - scp->ypos;
- sc_vtb_ins(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
- break;
-
- case 'M': /* Delete n lines */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->ysize - scp->ypos)
- n = scp->ysize - scp->ypos;
- sc_vtb_delete(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
- break;
-
- case 'P': /* Delete n chars */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->xsize - scp->xpos)
- n = scp->xsize - scp->xpos;
- count = scp->xsize - (scp->xpos + n);
- sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count);
- sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos + n + count - 1);
- break;
-
- case '@': /* Insert n chars */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->xsize - scp->xpos)
- n = scp->xsize - scp->xpos;
- count = scp->xsize - (scp->xpos + n);
- sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count);
- sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos + n + count - 1);
- break;
-
- case 'S': /* scroll up n lines */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->ysize)
- n = scp->ysize;
- sc_vtb_delete(&scp->vtb, 0, n * scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_all(scp);
- break;
-
- case 'T': /* scroll down n lines */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->ysize)
- n = scp->ysize;
- sc_vtb_ins(&scp->vtb, 0, n * scp->xsize,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_all(scp);
- break;
-
- case 'X': /* erase n characters in line */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if (n > scp->xsize - scp->xpos)
- n = scp->xsize - scp->xpos;
- sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
- sc->scr_map[0x20], scp->term.cur_color);
- mark_for_update(scp, scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos + n - 1);
- break;
-
- case 'Z': /* move n tabs backwards */
- n = scp->term.param[0]; if (n < 1) n = 1;
- if ((i = scp->xpos & 0xf8) == scp->xpos)
- i -= 8*n;
- else
- i -= 8*(n-1);
- if (i < 0)
- i = 0;
- move_crsr(scp, i, scp->ypos);
- break;
-
- case '`': /* move cursor to column n */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, n - 1, scp->ypos);
- break;
-
- case 'a': /* move cursor n columns to the right */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos + n, scp->ypos);
- break;
-
- case 'd': /* move cursor to row n */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos, n - 1);
- break;
-
- case 'e': /* move cursor n rows down */
- n = scp->term.param[0]; if (n < 1) n = 1;
- move_crsr(scp, scp->xpos, scp->ypos + n);
- break;
-
- case 'm': /* change attribute */
- if (scp->term.num_param == 0) {
- scp->term.attr_mask = NORMAL_ATTR;
- scp->term.cur_attr =
- scp->term.cur_color = scp->term.std_color;
- break;
- }
- for (i = 0; i < scp->term.num_param; i++) {
- switch (n = scp->term.param[i]) {
- case 0: /* back to normal */
- scp->term.attr_mask = NORMAL_ATTR;
- scp->term.cur_attr =
- scp->term.cur_color = scp->term.std_color;
- break;
- case 1: /* bold */
- scp->term.attr_mask |= BOLD_ATTR;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 4: /* underline */
- scp->term.attr_mask |= UNDERLINE_ATTR;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 5: /* blink */
- scp->term.attr_mask |= BLINK_ATTR;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 7: /* reverse video */
- scp->term.attr_mask |= REVERSE_ATTR;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 30: case 31: /* set fg color */
- case 32: case 33: case 34:
- case 35: case 36: case 37:
- scp->term.attr_mask |= FOREGROUND_CHANGED;
- scp->term.cur_color =
- (scp->term.cur_color&0xF000) | (ansi_col[(n-30)&7]<<8);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 40: case 41: /* set bg color */
- case 42: case 43: case 44:
- case 45: case 46: case 47:
- scp->term.attr_mask |= BACKGROUND_CHANGED;
- scp->term.cur_color =
- (scp->term.cur_color&0x0F00) | (ansi_col[(n-40)&7]<<12);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- }
- }
- break;
-
- case 's': /* Save cursor position */
- scp->saved_xpos = scp->xpos;
- scp->saved_ypos = scp->ypos;
- break;
-
- case 'u': /* Restore saved cursor position */
- if (scp->saved_xpos >= 0 && scp->saved_ypos >= 0)
- move_crsr(scp, scp->saved_xpos, scp->saved_ypos);
- break;
-
- case 'x':
- if (scp->term.num_param == 0)
- n = 0;
- else
- n = scp->term.param[0];
- switch (n) {
- case 0: /* reset attributes */
- scp->term.attr_mask = NORMAL_ATTR;
- scp->term.cur_attr =
- scp->term.cur_color = scp->term.std_color =
- current_default->std_color;
- scp->term.rev_color = current_default->rev_color;
- break;
- case 1: /* set ansi background */
- scp->term.attr_mask &= ~BACKGROUND_CHANGED;
- scp->term.cur_color = scp->term.std_color =
- (scp->term.std_color & 0x0F00) |
- (ansi_col[(scp->term.param[1])&0x0F]<<12);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 2: /* set ansi foreground */
- scp->term.attr_mask &= ~FOREGROUND_CHANGED;
- scp->term.cur_color = scp->term.std_color =
- (scp->term.std_color & 0xF000) |
- (ansi_col[(scp->term.param[1])&0x0F]<<8);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 3: /* set ansi attribute directly */
- scp->term.attr_mask &= ~(FOREGROUND_CHANGED|BACKGROUND_CHANGED);
- scp->term.cur_color = scp->term.std_color =
- (scp->term.param[1]&0xFF)<<8;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 5: /* set ansi reverse video background */
- scp->term.rev_color =
- (scp->term.rev_color & 0x0F00) |
- (ansi_col[(scp->term.param[1])&0x0F]<<12);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 6: /* set ansi reverse video foreground */
- scp->term.rev_color =
- (scp->term.rev_color & 0xF000) |
- (ansi_col[(scp->term.param[1])&0x0F]<<8);
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- case 7: /* set ansi reverse video directly */
- scp->term.rev_color =
- (scp->term.param[1]&0xFF)<<8;
- scp->term.cur_attr = mask2attr(&scp->term);
- break;
- }
- break;
-
- case 'z': /* switch to (virtual) console n */
- if (scp->term.num_param == 1)
- switch_scr(sc, scp->term.param[0]);
- break;
- }
- }
- else if (scp->term.esc == 3) { /* seen ESC [0-9]+ = */
- if (c >= '0' && c <= '9') {
- if (scp->term.num_param < MAX_ESC_PAR) {
- if (scp->term.last_param != scp->term.num_param) {
- scp->term.last_param = scp->term.num_param;
- scp->term.param[scp->term.num_param] = 0;
- }
- else
- scp->term.param[scp->term.num_param] *= 10;
- scp->term.param[scp->term.num_param] += c - '0';
- return;
- }
- }
- scp->term.num_param = scp->term.last_param + 1;
- switch (c) {
-
- case ';':
- if (scp->term.num_param < MAX_ESC_PAR)
- return;
- break;
-
- case 'A': /* set display border color */
- if (scp->term.num_param == 1) {
- scp->border=scp->term.param[0] & 0xff;
- if (scp == sc->cur_scp)
- set_border(scp, scp->border);
- }
- break;
-
- case 'B': /* set bell pitch and duration */
- if (scp->term.num_param == 2) {
- scp->bell_pitch = scp->term.param[0];
- scp->bell_duration = scp->term.param[1];
- }
- break;
-
- case 'C': /* set cursor type & shape */
- if (!ISGRAPHSC(sc->cur_scp))
- remove_cursor_image(sc->cur_scp);
- if (scp->term.num_param == 1) {
- if (scp->term.param[0] & 0x01)
- sc->flags |= SC_BLINK_CURSOR;
- else
- sc->flags &= ~SC_BLINK_CURSOR;
- if (scp->term.param[0] & 0x02)
- sc->flags |= SC_CHAR_CURSOR;
- else
- sc->flags &= ~SC_CHAR_CURSOR;
- }
- else if (scp->term.num_param == 2) {
- sc->cursor_base = scp->font_size
- - (scp->term.param[1] & 0x1F) - 1;
- sc->cursor_height = (scp->term.param[1] & 0x1F)
- - (scp->term.param[0] & 0x1F) + 1;
- }
- /*
- * The cursor shape is global property; all virtual consoles
- * are affected. Update the cursor in the current console...
- */
- if (!ISGRAPHSC(sc->cur_scp)) {
- i = spltty();
- sc_set_cursor_image(sc->cur_scp);
- draw_cursor_image(sc->cur_scp);
- splx(i);
- }
- break;
-
- case 'F': /* set ansi foreground */
- if (scp->term.num_param == 1) {
- scp->term.attr_mask &= ~FOREGROUND_CHANGED;
- scp->term.cur_color = scp->term.std_color =
- (scp->term.std_color & 0xF000)
- | ((scp->term.param[0] & 0x0F) << 8);
- scp->term.cur_attr = mask2attr(&scp->term);
- }
- break;
-
- case 'G': /* set ansi background */
- if (scp->term.num_param == 1) {
- scp->term.attr_mask &= ~BACKGROUND_CHANGED;
- scp->term.cur_color = scp->term.std_color =
- (scp->term.std_color & 0x0F00)
- | ((scp->term.param[0] & 0x0F) << 12);
- scp->term.cur_attr = mask2attr(&scp->term);
- }
- break;
-
- case 'H': /* set ansi reverse video foreground */
- if (scp->term.num_param == 1) {
- scp->term.rev_color =
- (scp->term.rev_color & 0xF000)
- | ((scp->term.param[0] & 0x0F) << 8);
- scp->term.cur_attr = mask2attr(&scp->term);
- }
- break;
-
- case 'I': /* set ansi reverse video background */
- if (scp->term.num_param == 1) {
- scp->term.rev_color =
- (scp->term.rev_color & 0x0F00)
- | ((scp->term.param[0] & 0x0F) << 12);
- scp->term.cur_attr = mask2attr(&scp->term);
- }
- break;
- }
- }
-#if notyet
- else if (scp->term.esc == 4) { /* seen ESC Q */
- /* to be filled */
- }
-#endif
- else if (scp->term.esc == 5) { /* seen ESC ( */
- switch (c) {
- case 'B': /* iso-2022: desginate ASCII into G0 */
- break;
- /* other items to be filled */
- default:
- break;
- }
- }
- scp->term.esc = 0;
-}
-
-static void
-ansi_put(scr_stat *scp, u_char *buf, int len)
+void
+sc_puts(scr_stat *scp, u_char *buf, int len)
{
- u_char *ptr = buf;
-
#if NSPLASH > 0
/* make screensaver happy */
if (!sticky_splash && scp == scp->sc->cur_scp)
run_scrn_saver = FALSE;
#endif
-outloop:
- scp->sc->write_in_progress++;
- if (scp->term.esc) {
- scan_esc(scp, *ptr++);
- len--;
- }
- else if (PRINTABLE(*ptr)) { /* Print only printables */
- vm_offset_t p;
- u_char *map;
- int cnt;
- int attr;
- int i;
-
- p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
- map = scp->sc->scr_map;
- attr = scp->term.cur_attr;
-
- cnt = (len <= scp->xsize - scp->xpos) ? len : (scp->xsize - scp->xpos);
- i = cnt;
- do {
- /*
- * gcc-2.6.3 generates poor (un)sign extension code. Casting the
- * pointers in the following to volatile should have no effect,
- * but in fact speeds up this inner loop from 26 to 18 cycles
- * (+ cache misses) on i486's.
- */
-#define UCVP(ucp) ((u_char volatile *)(ucp))
- p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], attr);
- ++ptr;
- --i;
- } while (i > 0 && PRINTABLE(*ptr));
-
- len -= cnt - i;
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += cnt - i;
- mark_for_update(scp, scp->cursor_pos - 1);
- scp->xpos += cnt - i;
-
- if (scp->xpos >= scp->xsize) {
- scp->xpos = 0;
- scp->ypos++;
- }
- }
- else {
- switch(*ptr) {
- case 0x07:
- do_bell(scp, scp->bell_pitch, scp->bell_duration);
- break;
-
- case 0x08: /* non-destructive backspace */
- if (scp->cursor_pos > 0) {
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos--;
- mark_for_update(scp, scp->cursor_pos);
- if (scp->xpos > 0)
- scp->xpos--;
- else {
- scp->xpos += scp->xsize - 1;
- scp->ypos--;
- }
- }
- break;
-
- case 0x09: /* non-destructive tab */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += (8 - scp->xpos % 8u);
- if ((scp->xpos += (8 - scp->xpos % 8u)) >= scp->xsize) {
- scp->xpos = 0;
- scp->ypos++;
- scp->cursor_pos = scp->xsize * scp->ypos;
- }
- mark_for_update(scp, scp->cursor_pos);
- break;
-
- case 0x0a: /* newline, same pos */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos += scp->xsize;
- mark_for_update(scp, scp->cursor_pos);
- scp->ypos++;
- break;
-
- case 0x0c: /* form feed, clears screen */
- sc_clear_screen(scp);
- break;
-
- case 0x0d: /* return, return to pos 0 */
- mark_for_update(scp, scp->cursor_pos);
- scp->cursor_pos -= scp->xpos;
- mark_for_update(scp, scp->cursor_pos);
- scp->xpos = 0;
- break;
+ if (scp->tsw)
+ (*scp->tsw->te_puts)(scp, buf, len);
- case 0x1b: /* start escape sequence */
- scp->term.esc = 1;
- scp->term.num_param = 0;
- break;
- }
- ptr++; len--;
- }
- /* do we have to scroll ?? */
- if (scp->cursor_pos >= scp->ysize * scp->xsize) {
- sc_remove_cutmarking(scp);
-#ifndef SC_NO_HISTORY
- if (scp->history != NULL)
- sc_hist_save_one_line(scp, 0);
-#endif
- sc_vtb_delete(&scp->vtb, 0, scp->xsize,
- scp->sc->scr_map[0x20], scp->term.cur_color);
- scp->cursor_pos -= scp->xsize;
- scp->ypos--;
- mark_all(scp);
- }
- scp->sc->write_in_progress--;
- if (len)
- goto outloop;
if (scp->sc->delayed_next_scr)
- switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
+ sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
-static void
-draw_cursor_image(scr_stat *scp)
+void
+sc_draw_cursor_image(scr_stat *scp)
{
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
@@ -3032,8 +2391,8 @@ draw_cursor_image(scr_stat *scp)
--scp->sc->videoio_in_progress;
}
-static void
-remove_cursor_image(scr_stat *scp)
+void
+sc_remove_cursor_image(scr_stat *scp)
{
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
@@ -3086,22 +2445,6 @@ sc_set_cursor_image(scr_stat *scp)
}
static void
-move_crsr(scr_stat *scp, int x, int y)
-{
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
- if (x >= scp->xsize)
- x = scp->xsize-1;
- if (y >= scp->ysize)
- y = scp->ysize-1;
- scp->xpos = x;
- scp->ypos = y;
- scp->cursor_pos = scp->ypos * scp->xsize + scp->xpos;
-}
-
-static void
scinit(int unit, int flags)
{
/*
@@ -3129,17 +2472,8 @@ scinit(int unit, int flags)
int i;
/* one time initialization */
- if (init_done == COLD) {
+ if (init_done == COLD)
sc_get_bios_values(&bios_value);
- current_default = &user_default;
- /* kernel console attributes */
- kernel_console.esc = 0;
- kernel_console.attr_mask = NORMAL_ATTR;
- kernel_console.cur_attr =
- kernel_console.cur_color = kernel_console.std_color =
- kernel_default.std_color;
- kernel_console.rev_color = kernel_default.rev_color;
- }
init_done = WARM;
/*
@@ -3159,8 +2493,8 @@ scinit(int unit, int flags)
i = kbd_release(sc->kbd, (void *)&sc->keyboard);
DPRINTF(5, ("sc%d: kbd_release returned %d\n", unit, i));
if (sc->kbd != NULL) {
- DPRINTF(5, ("sc%d: kbd != NULL!, index:%d, minor:%d, flags:0x%x\n",
- unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ DPRINTF(5, ("sc%d: kbd != NULL!, index:%d, unit:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_unit, sc->kbd->kb_flags));
}
sc->kbd = NULL;
}
@@ -3172,8 +2506,8 @@ scinit(int unit, int flags)
DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
sc->kbd = kbd_get_keyboard(sc->keyboard);
if (sc->kbd != NULL) {
- DPRINTF(1, ("sc%d: kbd index:%d, minor:%d, flags:0x%x\n",
- unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ DPRINTF(1, ("sc%d: kbd index:%d, unit:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_unit, sc->kbd->kb_flags));
}
if (!(sc->flags & SC_INIT_DONE) || (adp != sc->adp)) {
@@ -3199,7 +2533,7 @@ scinit(int unit, int flags)
/* set up the first console */
sc->first_vty = unit*MAXCONS;
- sc->vtys = MAXCONS;
+ sc->vtys = MAXCONS; /* XXX: should be configurable */
if (flags & SC_KERNEL_CONSOLE) {
sc->dev = main_devs;
sc->dev[0] = makedev(CDEV_MAJOR, unit*MAXCONS);
@@ -3209,6 +2543,11 @@ scinit(int unit, int flags)
init_scp(sc, sc->first_vty, scp);
sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize,
(void *)sc_buffer, FALSE);
+ if (sc_init_emulator(scp, SC_DFLT_TERM))
+ sc_init_emulator(scp, "*");
+ (*scp->tsw->te_default_attr)(scp,
+ kernel_default.std_color,
+ kernel_default.rev_color);
} else {
/* assert(sc_malloc) */
sc->dev = malloc(sizeof(dev_t)*sc->vtys, M_DEVBUF, M_WAITOK);
@@ -3243,7 +2582,7 @@ scinit(int unit, int flags)
sc->cursor_height = imin(i, scp->font_size);
if (!ISGRAPHSC(scp)) {
sc_set_cursor_image(scp);
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
}
/* save font and palette */
@@ -3256,26 +2595,26 @@ scinit(int unit, int flags)
bcopy(dflt_font_16, sc->font_16, sizeof(dflt_font_16));
sc->fonts_loaded = FONT_16 | FONT_14 | FONT_8;
if (scp->font_size < 14) {
- copy_font(scp, LOAD, 8, sc->font_8);
+ sc_load_font(scp, 0, 8, sc->font_8, 0, 256);
} else if (scp->font_size >= 16) {
- copy_font(scp, LOAD, 16, sc->font_16);
+ sc_load_font(scp, 0, 16, sc->font_16, 0, 256);
} else {
- copy_font(scp, LOAD, 14, sc->font_14);
+ sc_load_font(scp, 0, 14, sc->font_14, 0, 256);
}
#else /* !SC_DFLT_FONT */
if (scp->font_size < 14) {
- copy_font(scp, SAVE, 8, sc->font_8);
+ sc_save_font(scp, 0, 8, sc->font_8, 0, 256);
sc->fonts_loaded = FONT_8;
} else if (scp->font_size >= 16) {
- copy_font(scp, SAVE, 16, sc->font_16);
+ sc_save_font(scp, 0, 16, sc->font_16, 0, 256);
sc->fonts_loaded = FONT_16;
} else {
- copy_font(scp, SAVE, 14, sc->font_14);
+ sc_save_font(scp, 0, 14, sc->font_14, 0, 256);
sc->fonts_loaded = FONT_14;
}
#endif /* SC_DFLT_FONT */
/* FONT KLUDGE: always use the font page #0. XXX */
- (*vidsw[sc->adapter]->show_font)(sc->adp, 0);
+ sc_show_font(scp, 0);
}
#endif /* !SC_NO_FONT_LOADING */
@@ -3308,6 +2647,7 @@ static void
scterm(int unit, int flags)
{
sc_softc_t *sc;
+ scr_stat *scp;
sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
if (sc == NULL)
@@ -3332,6 +2672,13 @@ scterm(int unit, int flags)
if (sc->adapter >= 0)
vid_release(sc->adp, &sc->adapter);
+ /* stop the terminal emulator, if any */
+ scp = SC_STAT(sc->dev[0]);
+ if (scp->tsw)
+ (*scp->tsw->te_term)(scp, &scp->ts);
+ if (scp->ts != NULL)
+ free(scp->ts, M_DEVBUF);
+
/* clear the structure */
if (!(flags & SC_KERNEL_CONSOLE)) {
/* XXX: We need delete_dev() for this */
@@ -3362,7 +2709,7 @@ scshutdown(void *arg, int howto)
if (!cold && sc_console
&& sc_console->sc->cur_scp->smode.mode == VT_AUTO
&& sc_console->smode.mode == VT_AUTO)
- switch_scr(sc_console->sc, sc_console->index);
+ sc_switch_scr(sc_console->sc, sc_console->index);
shutdown_in_progress = TRUE;
}
@@ -3388,7 +2735,6 @@ sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
{
sc_vtb_t new;
sc_vtb_t old;
- int s;
old = scp->vtb;
sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait);
@@ -3402,11 +2748,7 @@ sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
sc_vtb_copy(&old, 0, &new, 0, scp->xsize*scp->ysize);
scp->vtb = new;
} else {
- /* clear the screen and move the text cursor to the top-left position */
- s = splhigh();
scp->vtb = new;
- sc_clear_screen(scp);
- splx(s);
sc_vtb_destroy(&old);
}
@@ -3427,6 +2769,8 @@ static scr_stat
init_scp(sc, vty, scp);
sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (sc_init_emulator(scp, SC_DFLT_TERM))
+ sc_init_emulator(scp, "*");
#ifndef SC_NO_SYSMOUSE
if (ISMOUSEAVAIL(sc->adp->va_flags))
@@ -3437,7 +2781,6 @@ static scr_stat
sc_alloc_history_buffer(scp, 0, 0, TRUE);
#endif
- sc_clear_screen(scp);
return scp;
}
@@ -3446,6 +2789,8 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
{
video_info_t info;
+ bzero(scp, sizeof(*scp));
+
scp->index = vty;
scp->sc = sc;
scp->status = 0;
@@ -3491,15 +2836,11 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
scp->xoff = scp->yoff = 0;
scp->xpos = scp->ypos = 0;
- scp->saved_xpos = scp->saved_ypos = -1;
scp->start = scp->xsize * scp->ysize - 1;
scp->end = 0;
- scp->term.esc = 0;
- scp->term.attr_mask = NORMAL_ATTR;
- scp->term.cur_attr =
- scp->term.cur_color = scp->term.std_color =
- current_default->std_color;
- scp->term.rev_color = current_default->rev_color;
+ scp->tsw = NULL;
+ scp->ts = NULL;
+ scp->rndr = NULL;
scp->border = BG_BLACK;
scp->cursor_base = sc->cursor_base;
scp->cursor_height = imin(sc->cursor_height, scp->font_size);
@@ -3521,10 +2862,64 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
scp->history = NULL;
scp->history_pos = 0;
scp->history_size = 0;
+}
+
+int
+sc_init_emulator(scr_stat *scp, char *name)
+{
+ sc_term_sw_t *sw;
+ sc_rndr_sw_t *rndr;
+ void *p;
+ int error;
+
+ if (name == NULL) /* if no name is given, use the current emulator */
+ sw = scp->tsw;
+ else /* ...otherwise find the named emulator */
+ sw = sc_term_match(name);
+ if (sw == NULL)
+ return EINVAL;
- /* what if the following call fails... XXX */
- scp->rndr = sc_render_match(scp, scp->sc->adp,
- scp->status & (GRAPHICS_MODE | PIXEL_MODE));
+ rndr = NULL;
+ if (strcmp(sw->te_renderer, "*") != 0) {
+ rndr = sc_render_match(scp, sw->te_renderer,
+ scp->status & (GRAPHICS_MODE | PIXEL_MODE));
+ }
+ if (rndr == NULL) {
+ rndr = sc_render_match(scp, scp->sc->adp->va_name,
+ scp->status & (GRAPHICS_MODE | PIXEL_MODE));
+ if (rndr == NULL)
+ return ENODEV;
+ }
+
+ if (sw == scp->tsw) {
+ error = (*sw->te_init)(scp, &scp->ts, SC_TE_WARM_INIT);
+ scp->rndr = rndr;
+ sc_clear_screen(scp);
+ /* assert(error == 0); */
+ return error;
+ }
+
+ if (sc_malloc && (sw->te_size > 0))
+ p = malloc(sw->te_size, M_DEVBUF, M_NOWAIT);
+ else
+ p = NULL;
+ error = (*sw->te_init)(scp, &p, SC_TE_COLD_INIT);
+ if (error)
+ return error;
+
+ if (scp->tsw)
+ (*scp->tsw->te_term)(scp, &scp->ts);
+ if (scp->ts != NULL)
+ free(scp->ts, M_DEVBUF);
+ scp->tsw = sw;
+ scp->ts = p;
+ scp->rndr = rndr;
+
+ /* XXX */
+ (*sw->te_default_attr)(scp, user_default.std_color, user_default.rev_color);
+ sc_clear_screen(scp);
+
+ return 0;
}
/*
@@ -3560,7 +2955,7 @@ next_code:
c = kbd_read_char(sc->kbd, !(flags & SCGETC_NONBLOCK));
if (c == ERRKEY) {
if (!(flags & SCGETC_CN))
- do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
} else if (c == NOKEY)
return c;
else
@@ -3584,7 +2979,7 @@ next_code:
if (!ISGRAPHSC(scp) && scp->history && scp->status & SLKED) {
scp->status &= ~CURSOR_ENABLED;
- remove_cursor_image(scp);
+ sc_remove_cursor_image(scp);
#ifndef SC_NO_HISTORY
if (!(scp->status & BUFFER_SAVED)) {
@@ -3607,14 +3002,14 @@ next_code:
sc_remove_cutmarking(scp);
if (sc_hist_up_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(58): /* down arrow key */
sc_remove_cutmarking(scp);
if (sc_hist_down_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(51): /* page up key */
@@ -3622,7 +3017,7 @@ next_code:
for (i=0; i<scp->ysize; i++)
if (sc_hist_up_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
@@ -3632,7 +3027,7 @@ next_code:
for (i=0; i<scp->ysize; i++)
if (sc_hist_down_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
@@ -3668,7 +3063,7 @@ next_code:
sc_remove_cutmarking(scp);
scp->status &= ~BUFFER_SAVED;
scp->status |= CURSOR_ENABLED;
- draw_cursor_image(scp);
+ sc_draw_cursor_image(scp);
}
tp = VIRTUAL_TTY(sc, scp->index);
if (tp->t_state & TS_ISOPEN)
@@ -3757,7 +3152,7 @@ next_code:
i = (i + 1)%sc->vtys) {
struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
if (tp && tp->t_state & TS_ISOPEN) {
- switch_scr(scp->sc, sc->first_vty + i);
+ sc_switch_scr(scp->sc, sc->first_vty + i);
break;
}
}
@@ -3770,7 +3165,7 @@ next_code:
i = (i + sc->vtys - 1)%sc->vtys) {
struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
if (tp && tp->t_state & TS_ISOPEN) {
- switch_scr(scp->sc, sc->first_vty + i);
+ sc_switch_scr(scp->sc, sc->first_vty + i);
break;
}
}
@@ -3778,7 +3173,7 @@ next_code:
default:
if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) {
- switch_scr(scp->sc, sc->first_vty + KEYCHAR(c) - F_SCR);
+ sc_switch_scr(scp->sc, sc->first_vty + KEYCHAR(c) - F_SCR);
break;
}
/* assert(c & FKEY) */
@@ -3802,43 +3197,12 @@ scmmap(dev_t dev, vm_offset_t offset, int nprot)
{
scr_stat *scp;
- if (SC_VTY(dev) == SC_MOUSE)
- return -1;
scp = SC_STAT(dev);
if (scp != scp->sc->cur_scp)
return -1;
return (*vidsw[scp->sc->adapter]->mmap)(scp->sc->adp, offset, nprot);
}
-/*
- * Calculate hardware attributes word using logical attributes mask and
- * hardware colors
- */
-
-static int
-mask2attr(struct term_stat *term)
-{
- int attr, mask = term->attr_mask;
-
- if (mask & REVERSE_ATTR) {
- attr = ((mask & FOREGROUND_CHANGED) ?
- ((term->cur_color & 0xF000) >> 4) :
- (term->rev_color & 0x0F00)) |
- ((mask & BACKGROUND_CHANGED) ?
- ((term->cur_color & 0x0F00) << 4) :
- (term->rev_color & 0xF000));
- } else
- attr = term->cur_color;
-
- /* XXX: underline mapping for Hercules adapter can be better */
- if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
- attr ^= 0x0800;
- if (mask & BLINK_ATTR)
- attr ^= 0x8000;
-
- return attr;
-}
-
static int
save_kbd_state(scr_stat *scp)
{
@@ -3914,13 +3278,13 @@ set_mode(scr_stat *scp)
if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->sc->adp->va_flags)) {
if (scp->font_size < 14) {
if (scp->sc->fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, scp->sc->font_8);
+ sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256);
} else if (scp->font_size >= 16) {
if (scp->sc->fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, scp->sc->font_16);
+ sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256);
} else {
if (scp->sc->fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, scp->sc->font_14);
+ sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256);
}
/*
* FONT KLUDGE:
@@ -3929,20 +3293,20 @@ set_mode(scr_stat *scp)
* Somehow we cannot show the font in other font pages on
* some video cards... XXX
*/
- (*vidsw[scp->sc->adapter]->show_font)(scp->sc->adp, 0);
+ sc_show_font(scp, 0);
}
mark_all(scp);
}
#endif /* !SC_NO_FONT_LOADING */
- set_border(scp, scp->border);
+ sc_set_border(scp, scp->border);
sc_set_cursor_image(scp);
return 0;
}
void
-set_border(scr_stat *scp, int color)
+sc_set_border(scr_stat *scp, int color)
{
++scp->sc->videoio_in_progress;
(*scp->rndr->draw_border)(scp, color);
@@ -3951,34 +3315,35 @@ set_border(scr_stat *scp, int color)
#ifndef SC_NO_FONT_LOADING
void
-copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
+sc_load_font(scr_stat *scp, int page, int size, u_char *buf,
+ int base, int count)
{
- /*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
- scp->sc->font_loading_in_progress = TRUE;
- if (operation == LOAD) {
- (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, font_size,
- buf, 0, 256);
- } else if (operation == SAVE) {
- (*vidsw[scp->sc->adapter]->save_font)(scp->sc->adp, 0, font_size,
- buf, 0, 256);
- }
- scp->sc->font_loading_in_progress = FALSE;
+ sc_softc_t *sc;
+
+ sc = scp->sc;
+ sc->font_loading_in_progress = TRUE;
+ (*vidsw[sc->adapter]->load_font)(sc->adp, page, size, buf, base, count);
+ sc->font_loading_in_progress = FALSE;
}
-#endif /* !SC_NO_FONT_LOADING */
-#ifndef SC_NO_SYSMOUSE
-struct tty
-*sc_get_mouse_tty(void)
+void
+sc_save_font(scr_stat *scp, int page, int size, u_char *buf,
+ int base, int count)
{
- return sc_mouse_tty;
+ sc_softc_t *sc;
+
+ sc = scp->sc;
+ sc->font_loading_in_progress = TRUE;
+ (*vidsw[sc->adapter]->save_font)(sc->adp, page, size, buf, base, count);
+ sc->font_loading_in_progress = FALSE;
+}
+
+void
+sc_show_font(scr_stat *scp, int page)
+{
+ (*vidsw[scp->sc->adapter]->show_font)(scp->sc->adp, page);
}
-#endif /* !SC_NO_SYSMOUSE */
+#endif /* !SC_NO_FONT_LOADING */
#ifndef SC_NO_CUTPASTE
void
@@ -3998,8 +3363,8 @@ sc_paste(scr_stat *scp, u_char *p, int count)
}
#endif /* SC_NO_CUTPASTE */
-static void
-do_bell(scr_stat *scp, int pitch, int duration)
+void
+sc_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress)
return;
@@ -4034,7 +3399,7 @@ blink_screen(void *arg)
if (tp->t_state & TS_ISOPEN)
scstart(tp);
if (scp->sc->delayed_next_scr)
- switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
+ sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
else {
(*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize,
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index 0f3ae5c03d39..de4c3e15107c 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -102,45 +102,18 @@
#define VR_CURSOR_BLINK 0x40000
#define VR_CURSOR_ON 0x80000
-/* attribute flags */
-#define NORMAL_ATTR 0x00
-#define BLINK_ATTR 0x01
-#define BOLD_ATTR 0x02
-#define UNDERLINE_ATTR 0x04
-#define REVERSE_ATTR 0x08
-#define FOREGROUND_CHANGED 0x10
-#define BACKGROUND_CHANGED 0x20
-
/* misc defines */
#define FALSE 0
#define TRUE 1
-#define MAX_ESC_PAR 5
-#define LOAD 1
-#define SAVE 0
#define COL 80
#define ROW 25
-#define CONSOLE_BUFSIZE 1024
#define PCBURST 128
-#define FONT_NONE 1
-#define FONT_8 2
-#define FONT_14 4
-#define FONT_16 8
#ifndef BELL_DURATION
#define BELL_DURATION 5
#define BELL_PITCH 800
#endif
-/* special characters */
-#define cntlc 0x03
-#define cntld 0x04
-#define bs 0x08
-#define lf 0x0a
-#define cr 0x0d
-#define del 0x7f
-
-#define DEAD_CHAR 0x07 /* char used for cursor */
-
/* virtual terminal buffer */
typedef struct sc_vtb {
int vtb_flags;
@@ -157,19 +130,6 @@ typedef struct sc_vtb {
int vtb_tail; /* valid for VTB_RINGBUFFER only */
} sc_vtb_t;
-/* terminal status */
-typedef struct term_stat {
- int esc; /* processing escape sequence */
- int num_param; /* # of parameters to ESC */
- int last_param; /* last parameter # */
- int param[MAX_ESC_PAR]; /* contains ESC parameters */
- int cur_attr; /* current hardware attr word */
- int attr_mask; /* current logical attr mask */
- int cur_color; /* current hardware color */
- int std_color; /* normal hardware color */
- int rev_color; /* reverse hardware color */
-} term_stat;
-
/* softc */
struct keyboard;
@@ -236,6 +196,10 @@ typedef struct sc_softc {
#ifndef SC_NO_FONT_LOADING
int fonts_loaded;
+#define FONT_NONE 1
+#define FONT_8 2
+#define FONT_14 4
+#define FONT_16 8
u_char *font_8;
u_char *font_14;
u_char *font_16;
@@ -252,29 +216,35 @@ typedef struct scr_stat {
struct sc_rndr_sw *rndr; /* renderer */
sc_vtb_t scr;
sc_vtb_t vtb;
+
int xpos; /* current X position */
int ypos; /* current Y position */
- int saved_xpos; /* saved X position */
- int saved_ypos; /* saved Y position */
int xsize; /* X text size */
int ysize; /* Y text size */
int xpixel; /* X graphics size */
int ypixel; /* Y graphics size */
int xoff; /* X offset in pixel mode */
int yoff; /* Y offset in pixel mode */
+
u_char *font; /* current font */
int font_size; /* fontsize in Y direction */
+
int start; /* modified area start */
int end; /* modified area end */
- term_stat term; /* terminal emulation stuff */
+
+ struct sc_term_sw *tsw;
+ void *ts;
+
int status; /* status (bitfield) */
int kbd_mode; /* keyboard I/O mode */
+
int cursor_pos; /* cursor buffer position */
int cursor_oldpos; /* cursor old buffer position */
u_short cursor_saveunder_char; /* saved char under cursor */
u_short cursor_saveunder_attr; /* saved attr under cursor */
char cursor_base; /* cursor base line # */
char cursor_height; /* cursor height */
+
int mouse_pos; /* mouse buffer position */
int mouse_oldpos; /* mouse old buffer position */
short mouse_xpos; /* mouse x coordinate */
@@ -285,16 +255,20 @@ typedef struct scr_stat {
struct proc *mouse_proc; /* proc* of controlling proc */
pid_t mouse_pid; /* pid of controlling proc */
int mouse_signal; /* signal # to report with */
+
u_short bell_duration;
u_short bell_pitch;
+
u_char border; /* border color */
int mode; /* mode */
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
+
sc_vtb_t *history; /* circular history buffer */
int history_pos; /* position shown on screen */
int history_size; /* size of history buffer */
+
int splash_save_mode; /* saved mode for splash screen */
int splash_save_status; /* saved status for splash screen */
#ifdef _SCR_MD_STAT_DECLARED_
@@ -302,11 +276,6 @@ typedef struct scr_stat {
#endif
} scr_stat;
-typedef struct default_attr {
- int std_color; /* normal hardware color */
- int rev_color; /* reverse hardware color */
-} default_attr;
-
#ifndef SC_NORM_ATTR
#define SC_NORM_ATTR (FG_LIGHTGREY | BG_BLACK)
#endif
@@ -320,6 +289,74 @@ typedef struct default_attr {
#define SC_KERNEL_CONS_REV_ATTR (FG_BLACK | BG_LIGHTGREY)
#endif
+/* terminal emulator */
+
+#ifndef SC_DFLT_TERM
+#define SC_DFLT_TERM "*" /* any */
+#endif
+
+typedef int sc_term_init_t(scr_stat *scp, void **tcp, int code);
+#define SC_TE_COLD_INIT 0
+#define SC_TE_WARM_INIT 1
+typedef int sc_term_term_t(scr_stat *scp, void **tcp);
+typedef void sc_term_puts_t(scr_stat *scp, u_char *buf, int len);
+typedef int sc_term_ioctl_t(scr_stat *scp, struct tty *tp, u_long cmd,
+ caddr_t data, int flag, struct proc *p);
+typedef int sc_term_reset_t(scr_stat *scp, int code);
+#define SC_TE_HARD_RESET 0
+#define SC_TE_SOFT_RESET 1
+typedef void sc_term_default_attr_t(scr_stat *scp, int norm, int rev);
+typedef void sc_term_clear_t(scr_stat *scp);
+typedef void sc_term_notify_t(scr_stat *scp, int event);
+#define SC_TE_NOTIFY_VTSWITCH_IN 0
+#define SC_TE_NOTIFY_VTSWITCH_OUT 1
+typedef int sc_term_input_t(scr_stat *scp, int c, struct tty *tp);
+
+typedef struct sc_term_sw {
+ LIST_ENTRY(sc_term_sw) link;
+ char *te_name; /* name of the emulator */
+ char *te_desc; /* description */
+ char *te_renderer; /* matching renderer */
+ size_t te_size; /* size of internal buffer */
+ int te_refcount; /* reference counter */
+ sc_term_init_t *te_init;
+ sc_term_term_t *te_term;
+ sc_term_puts_t *te_puts;
+ sc_term_ioctl_t *te_ioctl;
+ sc_term_reset_t *te_reset;
+ sc_term_default_attr_t *te_default_attr;
+ sc_term_clear_t *te_clear;
+ sc_term_notify_t *te_notify;
+ sc_term_input_t *te_input;
+} sc_term_sw_t;
+
+extern struct linker_set scterm_set;
+
+#define SCTERM_MODULE(name, sw) \
+ DATA_SET(scterm_set, sw); \
+ static int \
+ scterm_##name##_event(module_t mod, int type, void *data) \
+ { \
+ switch (type) { \
+ case MOD_LOAD: \
+ return sc_term_add(&sw); \
+ case MOD_UNLOAD: \
+ if (sw.te_refcount > 0) \
+ return EBUSY; \
+ return sc_term_remove(&sw); \
+ default: \
+ break; \
+ } \
+ return 0; \
+ } \
+ static moduledata_t scterm_##name##_mod = { \
+ "scterm-" #name, \
+ scterm_##name##_event, \
+ NULL, \
+ }; \
+ DECLARE_MODULE(scterm_##name, scterm_##name##_mod, \
+ SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
+
/* renderer function table */
typedef void vr_clear_t(scr_stat *scp, int c, int attr);
typedef void vr_draw_border_t(scr_stat *scp, int color);
@@ -343,18 +380,57 @@ typedef struct sc_rndr_sw {
} sc_rndr_sw_t;
typedef struct sc_renderer {
- char *name;
- int mode;
- sc_rndr_sw_t *rndrsw;
+ char *name;
+ int mode;
+ sc_rndr_sw_t *rndrsw;
+ LIST_ENTRY(sc_renderer) link;
} sc_renderer_t;
-#define RENDERER(name, mode, sw) \
- static struct sc_renderer name##_##mode##_renderer = { \
+extern struct linker_set scrndr_set;
+
+#define RENDERER(name, mode, sw, set) \
+ static struct sc_renderer scrndr_##name##_##mode## = { \
#name, mode, &sw \
}; \
- DATA_SET(scrndr_set, name##_##mode##_renderer)
-
-extern struct linker_set scrndr_set;
+ DATA_SET(scrndr_set, scrndr_##name##_##mode##); \
+ DATA_SET(set, scrndr_##name##_##mode##)
+
+#define RENDERER_MODULE(name, set) \
+ static int \
+ scrndr_##name##_event(module_t mod, int type, void *data) \
+ { \
+ sc_renderer_t **list; \
+ sc_renderer_t *p; \
+ int error = 0; \
+ switch (type) { \
+ case MOD_LOAD: \
+ list = (sc_renderer_t **)set.ls_items; \
+ while ((p = *list++) != NULL) { \
+ error = sc_render_add(p); \
+ if (error) \
+ break; \
+ } \
+ break; \
+ case MOD_UNLOAD: \
+ list = (sc_renderer_t **)set.ls_items; \
+ while ((p = *list++) != NULL) { \
+ error = sc_render_remove(p); \
+ if (error) \
+ break; \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ return error; \
+ } \
+ static moduledata_t scrndr_##name##_mod = { \
+ "scrndr-" #name, \
+ scrndr_##name##_event, \
+ NULL, \
+ }; \
+ DECLARE_MODULE(scrndr_##name##, scrndr_##name##_mod, \
+ SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
typedef struct {
int cursor_start;
@@ -415,21 +491,26 @@ int sc_resume_unit(int unit);
int set_mode(scr_stat *scp);
-void copy_font(scr_stat *scp, int operation, int font_size,
- u_char *font_image);
-void set_border(scr_stat *scp, int color);
+void sc_set_border(scr_stat *scp, int color);
+void sc_load_font(scr_stat *scp, int page, int size, u_char *font,
+ int base, int count);
+void sc_save_font(scr_stat *scp, int page, int size, u_char *font,
+ int base, int count);
+void sc_show_font(scr_stat *scp, int page);
void sc_touch_scrn_saver(void);
-void sc_clear_screen(scr_stat *scp);
+void sc_puts(scr_stat *scp, u_char *buf, int len);
+void sc_draw_cursor_image(scr_stat *scp);
+void sc_remove_cursor_image(scr_stat *scp);
void sc_set_cursor_image(scr_stat *scp);
int sc_clean_up(scr_stat *scp);
+int sc_switch_scr(sc_softc_t *sc, u_int next_scr);
void sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard);
-#ifndef SC_NO_SYSMOUSE
-struct tty *sc_get_mouse_tty(void);
-#endif /* SC_NO_SYSMOUSE */
+int sc_init_emulator(scr_stat *scp, char *name);
#ifndef SC_NO_CUTPASTE
void sc_paste(scr_stat *scp, u_char *p, int count);
#endif /* SC_NO_CUTPASTE */
+void sc_bell(scr_stat *scp, int pitch, int duration);
/* schistory.c */
#ifndef SC_NO_HISTORY
@@ -462,7 +543,6 @@ void sc_remove_all_mouse(sc_softc_t *scp);
#define sc_remove_cutmarking(scp)
#endif /* SC_NO_CUTPASTE */
#ifndef SC_NO_SYSMOUSE
-void sc_mouse_set_level(int level);
void sc_mouse_move(scr_stat *scp, int x, int y);
int sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data,
int flag, struct proc *p);
@@ -474,10 +554,13 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
int sc_set_pixel_mode(scr_stat *scp, struct tty *tp,
int xsize, int ysize, int fontsize);
-sc_rndr_sw_t *sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode);
int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
struct proc *p);
+int sc_render_add(sc_renderer_t *rndr);
+int sc_render_remove(sc_renderer_t *rndr);
+sc_rndr_sw_t *sc_render_match(scr_stat *scp, char *name, int mode);
+
/* scvtb.c */
void sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows,
void *buffer, int wait);
@@ -506,6 +589,17 @@ void sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count);
void sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr);
void sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr);
+/* sysmouse.c */
+int sysmouse_event(mouse_info_t *info);
+
+/* scterm.c */
+void sc_move_cursor(scr_stat *scp, int x, int y);
+void sc_clear_screen(scr_stat *scp);
+int sc_term_add(sc_term_sw_t *sw);
+int sc_term_remove(sc_term_sw_t *sw);
+sc_term_sw_t *sc_term_match(char *name);
+sc_term_sw_t *sc_term_match_by_number(int index);
+
/* machine dependent functions */
int sc_max_unit(void);
sc_softc_t *sc_get_softc(int unit, int flags);
diff --git a/sys/dev/syscons/sysmouse.c b/sys/dev/syscons/sysmouse.c
new file mode 100644
index 000000000000..8c28ab725119
--- /dev/null
+++ b/sys/dev/syscons/sysmouse.c
@@ -0,0 +1,344 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/mouse.h>
+
+#include <dev/syscons/syscons.h>
+
+#ifndef SC_NO_SYSMOUSE
+
+#define CDEV_MAJOR 12 /* major number, shared with syscons */
+#define SC_MOUSE 128 /* minor number */
+
+static d_open_t smopen;
+static d_close_t smclose;
+static d_ioctl_t smioctl;
+
+static struct cdevsw sm_cdevsw = {
+ /* open */ smopen,
+ /* close */ smclose,
+ /* read */ ttyread,
+ /* write */ nowrite,
+ /* ioctl */ smioctl,
+ /* poll */ ttypoll,
+ /* mmap */ nommap,
+ /* strategy */ nostrategy,
+ /* name */ "sysmouse",
+ /* maj */ CDEV_MAJOR,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ D_TTY,
+ /* bmaj */ -1
+};
+
+/* local variables */
+static struct tty *sysmouse_tty;
+static int mouse_level; /* sysmouse protocol level */
+static mousestatus_t mouse_status;
+
+static void smstart(struct tty *tp);
+static int smparam(struct tty *tp, struct termios *t);
+
+static int
+smopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tty *tp;
+
+ DPRINTF(5, ("smopen: dev:%d,%d, vty:%d\n",
+ major(dev), minor(dev), SC_VTY(dev)));
+
+#if 0
+ if (SC_VTY(dev) != SC_MOUSE)
+ return ENXIO;
+#endif
+
+ tp = dev->si_tty = ttymalloc(dev->si_tty);
+ if (!(tp->t_state & TS_ISOPEN)) {
+ tp->t_oproc = smstart;
+ tp->t_param = smparam;
+ tp->t_stop = nottystop;
+ tp->t_dev = dev;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
+ smparam(tp, &tp->t_termios);
+ (*linesw[tp->t_line].l_modem)(tp, 1);
+ } else if (tp->t_state & TS_XCLUDE && suser(p)) {
+ return EBUSY;
+ }
+
+ return (*linesw[tp->t_line].l_open)(dev, tp);
+}
+
+static int
+smclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tty *tp;
+ int s;
+
+ tp = dev->si_tty;
+ s = spltty();
+ mouse_level = 0;
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ splx(s);
+
+ return 0;
+}
+
+static void
+smstart(struct tty *tp)
+{
+ struct clist *rbp;
+ u_char buf[PCBURST];
+ int s;
+
+ s = spltty();
+ if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
+ tp->t_state |= TS_BUSY;
+ rbp = &tp->t_outq;
+ while (rbp->c_cc)
+ q_to_b(rbp, buf, PCBURST);
+ tp->t_state &= ~TS_BUSY;
+ ttwwakeup(tp);
+ }
+ splx(s);
+}
+
+static int
+smparam(struct tty *tp, struct termios *t)
+{
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+ return 0;
+}
+
+static int
+smioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct tty *tp;
+ mousehw_t *hw;
+ mousemode_t *mode;
+ int error;
+ int s;
+
+ tp = dev->si_tty;
+ switch (cmd) {
+
+ case MOUSE_GETHWINFO: /* get device information */
+ hw = (mousehw_t *)data;
+ hw->buttons = 10; /* XXX unknown */
+ hw->iftype = MOUSE_IF_SYSMOUSE;
+ hw->type = MOUSE_MOUSE;
+ hw->model = MOUSE_MODEL_GENERIC;
+ hw->hwid = 0;
+ return 0;
+
+ case MOUSE_GETMODE: /* get protocol/mode */
+ mode = (mousemode_t *)data;
+ mode->level = mouse_level;
+ switch (mode->level) {
+ case 0: /* emulate MouseSystems protocol */
+ mode->protocol = MOUSE_PROTO_MSC;
+ mode->rate = -1; /* unknown */
+ mode->resolution = -1; /* unknown */
+ mode->accelfactor = 0; /* disabled */
+ mode->packetsize = MOUSE_MSC_PACKETSIZE;
+ mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
+ mode->syncmask[1] = MOUSE_MSC_SYNC;
+ break;
+
+ case 1: /* sysmouse protocol */
+ mode->protocol = MOUSE_PROTO_SYSMOUSE;
+ mode->rate = -1;
+ mode->resolution = -1;
+ mode->accelfactor = 0;
+ mode->packetsize = MOUSE_SYS_PACKETSIZE;
+ mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
+ mode->syncmask[1] = MOUSE_SYS_SYNC;
+ break;
+ }
+ return 0;
+
+ case MOUSE_SETMODE: /* set protocol/mode */
+ mode = (mousemode_t *)data;
+ if ((mode->level < 0) || (mode->level > 1))
+ return EINVAL;
+ mouse_level = mode->level;
+ return 0;
+
+ case MOUSE_GETLEVEL: /* get operation level */
+ *(int *)data = mouse_level;
+ return 0;
+
+ case MOUSE_SETLEVEL: /* set operation level */
+ if ((*(int *)data < 0) || (*(int *)data > 1))
+ return EINVAL;
+ mouse_level = *(int *)data;
+ return 0;
+
+ case MOUSE_GETSTATUS: /* get accumulated mouse events */
+ s = spltty();
+ *(mousestatus_t *)data = mouse_status;
+ mouse_status.flags = 0;
+ mouse_status.obutton = mouse_status.button;
+ mouse_status.dx = 0;
+ mouse_status.dy = 0;
+ mouse_status.dz = 0;
+ splx(s);
+ return 0;
+
+#if notyet
+ case MOUSE_GETVARS: /* get internal mouse variables */
+ case MOUSE_SETVARS: /* set internal mouse variables */
+ return ENODEV;
+#endif
+
+ case MOUSE_READSTATE: /* read status from the device */
+ case MOUSE_READDATA: /* read data from the device */
+ return ENODEV;
+ }
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+ if (error != ENOIOCTL)
+ return error;
+ return ENOTTY;
+}
+
+static void
+sm_attach_mouse(void *unused)
+{
+ dev_t dev;
+
+ dev = make_dev(&sm_cdevsw, SC_MOUSE, UID_ROOT, GID_WHEEL, 0600,
+ "sysmouse");
+ dev->si_tty = sysmouse_tty = ttymalloc(sysmouse_tty);
+ /* sysmouse doesn't have scr_stat */
+}
+
+SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR,
+ sm_attach_mouse, NULL)
+
+int
+sysmouse_event(mouse_info_t *info)
+{
+ /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
+ static int butmap[8] = {
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON1UP,
+ 0,
+ };
+ u_char buf[8];
+ int x, y, z;
+ int i;
+
+ switch (info->operation) {
+ case MOUSE_ACTION:
+ mouse_status.button = info->u.data.buttons;
+ /* FALL THROUGH */
+ case MOUSE_MOTION_EVENT:
+ x = info->u.data.x;
+ y = info->u.data.y;
+ z = info->u.data.z;
+ break;
+ case MOUSE_BUTTON_EVENT:
+ x = y = z = 0;
+ if (info->u.event.value > 0)
+ mouse_status.button |= info->u.event.id;
+ else
+ mouse_status.button &= ~info->u.event.id;
+ break;
+ default:
+ return 0;
+ }
+
+ mouse_status.dx += x;
+ mouse_status.dy += y;
+ mouse_status.dz += z;
+ mouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0)
+ | (mouse_status.obutton ^ mouse_status.button);
+ if (mouse_status.flags == 0)
+ return 0;
+
+ if ((sysmouse_tty == NULL) || !(sysmouse_tty->t_state & TS_ISOPEN))
+ return mouse_status.flags;
+
+ /* the first five bytes are compatible with MouseSystems' */
+ buf[0] = MOUSE_MSC_SYNC
+ | butmap[mouse_status.button & MOUSE_STDBUTTONS];
+ x = imax(imin(x, 255), -256);
+ buf[1] = x >> 1;
+ buf[3] = x - buf[1];
+ y = -imax(imin(y, 255), -256);
+ buf[2] = y >> 1;
+ buf[4] = y - buf[2];
+ for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i)
+ (*linesw[sysmouse_tty->t_line].l_rint)(buf[i], sysmouse_tty);
+ if (mouse_level >= 1) {
+ /* extended part */
+ z = imax(imin(z, 127), -128);
+ buf[5] = (z >> 1) & 0x7f;
+ buf[6] = (z - (z >> 1)) & 0x7f;
+ /* buttons 4-10 */
+ buf[7] = (~mouse_status.button >> 3) & 0x7f;
+ for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i)
+ (*linesw[sysmouse_tty->t_line].l_rint)(buf[i],
+ sysmouse_tty);
+ }
+
+ return mouse_status.flags;
+}
+
+#endif /* !SC_NO_SYSMOUSE */
+
+#endif /* NSC */
diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c
index bc03f6446401..b056b486a039 100644
--- a/sys/modules/syscons/daemon/daemon_saver.c
+++ b/sys/modules/syscons/daemon/daemon_saver.c
@@ -240,7 +240,7 @@ daemon_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
xlen = ylen = tlen = 0;
}
if (blanked++ < 2)
diff --git a/sys/modules/syscons/snake/snake_saver.c b/sys/modules/syscons/snake/snake_saver.c
index 093e564bef13..e4277e3beee2 100644
--- a/sys/modules/syscons/snake/snake_saver.c
+++ b/sys/modules/syscons/snake/snake_saver.c
@@ -79,7 +79,7 @@ snake_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
diff --git a/sys/modules/syscons/star/star_saver.c b/sys/modules/syscons/star/star_saver.c
index 645e4fd3c354..27e992133ee7 100644
--- a/sys/modules/syscons/star/star_saver.c
+++ b/sys/modules/syscons/star/star_saver.c
@@ -85,7 +85,7 @@ star_saver(video_adapter_t *adp, int blank)
sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
(FG_LIGHTGREY | BG_BLACK) << 8);
(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
- set_border(scp, 0);
+ sc_set_border(scp, 0);
blanked = TRUE;
for(i=0; i<NUM_STARS; i++) {
stars[i][0] =
diff --git a/sys/sys/consio.h b/sys/sys/consio.h
index d3e9780241a1..2f5ae3de7d43 100644
--- a/sys/sys/consio.h
+++ b/sys/sys/consio.h
@@ -239,6 +239,21 @@ typedef struct vid_info vid_info_t;
/* release the current keyboard */
#define CONS_RELKBD _IO('c', 111)
+/* get/set the current terminal emulator info. */
+#define TI_NAME_LEN 32
+#define TI_DESC_LEN 64
+
+struct term_info {
+ int ti_index;
+ int ti_flags;
+ u_char ti_name[TI_NAME_LEN];
+ u_char ti_desc[TI_DESC_LEN];
+};
+typedef struct term_info term_info_t;
+
+#define CONS_GETTERM _IOWR('c', 112, term_info_t)
+#define CONS_SETTERM _IOW('c', 113, term_info_t)
+
#ifdef PC98
#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */
#endif