void * wsemul_dumb_attach(int console, const struct wsscreen_descr *type, void *cookie, int ccol, int crow, void *cbcookie, long defattr) { struct wsemul_dumb_emuldata *edp; if (console) edp = &wsemul_dumb_console_emuldata; else { edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK); edp->emulops = type->textops; edp->emulcookie = cookie; edp->nrows = type->nrows; edp->ncols = type->ncols; edp->crow = crow; edp->ccol = ccol; edp->defattr = defattr; wsemul_reset_abortstate(&edp->abortstate); } edp->cbcookie = cbcookie; return (edp); }
void wsemul_sun_init(struct wsemul_sun_emuldata *edp, const struct wsscreen_descr *type, void *cookie, int ccol, int crow, long defattr) { edp->emulops = type->textops; edp->emulcookie = cookie; edp->scrcapabilities = type->capabilities; edp->nrows = type->nrows; edp->ncols = type->ncols; edp->crow = crow; edp->ccol = ccol; edp->defattr = defattr; wsemul_reset_abortstate(&edp->abortstate); }
void * wsemul_dumb_cnattach(const struct wsscreen_descr *type, void *cookie, int ccol, int crow, long defattr) { struct wsemul_dumb_emuldata *edp; const struct wsdisplay_emulops *emulops; edp = &wsemul_dumb_console_emuldata; edp->emulops = emulops = type->textops; edp->emulcookie = cookie; edp->nrows = type->nrows; edp->ncols = type->ncols; edp->crow = crow; edp->ccol = ccol; edp->defattr = defattr; edp->cbcookie = NULL; edp->crippled = emulops->cursor == NULL || emulops->copycols == NULL || emulops->copyrows == NULL || emulops->erasecols == NULL || emulops->eraserows == NULL; wsemul_reset_abortstate(&edp->abortstate); return (edp); }
u_int wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) { struct wsemul_sun_emuldata *edp = cookie; struct wsemul_inputstate *instate; u_int processed = 0; #ifdef HAVE_JUMP_SCROLL int lines; #endif int rc = 0; #ifdef DIAGNOSTIC if (kernel && !edp->console) panic("wsemul_sun_output: kernel output, not console"); #endif instate = kernel ? &edp->kstate : &edp->instate; switch (edp->abortstate.state) { case ABORT_FAILED_CURSOR: /* * If we could not display the cursor back, we pretended not * having been able to display the last character. But this * is a lie, so compensate here. */ data++, count--; processed++; wsemul_reset_abortstate(&edp->abortstate); break; case ABORT_OK: /* remove cursor image */ rc = (*edp->emulops->cursor) (edp->emulcookie, 0, edp->crow, edp->ccol); if (rc != 0) return 0; break; default: break; } for (;;) { #ifdef HAVE_JUMP_SCROLL switch (edp->abortstate.state) { case ABORT_FAILED_JUMP_SCROLL: /* * If we failed a previous jump scroll attempt, we * need to try to resume it with the same distance. * We can not recompute it since there might be more * bytes in the tty ring, causing a different result. */ lines = edp->abortstate.lines; break; case ABORT_OK: /* * If scrolling is not disabled and we are the bottom of * the screen, count newlines until an escape sequence * appears. */ if ((edp->state == SUN_EMUL_STATE_NORMAL || kernel) && ROWS_LEFT == 0 && edp->scrolldist != 0) lines = wsemul_sun_jump_scroll(edp, data, count, kernel); else lines = 0; break; default: /* * If we are recovering a non-scrolling failure, * do not try to scroll yet. */ lines = 0; break; } if (lines > 1) { wsemul_resume_abort(&edp->abortstate); rc = wsemul_sun_scrollup(edp, lines); if (rc != 0) { wsemul_abort_jump_scroll(&edp->abortstate, lines); return processed; } wsemul_reset_abortstate(&edp->abortstate); edp->crow--; } #endif wsemul_resume_abort(&edp->abortstate); if (wsemul_getchar(&data, &count, instate, #ifdef HAVE_UTF8_SUPPORT (edp->state == SUN_EMUL_STATE_NORMAL && !kernel) ? edp->flags & SUN_EMUL_FLAGS_UTF8 : 0 #else 0 #endif ) != 0) break; if (instate->inchar < ' ') { rc = wsemul_sun_output_lowchars(edp, instate, kernel); if (rc != 0) break; processed++; continue; } if (kernel) { rc = wsemul_sun_output_normal(edp, instate, 1); if (rc != 0) break; processed++; continue; } switch (edp->state) { case SUN_EMUL_STATE_NORMAL: rc = wsemul_sun_output_normal(edp, instate, 0); break; case SUN_EMUL_STATE_HAVEESC: rc = wsemul_sun_output_haveesc(edp, instate); break; case SUN_EMUL_STATE_CONTROL: rc = wsemul_sun_output_control(edp, instate); break; #ifdef HAVE_UTF8_SUPPORT case SUN_EMUL_STATE_PERCENT: rc = wsemul_sun_output_percent(edp, instate); break; #endif default: #ifdef DIAGNOSTIC panic("wsemul_sun: invalid state %d", edp->state); #else /* try to recover, if things get screwed up... */ edp->state = SUN_EMUL_STATE_NORMAL; rc = wsemul_sun_output_normal(edp, instate, 0); #endif break; } if (rc != 0) break; processed++; } if (rc != 0) wsemul_abort_other(&edp->abortstate); else { /* put cursor image back */ rc = (*edp->emulops->cursor) (edp->emulcookie, 1, edp->crow, edp->ccol); if (rc != 0) { /* * Fail the last character output, remembering that * only the cursor operation really needs to be done. */ wsemul_abort_cursor(&edp->abortstate); processed--; } } if (rc == 0) wsemul_reset_abortstate(&edp->abortstate); return processed; }
u_int wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int kernel) { struct wsemul_dumb_emuldata *edp = cookie; u_int processed = 0; u_char c; int n; int rc = 0; if (edp->crippled) { while (count-- > 0) { wsemul_resume_abort(&edp->abortstate); c = *data++; if (c == ASCII_BEL) wsdisplay_emulbell(edp->cbcookie); else { WSEMULOP(rc, edp, &edp->abortstate, putchar, (edp->emulcookie, 0, 0, c, 0)); if (rc != 0) break; } processed++; } if (rc != 0) wsemul_abort_other(&edp->abortstate); return processed; } switch (edp->abortstate.state) { case ABORT_FAILED_CURSOR: /* * If we could not display the cursor back, we pretended not * having been able to display the last character. But this * is a lie, so compensate here. */ data++, count--; processed++; wsemul_reset_abortstate(&edp->abortstate); break; case ABORT_OK: /* remove cursor image */ rc = (*edp->emulops->cursor) (edp->emulcookie, 0, edp->crow, edp->ccol); if (rc != 0) return 0; break; default: break; } while (count-- > 0) { wsemul_resume_abort(&edp->abortstate); c = *data++; switch (c) { case ASCII_BEL: wsdisplay_emulbell(edp->cbcookie); break; case ASCII_BS: if (edp->ccol > 0) edp->ccol--; break; case ASCII_CR: edp->ccol = 0; break; case ASCII_HT: n = min(8 - (edp->ccol & 7), edp->ncols - edp->ccol - 1); WSEMULOP(rc, edp, &edp->abortstate, erasecols, (edp->emulcookie, edp->crow, edp->ccol, n, edp->defattr)); if (rc != 0) break; edp->ccol += n; break; case ASCII_FF: WSEMULOP(rc, edp, &edp->abortstate, eraserows, (edp->emulcookie, 0, edp->nrows, edp->defattr)); if (rc != 0) break; edp->ccol = 0; edp->crow = 0; break; case ASCII_VT: if (edp->crow > 0) edp->crow--; break; default: WSEMULOP(rc, edp, &edp->abortstate, putchar, (edp->emulcookie, edp->crow, edp->ccol, c, edp->defattr)); if (rc != 0) break; edp->ccol++; /* if cur col is still on cur line, done. */ if (edp->ccol < edp->ncols) break; /* wrap the column around. */ edp->ccol = 0; /* FALLTHROUGH */ case ASCII_LF: /* if the cur line isn't the last, incr and leave. */ if (edp->crow < edp->nrows - 1) { edp->crow++; break; } n = 1; /* number of lines to scroll */ WSEMULOP(rc, edp, &edp->abortstate, copyrows, (edp->emulcookie, n, 0, edp->nrows - n)); if (rc == 0) WSEMULOP(rc, edp, &edp->abortstate, eraserows, (edp->emulcookie, edp->nrows - n, n, edp->defattr)); if (rc != 0) { /* undo wrap-at-eol processing if necessary */ if (c != ASCII_LF) edp->ccol = edp->ncols - 1; break; } edp->crow -= n - 1; break; } if (rc != 0) break; processed++; } if (rc != 0) wsemul_abort_other(&edp->abortstate); else { /* put cursor image back */ rc = (*edp->emulops->cursor) (edp->emulcookie, 1, edp->crow, edp->ccol); if (rc != 0) { /* * Fail the last character output, remembering that * only the cursor operation really needs to be done. */ wsemul_abort_cursor(&edp->abortstate); processed--; } } if (rc == 0) wsemul_reset_abortstate(&edp->abortstate); return processed; }