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; }
void wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) { struct wsemul_sun_emuldata *edp = cookie; u_int newstate; #ifdef DIAGNOSTIC if (kernel && !edp->console) panic("wsemul_sun_output: kernel output, not console"); #endif /* XXX */ (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); for (; count > 0; data++, count--) { #ifdef JUMP_SCROLL /* * 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) wsemul_sun_jump_scroll(edp, data, count, kernel); #endif if (*data < ' ') { wsemul_sun_output_lowchars(edp, *data, kernel); continue; } if (kernel) { wsemul_sun_output_normal(edp, *data, 1); continue; } switch (newstate = edp->state) { case SUN_EMUL_STATE_NORMAL: wsemul_sun_output_normal(edp, *data, 0); break; case SUN_EMUL_STATE_HAVEESC: newstate = wsemul_sun_output_haveesc(edp, *data); break; case SUN_EMUL_STATE_CONTROL: newstate = wsemul_sun_output_control(edp, *data); break; default: #ifdef DIAGNOSTIC panic("wsemul_sun: invalid state %d", edp->state); #else /* try to recover, if things get screwed up... */ newstate = SUN_EMUL_STATE_NORMAL; wsemul_sun_output_normal(edp, *data, 0); #endif break; } edp->state = newstate; } /* XXX */ (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol); }