xref: /openbsd/sys/dev/wscons/wsemulvar.h (revision 7f8d19bf)
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