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