213 lines
6.9 KiB
C
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 */
|