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