summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons/syscons.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/syscons/syscons.c')
-rw-r--r--sys/dev/syscons/syscons.c1199
1 files changed, 282 insertions, 917 deletions
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,
OpenPOWER on IntegriCloud