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
wsemul_resume_abort(struct wsemul_abortstate * was)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
wsemul_abort_cursor(struct wsemul_abortstate * was)163 wsemul_abort_cursor(struct wsemul_abortstate *was)
164 {
165 was->state = ABORT_FAILED_CURSOR;
166 }
167
168 static inline void
wsemul_abort_jump_scroll(struct wsemul_abortstate * was,int lines)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
wsemul_abort_other(struct wsemul_abortstate * was)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
wsemul_reset_abortstate(struct wsemul_abortstate * was)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