svn commit: r189178 - in projects/jbuild/sys/dev/syscons: . teken
John Birrell
jb at FreeBSD.org
Sat Feb 28 09:55:00 PST 2009
Author: jb
Date: Sat Feb 28 17:54:59 2009
New Revision: 189178
URL: http://svn.freebsd.org/changeset/base/189178
Log:
MFC
Added:
projects/jbuild/sys/dev/syscons/scterm-teken.c
- copied unchanged from r189173, head/sys/dev/syscons/scterm-teken.c
projects/jbuild/sys/dev/syscons/teken/
- copied from r189173, head/sys/dev/syscons/teken/
Deleted:
projects/jbuild/sys/dev/syscons/scterm-dumb.c
projects/jbuild/sys/dev/syscons/scterm-sc.c
projects/jbuild/sys/dev/syscons/sctermvar.h
Modified:
projects/jbuild/sys/dev/syscons/scterm.c
projects/jbuild/sys/dev/syscons/syscons.c
projects/jbuild/sys/dev/syscons/syscons.h
Copied: projects/jbuild/sys/dev/syscons/scterm-teken.c (from r189173, head/sys/dev/syscons/scterm-teken.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/jbuild/sys/dev/syscons/scterm-teken.c Sat Feb 28 17:54:59 2009 (r189178, copy of r189173, head/sys/dev/syscons/scterm-teken.c)
@@ -0,0 +1,509 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota at zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008-2009 Ed Schouten <ed at FreeBSD.org>
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_syscons.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/consio.h>
+
+#if defined(__sparc64__) || defined(__powerpc__)
+#include <machine/sc_machdep.h>
+#else
+#include <machine/pc/display.h>
+#endif
+
+#include <dev/syscons/syscons.h>
+
+#include <dev/syscons/teken/teken.h>
+
+static void scteken_revattr(unsigned char, teken_attr_t *);
+static unsigned int scteken_attr(const teken_attr_t *);
+
+static sc_term_init_t scteken_init;
+static sc_term_term_t scteken_term;
+static sc_term_puts_t scteken_puts;
+static sc_term_ioctl_t scteken_ioctl;
+static sc_term_default_attr_t scteken_default_attr;
+static sc_term_clear_t scteken_clear;
+static sc_term_input_t scteken_input;
+static void scteken_nop(void);
+
+typedef struct {
+ teken_t ts_teken;
+ int ts_busy;
+} teken_stat;
+
+static teken_stat reserved_teken_stat;
+
+static sc_term_sw_t sc_term_scteken = {
+ { NULL, NULL },
+ "scteken", /* emulator name */
+ "teken terminal", /* description */
+ "*", /* matching renderer */
+ sizeof(teken_stat), /* softc size */
+ 0,
+ scteken_init,
+ scteken_term,
+ scteken_puts,
+ scteken_ioctl,
+ (sc_term_reset_t *)scteken_nop,
+ scteken_default_attr,
+ scteken_clear,
+ (sc_term_notify_t *)scteken_nop,
+ scteken_input,
+};
+
+SCTERM_MODULE(scteken, sc_term_scteken);
+
+static tf_bell_t scteken_bell;
+static tf_cursor_t scteken_cursor;
+static tf_putchar_t scteken_putchar;
+static tf_fill_t scteken_fill;
+static tf_copy_t scteken_copy;
+static tf_param_t scteken_param;
+static tf_respond_t scteken_respond;
+
+static const teken_funcs_t scteken_funcs = {
+ .tf_bell = scteken_bell,
+ .tf_cursor = scteken_cursor,
+ .tf_putchar = scteken_putchar,
+ .tf_fill = scteken_fill,
+ .tf_copy = scteken_copy,
+ .tf_param = scteken_param,
+ .tf_respond = scteken_respond,
+};
+
+static int
+scteken_init(scr_stat *scp, void **softc, int code)
+{
+ teken_stat *ts;
+ teken_pos_t tp;
+
+ if (*softc == NULL) {
+ if (reserved_teken_stat.ts_busy)
+ return (EINVAL);
+ *softc = &reserved_teken_stat;
+ }
+ ts = *softc;
+
+ switch (code) {
+ case SC_TE_COLD_INIT:
+ ++sc_term_scteken.te_refcount;
+ ts->ts_busy = 1;
+ /* FALLTHROUGH */
+ case SC_TE_WARM_INIT:
+ teken_init(&ts->ts_teken, &scteken_funcs, scp);
+
+ tp.tp_row = scp->ysize;
+ tp.tp_col = scp->xsize;
+ teken_set_winsize(&ts->ts_teken, &tp);
+
+ tp.tp_row = scp->cursor_pos / scp->xsize;
+ tp.tp_col = scp->cursor_pos % scp->xsize;
+ teken_set_cursor(&ts->ts_teken, &tp);
+ break;
+ }
+
+ return (0);
+}
+
+static int
+scteken_term(scr_stat *scp, void **softc)
+{
+
+ if (*softc == &reserved_teken_stat) {
+ *softc = NULL;
+ reserved_teken_stat.ts_busy = 0;
+ }
+ --sc_term_scteken.te_refcount;
+
+ return (0);
+}
+
+static void
+scteken_puts(scr_stat *scp, u_char *buf, int len)
+{
+ teken_stat *ts = scp->ts;
+
+ scp->sc->write_in_progress++;
+ teken_input(&ts->ts_teken, buf, len);
+ scp->sc->write_in_progress--;
+}
+
+static int
+scteken_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
+ struct thread *td)
+{
+ teken_stat *ts = scp->ts;
+ vid_info_t *vi;
+ unsigned int attr;
+
+ switch (cmd) {
+ case GIO_ATTR: /* get current attributes */
+ *(int*)data =
+ scteken_attr(teken_get_curattr(&ts->ts_teken));
+ return (0);
+ case CONS_GETINFO: /* get current (virtual) console info */
+ vi = (vid_info_t *)data;
+ if (vi->size != sizeof(struct vid_info))
+ return EINVAL;
+
+ attr = scteken_attr(teken_get_defattr(&ts->ts_teken));
+ vi->mv_norm.fore = attr & 0x0f;
+ vi->mv_norm.back = (attr >> 4) & 0x0f;
+ vi->mv_rev.fore = vi->mv_norm.back;
+ vi->mv_rev.back = vi->mv_norm.fore;
+ /*
+ * The other fields are filled by the upper routine. XXX
+ */
+ return (ENOIOCTL);
+ }
+
+ return (ENOIOCTL);
+}
+
+static void
+scteken_default_attr(scr_stat *scp, int color, int rev_color)
+{
+ teken_stat *ts = scp->ts;
+ teken_attr_t ta;
+
+ scteken_revattr(color, &ta);
+ teken_set_defattr(&ts->ts_teken, &ta);
+}
+
+static void
+scteken_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
+scteken_input(scr_stat *scp, int c, struct tty *tp)
+{
+
+ return FALSE;
+}
+
+static void
+scteken_nop(void)
+{
+
+}
+
+/*
+ * libteken routines.
+ */
+
+static const unsigned char fgcolors_normal[TC_NCOLORS] = {
+ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN,
+ FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY,
+};
+
+static const unsigned char fgcolors_bold[TC_NCOLORS] = {
+ FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW,
+ FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE,
+};
+
+static const unsigned char bgcolors[TC_NCOLORS] = {
+ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN,
+ BG_BLUE, BG_MAGENTA, BG_CYAN, BG_LIGHTGREY,
+};
+
+static void
+scteken_revattr(unsigned char color, teken_attr_t *a)
+{
+ teken_color_t fg, bg;
+
+ /*
+ * XXX: Reverse conversion of syscons to teken attributes. Not
+ * realiable. Maybe we should turn it into a 1:1 mapping one of
+ * these days?
+ */
+
+ a->ta_format = 0;
+ a->ta_fgcolor = TC_WHITE;
+ a->ta_bgcolor = TC_BLACK;
+
+#ifdef FG_BLINK
+ if (color & FG_BLINK) {
+ a->ta_format |= TF_BLINK;
+ color &= ~FG_BLINK;
+ }
+#endif /* FG_BLINK */
+
+ for (fg = 0; fg < TC_NCOLORS; fg++) {
+ for (bg = 0; bg < TC_NCOLORS; bg++) {
+ if ((fgcolors_normal[fg] | bgcolors[bg]) == color) {
+ a->ta_fgcolor = fg;
+ a->ta_bgcolor = bg;
+ return;
+ }
+
+ if ((fgcolors_bold[fg] | bgcolors[bg]) == color) {
+ a->ta_fgcolor = fg;
+ a->ta_bgcolor = bg;
+ a->ta_format |= TF_BOLD;
+ return;
+ }
+ }
+ }
+}
+
+static unsigned int
+scteken_attr(const teken_attr_t *a)
+{
+ unsigned int attr = 0;
+
+ if (a->ta_format & TF_BOLD)
+ attr |= fgcolors_bold[a->ta_fgcolor];
+ else
+ attr |= fgcolors_normal[a->ta_fgcolor];
+ attr |= bgcolors[a->ta_bgcolor];
+
+#ifdef FG_UNDERLINE
+ if (a->ta_format & TF_UNDERLINE)
+ attr |= FG_UNDERLINE;
+#endif /* FG_UNDERLINE */
+#ifdef FG_BLINK
+ if (a->ta_format & TF_BLINK)
+ attr |= FG_BLINK;
+#endif /* FG_BLINK */
+
+ return (attr);
+}
+
+static void
+scteken_bell(void *arg)
+{
+ scr_stat *scp = arg;
+
+ sc_bell(scp, scp->bell_pitch, scp->bell_duration);
+}
+
+static void
+scteken_cursor(void *arg, const teken_pos_t *p)
+{
+ scr_stat *scp = arg;
+
+ sc_move_cursor(scp, p->tp_col, p->tp_row);
+}
+
+static void
+scteken_putchar(void *arg, const teken_pos_t *tp, teken_char_t c,
+ const teken_attr_t *a)
+{
+ scr_stat *scp = arg;
+ u_char *map;
+ u_char ch;
+ vm_offset_t p;
+ int cursor, attr;
+
+#ifdef TEKEN_UTF8
+ if (c >= 0x80) {
+ /* XXX: Don't display UTF-8 yet. */
+ attr = (FG_YELLOW|BG_RED) << 8;
+ ch = '?';
+ } else
+#endif /* TEKEN_UTF8 */
+ {
+ attr = scteken_attr(a) << 8;
+ ch = c;
+ }
+
+ map = scp->sc->scr_map;
+
+ cursor = tp->tp_row * scp->xsize + tp->tp_col;
+ p = sc_vtb_pointer(&scp->vtb, cursor);
+ sc_vtb_putchar(&scp->vtb, p, map[ch], attr);
+
+ mark_for_update(scp, cursor);
+ /*
+ * XXX: Why do we need this? Only marking `cursor' should be
+ * enough. Without this line, we get artifacts.
+ */
+ mark_for_update(scp, imin(cursor + 1, scp->xsize * scp->ysize - 1));
+}
+
+static void
+scteken_fill(void *arg, const teken_rect_t *r, teken_char_t c,
+ const teken_attr_t *a)
+{
+ scr_stat *scp = arg;
+ u_char *map;
+ u_char ch;
+ unsigned int width;
+ int attr, row;
+
+#ifdef TEKEN_UTF8
+ if (c >= 0x80) {
+ /* XXX: Don't display UTF-8 yet. */
+ attr = (FG_YELLOW|BG_RED) << 8;
+ ch = '?';
+ } else
+#endif /* TEKEN_UTF8 */
+ {
+ attr = scteken_attr(a) << 8;
+ ch = c;
+ }
+
+ map = scp->sc->scr_map;
+
+ if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+ /* Single contiguous region to fill. */
+ sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+ (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize,
+ map[ch], attr);
+ } else {
+ /* Fill display line by line. */
+ width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+ for (row = r->tr_begin.tp_row; row < r->tr_end.tp_row; row++) {
+ sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row *
+ scp->xsize + r->tr_begin.tp_col,
+ width, map[ch], attr);
+ }
+ }
+
+ /* Mark begin and end positions to be refreshed. */
+ mark_for_update(scp,
+ r->tr_begin.tp_row * scp->xsize + r->tr_begin.tp_col);
+ mark_for_update(scp,
+ (r->tr_end.tp_row - 1) * scp->xsize + (r->tr_end.tp_col - 1));
+ sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
+{
+ scr_stat *scp = arg;
+ unsigned int width;
+ int src, dst, end;
+
+#ifndef SC_NO_HISTORY
+ /*
+ * We count a line of input as history if we perform a copy of
+ * one whole line upward. In other words: if a line of text gets
+ * overwritten by a rectangle that's right below it.
+ */
+ if (scp->history != NULL &&
+ r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize &&
+ r->tr_begin.tp_row == p->tp_row + 1) {
+ sc_hist_save_one_line(scp, p->tp_row);
+ }
+#endif
+
+ if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+ /* Single contiguous region to copy. */
+ sc_vtb_move(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+ p->tp_row * scp->xsize,
+ (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize);
+ } else {
+ /* Copy line by line. */
+ width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+ if (p->tp_row < r->tr_begin.tp_row) {
+ /* Copy from top to bottom. */
+ src = r->tr_begin.tp_row * scp->xsize +
+ r->tr_begin.tp_col;
+ end = r->tr_end.tp_row * scp->xsize +
+ r->tr_end.tp_col;
+ dst = p->tp_row * scp->xsize + p->tp_col;
+
+ while (src < end) {
+ sc_vtb_move(&scp->vtb, src, dst, width);
+
+ src += scp->xsize;
+ dst += scp->xsize;
+ }
+ } else {
+ /* Copy from bottom to top. */
+ src = (r->tr_end.tp_row - 1) * scp->xsize +
+ r->tr_begin.tp_col;
+ end = r->tr_begin.tp_row * scp->xsize +
+ r->tr_begin.tp_col;
+ dst = (p->tp_row + r->tr_end.tp_row -
+ r->tr_begin.tp_row - 1) * scp->xsize + p->tp_col;
+
+ while (src >= end) {
+ sc_vtb_move(&scp->vtb, src, dst, width);
+
+ src -= scp->xsize;
+ dst -= scp->xsize;
+ }
+ }
+ }
+
+ /* Mark begin and end positions to be refreshed. */
+ mark_for_update(scp,
+ p->tp_row * scp->xsize + p->tp_col);
+ mark_for_update(scp,
+ (p->tp_row + r->tr_end.tp_row - r->tr_begin.tp_row - 1) *
+ scp->xsize +
+ (p->tp_col + r->tr_end.tp_col - r->tr_begin.tp_col - 1));
+ sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_param(void *arg, int cmd, int value)
+{
+ scr_stat *scp = arg;
+
+ switch (cmd) {
+ case TP_SHOWCURSOR:
+ if (value) {
+ sc_change_cursor_shape(scp,
+ CONS_RESET_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+ } else {
+ sc_change_cursor_shape(scp,
+ CONS_HIDDEN_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+ }
+ break;
+ case TP_SWITCHVT:
+ sc_switch_scr(scp->sc, value);
+ break;
+ }
+}
+
+static void
+scteken_respond(void *arg, const void *buf, size_t len)
+{
+ scr_stat *scp = arg;
+
+ sc_respond(scp, buf, len);
+}
Modified: projects/jbuild/sys/dev/syscons/scterm.c
==============================================================================
--- projects/jbuild/sys/dev/syscons/scterm.c Sat Feb 28 17:54:49 2009 (r189177)
+++ projects/jbuild/sys/dev/syscons/scterm.c Sat Feb 28 17:54:59 2009 (r189178)
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
#include <sys/consio.h>
#include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
SET_DECLARE(scterm_set, sc_term_sw_t);
Modified: projects/jbuild/sys/dev/syscons/syscons.c
==============================================================================
--- projects/jbuild/sys/dev/syscons/syscons.c Sat Feb 28 17:54:49 2009 (r189177)
+++ projects/jbuild/sys/dev/syscons/syscons.c Sat Feb 28 17:54:59 2009 (r189178)
@@ -2741,6 +2741,16 @@ 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);
+
+ /* move cursors to the initial positions */
+ if (col >= scp->xsize)
+ col = 0;
+ if (row >= scp->ysize)
+ row = scp->ysize - 1;
+ scp->xpos = col;
+ scp->ypos = row;
+ scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
+
if (sc_init_emulator(scp, SC_DFLT_TERM))
sc_init_emulator(scp, "*");
(*scp->tsw->te_default_attr)(scp,
@@ -2764,15 +2774,6 @@ scinit(int unit, int flags)
sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize);
#endif
- /* move cursors to the initial positions */
- if (col >= scp->xsize)
- col = 0;
- if (row >= scp->ysize)
- row = scp->ysize - 1;
- scp->xpos = col;
- scp->ypos = row;
- scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
-
if (bios_value.cursor_end < scp->font_size)
sc->dflt_curs_attr.base = scp->font_size -
bios_value.cursor_end - 1;
@@ -3569,7 +3570,7 @@ sc_show_font(scr_stat *scp, int page)
#endif /* !SC_NO_FONT_LOADING */
void
-sc_paste(scr_stat *scp, u_char *p, int count)
+sc_paste(scr_stat *scp, const u_char *p, int count)
{
struct tty *tp;
u_char *rmap;
@@ -3584,6 +3585,22 @@ sc_paste(scr_stat *scp, u_char *p, int c
}
void
+sc_respond(scr_stat *scp, const u_char *p, int count)
+{
+ struct tty *tp;
+
+ tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
+ if (!tty_opened(tp))
+ return;
+ for (; count > 0; --count)
+ ttydisc_rint(tp, *p++, 0);
+#if 0
+ /* XXX: we can't call ttydisc_rint_done() here! */
+ ttydisc_rint_done(tp);
+#endif
+}
+
+void
sc_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress || !enable_bell)
Modified: projects/jbuild/sys/dev/syscons/syscons.h
==============================================================================
--- projects/jbuild/sys/dev/syscons/syscons.h Sat Feb 28 17:54:49 2009 (r189177)
+++ projects/jbuild/sys/dev/syscons/syscons.h Sat Feb 28 17:54:59 2009 (r189178)
@@ -563,7 +563,8 @@ 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);
int sc_init_emulator(scr_stat *scp, char *name);
-void sc_paste(scr_stat *scp, u_char *p, int count);
+void sc_paste(scr_stat *scp, const u_char *p, int count);
+void sc_respond(scr_stat *scp, const u_char *p, int count);
void sc_bell(scr_stat *scp, int pitch, int duration);
/* schistory.c */
More information about the svn-src-projects
mailing list