src/sys/dev/wscons/wsemulvar.h

213 lines
6.9 KiB
C

/* $OpenBSD: wsemulvar.h,v 1.19 2023/03/06 17:14:44 miod Exp $ */
/* $NetBSD: wsemulvar.h,v 1.6 1999/01/17 15:46:15 drochner Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _KERNEL
#include <dev/wscons/wscons_features.h>
struct device;
struct wsdisplay_emulops;
enum wsemul_resetops {
WSEMUL_RESET,
WSEMUL_SYNCFONT,
WSEMUL_CLEARSCREEN,
WSEMUL_CLEARCURSOR
};
struct wsemul_ops {
char name[WSEMUL_NAME_SIZE];
void *(*cnattach)(const struct wsscreen_descr *, void *,
int, int, uint32_t);
void *(*attach)(int, const struct wsscreen_descr *, void *,
int, int, void *, uint32_t);
u_int (*output)(void *, const u_char *, u_int, int);
int (*translate)(void *, kbd_t, keysym_t, const u_char **);
void (*detach)(void *, u_int *, u_int *);
void (*reset)(void *, enum wsemul_resetops);
};
/*
* Structure carrying the state of multi-byte character sequences
* decoding.
*/
struct wsemul_inputstate {
uint32_t inchar; /* character being reconstructed */
uint32_t lbound; /* lower bound of above */
u_int mbleft; /* multibyte bytes left until char complete */
};
extern const struct wsemul_ops wsemul_dumb_ops;
extern const struct wsemul_ops wsemul_sun_ops;
extern const struct wsemul_ops wsemul_vt100_ops;
const struct wsemul_ops *wsemul_pick(const char *);
const char *wsemul_getname(int);
/*
* Callbacks from the emulation code to the display interface driver.
*/
void wsdisplay_emulbell(void *v);
void wsdisplay_emulinput(void *v, const u_char *, u_int);
/*
* Get characters from an input stream and update the input state.
* Processing stops when the stream is empty, or a complete character
* sequence has been recognized, in which case it returns zero.
*/
int wsemul_getchar(const u_char **, u_int *, struct wsemul_inputstate *,
int);
/*
* Keysym to UTF-8 sequence translation function.
*/
int wsemul_utf8_translate(u_int32_t, kbd_t, u_char *, int);
/*
* emulops failure abort/recovery state
*
* The tty layer needs a character output to be atomic. Since this may
* expand to multiple emulops operations, which may fail, it is necessary
* for each emulation code to keep state of its current processing, so
* that if an operation fails, the whole character from the tty layer is
* reported as not having been output, while it has in fact been partly
* processed.
*
* When the tty layer will try to retransmit the character, this state
* information is used to not retrig the emulops which have been issued
* successfully already.
*
* In order to make things more confusing, there is a particular failure
* case, when all characters have been processed successfully, but
* displaying the cursor image fails.
*
* Since there might not be tty output in a while, we need to report
* failure, so we pretend not having been able to issue the last character.
* When the tty layer tries again to display this character (really to get
* the cursor image back), it will directly be skipped. This is done with
* a special state value.
*/
struct wsemul_abortstate {
enum {
ABORT_OK,
ABORT_FAILED_CURSOR,
ABORT_FAILED_JUMP_SCROLL,
ABORT_FAILED_OTHER
} state;
int skip; /* emulops to skip before reaching resume point */
int done; /* emulops completed */
int lines; /* jump scroll lines */
};
/* start character processing, assuming cursor or jump scroll failure condition
has been taken care of */
static inline void
wsemul_resume_abort(struct wsemul_abortstate *was)
{
was->state = ABORT_OK;
was->done = 0;
}
/* register processing failure points */
static inline void
wsemul_abort_cursor(struct wsemul_abortstate *was)
{
was->state = ABORT_FAILED_CURSOR;
}
static inline void
wsemul_abort_jump_scroll(struct wsemul_abortstate *was, int lines)
{
was->state = ABORT_FAILED_JUMP_SCROLL;
was->skip = was->done;
was->lines = lines;
}
static inline void
wsemul_abort_other(struct wsemul_abortstate *was)
{
was->state = ABORT_FAILED_OTHER;
was->skip = was->done;
}
/* initialize abortstate structure */
static inline void
wsemul_reset_abortstate(struct wsemul_abortstate *was)
{
was->state = ABORT_OK;
was->skip = 0;
/* was->done = 0; */
}
/*
* Wrapper macro to handle failing emulops calls consistently.
*/
#ifdef HAVE_RESTARTABLE_EMULOPS
#define WSEMULOP(rc, edp, was, rutin, args) \
do { \
if ((was)->skip != 0) { \
(was)->skip--; \
(rc) = 0; \
} else { \
(rc) = (*(edp)->emulops->rutin) args ; \
} \
if ((rc) == 0) \
(was)->done++; \
} while (0)
#else
#define WSEMULOP(rc, edp, was, rutin, args) \
do { \
(void)(*(edp)->emulops->rutin) args ; \
(rc) = 0; \
} while(0)
#endif
#endif /* _KERNEL */