summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryokota <yokota@FreeBSD.org>2000-01-15 15:25:43 +0000
committeryokota <yokota@FreeBSD.org>2000-01-15 15:25:43 +0000
commit5db3ba7b9b236e9d8bbec14080167428916e1668 (patch)
tree17ba6cb453aac84fa60f284601f3294270a28946
parent164674f31b90b79c19ca15d4ee3fac064d785c59 (diff)
downloadFreeBSD-src-5db3ba7b9b236e9d8bbec14080167428916e1668.zip
FreeBSD-src-5db3ba7b9b236e9d8bbec14080167428916e1668.tar.gz
This is the 3rd stage of syscons code reorganization.
- Split terminal emulation code from the main part of the driver so that we can have alternative terminal emulator modules if we like in the future. (We are not quite there yet, though.) - Put sysmouse related code in a separate file, thus, simplifying the main part of the driver. As some files are added to the source tree, you need to run config(8) before you compile a new kernel next time. You shouldn't see any functional change by this commit; this is only internal code reorganization.
-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 b7434e4..ecb411e 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 813aa93..e9bbc68 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 bc03f64..b056b48 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 7290558..afdd073 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 aa7de06..49fc6ea 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 b0663a0..e55946c 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 0000000..19e421d
--- /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 0000000..317f7da
--- /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 0000000..c635993
--- /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 0000000..2ef75f0
--- /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 7290558..afdd073 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 0923a7b..3c03ee5 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 eebeb23..aac9024 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 093e564..e4277e3 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 645e4fd..27e9921 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 64ecd73..6d46128 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 0f3ae5c..de4c3e1 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 0000000..8c28ab7
--- /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 bc03f64..b056b48 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 093e564..e4277e3 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 645e4fd..27e9921 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 d3e9780..2f5ae3d 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
OpenPOWER on IntegriCloud