wsemul_dumb.c revision 1.16
1/* $NetBSD: wsemul_dumb.c,v 1.16 2017/05/19 19:22:33 macallan Exp $ */ 2 3/* 4 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Christopher G. Demetriou 17 * for the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: wsemul_dumb.c,v 1.16 2017/05/19 19:22:33 macallan Exp $"); 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/time.h> 39#include <sys/malloc.h> 40#include <sys/fcntl.h> 41 42#include <dev/wscons/wsconsio.h> 43#include <dev/wscons/wsdisplayvar.h> 44#include <dev/wscons/wsemulvar.h> 45#include <dev/wscons/ascii.h> 46#include <dev/wscons/wsksymdef.h> 47 48void *wsemul_dumb_cnattach(const struct wsscreen_descr *, void *, 49 int, int, long); 50void *wsemul_dumb_attach(int console, const struct wsscreen_descr *, 51 void *, int, int, void *, long); 52void wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int); 53int wsemul_dumb_translate(void *cookie, keysym_t, const char **); 54void wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp); 55void wsemul_dumb_resetop(void *, enum wsemul_resetops); 56 57const struct wsemul_ops wsemul_dumb_ops = { 58 "dumb", 59 wsemul_dumb_cnattach, 60 wsemul_dumb_attach, 61 wsemul_dumb_output, 62 wsemul_dumb_translate, 63 wsemul_dumb_detach, 64 wsemul_dumb_resetop, 65 NULL, /* getmsgattrs */ 66 NULL, /* setmsgattrs */ 67 NULL /* resize */ 68}; 69 70struct wsemul_dumb_emuldata { 71 const struct wsdisplay_emulops *emulops; 72 void *emulcookie; 73 void *cbcookie; 74 u_int nrows, ncols, crow, ccol; 75 long defattr; 76}; 77 78struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata; 79 80void * 81wsemul_dumb_cnattach(const struct wsscreen_descr *type, void *cookie, 82 int ccol, int crow, long defattr) 83{ 84 struct wsemul_dumb_emuldata *edp; 85 86 edp = &wsemul_dumb_console_emuldata; 87 88 edp->emulops = type->textops; 89 edp->emulcookie = cookie; 90 edp->nrows = type->nrows; 91 edp->ncols = type->ncols; 92 edp->crow = crow; 93 edp->ccol = ccol; 94 edp->defattr = defattr; 95 edp->cbcookie = NULL; 96 97 return (edp); 98} 99 100void * 101wsemul_dumb_attach(int console, const struct wsscreen_descr *type, 102 void *cookie, int ccol, int crow, void *cbcookie, long defattr) 103{ 104 struct wsemul_dumb_emuldata *edp; 105 106 if (console) 107 edp = &wsemul_dumb_console_emuldata; 108 else { 109 edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK); 110 111 edp->emulops = type->textops; 112 edp->emulcookie = cookie; 113 edp->nrows = type->nrows; 114 edp->ncols = type->ncols; 115 edp->crow = crow; 116 edp->ccol = ccol; 117 edp->defattr = defattr; 118 } 119 120 edp->cbcookie = cbcookie; 121 122 return (edp); 123} 124 125void 126wsemul_dumb_output(void *cookie, const u_char *data, u_int count, 127 int kernel) 128{ 129 struct wsemul_dumb_emuldata *edp = cookie; 130 u_char c; 131 int n; 132 133 /* XXX */ 134 (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); 135 while (count-- > 0) { 136 c = *data++; 137 switch (c) { 138 case ASCII_BEL: 139 wsdisplay_emulbell(edp->cbcookie); 140 break; 141 142 case ASCII_BS: 143 if (edp->ccol > 0) 144 edp->ccol--; 145 break; 146 147 case ASCII_CR: 148 edp->ccol = 0; 149 break; 150 151 case ASCII_HT: 152 n = min(8 - (edp->ccol & 7), 153 edp->ncols - edp->ccol - 1); 154 (*edp->emulops->erasecols)(edp->emulcookie, 155 edp->crow, edp->ccol, n, edp->defattr); 156 edp->ccol += n; 157 break; 158 159 case ASCII_FF: 160 (*edp->emulops->eraserows)(edp->emulcookie, 0, 161 edp->nrows, edp->defattr); 162 edp->ccol = 0; 163 edp->crow = 0; 164 break; 165 166 case ASCII_VT: 167 if (edp->crow > 0) 168 edp->crow--; 169 break; 170 171 default: 172 (*edp->emulops->putchar)(edp->emulcookie, edp->crow, 173 edp->ccol, c, edp->defattr); 174 edp->ccol++; 175 176 /* if cur col is still on cur line, done. */ 177 if (edp->ccol < edp->ncols) 178 break; 179 180 /* wrap the column around. */ 181 edp->ccol = 0; 182 183 /* FALLTHRU */ 184 185 case ASCII_LF: 186 /* if the cur line isn't the last, incr and leave. */ 187 if (edp->crow < edp->nrows - 1) { 188 edp->crow++; 189 break; 190 } 191 n = 1; /* number of lines to scroll */ 192 (*edp->emulops->copyrows)(edp->emulcookie, n, 0, 193 edp->nrows - n); 194 (*edp->emulops->eraserows)(edp->emulcookie, 195 edp->nrows - n, n, edp->defattr); 196 edp->crow -= n - 1; 197 break; 198 } 199 } 200 /* XXX */ 201 (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol); 202} 203 204int 205wsemul_dumb_translate(void *cookie, keysym_t in, 206 const char **out) 207{ 208 static char c; 209 210 if (KS_GROUP(in) == KS_GROUP_Plain) { 211 /* allow ISO-1 */ 212 c = KS_VALUE(in); 213 *out = &c; 214 return (1); 215 } 216 return (0); 217} 218 219void 220wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp) 221{ 222 struct wsemul_dumb_emuldata *edp = cookie; 223 224 *crowp = edp->crow; 225 *ccolp = edp->ccol; 226 if (edp != &wsemul_dumb_console_emuldata) 227 free(edp, M_DEVBUF); 228} 229 230void 231wsemul_dumb_resetop(void *cookie, enum wsemul_resetops op) 232{ 233 struct wsemul_dumb_emuldata *edp = cookie; 234 235 switch (op) { 236 case WSEMUL_CLEARSCREEN: 237 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows, 238 edp->defattr); 239 edp->ccol = edp->crow = 0; 240 (*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0); 241 break; 242 default: 243 break; 244 } 245} 246