1 /* $OpenBSD: wsemulvar.h,v 1.18 2020/09/13 10:05:46 fcambus 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 u_int32_t inchar; /* character being reconstructed */ 82 u_int mbleft; /* multibyte bytes left until char complete */ 83 }; 84 85 extern const struct wsemul_ops wsemul_dumb_ops; 86 extern const struct wsemul_ops wsemul_sun_ops; 87 extern const struct wsemul_ops wsemul_vt100_ops; 88 89 const struct wsemul_ops *wsemul_pick(const char *); 90 const char *wsemul_getname(int); 91 92 /* 93 * Callbacks from the emulation code to the display interface driver. 94 */ 95 void wsdisplay_emulbell(void *v); 96 void wsdisplay_emulinput(void *v, const u_char *, u_int); 97 98 /* 99 * Get characters from an input stream and update the input state. 100 * Processing stops when the stream is empty, or a complete character 101 * sequence has been recognized, in which case it returns zero. 102 */ 103 int wsemul_getchar(const u_char **, u_int *, struct wsemul_inputstate *, 104 int); 105 106 /* 107 * Keysym to UTF-8 sequence translation function. 108 */ 109 int wsemul_utf8_translate(u_int32_t, kbd_t, u_char *, int); 110 111 /* 112 * emulops failure abort/recovery state 113 * 114 * The tty layer needs a character output to be atomic. Since this may 115 * expand to multiple emulops operations, which may fail, it is necessary 116 * for each emulation code to keep state of its current processing, so 117 * that if an operation fails, the whole character from the tty layer is 118 * reported as not having been output, while it has in fact been partly 119 * processed. 120 * 121 * When the tty layer will try to retransmit the character, this state 122 * information is used to not retrig the emulops which have been issued 123 * successfully already. 124 * 125 * In order to make things more confusing, there is a particular failure 126 * case, when all characters have been processed successfully, but 127 * displaying the cursor image fails. 128 * 129 * Since there might not be tty output in a while, we need to report 130 * failure, so we pretend not having been able to issue the last character. 131 * When the tty layer tries again to display this character (really to get 132 * the cursor image back), it will directly be skipped. This is done with 133 * a special state value. 134 */ 135 136 struct wsemul_abortstate { 137 enum { 138 ABORT_OK, 139 ABORT_FAILED_CURSOR, 140 ABORT_FAILED_JUMP_SCROLL, 141 ABORT_FAILED_OTHER 142 } state; 143 int skip; /* emulops to skip before reaching resume point */ 144 int done; /* emulops completed */ 145 int lines; /* jump scroll lines */ 146 }; 147 148 /* start character processing, assuming cursor or jump scroll failure condition 149 has been taken care of */ 150 static inline void 151 wsemul_resume_abort(struct wsemul_abortstate *was) 152 { 153 was->state = ABORT_OK; 154 was->done = 0; 155 } 156 157 /* register processing failure points */ 158 static inline void 159 wsemul_abort_cursor(struct wsemul_abortstate *was) 160 { 161 was->state = ABORT_FAILED_CURSOR; 162 } 163 164 static inline void 165 wsemul_abort_jump_scroll(struct wsemul_abortstate *was, int lines) 166 { 167 was->state = ABORT_FAILED_JUMP_SCROLL; 168 was->skip = was->done; 169 was->lines = lines; 170 } 171 172 static inline void 173 wsemul_abort_other(struct wsemul_abortstate *was) 174 { 175 was->state = ABORT_FAILED_OTHER; 176 was->skip = was->done; 177 } 178 179 /* initialize abortstate structure */ 180 static inline void 181 wsemul_reset_abortstate(struct wsemul_abortstate *was) 182 { 183 was->state = ABORT_OK; 184 was->skip = 0; 185 /* was->done = 0; */ 186 } 187 188 /* 189 * Wrapper macro to handle failing emulops calls consistently. 190 */ 191 192 #ifdef HAVE_RESTARTABLE_EMULOPS 193 #define WSEMULOP(rc, edp, was, rutin, args) \ 194 do { \ 195 if ((was)->skip != 0) { \ 196 (was)->skip--; \ 197 (rc) = 0; \ 198 } else { \ 199 (rc) = (*(edp)->emulops->rutin) args ; \ 200 } \ 201 if ((rc) == 0) \ 202 (was)->done++; \ 203 } while (0) 204 #else 205 #define WSEMULOP(rc, edp, was, rutin, args) \ 206 do { \ 207 (void)(*(edp)->emulops->rutin) args ; \ 208 (rc) = 0; \ 209 } while(0) 210 #endif 211 212 #endif /* _KERNEL */ 213