1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer as 13 * the first lines of this file unmodified. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer as 13 * the first lines of this file unmodified. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
|
31__FBSDID("$FreeBSD: head/sys/dev/syscons/scterm-teken.c 186681 2009-01-01 13:26:53Z ed $");
| 31__FBSDID("$FreeBSD: head/sys/dev/syscons/scterm-teken.c 188391 2009-02-09 15:55:21Z ed $");
|
32 33#include "opt_syscons.h" 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/consio.h> 40 41#if defined(__sparc64__) || defined(__powerpc__) 42#include <machine/sc_machdep.h> 43#else 44#include <machine/pc/display.h> 45#endif 46 47#include <dev/syscons/syscons.h> 48 49#include <dev/syscons/teken/teken.h> 50 51static void scteken_revattr(unsigned char, teken_attr_t *);
| 32 33#include "opt_syscons.h" 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/consio.h> 40 41#if defined(__sparc64__) || defined(__powerpc__) 42#include <machine/sc_machdep.h> 43#else 44#include <machine/pc/display.h> 45#endif 46 47#include <dev/syscons/syscons.h> 48 49#include <dev/syscons/teken/teken.h> 50 51static void scteken_revattr(unsigned char, teken_attr_t *);
|
| 52static unsigned int scteken_attr(const teken_attr_t *);
|
52 53static sc_term_init_t scteken_init; 54static sc_term_term_t scteken_term; 55static sc_term_puts_t scteken_puts; 56static sc_term_ioctl_t scteken_ioctl; 57static sc_term_default_attr_t scteken_default_attr; 58static sc_term_clear_t scteken_clear; 59static sc_term_input_t scteken_input; 60static void scteken_nop(void); 61 62typedef struct { 63 teken_t ts_teken; 64 int ts_busy; 65} teken_stat; 66 67static teken_stat reserved_teken_stat; 68 69static sc_term_sw_t sc_term_scteken = { 70 { NULL, NULL }, 71 "scteken", /* emulator name */ 72 "teken terminal", /* description */ 73 "*", /* matching renderer */ 74 sizeof(teken_stat), /* softc size */ 75 0, 76 scteken_init, 77 scteken_term, 78 scteken_puts, 79 scteken_ioctl, 80 (sc_term_reset_t *)scteken_nop, 81 scteken_default_attr, 82 scteken_clear, 83 (sc_term_notify_t *)scteken_nop, 84 scteken_input, 85}; 86 87SCTERM_MODULE(scteken, sc_term_scteken); 88 89static tf_bell_t scteken_bell; 90static tf_cursor_t scteken_cursor; 91static tf_putchar_t scteken_putchar; 92static tf_fill_t scteken_fill; 93static tf_copy_t scteken_copy; 94static tf_param_t scteken_param; 95static tf_respond_t scteken_respond; 96 97static const teken_funcs_t scteken_funcs = { 98 .tf_bell = scteken_bell, 99 .tf_cursor = scteken_cursor, 100 .tf_putchar = scteken_putchar, 101 .tf_fill = scteken_fill, 102 .tf_copy = scteken_copy, 103 .tf_param = scteken_param, 104 .tf_respond = scteken_respond, 105}; 106 107static int 108scteken_init(scr_stat *scp, void **softc, int code) 109{ 110 teken_stat *ts = scp->ts; 111 teken_pos_t tp; 112 113 if (*softc == NULL) { 114 if (reserved_teken_stat.ts_busy) 115 return (EINVAL); 116 *softc = &reserved_teken_stat; 117 } 118 ts = *softc; 119 120 switch (code) { 121 case SC_TE_COLD_INIT: 122 ++sc_term_scteken.te_refcount; 123 ts->ts_busy = 1; 124 /* FALLTHROUGH */ 125 case SC_TE_WARM_INIT: 126 teken_init(&ts->ts_teken, &scteken_funcs, scp); 127 128 tp.tp_row = scp->ysize; 129 tp.tp_col = scp->xsize; 130 teken_set_winsize(&ts->ts_teken, &tp); 131 132 tp.tp_row = scp->cursor_pos / scp->xsize; 133 tp.tp_col = scp->cursor_pos % scp->xsize; 134 teken_set_cursor(&ts->ts_teken, &tp); 135 break; 136 } 137 138 return (0); 139} 140 141static int 142scteken_term(scr_stat *scp, void **softc) 143{ 144 145 if (*softc == &reserved_teken_stat) { 146 *softc = NULL; 147 reserved_teken_stat.ts_busy = 0; 148 } 149 --sc_term_scteken.te_refcount; 150 151 return (0); 152} 153 154static void 155scteken_puts(scr_stat *scp, u_char *buf, int len) 156{ 157 teken_stat *ts = scp->ts; 158 159 scp->sc->write_in_progress++; 160 teken_input(&ts->ts_teken, buf, len); 161 scp->sc->write_in_progress--; 162} 163 164static int 165scteken_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 166 struct thread *td) 167{
| 53 54static sc_term_init_t scteken_init; 55static sc_term_term_t scteken_term; 56static sc_term_puts_t scteken_puts; 57static sc_term_ioctl_t scteken_ioctl; 58static sc_term_default_attr_t scteken_default_attr; 59static sc_term_clear_t scteken_clear; 60static sc_term_input_t scteken_input; 61static void scteken_nop(void); 62 63typedef struct { 64 teken_t ts_teken; 65 int ts_busy; 66} teken_stat; 67 68static teken_stat reserved_teken_stat; 69 70static sc_term_sw_t sc_term_scteken = { 71 { NULL, NULL }, 72 "scteken", /* emulator name */ 73 "teken terminal", /* description */ 74 "*", /* matching renderer */ 75 sizeof(teken_stat), /* softc size */ 76 0, 77 scteken_init, 78 scteken_term, 79 scteken_puts, 80 scteken_ioctl, 81 (sc_term_reset_t *)scteken_nop, 82 scteken_default_attr, 83 scteken_clear, 84 (sc_term_notify_t *)scteken_nop, 85 scteken_input, 86}; 87 88SCTERM_MODULE(scteken, sc_term_scteken); 89 90static tf_bell_t scteken_bell; 91static tf_cursor_t scteken_cursor; 92static tf_putchar_t scteken_putchar; 93static tf_fill_t scteken_fill; 94static tf_copy_t scteken_copy; 95static tf_param_t scteken_param; 96static tf_respond_t scteken_respond; 97 98static const teken_funcs_t scteken_funcs = { 99 .tf_bell = scteken_bell, 100 .tf_cursor = scteken_cursor, 101 .tf_putchar = scteken_putchar, 102 .tf_fill = scteken_fill, 103 .tf_copy = scteken_copy, 104 .tf_param = scteken_param, 105 .tf_respond = scteken_respond, 106}; 107 108static int 109scteken_init(scr_stat *scp, void **softc, int code) 110{ 111 teken_stat *ts = scp->ts; 112 teken_pos_t tp; 113 114 if (*softc == NULL) { 115 if (reserved_teken_stat.ts_busy) 116 return (EINVAL); 117 *softc = &reserved_teken_stat; 118 } 119 ts = *softc; 120 121 switch (code) { 122 case SC_TE_COLD_INIT: 123 ++sc_term_scteken.te_refcount; 124 ts->ts_busy = 1; 125 /* FALLTHROUGH */ 126 case SC_TE_WARM_INIT: 127 teken_init(&ts->ts_teken, &scteken_funcs, scp); 128 129 tp.tp_row = scp->ysize; 130 tp.tp_col = scp->xsize; 131 teken_set_winsize(&ts->ts_teken, &tp); 132 133 tp.tp_row = scp->cursor_pos / scp->xsize; 134 tp.tp_col = scp->cursor_pos % scp->xsize; 135 teken_set_cursor(&ts->ts_teken, &tp); 136 break; 137 } 138 139 return (0); 140} 141 142static int 143scteken_term(scr_stat *scp, void **softc) 144{ 145 146 if (*softc == &reserved_teken_stat) { 147 *softc = NULL; 148 reserved_teken_stat.ts_busy = 0; 149 } 150 --sc_term_scteken.te_refcount; 151 152 return (0); 153} 154 155static void 156scteken_puts(scr_stat *scp, u_char *buf, int len) 157{ 158 teken_stat *ts = scp->ts; 159 160 scp->sc->write_in_progress++; 161 teken_input(&ts->ts_teken, buf, len); 162 scp->sc->write_in_progress--; 163} 164 165static int 166scteken_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 167 struct thread *td) 168{
|
| 169 teken_stat *ts = scp->ts;
|
168 vid_info_t *vi;
| 170 vid_info_t *vi;
|
| 171 unsigned int attr;
|
169 170 switch (cmd) { 171 case GIO_ATTR: /* get current attributes */
| 172 173 switch (cmd) { 174 case GIO_ATTR: /* get current attributes */
|
172 *(int*)data = SC_NORM_ATTR;
| 175 *(int*)data = 176 scteken_attr(teken_get_curattr(&ts->ts_teken));
|
173 return (0); 174 case CONS_GETINFO: /* get current (virtual) console info */
| 177 return (0); 178 case CONS_GETINFO: /* get current (virtual) console info */
|
175 /* XXX: INCORRECT! */
| |
176 vi = (vid_info_t *)data; 177 if (vi->size != sizeof(struct vid_info)) 178 return EINVAL;
| 179 vi = (vid_info_t *)data; 180 if (vi->size != sizeof(struct vid_info)) 181 return EINVAL;
|
179 vi->mv_norm.fore = SC_NORM_ATTR & 0x0f; 180 vi->mv_norm.back = (SC_NORM_ATTR >> 4) & 0x0f; 181 vi->mv_rev.fore = SC_NORM_ATTR & 0x0f; 182 vi->mv_rev.back = (SC_NORM_ATTR >> 4) & 0x0f;
| 182 183 attr = scteken_attr(teken_get_defattr(&ts->ts_teken)); 184 vi->mv_norm.fore = attr & 0x0f; 185 vi->mv_norm.back = (attr >> 4) & 0x0f; 186 vi->mv_rev.fore = vi->mv_norm.back; 187 vi->mv_rev.back = vi->mv_norm.fore;
|
183 /* 184 * The other fields are filled by the upper routine. XXX 185 */ 186 return (ENOIOCTL); 187 } 188 189 return (ENOIOCTL); 190} 191 192static void 193scteken_default_attr(scr_stat *scp, int color, int rev_color) 194{ 195 teken_stat *ts = scp->ts; 196 teken_attr_t ta; 197 198 scteken_revattr(color, &ta); 199 teken_set_defattr(&ts->ts_teken, &ta); 200} 201 202static void 203scteken_clear(scr_stat *scp) 204{ 205 206 sc_move_cursor(scp, 0, 0); 207 sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8); 208 mark_all(scp); 209} 210 211static int 212scteken_input(scr_stat *scp, int c, struct tty *tp) 213{ 214 215 return FALSE; 216} 217 218static void 219scteken_nop(void) 220{ 221 222} 223 224/* 225 * libteken routines. 226 */ 227 228static const unsigned char fgcolors_normal[TC_NCOLORS] = { 229 FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 230 FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 231}; 232 233static const unsigned char fgcolors_bold[TC_NCOLORS] = { 234 FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 235 FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE, 236}; 237 238static const unsigned char bgcolors[TC_NCOLORS] = { 239 BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, 240 BG_BLUE, BG_MAGENTA, BG_CYAN, BG_LIGHTGREY, 241}; 242 243static void 244scteken_revattr(unsigned char color, teken_attr_t *a) 245{ 246 teken_color_t fg, bg; 247 248 /* 249 * XXX: Reverse conversion of syscons to teken attributes. Not 250 * realiable. Maybe we should turn it into a 1:1 mapping one of 251 * these days? 252 */ 253 254 a->ta_format = 0; 255 a->ta_fgcolor = TC_WHITE; 256 a->ta_bgcolor = TC_BLACK; 257 258#ifdef FG_BLINK 259 if (color & FG_BLINK) { 260 a->ta_format |= TF_BLINK; 261 color &= ~FG_BLINK; 262 } 263#endif /* FG_BLINK */ 264 265 for (fg = 0; fg < TC_NCOLORS; fg++) { 266 for (bg = 0; bg < TC_NCOLORS; bg++) { 267 if ((fgcolors_normal[fg] | bgcolors[bg]) == color) { 268 a->ta_fgcolor = fg; 269 a->ta_bgcolor = bg; 270 return; 271 } 272 273 if ((fgcolors_bold[fg] | bgcolors[bg]) == color) { 274 a->ta_fgcolor = fg; 275 a->ta_bgcolor = bg; 276 a->ta_format |= TF_BOLD; 277 return; 278 } 279 } 280 } 281} 282
| 188 /* 189 * The other fields are filled by the upper routine. XXX 190 */ 191 return (ENOIOCTL); 192 } 193 194 return (ENOIOCTL); 195} 196 197static void 198scteken_default_attr(scr_stat *scp, int color, int rev_color) 199{ 200 teken_stat *ts = scp->ts; 201 teken_attr_t ta; 202 203 scteken_revattr(color, &ta); 204 teken_set_defattr(&ts->ts_teken, &ta); 205} 206 207static void 208scteken_clear(scr_stat *scp) 209{ 210 211 sc_move_cursor(scp, 0, 0); 212 sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8); 213 mark_all(scp); 214} 215 216static int 217scteken_input(scr_stat *scp, int c, struct tty *tp) 218{ 219 220 return FALSE; 221} 222 223static void 224scteken_nop(void) 225{ 226 227} 228 229/* 230 * libteken routines. 231 */ 232 233static const unsigned char fgcolors_normal[TC_NCOLORS] = { 234 FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 235 FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 236}; 237 238static const unsigned char fgcolors_bold[TC_NCOLORS] = { 239 FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 240 FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE, 241}; 242 243static const unsigned char bgcolors[TC_NCOLORS] = { 244 BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, 245 BG_BLUE, BG_MAGENTA, BG_CYAN, BG_LIGHTGREY, 246}; 247 248static void 249scteken_revattr(unsigned char color, teken_attr_t *a) 250{ 251 teken_color_t fg, bg; 252 253 /* 254 * XXX: Reverse conversion of syscons to teken attributes. Not 255 * realiable. Maybe we should turn it into a 1:1 mapping one of 256 * these days? 257 */ 258 259 a->ta_format = 0; 260 a->ta_fgcolor = TC_WHITE; 261 a->ta_bgcolor = TC_BLACK; 262 263#ifdef FG_BLINK 264 if (color & FG_BLINK) { 265 a->ta_format |= TF_BLINK; 266 color &= ~FG_BLINK; 267 } 268#endif /* FG_BLINK */ 269 270 for (fg = 0; fg < TC_NCOLORS; fg++) { 271 for (bg = 0; bg < TC_NCOLORS; bg++) { 272 if ((fgcolors_normal[fg] | bgcolors[bg]) == color) { 273 a->ta_fgcolor = fg; 274 a->ta_bgcolor = bg; 275 return; 276 } 277 278 if ((fgcolors_bold[fg] | bgcolors[bg]) == color) { 279 a->ta_fgcolor = fg; 280 a->ta_bgcolor = bg; 281 a->ta_format |= TF_BOLD; 282 return; 283 } 284 } 285 } 286} 287
|
283static inline unsigned int
| 288static unsigned int
|
284scteken_attr(const teken_attr_t *a) 285{ 286 unsigned int attr = 0; 287 288 if (a->ta_format & TF_BOLD) 289 attr |= fgcolors_bold[a->ta_fgcolor]; 290 else 291 attr |= fgcolors_normal[a->ta_fgcolor]; 292 attr |= bgcolors[a->ta_bgcolor]; 293 294#ifdef FG_UNDERLINE 295 if (a->ta_format & TF_UNDERLINE) 296 attr |= FG_UNDERLINE; 297#endif /* FG_UNDERLINE */ 298#ifdef FG_BLINK 299 if (a->ta_format & TF_BLINK) 300 attr |= FG_BLINK; 301#endif /* FG_BLINK */ 302
| 289scteken_attr(const teken_attr_t *a) 290{ 291 unsigned int attr = 0; 292 293 if (a->ta_format & TF_BOLD) 294 attr |= fgcolors_bold[a->ta_fgcolor]; 295 else 296 attr |= fgcolors_normal[a->ta_fgcolor]; 297 attr |= bgcolors[a->ta_bgcolor]; 298 299#ifdef FG_UNDERLINE 300 if (a->ta_format & TF_UNDERLINE) 301 attr |= FG_UNDERLINE; 302#endif /* FG_UNDERLINE */ 303#ifdef FG_BLINK 304 if (a->ta_format & TF_BLINK) 305 attr |= FG_BLINK; 306#endif /* FG_BLINK */ 307
|
303 return (attr << 8);
| 308 return (attr);
|
304} 305 306static void 307scteken_bell(void *arg) 308{ 309 scr_stat *scp = arg; 310 311 sc_bell(scp, scp->bell_pitch, scp->bell_duration); 312} 313 314static void 315scteken_cursor(void *arg, const teken_pos_t *p) 316{ 317 scr_stat *scp = arg; 318 319 sc_move_cursor(scp, p->tp_col, p->tp_row); 320} 321 322static void 323scteken_putchar(void *arg, const teken_pos_t *tp, teken_char_t c, 324 const teken_attr_t *a) 325{ 326 scr_stat *scp = arg; 327 u_char *map; 328 u_char ch; 329 vm_offset_t p; 330 int cursor, attr; 331 332#ifdef TEKEN_UTF8 333 if (c >= 0x80) { 334 /* XXX: Don't display UTF-8 yet. */ 335 attr = (FG_YELLOW|BG_RED) << 8; 336 ch = '?'; 337 } else 338#endif /* TEKEN_UTF8 */ 339 {
| 309} 310 311static void 312scteken_bell(void *arg) 313{ 314 scr_stat *scp = arg; 315 316 sc_bell(scp, scp->bell_pitch, scp->bell_duration); 317} 318 319static void 320scteken_cursor(void *arg, const teken_pos_t *p) 321{ 322 scr_stat *scp = arg; 323 324 sc_move_cursor(scp, p->tp_col, p->tp_row); 325} 326 327static void 328scteken_putchar(void *arg, const teken_pos_t *tp, teken_char_t c, 329 const teken_attr_t *a) 330{ 331 scr_stat *scp = arg; 332 u_char *map; 333 u_char ch; 334 vm_offset_t p; 335 int cursor, attr; 336 337#ifdef TEKEN_UTF8 338 if (c >= 0x80) { 339 /* XXX: Don't display UTF-8 yet. */ 340 attr = (FG_YELLOW|BG_RED) << 8; 341 ch = '?'; 342 } else 343#endif /* TEKEN_UTF8 */ 344 {
|
340 attr = scteken_attr(a);
| 345 attr = scteken_attr(a) << 8;
|
341 ch = c; 342 } 343 344 map = scp->sc->scr_map; 345 346 cursor = tp->tp_row * scp->xsize + tp->tp_col; 347 p = sc_vtb_pointer(&scp->vtb, cursor); 348 sc_vtb_putchar(&scp->vtb, p, map[ch], attr); 349 350 mark_for_update(scp, cursor); 351 /* 352 * XXX: Why do we need this? Only marking `cursor' should be 353 * enough. Without this line, we get artifacts. 354 */ 355 mark_for_update(scp, imin(cursor + 1, scp->xsize * scp->ysize - 1)); 356} 357 358static void 359scteken_fill(void *arg, const teken_rect_t *r, teken_char_t c, 360 const teken_attr_t *a) 361{ 362 scr_stat *scp = arg; 363 u_char *map; 364 u_char ch; 365 unsigned int width; 366 int attr, row; 367 368#ifdef TEKEN_UTF8 369 if (c >= 0x80) { 370 /* XXX: Don't display UTF-8 yet. */ 371 attr = (FG_YELLOW|BG_RED) << 8; 372 ch = '?'; 373 } else 374#endif /* TEKEN_UTF8 */ 375 {
| 346 ch = c; 347 } 348 349 map = scp->sc->scr_map; 350 351 cursor = tp->tp_row * scp->xsize + tp->tp_col; 352 p = sc_vtb_pointer(&scp->vtb, cursor); 353 sc_vtb_putchar(&scp->vtb, p, map[ch], attr); 354 355 mark_for_update(scp, cursor); 356 /* 357 * XXX: Why do we need this? Only marking `cursor' should be 358 * enough. Without this line, we get artifacts. 359 */ 360 mark_for_update(scp, imin(cursor + 1, scp->xsize * scp->ysize - 1)); 361} 362 363static void 364scteken_fill(void *arg, const teken_rect_t *r, teken_char_t c, 365 const teken_attr_t *a) 366{ 367 scr_stat *scp = arg; 368 u_char *map; 369 u_char ch; 370 unsigned int width; 371 int attr, row; 372 373#ifdef TEKEN_UTF8 374 if (c >= 0x80) { 375 /* XXX: Don't display UTF-8 yet. */ 376 attr = (FG_YELLOW|BG_RED) << 8; 377 ch = '?'; 378 } else 379#endif /* TEKEN_UTF8 */ 380 {
|
376 attr = scteken_attr(a);
| 381 attr = scteken_attr(a) << 8;
|
377 ch = c; 378 } 379 380 map = scp->sc->scr_map; 381 382 if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) { 383 /* Single contiguous region to fill. */ 384 sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * scp->xsize, 385 (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize, 386 map[ch], attr); 387 } else { 388 /* Fill display line by line. */ 389 width = r->tr_end.tp_col - r->tr_begin.tp_col; 390 391 for (row = r->tr_begin.tp_row; row < r->tr_end.tp_row; row++) { 392 sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * 393 scp->xsize + r->tr_begin.tp_col, 394 width, map[ch], attr); 395 } 396 } 397 398 /* Mark begin and end positions to be refreshed. */ 399 mark_for_update(scp, 400 r->tr_begin.tp_row * scp->xsize + r->tr_begin.tp_col); 401 mark_for_update(scp, 402 (r->tr_end.tp_row - 1) * scp->xsize + (r->tr_end.tp_col - 1)); 403 sc_remove_cutmarking(scp); 404} 405 406static void 407scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p) 408{ 409 scr_stat *scp = arg; 410 unsigned int width; 411 int src, dst, end; 412 413#ifndef SC_NO_HISTORY 414 /* 415 * We count a line of input as history if we perform a copy of 416 * one whole line upward. In other words: if a line of text gets 417 * overwritten by a rectangle that's right below it. 418 */ 419 if (scp->history != NULL && 420 r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize && 421 r->tr_begin.tp_row == p->tp_row + 1) { 422 sc_hist_save_one_line(scp, p->tp_row); 423 } 424#endif 425 426 if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) { 427 /* Single contiguous region to copy. */ 428 sc_vtb_move(&scp->vtb, r->tr_begin.tp_row * scp->xsize, 429 p->tp_row * scp->xsize, 430 (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize); 431 } else { 432 /* Copy line by line. */ 433 width = r->tr_end.tp_col - r->tr_begin.tp_col; 434 435 if (p->tp_row < r->tr_begin.tp_row) { 436 /* Copy from top to bottom. */ 437 src = r->tr_begin.tp_row * scp->xsize + 438 r->tr_begin.tp_col; 439 end = r->tr_end.tp_row * scp->xsize + 440 r->tr_end.tp_col; 441 dst = p->tp_row * scp->xsize + p->tp_col; 442 443 while (src < end) { 444 sc_vtb_move(&scp->vtb, src, dst, width); 445 446 src += scp->xsize; 447 dst += scp->xsize; 448 } 449 } else { 450 /* Copy from bottom to top. */ 451 src = (r->tr_end.tp_row - 1) * scp->xsize + 452 r->tr_begin.tp_col; 453 end = r->tr_begin.tp_row * scp->xsize + 454 r->tr_begin.tp_col; 455 dst = (p->tp_row + r->tr_end.tp_row - 456 r->tr_begin.tp_row - 1) * scp->xsize + p->tp_col; 457 458 while (src >= end) { 459 sc_vtb_move(&scp->vtb, src, dst, width); 460 461 src -= scp->xsize; 462 dst -= scp->xsize; 463 } 464 } 465 } 466 467 /* Mark begin and end positions to be refreshed. */ 468 mark_for_update(scp, 469 p->tp_row * scp->xsize + p->tp_col); 470 mark_for_update(scp, 471 (p->tp_row + r->tr_end.tp_row - r->tr_begin.tp_row - 1) * 472 scp->xsize + 473 (p->tp_col + r->tr_end.tp_col - r->tr_begin.tp_col - 1)); 474 sc_remove_cutmarking(scp); 475} 476 477static void 478scteken_param(void *arg, int cmd, int value) 479{ 480 scr_stat *scp = arg; 481 482 switch (cmd) { 483 case TP_SHOWCURSOR: 484 if (value) { 485 sc_change_cursor_shape(scp, 486 CONS_RESET_CURSOR|CONS_LOCAL_CURSOR, -1, -1); 487 } else { 488 sc_change_cursor_shape(scp, 489 CONS_HIDDEN_CURSOR|CONS_LOCAL_CURSOR, -1, -1); 490 } 491 break; 492 case TP_SWITCHVT: 493 sc_switch_scr(scp->sc, value); 494 break; 495 } 496} 497 498static void 499scteken_respond(void *arg, const void *buf, size_t len) 500{ 501 scr_stat *scp = arg; 502 503 sc_respond(scp, buf, len); 504}
| 382 ch = c; 383 } 384 385 map = scp->sc->scr_map; 386 387 if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) { 388 /* Single contiguous region to fill. */ 389 sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * scp->xsize, 390 (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize, 391 map[ch], attr); 392 } else { 393 /* Fill display line by line. */ 394 width = r->tr_end.tp_col - r->tr_begin.tp_col; 395 396 for (row = r->tr_begin.tp_row; row < r->tr_end.tp_row; row++) { 397 sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * 398 scp->xsize + r->tr_begin.tp_col, 399 width, map[ch], attr); 400 } 401 } 402 403 /* Mark begin and end positions to be refreshed. */ 404 mark_for_update(scp, 405 r->tr_begin.tp_row * scp->xsize + r->tr_begin.tp_col); 406 mark_for_update(scp, 407 (r->tr_end.tp_row - 1) * scp->xsize + (r->tr_end.tp_col - 1)); 408 sc_remove_cutmarking(scp); 409} 410 411static void 412scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p) 413{ 414 scr_stat *scp = arg; 415 unsigned int width; 416 int src, dst, end; 417 418#ifndef SC_NO_HISTORY 419 /* 420 * We count a line of input as history if we perform a copy of 421 * one whole line upward. In other words: if a line of text gets 422 * overwritten by a rectangle that's right below it. 423 */ 424 if (scp->history != NULL && 425 r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize && 426 r->tr_begin.tp_row == p->tp_row + 1) { 427 sc_hist_save_one_line(scp, p->tp_row); 428 } 429#endif 430 431 if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) { 432 /* Single contiguous region to copy. */ 433 sc_vtb_move(&scp->vtb, r->tr_begin.tp_row * scp->xsize, 434 p->tp_row * scp->xsize, 435 (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize); 436 } else { 437 /* Copy line by line. */ 438 width = r->tr_end.tp_col - r->tr_begin.tp_col; 439 440 if (p->tp_row < r->tr_begin.tp_row) { 441 /* Copy from top to bottom. */ 442 src = r->tr_begin.tp_row * scp->xsize + 443 r->tr_begin.tp_col; 444 end = r->tr_end.tp_row * scp->xsize + 445 r->tr_end.tp_col; 446 dst = p->tp_row * scp->xsize + p->tp_col; 447 448 while (src < end) { 449 sc_vtb_move(&scp->vtb, src, dst, width); 450 451 src += scp->xsize; 452 dst += scp->xsize; 453 } 454 } else { 455 /* Copy from bottom to top. */ 456 src = (r->tr_end.tp_row - 1) * scp->xsize + 457 r->tr_begin.tp_col; 458 end = r->tr_begin.tp_row * scp->xsize + 459 r->tr_begin.tp_col; 460 dst = (p->tp_row + r->tr_end.tp_row - 461 r->tr_begin.tp_row - 1) * scp->xsize + p->tp_col; 462 463 while (src >= end) { 464 sc_vtb_move(&scp->vtb, src, dst, width); 465 466 src -= scp->xsize; 467 dst -= scp->xsize; 468 } 469 } 470 } 471 472 /* Mark begin and end positions to be refreshed. */ 473 mark_for_update(scp, 474 p->tp_row * scp->xsize + p->tp_col); 475 mark_for_update(scp, 476 (p->tp_row + r->tr_end.tp_row - r->tr_begin.tp_row - 1) * 477 scp->xsize + 478 (p->tp_col + r->tr_end.tp_col - r->tr_begin.tp_col - 1)); 479 sc_remove_cutmarking(scp); 480} 481 482static void 483scteken_param(void *arg, int cmd, int value) 484{ 485 scr_stat *scp = arg; 486 487 switch (cmd) { 488 case TP_SHOWCURSOR: 489 if (value) { 490 sc_change_cursor_shape(scp, 491 CONS_RESET_CURSOR|CONS_LOCAL_CURSOR, -1, -1); 492 } else { 493 sc_change_cursor_shape(scp, 494 CONS_HIDDEN_CURSOR|CONS_LOCAL_CURSOR, -1, -1); 495 } 496 break; 497 case TP_SWITCHVT: 498 sc_switch_scr(scp->sc, value); 499 break; 500 } 501} 502 503static void 504scteken_respond(void *arg, const void *buf, size_t len) 505{ 506 scr_stat *scp = arg; 507 508 sc_respond(scp, buf, len); 509}
|