diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 111 |
1 files changed, 69 insertions, 42 deletions
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 9e7df4b852f..d0b2aca5b6e 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplay.c,v 1.122 2015/05/07 00:16:25 jsg Exp $ */ +/* $OpenBSD: wsdisplay.c,v 1.123 2015/05/08 19:17:20 miod Exp $ */ /* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */ /* @@ -144,6 +144,8 @@ void wsdisplay_suspend_device(struct device *); void wsdisplay_addscreen_print(struct wsdisplay_softc *, int, int); void wsdisplay_closescreen(struct wsdisplay_softc *, struct wsscreen *); int wsdisplay_delscreen(struct wsdisplay_softc *, int, int); + +void wsdisplay_burner_setup(struct wsdisplay_softc *, struct wsscreen *); void wsdisplay_burner(void *v); struct wsdisplay_softc { @@ -160,10 +162,10 @@ struct wsdisplay_softc { #ifdef HAVE_BURNER_SUPPORT struct timeout sc_burner; - int sc_burnoutintvl; - int sc_burninintvl; - int sc_burnout; - int sc_burnman; + int sc_burnoutintvl; /* delay before blanking */ + int sc_burninintvl; /* delay before unblanking */ + int sc_burnout; /* current sc_burner delay */ + int sc_burnman; /* nonzero if screen blanked */ int sc_burnflags; #endif @@ -480,12 +482,12 @@ wsdisplay_delscreen(struct wsdisplay_softc *sc, int idx, int flags) */ s = spltty(); if (sc->sc_focus == scr) { - sc->sc_focus = 0; + sc->sc_focus = NULL; #ifdef WSDISPLAY_COMPAT_RAWKBD wsdisplay_update_rawkbd(sc, 0); #endif } - sc->sc_scr[idx] = 0; + sc->sc_scr[idx] = NULL; splx(s); /* @@ -1142,24 +1144,11 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr, /* clear cursor */ (*scr->scr_dconf->wsemul->reset) (scr->scr_dconf->wsemulcookie, WSEMUL_CLEARCURSOR); + } #ifdef HAVE_BURNER_SUPPORT - /* enable video _immediately_ if it nedes to be... */ - if (sc->sc_burnman) - wsdisplay_burner(sc); - /* ...and disable the burner while X is running */ - if (sc->sc_burnout) { - timeout_del(&sc->sc_burner); - sc->sc_burnout = 0; - } - } else { - /* reenable the burner after exiting from X */ - if (!sc->sc_burnman) { - sc->sc_burnout = sc->sc_burnoutintvl; - wsdisplay_burn(sc, sc->sc_burnflags); - } + wsdisplay_burner_setup(sc, scr); #endif - } (void)(*sc->sc_accessops->ioctl)(sc->sc_accesscookie, cmd, data, flag, p); @@ -1171,7 +1160,7 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr, #define d ((struct wsdisplay_font *)data) if (!sc->sc_accessops->load_font) return (EINVAL); - d->data = 0; + d->data = NULL; error = (*sc->sc_accessops->load_font)(sc->sc_accesscookie, scr->scr_dconf->emulcookie, d); if (!error) @@ -1203,40 +1192,46 @@ wsdisplay_internal_ioctl(struct wsdisplay_softc *sc, struct wsscreen *scr, return (0); case WSDISPLAYIO_SBURNER: + { + struct wsscreen *active; + if (d->flags & ~(WSDISPLAY_BURN_VBLANK | WSDISPLAY_BURN_KBD | WSDISPLAY_BURN_MOUSE | WSDISPLAY_BURN_OUTPUT)) - error = EINVAL; - else { - error = 0; - sc->sc_burnflags = d->flags; - /* disable timeout if necessary */ - if ((sc->sc_burnflags & (WSDISPLAY_BURN_OUTPUT | - WSDISPLAY_BURN_KBD | WSDISPLAY_BURN_MOUSE)) == 0) { - if (sc->sc_burnout) - timeout_del(&sc->sc_burner); - } + return EINVAL; + + error = 0; + sc->sc_burnflags = d->flags; + /* disable timeout if necessary */ + if ((sc->sc_burnflags & (WSDISPLAY_BURN_OUTPUT | + WSDISPLAY_BURN_KBD | WSDISPLAY_BURN_MOUSE)) == 0) { + if (sc->sc_burnout) + timeout_del(&sc->sc_burner); } + + active = sc->sc_focus; + if (active == NULL) + active = scr; + if (d->on) { - error = 0; sc->sc_burninintvl = hz * d->on / 1000; if (sc->sc_burnman) { sc->sc_burnout = sc->sc_burninintvl; /* reinit timeout if changed */ - if ((scr->scr_flags & SCR_GRAPHICS) == 0) + if ((active->scr_flags & SCR_GRAPHICS) == 0) wsdisplay_burn(sc, sc->sc_burnflags); } } if (d->off) { - error = 0; sc->sc_burnoutintvl = hz * d->off / 1000; if (!sc->sc_burnman) { sc->sc_burnout = sc->sc_burnoutintvl; /* reinit timeout if changed */ - if ((scr->scr_flags & SCR_GRAPHICS) == 0) + if ((active->scr_flags & SCR_GRAPHICS) == 0) wsdisplay_burn(sc, sc->sc_burnflags); } } return (error); + } #undef d #endif /* HAVE_BURNER_SUPPORT */ case WSDISPLAYIO_GETSCREEN: @@ -1664,7 +1659,7 @@ wsdisplay_switch3(void *arg, int error, int waitok) if (sc->sc_oldscreen == WSDISPLAY_NULLSCREEN) { printf("wsdisplay_switch3: giving up\n"); - sc->sc_focus = 0; + sc->sc_focus = NULL; #ifdef WSDISPLAY_COMPAT_RAWKBD wsdisplay_update_rawkbd(sc, 0); #endif @@ -1688,6 +1683,11 @@ wsdisplay_switch3(void *arg, int error, int waitok) CLR(sc->sc_flags, SC_SWITCHPENDING); +#ifdef HAVE_BURNER_SUPPORT + if (!error) + wsdisplay_burner_setup(sc, scr); +#endif + if (!error && (scr->scr_flags & SCR_WAITACTIVE)) wakeup(scr); return (error); @@ -1719,7 +1719,7 @@ wsdisplay_switch2(void *arg, int error, int waitok) if (sc->sc_oldscreen == WSDISPLAY_NULLSCREEN) { printf("wsdisplay_switch2: giving up\n"); - sc->sc_focus = 0; + sc->sc_focus = NULL; CLR(sc->sc_flags, SC_SWITCHPENDING); return (error); } @@ -1769,7 +1769,7 @@ wsdisplay_switch1(void *arg, int error, int waitok) if (no == WSDISPLAY_NULLSCREEN) { CLR(sc->sc_flags, SC_SWITCHPENDING); if (!error) { - sc->sc_focus = 0; + sc->sc_focus = NULL; } wakeup(sc); return (error); @@ -1916,7 +1916,7 @@ wsscreen_detach_sync(struct wsscreen *scr) { if (!scr->scr_syncops) return (EINVAL); - scr->scr_syncops = 0; + scr->scr_syncops = NULL; return (0); } @@ -2112,7 +2112,7 @@ wsdisplay_unset_cons_kbd(void) { wsdisplay_cons.cn_getc = wsdisplay_getc_dummy; wsdisplay_cons.cn_bell = NULL; - wsdisplay_cons_kbd_pollc = 0; + wsdisplay_cons_kbd_pollc = NULL; } /* @@ -2258,6 +2258,33 @@ wsscrollback(void *arg, int op) #endif #ifdef HAVE_BURNER_SUPPORT +/* + * Update screen burner behaviour after either a screen focus change or + * a screen mode change. + * This is needed to allow X11 to manage screen blanking without any + * interference from the kernel. + */ +void +wsdisplay_burner_setup(struct wsdisplay_softc *sc, struct wsscreen *scr) +{ + if (scr->scr_flags & SCR_GRAPHICS) { + /* enable video _immediately_ if it needs to be... */ + if (sc->sc_burnman) + wsdisplay_burner(sc); + /* ...and disable the burner while X is running */ + if (sc->sc_burnout) { + timeout_del(&sc->sc_burner); + sc->sc_burnout = 0; + } + } else { + /* reenable the burner after exiting from X */ + if (!sc->sc_burnman) { + sc->sc_burnout = sc->sc_burnoutintvl; + wsdisplay_burn(sc, sc->sc_burnflags); + } + } +} + void wsdisplay_burn(void *v, u_int flags) { |