/* $OpenBSD: wsemulvar.h,v 1.18 2020/09/13 10:05:46 fcambus Exp $ */ /* $NetBSD: wsemulvar.h,v 1.6 1999/01/17 15:46:15 drochner Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef _KERNEL #include struct device; struct wsdisplay_emulops; enum wsemul_resetops { WSEMUL_RESET, WSEMUL_SYNCFONT, WSEMUL_CLEARSCREEN, WSEMUL_CLEARCURSOR }; struct wsemul_ops { char name[WSEMUL_NAME_SIZE]; void *(*cnattach)(const struct wsscreen_descr *, void *, int, int, uint32_t); void *(*attach)(int, const struct wsscreen_descr *, void *, int, int, void *, uint32_t); u_int (*output)(void *, const u_char *, u_int, int); int (*translate)(void *, kbd_t, keysym_t, const u_char **); void (*detach)(void *, u_int *, u_int *); void (*reset)(void *, enum wsemul_resetops); }; /* * Structure carrying the state of multi-byte character sequences * decoding. */ struct wsemul_inputstate { u_int32_t inchar; /* character being reconstructed */ u_int mbleft; /* multibyte bytes left until char complete */ }; extern const struct wsemul_ops wsemul_dumb_ops; extern const struct wsemul_ops wsemul_sun_ops; extern const struct wsemul_ops wsemul_vt100_ops; const struct wsemul_ops *wsemul_pick(const char *); const char *wsemul_getname(int); /* * Callbacks from the emulation code to the display interface driver. */ void wsdisplay_emulbell(void *v); void wsdisplay_emulinput(void *v, const u_char *, u_int); /* * Get characters from an input stream and update the input state. * Processing stops when the stream is empty, or a complete character * sequence has been recognized, in which case it returns zero. */ int wsemul_getchar(const u_char **, u_int *, struct wsemul_inputstate *, int); /* * Keysym to UTF-8 sequence translation function. */ int wsemul_utf8_translate(u_int32_t, kbd_t, u_char *, int); /* * emulops failure abort/recovery state * * The tty layer needs a character output to be atomic. Since this may * expand to multiple emulops operations, which may fail, it is necessary * for each emulation code to keep state of its current processing, so * that if an operation fails, the whole character from the tty layer is * reported as not having been output, while it has in fact been partly * processed. * * When the tty layer will try to retransmit the character, this state * information is used to not retrig the emulops which have been issued * successfully already. * * In order to make things more confusing, there is a particular failure * case, when all characters have been processed successfully, but * displaying the cursor image fails. * * Since there might not be tty output in a while, we need to report * failure, so we pretend not having been able to issue the last character. * When the tty layer tries again to display this character (really to get * the cursor image back), it will directly be skipped. This is done with * a special state value. */ struct wsemul_abortstate { enum { ABORT_OK, ABORT_FAILED_CURSOR, ABORT_FAILED_JUMP_SCROLL, ABORT_FAILED_OTHER } state; int skip; /* emulops to skip before reaching resume point */ int done; /* emulops completed */ int lines; /* jump scroll lines */ }; /* start character processing, assuming cursor or jump scroll failure condition has been taken care of */ static inline void wsemul_resume_abort(struct wsemul_abortstate *was) { was->state = ABORT_OK; was->done = 0; } /* register processing failure points */ static inline void wsemul_abort_cursor(struct wsemul_abortstate *was) { was->state = ABORT_FAILED_CURSOR; } static inline void wsemul_abort_jump_scroll(struct wsemul_abortstate *was, int lines) { was->state = ABORT_FAILED_JUMP_SCROLL; was->skip = was->done; was->lines = lines; } static inline void wsemul_abort_other(struct wsemul_abortstate *was) { was->state = ABORT_FAILED_OTHER; was->skip = was->done; } /* initialize abortstate structure */ static inline void wsemul_reset_abortstate(struct wsemul_abortstate *was) { was->state = ABORT_OK; was->skip = 0; /* was->done = 0; */ } /* * Wrapper macro to handle failing emulops calls consistently. */ #ifdef HAVE_RESTARTABLE_EMULOPS #define WSEMULOP(rc, edp, was, rutin, args) \ do { \ if ((was)->skip != 0) { \ (was)->skip--; \ (rc) = 0; \ } else { \ (rc) = (*(edp)->emulops->rutin) args ; \ } \ if ((rc) == 0) \ (was)->done++; \ } while (0) #else #define WSEMULOP(rc, edp, was, rutin, args) \ do { \ (void)(*(edp)->emulops->rutin) args ; \ (rc) = 0; \ } while(0) #endif #endif /* _KERNEL */