1 /* $OpenBSD: wsemulvar.h,v 1.20 2024/11/05 08:12:08 miod Exp $ */ 2 /* $NetBSD: wsemulvar.h,v 1.6 1999/01/17 15:46:15 drochner Exp $ */ 3 4 /* 5 * Copyright (c) 2009 Miodrag Vallat. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 /* 20 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the above copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * This product includes software developed by Christopher G. Demetriou 33 * for the NetBSD Project. 34 * 4. The name of the author may not be used to endorse or promote products 35 * derived from this software without specific prior written permission 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 38 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 40 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 43 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 44 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 46 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47 */ 48 49 #ifdef _KERNEL 50 51 #include <dev/wscons/wscons_features.h> 52 53 struct device; 54 struct wsdisplay_emulops; 55 56 enum wsemul_resetops { 57 WSEMUL_RESET, 58 WSEMUL_SYNCFONT, 59 WSEMUL_CLEARSCREEN, 60 WSEMUL_CLEARCURSOR 61 }; 62 63 struct wsemul_ops { 64 char name[WSEMUL_NAME_SIZE]; 65 66 void *(*cnattach)(const struct wsscreen_descr *, void *, 67 int, int, uint32_t); 68 void *(*attach)(int, const struct wsscreen_descr *, void *, 69 int, int, void *, uint32_t); 70 u_int (*output)(void *, const u_char *, u_int, int); 71 int (*translate)(void *, kbd_t, keysym_t, const u_char **); 72 void (*detach)(void *, u_int *, u_int *); 73 void (*reset)(void *, enum wsemul_resetops); 74 }; 75 76 /* 77 * Structure carrying the state of multi-byte character sequences 78 * decoding. 79 */ 80 struct wsemul_inputstate { 81 uint32_t inchar; /* character being reconstructed */ 82 uint32_t lbound; /* lower bound of above */ 83 u_int mbleft; /* multibyte bytes left until char complete */ 84 85 uint32_t last_output; /* last printable character */ 86 /* (used by vt100 emul only) */ 87 }; 88 89 extern const struct wsemul_ops wsemul_dumb_ops; 90 extern const struct wsemul_ops wsemul_sun_ops; 91 extern const struct wsemul_ops wsemul_vt100_ops; 92 93 const struct wsemul_ops *wsemul_pick(const char *); 94 const char *wsemul_getname(int); 95 96 /* 97 * Callbacks from the emulation code to the display interface driver. 98 */ 99 void wsdisplay_emulbell(void *v); 100 void wsdisplay_emulinput(void *v, const u_char *, u_int); 101 102 /* 103 * Get characters from an input stream and update the input state. 104 * Processing stops when the stream is empty, or a complete character 105 * sequence has been recognized, in which case it returns zero. 106 */ 107 int wsemul_getchar(const u_char **, u_int *, struct wsemul_inputstate *, 108 int); 109 110 /* 111 * Keysym to UTF-8 sequence translation function. 112 */ 113 int wsemul_utf8_translate(u_int32_t, kbd_t, u_char *, int); 114 115 /* 116 * emulops failure abort/recovery state 117 * 118 * The tty layer needs a character output to be atomic. Since this may 119 * expand to multiple emulops operations, which may fail, it is necessary 120 * for each emulation code to keep state of its current processing, so 121 * that if an operation fails, the whole character from the tty layer is 122 * reported as not having been output, while it has in fact been partly 123 * processed. 124 * 125 * When the tty layer will try to retransmit the character, this state 126 * information is used to not retrig the emulops which have been issued 127 * successfully already. 128 * 129 * In order to make things more confusing, there is a particular failure 130 * case, when all characters have been processed successfully, but 131 * displaying the cursor image fails. 132 * 133 * Since there might not be tty output in a while, we need to report 134 * failure, so we pretend not having been able to issue the last character. 135 * When the tty layer tries again to display this character (really to get 136 * the cursor image back), it will directly be skipped. This is done with 137 * a special state value. 138 */ 139 140 struct wsemul_abortstate { 141 enum { 142 ABORT_OK, 143 ABORT_FAILED_CURSOR, 144 ABORT_FAILED_JUMP_SCROLL, 145 ABORT_FAILED_OTHER 146 } state; 147 int skip; /* emulops to skip before reaching resume point */ 148 int done; /* emulops completed */ 149 int lines; /* jump scroll lines */ 150 }; 151 152 /* start character processing, assuming cursor or jump scroll failure condition 153 has been taken care of */ 154 static inline void 155 wsemul_resume_abort(struct wsemul_abortstate *was) 156 { 157 was->state = ABORT_OK; 158 was->done = 0; 159 } 160 161 /* register processing failure points */ 162 static inline void 163 wsemul_abort_cursor(struct wsemul_abortstate *was) 164 { 165 was->state = ABORT_FAILED_CURSOR; 166 } 167 168 static inline void 169 wsemul_abort_jump_scroll(struct wsemul_abortstate *was, int lines) 170 { 171 was->state = ABORT_FAILED_JUMP_SCROLL; 172 was->skip = was->done; 173 was->lines = lines; 174 } 175 176 static inline void 177 wsemul_abort_other(struct wsemul_abortstate *was) 178 { 179 was->state = ABORT_FAILED_OTHER; 180 was->skip = was->done; 181 } 182 183 /* initialize abortstate structure */ 184 static inline void 185 wsemul_reset_abortstate(struct wsemul_abortstate *was) 186 { 187 was->state = ABORT_OK; 188 was->skip = 0; 189 /* was->done = 0; */ 190 } 191 192 /* 193 * Wrapper macro to handle failing emulops calls consistently. 194 */ 195 196 #ifdef HAVE_RESTARTABLE_EMULOPS 197 #define WSEMULOP(rc, edp, was, rutin, args) \ 198 do { \ 199 if ((was)->skip != 0) { \ 200 (was)->skip--; \ 201 (rc) = 0; \ 202 } else { \ 203 (rc) = (*(edp)->emulops->rutin) args ; \ 204 } \ 205 if ((rc) == 0) \ 206 (was)->done++; \ 207 } while (0) 208 #else 209 #define WSEMULOP(rc, edp, was, rutin, args) \ 210 do { \ 211 (void)(*(edp)->emulops->rutin) args ; \ 212 (rc) = 0; \ 213 } while(0) 214 #endif 215 216 #endif /* _KERNEL */ 217