1 /* $NetBSD: wsemul_dumb.c,v 1.8 2001/10/13 15:56:15 augustss 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.8 2001/10/13 15:56:15 augustss 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 47 void *wsemul_dumb_cnattach(const struct wsscreen_descr *, void *, 48 int, int, long); 49 void *wsemul_dumb_attach(int console, const struct wsscreen_descr *, 50 void *, int, int, void *, long); 51 void wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int); 52 int wsemul_dumb_translate(void *cookie, keysym_t, char **); 53 void wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp); 54 void wsemul_dumb_resetop(void *, enum wsemul_resetops); 55 56 const struct wsemul_ops wsemul_dumb_ops = { 57 "dumb", 58 wsemul_dumb_cnattach, 59 wsemul_dumb_attach, 60 wsemul_dumb_output, 61 wsemul_dumb_translate, 62 wsemul_dumb_detach, 63 wsemul_dumb_resetop 64 }; 65 66 struct wsemul_dumb_emuldata { 67 const struct wsdisplay_emulops *emulops; 68 void *emulcookie; 69 void *cbcookie; 70 u_int nrows, ncols, crow, ccol; 71 long defattr; 72 }; 73 74 struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata; 75 76 void * 77 wsemul_dumb_cnattach(const struct wsscreen_descr *type, void *cookie, 78 int ccol, int crow, long defattr) 79 { 80 struct wsemul_dumb_emuldata *edp; 81 82 edp = &wsemul_dumb_console_emuldata; 83 84 edp->emulops = type->textops; 85 edp->emulcookie = cookie; 86 edp->nrows = type->nrows; 87 edp->ncols = type->ncols; 88 edp->crow = crow; 89 edp->ccol = ccol; 90 edp->defattr = defattr; 91 edp->cbcookie = NULL; 92 93 return (edp); 94 } 95 96 void * 97 wsemul_dumb_attach(int console, const struct wsscreen_descr *type, 98 void *cookie, int ccol, int crow, void *cbcookie, long defattr) 99 { 100 struct wsemul_dumb_emuldata *edp; 101 102 if (console) 103 edp = &wsemul_dumb_console_emuldata; 104 else { 105 edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK); 106 107 edp->emulops = type->textops; 108 edp->emulcookie = cookie; 109 edp->nrows = type->nrows; 110 edp->ncols = type->ncols; 111 edp->crow = crow; 112 edp->ccol = ccol; 113 edp->defattr = defattr; 114 } 115 116 edp->cbcookie = cbcookie; 117 118 return (edp); 119 } 120 121 void 122 wsemul_dumb_output(void *cookie, const u_char *data, u_int count, 123 int kernel /* ignored */) 124 { 125 struct wsemul_dumb_emuldata *edp = cookie; 126 u_char c; 127 int n; 128 129 /* XXX */ 130 (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); 131 while (count-- > 0) { 132 c = *data++; 133 switch (c) { 134 case ASCII_BEL: 135 wsdisplay_emulbell(edp->cbcookie); 136 break; 137 138 case ASCII_BS: 139 if (edp->ccol > 0) 140 edp->ccol--; 141 break; 142 143 case ASCII_CR: 144 edp->ccol = 0; 145 break; 146 147 case ASCII_HT: 148 n = min(8 - (edp->ccol & 7), 149 edp->ncols - edp->ccol - 1); 150 (*edp->emulops->erasecols)(edp->emulcookie, 151 edp->crow, edp->ccol, n, edp->defattr); 152 edp->ccol += n; 153 break; 154 155 case ASCII_FF: 156 (*edp->emulops->eraserows)(edp->emulcookie, 0, 157 edp->nrows, edp->defattr); 158 edp->ccol = 0; 159 edp->crow = 0; 160 break; 161 162 case ASCII_VT: 163 if (edp->crow > 0) 164 edp->crow--; 165 break; 166 167 default: 168 (*edp->emulops->putchar)(edp->emulcookie, edp->crow, 169 edp->ccol, c, edp->defattr); 170 edp->ccol++; 171 172 /* if cur col is still on cur line, done. */ 173 if (edp->ccol < edp->ncols) 174 break; 175 176 /* wrap the column around. */ 177 edp->ccol = 0; 178 179 /* FALLTHRU */ 180 181 case ASCII_LF: 182 /* if the cur line isn't the last, incr and leave. */ 183 if (edp->crow < edp->nrows - 1) { 184 edp->crow++; 185 break; 186 } 187 n = 1; /* number of lines to scroll */ 188 (*edp->emulops->copyrows)(edp->emulcookie, n, 0, 189 edp->nrows - n); 190 (*edp->emulops->eraserows)(edp->emulcookie, 191 edp->nrows - n, n, edp->defattr); 192 edp->crow -= n - 1; 193 break; 194 } 195 } 196 /* XXX */ 197 (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol); 198 } 199 200 int 201 wsemul_dumb_translate(void *cookie, keysym_t in, char **out) 202 { 203 return (0); 204 } 205 206 void 207 wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp) 208 { 209 struct wsemul_dumb_emuldata *edp = cookie; 210 211 *crowp = edp->crow; 212 *ccolp = edp->ccol; 213 if (edp != &wsemul_dumb_console_emuldata) 214 free(edp, M_DEVBUF); 215 } 216 217 void 218 wsemul_dumb_resetop(void *cookie, enum wsemul_resetops op) 219 { 220 struct wsemul_dumb_emuldata *edp = cookie; 221 222 switch (op) { 223 case WSEMUL_CLEARSCREEN: 224 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows, 225 edp->defattr); 226 edp->ccol = edp->crow = 0; 227 (*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0); 228 break; 229 default: 230 break; 231 } 232 } 233