diff options
author | nyan <nyan@FreeBSD.org> | 2002-08-20 14:39:29 +0000 |
---|---|---|
committer | nyan <nyan@FreeBSD.org> | 2002-08-20 14:39:29 +0000 |
commit | 6cd21c7a13f80ae9e40123a94dabb5325167543a (patch) | |
tree | fc4eb49453d93e4c6f44172155a87cb07698c2aa /sys | |
parent | 2373503eaf44103e42274ecc8f3859ff11dbff49 (diff) | |
download | FreeBSD-src-6cd21c7a13f80ae9e40123a94dabb5325167543a.zip FreeBSD-src-6cd21c7a13f80ae9e40123a94dabb5325167543a.tar.gz |
Merged from sys/dev/syscons/syscons.c revisions 1.386 and 1.387.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/pc98/pc98/syscons.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index 6d00003..7691379 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -751,6 +751,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) ptr->mv_row = scp->ypos; ptr->mv_csz = scp->xsize; ptr->mv_rsz = scp->ysize; + ptr->mv_hsz = (scp->history != NULL) ? scp->history->vtb_rows : 0; /* * The following fields are filled by the terminal emulator. XXX * @@ -837,20 +838,58 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) case CONS_SCRSHOT: /* get a screen shot */ { - scrshot_t *ptr = (scrshot_t*)data; + int retval, hist_rsz; + size_t lsize, csize; + vm_offset_t frbp, hstp; + unsigned lnum; + scrshot_t *ptr = (scrshot_t *)data; + void *outp = ptr->buf; + s = spltty(); if (ISGRAPHSC(scp)) { splx(s); return EOPNOTSUPP; } - if (scp->xsize != ptr->xsize || scp->ysize != ptr->ysize) { + hist_rsz = (scp->history != NULL) ? scp->history->vtb_rows : 0; + if ((ptr->x + ptr->xsize) > scp->xsize || + (ptr->y + ptr->ysize) > (scp->ysize + hist_rsz)) { splx(s); return EINVAL; } - copyout ((void*)scp->vtb.vtb_buffer, ptr->buf, - ptr->xsize * ptr->ysize * sizeof(u_int16_t)); + + lsize = scp->xsize * sizeof(u_int16_t); + csize = ptr->xsize * sizeof(u_int16_t); + /* Pointer to the last line of framebuffer */ + frbp = scp->vtb.vtb_buffer + scp->ysize * lsize + ptr->x * + sizeof(u_int16_t); + /* Pointer to the last line of target buffer */ + (vm_offset_t)outp += ptr->ysize * csize; + /* Pointer to the last line of history buffer */ + if (scp->history != NULL) + hstp = scp->history->vtb_buffer + sc_vtb_tail(scp->history) * + sizeof(u_int16_t) + ptr->x * sizeof(u_int16_t); + else + hstp = NULL; + + retval = 0; + for (lnum = 0; lnum < (ptr->y + ptr->ysize); lnum++) { + if (lnum < scp->ysize) { + frbp -= lsize; + } else { + hstp -= lsize; + if (hstp < scp->history->vtb_buffer) + hstp += scp->history->vtb_rows * lsize; + frbp = hstp; + } + if (lnum < ptr->y) + continue; + (vm_offset_t)outp -= csize; + retval = copyout((void *)frbp, outp, csize); + if (retval != 0) + break; + } splx(s); - return 0; + return retval; } case VT_SETMODE: /* set screen switcher mode */ @@ -983,6 +1022,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) *(int *)data = scp->index + 1; return 0; + case VT_LOCKSWITCH: /* prevent vty switching */ + if ((*(int *)data) & 0x01) + sc->flags |= SC_SCRN_VTYLOCK; + else + sc->flags &= ~SC_SCRN_VTYLOCK; + return 0; + case KDENABIO: /* allow io operations */ error = suser(td); if (error != 0) @@ -2090,6 +2136,13 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) DPRINTF(5, ("sc0: sc_switch_scr() %d ", next_scr + 1)); + /* prevent switch if previously requested */ + if (sc->flags & SC_SCRN_VTYLOCK) { + sc_bell(sc->cur_scp, sc->cur_scp->bell_pitch, + sc->cur_scp->bell_duration); + return EPERM; + } + /* delay switch if the screen is blanked or being updated */ if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress || sc->blink_in_progress || sc->videoio_in_progress) { |