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