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