-allow the "show_screen" call to the display driver to complete
asynchronously, in the same style like the process attach/detach functions -intercept the "cnpollc" call which originally went directly to the keyboard driver and keep track whether the console is in "polling" state (DDB!) -pass a NULL callback to the screen switcher and the process attach/detach functions if the console is "polling", to tell them that asynchronous completion is forbidden
This commit is contained in:
parent
c9457413cb
commit
8996199a85
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsdisplay.c,v 1.32 1999/12/01 23:22:59 augustss Exp $ */
|
||||
/* $NetBSD: wsdisplay.c,v 1.33 1999/12/06 18:52:23 drochner Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -33,7 +33,7 @@
|
||||
static const char _copyright[] __attribute__ ((unused)) =
|
||||
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
|
||||
static const char _rcsid[] __attribute__ ((unused)) =
|
||||
"$NetBSD: wsdisplay.c,v 1.32 1999/12/01 23:22:59 augustss Exp $";
|
||||
"$NetBSD: wsdisplay.c,v 1.33 1999/12/06 18:52:23 drochner Exp $";
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -199,11 +199,14 @@ static struct wsdisplay_softc *wsdisplay_console_device;
|
||||
static struct wsscreen_internal wsdisplay_console_conf;
|
||||
|
||||
static int wsdisplay_getc_dummy __P((dev_t));
|
||||
static void wsdisplay_pollc_dummy __P((dev_t, int));
|
||||
static void wsdisplay_pollc __P((dev_t, int));
|
||||
|
||||
static int wsdisplay_cons_pollmode;
|
||||
static void (*wsdisplay_cons_kbd_pollc) __P((dev_t, int));
|
||||
|
||||
static struct consdev wsdisplay_cons = {
|
||||
NULL, NULL, wsdisplay_getc_dummy, wsdisplay_cnputc,
|
||||
wsdisplay_pollc_dummy, NODEV, CN_NORMAL
|
||||
wsdisplay_pollc, NODEV, CN_NORMAL
|
||||
};
|
||||
|
||||
#ifndef WSDISPLAY_DEFAULTSCREENS
|
||||
@ -212,6 +215,7 @@ static struct consdev wsdisplay_cons = {
|
||||
int wsdisplay_defaultscreens = WSDISPLAY_DEFAULTSCREENS;
|
||||
|
||||
int wsdisplay_switch1 __P((void *, int, int));
|
||||
int wsdisplay_switch2 __P((void *, int, int));
|
||||
int wsdisplay_switch3 __P((void *, int, int));
|
||||
|
||||
int wsdisplay_clearonclose;
|
||||
@ -378,7 +382,8 @@ wsdisplay_addscreen(sc, idx, screentype, emul)
|
||||
s = spltty();
|
||||
if (!sc->sc_focus) {
|
||||
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
|
||||
scr->scr_dconf->emulcookie);
|
||||
scr->scr_dconf->emulcookie,
|
||||
0, 0, 0);
|
||||
sc->sc_focusidx = idx;
|
||||
sc->sc_focus = scr;
|
||||
}
|
||||
@ -1405,6 +1410,65 @@ wsdisplay_switch3(arg, error, waitok)
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
wsdisplay_switch2(arg, error, waitok)
|
||||
void *arg;
|
||||
int error, waitok;
|
||||
{
|
||||
struct wsdisplay_softc *sc = arg;
|
||||
int no;
|
||||
struct wsscreen *scr;
|
||||
|
||||
if (!(sc->sc_flags & SC_SWITCHPENDING)) {
|
||||
printf("wsdisplay_switch2: not switching\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
no = sc->sc_screenwanted;
|
||||
if (no < 0 || no >= WSDISPLAY_MAXSCREEN)
|
||||
panic("wsdisplay_switch2: invalid screen %d", no);
|
||||
scr = sc->sc_scr[no];
|
||||
if (!scr) {
|
||||
printf("wsdisplay_switch2: screen %d disappeared\n", no);
|
||||
error = ENXIO;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
/* try to recover, avoid recursion */
|
||||
|
||||
if (sc->sc_oldscreen == -1) {
|
||||
printf("wsdisplay_switch2: giving up\n");
|
||||
sc->sc_focus = 0;
|
||||
sc->sc_flags &= ~SC_SWITCHPENDING;
|
||||
return (error);
|
||||
}
|
||||
|
||||
sc->sc_screenwanted = sc->sc_oldscreen;
|
||||
sc->sc_oldscreen = -1;
|
||||
return (wsdisplay_switch1(arg, 0, waitok));
|
||||
}
|
||||
|
||||
sc->sc_focusidx = no;
|
||||
sc->sc_focus = scr;
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
(void) wsdisplay_update_rawkbd(sc, scr);
|
||||
#endif
|
||||
/* keyboard map??? */
|
||||
|
||||
#define wsswitch_cb3 ((void (*) __P((void *, int, int)))wsdisplay_switch3)
|
||||
if (scr->scr_syncops) {
|
||||
error = (*scr->scr_syncops->attach)(scr->scr_synccookie, waitok,
|
||||
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb3, sc);
|
||||
if (error == EAGAIN) {
|
||||
/* switch will be done asynchronously */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (wsdisplay_switch3(sc, error, waitok));
|
||||
}
|
||||
|
||||
int
|
||||
wsdisplay_switch1(arg, error, waitok)
|
||||
void *arg;
|
||||
@ -1433,27 +1497,17 @@ wsdisplay_switch1(arg, error, waitok)
|
||||
return (error);
|
||||
}
|
||||
|
||||
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
|
||||
scr->scr_dconf->emulcookie);
|
||||
sc->sc_focusidx = no;
|
||||
sc->sc_focus = scr;
|
||||
|
||||
#ifdef WSDISPLAY_COMPAT_RAWKBD
|
||||
(void) wsdisplay_update_rawkbd(sc, scr);
|
||||
#endif
|
||||
/* keyboard map??? */
|
||||
|
||||
#define wsswitch_cb3 ((void (*) __P((void *, int, int)))wsdisplay_switch3)
|
||||
if (scr->scr_syncops) {
|
||||
error = (*scr->scr_syncops->attach)(scr->scr_synccookie, waitok,
|
||||
wsswitch_cb3, sc);
|
||||
if (error == EAGAIN) {
|
||||
/* switch will be done asynchronously */
|
||||
return (0);
|
||||
}
|
||||
#define wsswitch_cb2 ((void (*) __P((void *, int, int)))wsdisplay_switch2)
|
||||
error = (*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
|
||||
scr->scr_dconf->emulcookie,
|
||||
waitok,
|
||||
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb2, sc);
|
||||
if (error == EAGAIN) {
|
||||
/* switch will be done asynchronously */
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (wsdisplay_switch3(sc, error, waitok));
|
||||
return (wsdisplay_switch2(sc, error, waitok));
|
||||
}
|
||||
|
||||
int
|
||||
@ -1495,7 +1549,7 @@ wsdisplay_switch(dev, no, waitok)
|
||||
#define wsswitch_cb1 ((void (*) __P((void *, int, int)))wsdisplay_switch1)
|
||||
if (scr->scr_syncops) {
|
||||
res = (*scr->scr_syncops->detach)(scr->scr_synccookie, waitok,
|
||||
wsswitch_cb1, sc);
|
||||
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb1, sc);
|
||||
if (res == EAGAIN) {
|
||||
/* switch will be done asynchronously */
|
||||
return (0);
|
||||
@ -1697,10 +1751,15 @@ wsdisplay_getc_dummy(dev)
|
||||
}
|
||||
|
||||
static void
|
||||
wsdisplay_pollc_dummy(dev, on)
|
||||
wsdisplay_pollc(dev, on)
|
||||
dev_t dev;
|
||||
int on;
|
||||
{
|
||||
|
||||
wsdisplay_cons_pollmode = on;
|
||||
|
||||
if (wsdisplay_cons_kbd_pollc)
|
||||
(*wsdisplay_cons_kbd_pollc)(dev, on);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1709,14 +1768,14 @@ wsdisplay_set_cons_kbd(get, poll)
|
||||
void (*poll) __P((dev_t, int));
|
||||
{
|
||||
wsdisplay_cons.cn_getc = get;
|
||||
wsdisplay_cons.cn_pollc = poll;
|
||||
wsdisplay_cons_kbd_pollc = poll;
|
||||
}
|
||||
|
||||
void
|
||||
wsdisplay_unset_cons_kbd()
|
||||
{
|
||||
wsdisplay_cons.cn_getc = wsdisplay_getc_dummy;
|
||||
wsdisplay_cons.cn_pollc = wsdisplay_pollc_dummy;
|
||||
wsdisplay_cons_kbd_pollc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsdisplay_compat_usl.c,v 1.10 1999/10/19 00:03:18 mycroft Exp $ */
|
||||
/* $NetBSD: wsdisplay_compat_usl.c,v 1.11 1999/12/06 18:52:23 drochner Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998
|
||||
@ -172,6 +172,10 @@ usl_detachproc(cookie, waitok, callback, cbarg)
|
||||
if (!usl_sync_check(sd))
|
||||
return (0);
|
||||
|
||||
/* we really need a callback */
|
||||
if (!callback)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Normally, this is called from the controlling process.
|
||||
* Is is supposed to reply with a VT_RELDISP ioctl(), so
|
||||
@ -238,6 +242,10 @@ usl_attachproc(cookie, waitok, callback, cbarg)
|
||||
if (!usl_sync_check(sd))
|
||||
return (0);
|
||||
|
||||
/* we really need a callback */
|
||||
if (!callback)
|
||||
return (EINVAL);
|
||||
|
||||
sd->s_callback = callback;
|
||||
sd->s_cbarg = cbarg;
|
||||
sd->s_flags |= SF_ATTACHPENDING;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: wsdisplayvar.h,v 1.13 1999/10/19 00:03:18 mycroft Exp $ */
|
||||
/* $NetBSD: wsdisplayvar.h,v 1.14 1999/12/06 18:52:23 drochner Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
|
||||
@ -107,7 +107,8 @@ struct wsdisplay_accessops {
|
||||
int (*alloc_screen) __P((void *, const struct wsscreen_descr *,
|
||||
void **, int *, int *, long *));
|
||||
void (*free_screen) __P((void *, void *));
|
||||
void (*show_screen) __P((void *, void *));
|
||||
int (*show_screen) __P((void *, void *, int,
|
||||
void (*) (void *, int, int), void *));
|
||||
int (*load_font) __P((void *, void *, struct wsdisplay_font *));
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user