summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>2000-09-01 05:46:03 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>2000-09-01 05:46:03 +0000
commit3792ae36e016293db570ba44569964b6f1958cf1 (patch)
treedb694f9e74727ef1d7aecfc1af5a4ff2f0bef847 /sys/arch/i386
parent001402bb9c907b93d531c87f15f4ce0f9f4bdc4c (diff)
Kernel support for new PCVT console mouse features.
- Basic cut/paste functionality. - Wheel mouse support (wheel rolls page-by-page through scrollback buffer). - Copybuffer ownership. i.e., if User X logs in the console and selects text, when User Y logs in later the buffer cannot be pasted. Big thanks to Jean-Baptiste Marchand, Julien Montagne, and Jerome Verdon for implementing this.
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/conf/files.i3863
-rw-r--r--sys/arch/i386/isa/pcvt/Util/Makefile6
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_drv.c55
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ext.c9
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_hdr.h28
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ioctl.h10
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_kbd.c128
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_mouse.c723
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_mouse.h96
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_out.c15
10 files changed, 1041 insertions, 32 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index 3652a1ae64a..29f86df4b78 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.70 2000/08/17 20:15:33 mickey Exp $
+# $OpenBSD: files.i386,v 1.71 2000/09/01 05:46:01 aaron Exp $
# $NetBSD: files.i386,v 1.73 1996/05/07 00:58:36 thorpej Exp $
#
# new style config file for i386 architecture
@@ -144,6 +144,7 @@ attach vt at isa
file arch/i386/isa/pcvt/pcvt_drv.c vt needs-flag
file arch/i386/isa/pcvt/pcvt_ext.c vt needs-flag
file arch/i386/isa/pcvt/pcvt_kbd.c vt needs-flag
+file arch/i386/isa/pcvt/pcvt_mouse.c vt needs-flag
file arch/i386/isa/pcvt/pcvt_out.c vt needs-flag
file arch/i386/isa/pcvt/pcvt_sup.c vt needs-flag
file arch/i386/isa/pcvt/pcvt_vtf.c vt needs-flag
diff --git a/sys/arch/i386/isa/pcvt/Util/Makefile b/sys/arch/i386/isa/pcvt/Util/Makefile
index 4680544fa44..8e3fa97792c 100644
--- a/sys/arch/i386/isa/pcvt/Util/Makefile
+++ b/sys/arch/i386/isa/pcvt/Util/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.6 2000/05/29 08:17:32 deraadt Exp $
+# $OpenBSD: Makefile,v 1.7 2000/09/01 05:46:02 aaron Exp $
SUBDIR= keycap cursor fontedit kcon loadfont scon \
userkeys vttest ispcvt pcvtdoc fed
@@ -16,5 +16,9 @@ includes:
${DESTDIR}/usr/include/machine/pcvt_ioctl.h > /dev/null 2>&1 || \
install -c -o ${BINOWN} -g ${BINGRP} -m 444 ../pcvt_ioctl.h \
${DESTDIR}/usr/include/machine
+ -cd ${.CURDIR}; cmp -s ../pcvt_mouse.h \
+ ${DESTDIR}/usr/include/machine/pcvt_mouse.h > /dev/null 2>&1 || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ../pcvt_mouse.h \
+ ${DESTDIR}/usr/include/machine
.include <bsd.subdir.mk>
diff --git a/sys/arch/i386/isa/pcvt/pcvt_drv.c b/sys/arch/i386/isa/pcvt/pcvt_drv.c
index a816ef307cb..f92fdf6c7bc 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_drv.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_drv.c,v 1.30 2000/07/19 13:39:34 art Exp $ */
+/* $OpenBSD: pcvt_drv.c,v 1.31 2000/09/01 05:46:01 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
*
@@ -97,12 +97,6 @@ void pccnpollc(Dev_t, int);
int pcprobe(struct device *, void *, void *);
void pcattach(struct device *, struct device *, void *);
-
-#if PCVT_KBD_FIFO
-struct timeout pcvt_to;
-void pcvt_timeout(void *);
-#endif
-
int
pcprobe(struct device *parent, void *match, void *aux)
{
@@ -185,10 +179,6 @@ pcattach(struct device *parent, struct device *self, void *aux)
async_update();
-#if PCVT_KBD_FIFO
- timeout_set(&pcvt_to, pcvt_timeout, NULL);
-#endif
-
sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
IPL_TTY, pcintr, (void *)0, sc->sc_dev.dv_xname);
@@ -229,6 +219,10 @@ pcopen(Dev_t dev, int flag, int mode, struct proc *p)
vsx = &vs[i];
+ if (i == PCVTCTL_MINOR) {
+ return (0);
+ }
+
if((tp = get_pccons(dev)) == NULL)
return ENXIO;
@@ -342,6 +336,9 @@ pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
register int error;
register struct tty *tp;
+ if((error = mouse_ioctl(dev, cmd, data, flag, p)) >= 0)
+ return (error);
+
if((tp = get_pccons(dev)) == NULL)
return(ENXIO);
@@ -350,7 +347,7 @@ pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* sessions are a suspicious wish. If you really need this make the
* appropriate variables arrays
*/
-
+
if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0)
return (error == PCVT_ERESTART) ? ERESTART : error;
@@ -395,16 +392,19 @@ u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
int pcvt_kbd_wptr = 0;
int pcvt_kbd_rptr = 0;
short pcvt_kbd_count= 0;
+static u_char pcvt_timeout_scheduled;
-void
+static void
pcvt_timeout(void *arg)
{
+ int s;
u_char *cp;
+ pcvt_timeout_scheduled = 0;
+
#if PCVT_SCREENSAVER
pcvt_scrnsv_reset();
#endif /* PCVT_SCREENSAVER */
-
while (pcvt_kbd_count) {
if ((cp = sgetc(1)) && (vs[current_video_screen].openf)) {
#if PCVT_NULLCHARS
@@ -420,6 +420,13 @@ pcvt_timeout(void *arg)
(*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff,
pcconsp);
}
+
+ s = spltty();
+
+ if (!pcvt_kbd_count)
+ pcvt_timeout_scheduled = 0;
+
+ splx(s);
}
return;
@@ -442,7 +449,6 @@ pcintr(void *arg)
#if PCVT_SCREENSAVER
pcvt_scrnsv_reset();
#endif /* PCVT_SCREENSAVER */
-
#if PCVT_KBD_FIFO
if (kbd_polling) {
if(sgetc(1) == 0)
@@ -473,8 +479,11 @@ pcintr(void *arg)
}
if (ret == 1) { /* got data from keyboard ? */
- if (!timeout_pending(&pcvt_to)) {/* if not already active .. */
- timeout_add(&pcvt_to, 1);
+ if (!pcvt_timeout_scheduled) { /* if not already active .. */
+ s = spltty();
+ pcvt_timeout_scheduled = 1; /* flag active */
+ timeout((TIMEOUT_FUNC_T)pcvt_timeout, (caddr_t) 0, 1);
+ splx(s);
}
}
return (ret);
@@ -534,6 +543,14 @@ pcstart(register struct tty *tp)
while ((len = q_to_b(&tp->t_outq, buf, PCVT_PCBURST)) != 0) {
if (vs[minor(tp->t_dev)].scrolling)
sgetc(31337);
+ if (vsp == &vs[minor(tp->t_dev)]) {
+ if (IS_SEL_EXISTS(vsp)) {
+ /* hides a potential selection */
+ remove_selection();
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ mouse_hide(); /* hides a potential mouse cursor */
+ }
sput(&buf[0], 0, len, minor(tp->t_dev));
}
@@ -542,7 +559,7 @@ pcstart(register struct tty *tp)
tp->t_state &= ~TS_BUSY;
tp->t_state |= TS_TIMEOUT;
- timeout_add(&tp->t_rstrt_to, 1);
+ timeout(ttrstrt, tp, 1);
if (tp->t_outq.c_cc <= tp->t_lowat) {
low:
@@ -630,7 +647,7 @@ pccngetc(Dev_t dev)
cp = sgetc(0);
splx(s);
async_update();
-
+
/* this belongs to cons.c */
if (*cp == '\r')
return('\n');
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ext.c b/sys/arch/i386/isa/pcvt/pcvt_ext.c
index 7088edb424f..d7e3ca381dd 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_ext.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_ext.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_ext.c,v 1.26 1999/12/01 09:59:59 deraadt Exp $ */
+/* $OpenBSD: pcvt_ext.c,v 1.27 2000/09/01 05:46:01 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -2417,6 +2417,13 @@ vgapage(int new_screen)
{
int x;
+ if (IS_SEL_EXISTS(vsp)) {
+ /* hides a potential selection */
+ remove_selection();
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ mouse_hide(); /* hides a potential mouse cursor */
+
if(new_screen < 0 || new_screen >= totalscreens)
return EINVAL;
diff --git a/sys/arch/i386/isa/pcvt/pcvt_hdr.h b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
index 04b8d41d762..be63f60719a 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_hdr.h
+++ b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_hdr.h,v 1.36 2000/06/08 22:25:20 niklas Exp $ */
+/* $OpenBSD: pcvt_hdr.h,v 1.37 2000/09/01 05:46:01 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -703,6 +703,18 @@ typedef struct video_state {
unsigned vt_status; /* state of the vt */
/* becoming active */
int kbd_state; /* keyboard raw or translated */
+
+ unsigned short mouse; /* mouse cursor position */
+ unsigned short cpy_start; /* position of the copy start mark*/
+ unsigned short cpy_end; /* position of the copy end mark */
+ unsigned short cpy_orig; /* original copy position */
+#define MOUSE_VISIBLE (1 << 0) /* flag, the mouse cursor is visible */
+#define SEL_EXISTS (1 << 1) /* flag, a selection exists */
+#define SEL_IN_PROGRESS (1 << 2) /* flag, a selection is in progress */
+#define IS_MOUSE_VISIBLE(vsp) ((vsp)->mouse_flags & MOUSE_VISIBLE)
+#define IS_SEL_EXISTS(vsp) ((vsp)->mouse_flags & SEL_EXISTS)
+#define IS_SEL_IN_PROGRESS(vsp) ((vsp)->mouse_flags & SEL_IN_PROGRESS)
+ unsigned char mouse_flags; /* flags, status of the mouse */
} video_state;
EXTERN video_state vs[PCVT_NSCREENS]; /* parameters for screens */
@@ -1113,4 +1125,18 @@ static __inline void vt_selattr(struct video_state *svsp)
#define PCVT_KBD_DELAY() delay(7)
#endif /* PCVT_PORTIO_DELAY */
+/* mouse console support prototype */
+
+char *Copybuffer; /* buffer that contains mouse selections */
+uid_t Copyowner; /* uid of the owner of the selection, useful for verifying
+ permissions on it
+ */
+char Paste_avail; /* flag, to indicate whether a selection is in the
+ Copy buffer */
+
+int mouse_ioctl(Dev_t, u_long, caddr_t, int, struct proc *);
+void remove_selection(void);
+void mouse_hide(void);
+void scrollback_mouse(int);
+
/*---------------------------------- E O F ----------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ioctl.h b/sys/arch/i386/isa/pcvt/pcvt_ioctl.h
index 92bca972f33..03b00f3e586 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_ioctl.h
+++ b/sys/arch/i386/isa/pcvt/pcvt_ioctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_ioctl.h,v 1.14 2000/01/18 19:34:41 aaron Exp $ */
+/* $OpenBSD: pcvt_ioctl.h,v 1.15 2000/09/01 05:46:02 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -71,6 +71,10 @@
#ifndef _MACHINE_PCVT_IOCTL_H_
#define _MACHINE_PCVT_IOCTL_H_
+/* Include for mouse console support */
+
+#include "pcvt_mouse.h"
+
/* pcvt version information for VGAPCVTID ioctl */
#define PCVTIDNAME "pcvt" /* driver id - string */
@@ -585,4 +589,8 @@ typedef struct keymap keymap_t;
/* end of USL VT compatibility stuff */
+/* Ioctl for mouse console support */
+
+#define PCVT_MOUSECTL _IOW('M',1,mouse_info_t)
+
#endif /* ! _MACHINE_PCVT_IOCTL_H_ */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.c b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
index 00490e6c35b..2c0ec4e3764 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_kbd.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_kbd.c,v 1.35 2000/07/19 13:40:26 art Exp $ */
+/* $OpenBSD: pcvt_kbd.c,v 1.36 2000/09/01 05:46:02 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -169,11 +169,12 @@ do_vgapage(int page)
* get lost other times as well.
*/
-struct timeout kbd_led_intr_to;
+static int lost_intr_timeout_queued = 0;
static void
check_for_lost_intr (void *arg)
{
+ lost_intr_timeout_queued = 0;
if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) {
int opri = spltty();
(void)pcrint();
@@ -243,7 +244,11 @@ update_led(void)
}
#if PCVT_UPDLED_LOSES_INTR
- timeout_add(&kbd_led_intr_to, hz);
+ if (lost_intr_timeout_queued)
+ untimeout(check_for_lost_intr, (void *)NULL);
+
+ timeout(check_for_lost_intr, (void *)NULL, hz);
+ lost_intr_timeout_queued = 1;
#endif /* PCVT_UPDLED_LOSES_INTR */
}
bail:
@@ -576,9 +581,6 @@ kbd_code_init(void)
doreset();
ovlinit(0);
keyboard_is_initialized = 1;
-#if !PCVT_NO_LED_UPDATE && PCVT_UPDLED_LOSES_INTR
- timeout_set(&kbd_led_intr_to, check_for_lost_intr, NULL);
-#endif
}
/*---------------------------------------------------------------------------*
@@ -1104,6 +1106,17 @@ regular:
if ((key == 85) && shift_down &&
(kbd_lastkey != 85 || !kbd_status.breakseen)) {
+ /* removing of visual regions for mouse console support */
+ if (IS_SEL_EXISTS(vsp)) {
+ remove_selection(); /* remove current selection before
+ leaving this screen */
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ if (IS_MOUSE_VISIBLE(vsp)) {
+ mouse_hide();
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+ }
+ /* end of visual regions part */
if (vsp->scr_offset && vsp->scr_offset >= vsp->row) {
if (!vsp->scrolling) {
vsp->scrolling += vsp->row - 1;
@@ -1142,6 +1155,17 @@ regular:
else if ((key == 86) && shift_down &&
(kbd_lastkey != 86 || !kbd_status.breakseen)) {
scroll_reset:
+ /* removing of visual regions for mouse console support */
+ if (IS_SEL_EXISTS(vsp)) {
+ remove_selection(); /* remove current selection before
+ leaving this screen */
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ if (IS_MOUSE_VISIBLE(vsp)) {
+ mouse_hide();
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+ }
+ /* end of visual regions part */
if (vsp->scrolling > 0) {
vsp->scrolling -= vsp->screen_rows - 1;
if (vsp->scrolling < 0)
@@ -2118,4 +2142,96 @@ scrollback_restore_screen(void)
bcopy(scrollback_savedscreen, vsp->Crtat, scrnsv_size);
}
+/*
+ * Function to handle the wheel
+ * z == 1 means to scroll to the lower page
+ * z == -1 means to scroll to the upper page
+ */
+
+void
+scrollback_mouse(int z)
+{
+
+ /* removing of visual regions for mouse console support */
+
+ if (IS_SEL_EXISTS(vsp)) {
+ remove_selection(); /* remove current selection before
+ leaving this screen */
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ if (IS_MOUSE_VISIBLE(vsp)) {
+ mouse_hide();
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+ }
+
+ if (z <= -1)
+
+ {
+ if (vsp->scr_offset && vsp->scr_offset >= vsp->row) {
+ if (!vsp->scrolling) {
+ vsp->scrolling += vsp->row - 1;
+ if (vsp->Scrollback) {
+ scrollback_save_screen();
+ if (vsp->scr_offset == vsp->max_off) {
+ bcopy(vsp->Scrollback +
+ vsp->maxcol,
+ vsp->Scrollback,
+ vsp->maxcol *
+ vsp->max_off * CHR);
+ vsp->scr_offset--;
+ }
+ bcopy(vsp->Crtat + vsp->cur_offset -
+ vsp->col, vsp->Scrollback +
+ (vsp->scr_offset + 1) *
+ vsp->maxcol, vsp->maxcol * CHR);
+ }
+
+ if (vsp->cursor_on)
+ sw_cursor(0);
+ }
+
+ vsp->scrolling += vsp->screen_rows - 1;
+ if (vsp->scrolling > vsp->scr_offset) {
+ vsp->scrolling = vsp->scr_offset;
+ }
+
+ bcopy(vsp->Scrollback + ((vsp->scr_offset -
+ vsp->scrolling) * vsp->maxcol), vsp->Crtat,
+ vsp->screen_rows * vsp->maxcol * CHR);
+ }
+ }
+ else /* positive z */
+ {
+ if (IS_SEL_EXISTS(vsp)) {
+ remove_selection();
+ vsp->mouse_flags &= ~SEL_EXISTS;
+ }
+ if (vsp->scrolling > 0) {
+ vsp->scrolling -= vsp->screen_rows - 1;
+ if (vsp->scrolling < 0)
+ vsp->scrolling = 0;
+
+ if (vsp->scrolling <= vsp->row) {
+ vsp->scrolling = 0;
+ scrollback_restore_screen();
+ }
+ else {
+ if (vsp->scrolling + 2 < vsp->screen_rows)
+ fillw(user_attr | ' ',
+ (caddr_t)vsp->Crtat,
+ vsp->screen_rows * vsp->maxcol);
+
+ bcopy(vsp->Scrollback + ((vsp->scr_offset -
+ vsp->scrolling) * vsp->maxcol),
+ vsp->Crtat, (vsp->scrolling + 2 <
+ vsp->screen_rows ? vsp->scrolling + 2 :
+ vsp->screen_rows) * vsp->maxcol * CHR);
+ }
+ }
+ if (vsp->scrolling == 0) {
+ if (vsp->cursor_on)
+ sw_cursor(1);
+ }
+ }
+}
/* ------------------------------- EOF -------------------------------------*/
diff --git a/sys/arch/i386/isa/pcvt/pcvt_mouse.c b/sys/arch/i386/isa/pcvt/pcvt_mouse.c
new file mode 100644
index 00000000000..26e355c61a6
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_mouse.c
@@ -0,0 +1,723 @@
+/* $OpenBSD: pcvt_mouse.c,v 1.1 2000/09/01 05:46:02 aaron Exp $ */
+
+/*
+ * Copyright (c) 2000 Jean-Baptiste Marchand, Julien Montagne and Jerome Verdon
+ *
+ * All rights reserved.
+ *
+ * This code is for mouse console support under the pcvt console driver.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
+ * and Charles Hannum.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ */
+
+#include "pcvt_hdr.h"
+
+void mouse_moverel(char dx, char dy);
+
+void inverse_char(unsigned short c);
+void inverse_region(unsigned short start, unsigned short end);
+void order_region(void);
+
+unsigned char skip_spc_right(char);
+unsigned char skip_spc_left(void);
+unsigned char skip_char_right(void);
+unsigned char skip_char_left(void);
+
+void mouse_copy_start(void);
+void mouse_copy_end(void);
+void mouse_copy_word(void);
+void mouse_copy_line(void);
+void mouse_copy_extend(void);
+void remove_selection(void);
+void mouse_copy_selection(void);
+void mouse_paste(void);
+uid_t current_uid(void);
+
+void mouse_zaxis(int z);
+void mouse_button(int button, int clicks);
+
+#define NO_BORDER 0
+#define BORDER 1
+
+#define MAXCOL (vsp->maxcol - 1)
+#define MAXROW (vsp->screen_rows - 1)
+
+#define XY_TO_X(col,row) (((row) * (vsp->maxcol)) + (col))
+#define XABS_TO_XREL(col) (((col) - vsp->Crtat) % vsp->maxcol)
+
+#define IS_ALPHANUM(pos) ((*(vsp->Crtat + (pos)) & 0x00ff) != ' ')
+#define IS_SPACE(c) ((c) == ' ')
+
+int
+mouse_ioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ int device = minor(dev);
+ mouse_info_t mouse_infos = *(mouse_info_t *) data;
+ unsigned char c;
+ video_state *cs;
+
+ if (device == PCVTCTL_MINOR && cmd == PCVT_MOUSECTL) {
+ switch (mouse_infos.operation) {
+ case MOUSE_INIT:
+ for (c = 0; c < PCVT_NSCREENS; c++) {
+ cs = &vs[c];
+ cs->mouse = (cs->maxcol *
+ cs->screen_rows) / 2;
+ cs->mouse_flags = 0;
+ }
+ Paste_avail = 0;
+ break;
+
+ case MOUSE_HIDE:
+ remove_selection();
+ mouse_hide();
+ break;
+
+ case MOUSE_MOTION_EVENT :
+ mouse_moverel(mouse_infos.u.data.x,
+ mouse_infos.u.data.y);
+ if (mouse_infos.u.data.z)
+ mouse_zaxis(mouse_infos.u.data.z);
+ break;
+
+ case MOUSE_BUTTON_EVENT :
+ mouse_button(mouse_infos.u.event.id,
+ mouse_infos.u.event.value);
+ break;
+
+ default:
+ return 0;
+ }
+ return 0;
+ }
+ return (-1); /* continue treatment in pcioctl */
+}
+
+void
+mouse_hide(void)
+{
+ if (IS_MOUSE_VISIBLE(vsp)) {
+ inverse_char(vsp->mouse);
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+ }
+}
+
+/*
+ * function to move the cursor to a relative new position
+ */
+
+void
+mouse_moverel(char dx, char dy)
+{
+ unsigned short old_mouse = vsp->mouse;
+ unsigned char mouse_col = (vsp->mouse % vsp->maxcol);
+ unsigned char mouse_row = (vsp->mouse / vsp->maxcol);
+
+ if (scrnsv_active) /* if the screen saver is active */
+ pcvt_scrnsv_reset(); /* unblank NOW ! */
+
+ /* update position */
+ if (mouse_col + dx >= MAXCOL)
+ mouse_col = MAXCOL;
+ else
+ if (mouse_col + dx <= 0)
+ mouse_col = 0;
+ else
+ mouse_col += dx;
+ if (mouse_row + dy >= MAXROW)
+ mouse_row = MAXROW;
+ else
+ if (mouse_row + dy <= 0)
+ mouse_row = 0;
+ else
+ mouse_row += dy;
+ vsp->mouse = XY_TO_X(mouse_col, mouse_row);
+
+ /* if we have moved */
+ if (old_mouse != vsp->mouse) {
+ /* hide the previous cursor, if not in a selection */
+ if (IS_MOUSE_VISIBLE(vsp) && (!IS_SEL_IN_PROGRESS(vsp)))
+ inverse_char(old_mouse);
+
+ if (IS_SEL_IN_PROGRESS(vsp)) {
+ /* selection in progress */
+ mouse_copy_extend();
+ }
+ else {
+ inverse_char(vsp->mouse);
+ vsp->mouse_flags |= MOUSE_VISIBLE;
+ }
+ }
+}
+
+/*
+ * function to video inverse a character of the display
+ */
+
+void
+inverse_char(unsigned short pos)
+{
+ u_short *current_char = vsp->Crtat + pos;
+ u_short inverse = *current_char;
+
+ if ((inverse >> 8) == 0)
+ inverse = (FG_LIGHTGREY << 8);
+
+ inverse = (((inverse >> 8) & 0x88) | ((((inverse >> 8) >> 4) |
+ ((inverse >> 8) << 4)) & 0x77)) << 8;
+
+ *current_char = inverse | ((*current_char) & 0x00ff);
+}
+
+/*
+ * Function to order extremum of the selection region
+ */
+
+void
+order_region(void)
+{
+ unsigned short max_pos;
+
+ if (vsp->cpy_start > vsp->cpy_end) {
+ max_pos = vsp->cpy_start;
+ vsp->cpy_start = vsp->cpy_end;
+ vsp->cpy_end = max_pos;
+ }
+}
+
+/*
+ * Function to video inverse a region of the display
+ * start must be inferior to end
+ */
+
+void
+inverse_region(unsigned short start, unsigned short end)
+{
+ unsigned short current_pos;
+ unsigned char c = 0;
+
+ current_pos = start;
+ while (current_pos <= end) {
+ inverse_char(current_pos++);
+ c++;
+ }
+}
+
+/*
+ * Function which returns the number of contiguous blank characters between
+ * the right margin if border == 1 or between the next non-blank character
+ * and the current mouse cursor if border == 0
+ */
+
+unsigned char
+skip_spc_right(char border)
+{
+ unsigned short *current;
+ unsigned short *limit;
+ unsigned char mouse_col = (vsp->mouse % vsp->maxcol);
+ unsigned char res = 0;
+
+ current = vsp->Crtat + vsp->cpy_end;
+ limit = current + (vsp->maxcol - mouse_col - 1);
+ while (((*current & 0x00ff) == ' ') && (current <= limit)) {
+ current++;
+ res++;
+ }
+ if (border == BORDER) {
+ if (current > limit)
+ return (res - 1);
+ else
+ return (0);
+ }
+ else
+ return (res - 1);
+}
+
+/*
+ * Function which returns the number of contiguous blank characters between
+ * the first of the contiguous blank characters and the current mouse cursor
+ */
+
+unsigned char
+skip_spc_left(void)
+{
+ unsigned short *current;
+ unsigned short *limit;
+ unsigned char mouse_col = (vsp->mouse % vsp->maxcol);
+ unsigned char res = 0;
+
+ current = vsp->Crtat + vsp->cpy_start;
+ limit = current - mouse_col;
+ while (((*current & 0x00ff) == ' ') && (current >= limit)) {
+ current--;
+ res++;
+ }
+
+ if (res)
+ res--;
+ return (res);
+}
+
+/*
+ * Function which find the first blank beginning after the current cursor
+ * position
+ */
+
+unsigned char
+skip_char_right(void)
+{
+ unsigned short *current;
+ unsigned short *limit;
+ unsigned char mouse_col = (vsp->mouse % vsp->maxcol);
+ unsigned char res = 0;
+
+ current = vsp->Crtat + vsp->cpy_end;
+ limit = current + (vsp->maxcol - mouse_col - 1);
+ while (((*current & 0x00ff) != ' ') && (current <= limit)) {
+ current++;
+ res++;
+ }
+
+ if (res)
+ res--;
+ return (res);
+}
+
+/*
+ * Function which find the first non-blank character before the cursor position
+ */
+
+unsigned char
+skip_char_left(void)
+{
+ unsigned short *current;
+ unsigned short *limit;
+ unsigned char mouse_col = (vsp->mouse % vsp->maxcol);
+ unsigned char res = 0;
+
+ current = vsp->Crtat + vsp->cpy_start;
+ limit = current - mouse_col;
+ while (((*current & 0x00ff) != ' ') && (current >= limit)) {
+ current--;
+ res++;
+ }
+
+ if (res)
+ res--;
+ return (res);
+}
+
+/*
+ * Function to handle beginning of a copy operation
+ */
+
+void
+mouse_copy_start(void)
+{
+#if 0
+ unsigned char right;
+ unsigned char left;
+#endif
+
+ /* if no selection, then that's the first one */
+ if (!Paste_avail)
+ Paste_avail = 1;
+
+ /* remove the previous selection */
+ if (IS_SEL_EXISTS(vsp)) {
+ remove_selection();
+ }
+
+ /* initial show of the cursor */
+ if (!IS_MOUSE_VISIBLE(vsp))
+ inverse_char(vsp->mouse);
+
+ vsp->cpy_start = vsp->mouse;
+ vsp->cpy_end = vsp->mouse;
+
+#if 0
+ /* if there is a blank region, we select all the region */
+ if ((right = skip_spc_right(BORDER)) > 0) {
+ left = skip_spc_left();
+ vsp->cpy_start -= left;
+ vsp->cpy_end += right;
+ if (vsp->cpy_start % vsp->maxcol) {
+ inverse_region(vsp->cpy_start, vsp->cpy_end);
+ inverse_char(vsp->mouse); /* reverse back the cursor */
+ }
+ else {
+ /* we select only one character on a full blank line */
+ vsp->cpy_start = vsp->mouse;
+ vsp->cpy_end = vsp->mouse;
+ }
+ }
+#endif
+
+ /* for correct action in remove_selection() */
+ vsp->cpy_orig = vsp->cpy_start;
+
+ vsp->mouse_flags |= SEL_IN_PROGRESS;
+ vsp->mouse_flags |= SEL_EXISTS;
+
+ /* mouse cursor hidden in the selection */
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+}
+
+/*
+ * Function to handle copy of the word under the cursor
+ */
+
+void
+mouse_copy_word()
+{
+ unsigned char right;
+ unsigned char left;
+
+ if (IS_SEL_EXISTS(vsp))
+ remove_selection();
+
+ if (IS_SEL_IN_PROGRESS(vsp))
+ vsp->mouse_flags &= ~SEL_IN_PROGRESS;
+
+ if (IS_MOUSE_VISIBLE(vsp))
+ inverse_char(vsp->mouse);
+
+ vsp->cpy_start = vsp->mouse;
+ vsp->cpy_end = vsp->mouse;
+
+ if (IS_ALPHANUM(vsp->mouse)) {
+ right = skip_char_right();
+ left = skip_char_left();
+ }
+ else {
+ right = skip_spc_right(NO_BORDER);
+ left = skip_spc_left();
+ }
+
+ vsp->cpy_start -= left;
+ vsp->cpy_end += right;
+ vsp->cpy_orig = vsp->cpy_start;
+ inverse_region(vsp->cpy_start, vsp->cpy_end);
+ vsp->mouse_flags |= SEL_EXISTS;
+
+ /* mouse cursor hidden in the selection */
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+}
+
+/*
+ * Function to handle copy of the current line
+ */
+
+void
+mouse_copy_line(void)
+{
+ unsigned char row = vsp->mouse / vsp->maxcol;
+
+ if (IS_SEL_EXISTS(vsp))
+ remove_selection();
+
+ if (IS_SEL_IN_PROGRESS(vsp))
+ vsp->mouse_flags &= ~(SEL_IN_PROGRESS);
+
+ if (IS_MOUSE_VISIBLE(vsp))
+ inverse_char(vsp->mouse);
+
+ vsp->cpy_start = row * vsp->maxcol;
+ vsp->cpy_end = vsp->cpy_start + MAXCOL;
+ vsp->cpy_orig = vsp->cpy_start;
+ inverse_region(vsp->cpy_start, vsp->cpy_end);
+
+ vsp->mouse_flags |= SEL_EXISTS;
+ vsp->mouse_flags &= ~MOUSE_VISIBLE;
+}
+
+/*
+ * Function to handle the end of a copy operation
+ */
+
+void
+mouse_copy_end(void)
+{
+ vsp->mouse_flags &= ~(SEL_IN_PROGRESS);
+}
+
+/*
+ * Function to extend a previously selected region
+ */
+
+void
+mouse_copy_extend()
+{
+ if (IS_SEL_EXISTS(vsp)) {
+ if (vsp->mouse < vsp->cpy_start) {
+ /* we are over the initial selection position */
+
+ /* reverse the old selection region */
+ if (IS_SEL_EXISTS(vsp))
+ remove_selection();
+
+ /* new delimiters for the selection zone */
+ vsp->cpy_start = vsp->mouse;
+ vsp->cpy_end = vsp->cpy_orig - 1;
+ inverse_char(vsp->cpy_end);
+ }
+ if (vsp->cpy_start < vsp->cpy_orig && vsp->mouse >= vsp->cpy_orig)
+ {
+ /* we go back behind the initial selection
+ position */
+
+ /* reverse the old selection region */
+ if (IS_SEL_EXISTS(vsp))
+ remove_selection();
+
+ vsp->cpy_start = vsp->cpy_orig;
+ vsp->cpy_end = vsp->cpy_orig;
+ inverse_char(vsp->cpy_start);
+ }
+
+ if (vsp->mouse < vsp->cpy_end) {
+ /* reducing selection */
+ if (vsp->mouse >= vsp->cpy_orig)
+ inverse_region(vsp->mouse + 1, vsp->cpy_end);
+ else
+ inverse_region(vsp->mouse, vsp->cpy_end - 1);
+ }
+ else {
+ /* extending selection */
+ if (vsp->mouse >= vsp->cpy_orig)
+ inverse_region(vsp->cpy_end + 1, vsp->mouse);
+ else
+ inverse_region(vsp->cpy_end, vsp->mouse - 1);
+ }
+ vsp->cpy_end = vsp->mouse;
+ order_region();
+ }
+ else {
+ /* no selection yet! */
+ sysbeep(PCVT_SYSBEEPF / 1500, hz / 4);
+ }
+}
+
+/*
+ * Function to remove a previously selected region
+ */
+
+void
+remove_selection()
+{
+ if (vsp->cpy_start < vsp->cpy_orig)
+ /* backward selection */
+ inverse_region(vsp->cpy_end, vsp->cpy_orig - 1);
+ else
+ /* forward selection */
+ inverse_region(vsp->cpy_start, vsp->cpy_end);
+}
+
+/*
+ * Function to get the uid of the user behind the *shell* on the current tty
+ * We handle su and sudo cases...
+ */
+
+uid_t
+current_uid(void)
+{
+ pid_t pg; /* process group id */
+ struct proc *owner_proc;
+
+ pg = vsp->vs_tty->t_pgrp->pg_id;
+ owner_proc = pfind(pg);
+ if (!owner_proc) {
+ Paste_avail = 0; /* this selection will never be available
+ because the process doesn't exist... */
+ return (0); /* the uid of root, just to be sure */
+ }
+
+ /*
+ * We use the real user id and not the *effective* one, as a foreground
+ * setuid process could permit to paste selection of another user
+ */
+
+ return (owner_proc->p_cred->p_ruid);
+}
+
+/*
+ * Function to put the current visual selection in the selection buffer
+ */
+
+void
+mouse_copy_selection(void)
+{
+ unsigned short current = 0;
+ unsigned short blank = current;
+ unsigned short buf_end = ((vsp->maxcol + 1) * vsp->screen_rows);
+ unsigned short *sel_cur;
+ unsigned short *sel_end;
+
+ if (vsp->cpy_start < vsp->cpy_orig) {
+ /* backward selection */
+ sel_cur = vsp->Crtat + vsp->cpy_end;
+ sel_end = vsp->Crtat + vsp->cpy_orig - 1;
+ }
+ else {
+ /* forward selection */
+ sel_cur = vsp->Crtat + vsp->cpy_start;
+ sel_end = vsp->Crtat + vsp->cpy_end;
+ }
+ while (sel_cur <= sel_end && current < buf_end - 1) {
+ Copybuffer[current] = ((*sel_cur) & 0x00ff);
+
+ if (!IS_SPACE(Copybuffer[current]))
+ blank = current + 1; /* first blank after non-blank */
+ current++;
+
+ if (XABS_TO_XREL(sel_cur) == MAXCOL) {
+ /* we are on the last col of the screen */
+ Copybuffer[blank] = '\r'; /* carriage return */
+ current = blank + 1; /* restart just after the carriage
+ return in the buffer */
+ blank = current;
+ }
+ sel_cur++;
+ }
+
+ Copybuffer[current] = '\0';
+
+#if 0
+ /*
+ examine the last line of selection to see if it finishes with blank.
+ In that case, we put a carriage return after the last non-blank
+ character in the buffer
+ */
+ sel_cur = sel_end;
+ while (IS_SPACE(*sel_cur & 0x00ff) && XABS_TO_XREL(sel_cur) < MAXCOL) {
+ sel_cur--;
+ current--;
+ }
+ if (sel_cur != sel_end) {
+ Copybuffer[current++] = '\r';
+ Copybuffer[current] = '\0';
+ }
+#endif
+ Copyowner = current_uid();
+}
+/*
+ * Function to paste the current selection
+ */
+
+void
+mouse_paste(void)
+{
+ unsigned short len;
+ char *current = Copybuffer;
+ uid_t cur_uid;
+
+ cur_uid = current_uid();
+ if (Paste_avail && ((cur_uid == Copyowner) || !cur_uid)) {
+ /* either the owner of the selection or root */
+ len = strlen(Copybuffer);
+ for (; len > 0; len--) {
+ (*linesw[vsp->vs_tty->t_line].l_rint)
+ (*current++, vsp->vs_tty);
+ }
+ }
+ else
+ sysbeep(PCVT_SYSBEEPF / 1500, hz / 4);
+}
+
+/*
+ * Function to handle button clicks
+ */
+
+void
+mouse_button(int button, int clicks)
+{
+ if (scrnsv_active) /* if the screen saver is active */
+ pcvt_scrnsv_reset(); /* unblank NOW ! */
+
+ switch (button) {
+ case MOUSE_COPY_BUTTON:
+ switch (clicks % 4) {
+ case 0: /* button is up */
+ mouse_copy_end();
+ mouse_copy_selection();
+ break;
+ case 1: /* single click */
+ mouse_copy_start();
+ mouse_copy_selection();
+ break;
+ case 2: /* double click */
+ mouse_copy_word();
+ mouse_copy_selection();
+ break;
+ case 3: /* triple click */
+ mouse_copy_line();
+ mouse_copy_selection();
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case MOUSE_PASTE_BUTTON:
+ switch (clicks) {
+ case 0: /* button is up */
+ break;
+ default: /* paste */
+ mouse_paste();
+ break;
+ }
+ break;
+
+ case MOUSE_EXTEND_BUTTON:
+ switch (clicks) {
+ case 0: /* button is up */
+ break;
+ default: /* extend the selection */
+ mouse_copy_extend();
+ mouse_copy_selection();
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * Function to handle the z axis
+ * The z axis (roller or wheel) is mapped by default to scrollback
+ */
+
+void
+mouse_zaxis(int z)
+{
+ scrollback_mouse(z);
+}
diff --git a/sys/arch/i386/isa/pcvt/pcvt_mouse.h b/sys/arch/i386/isa/pcvt/pcvt_mouse.h
new file mode 100644
index 00000000000..985f2f512e5
--- /dev/null
+++ b/sys/arch/i386/isa/pcvt/pcvt_mouse.h
@@ -0,0 +1,96 @@
+/* $OpenBSD: pcvt_mouse.h,v 1.1 2000/09/01 05:46:02 aaron Exp $ */
+
+/*
+ * Copyright (c) 2000 Jean-Baptiste Marchand, Julien Montagne and Jerome Verdon
+ *
+ * All rights reserved.
+ *
+ * This code is for mouse console support under the pcvt console driver.
+ *
+ * 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
+ * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
+ * and Charles Hannum.
+ * 4. The name authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ *
+ *
+ */
+
+#define PCVTCTL_MINOR 255
+
+/* Mouse buttons */
+
+#define MOUSE_BUTTON1DOWN 0x0001 /* left */
+#define MOUSE_BUTTON2DOWN 0x0002 /* middle */
+#define MOUSE_BUTTON3DOWN 0x0004 /* right */
+#define MOUSE_BUTTON4DOWN 0x0008
+#define MOUSE_BUTTON5DOWN 0x0010
+#define MOUSE_BUTTON6DOWN 0x0020
+#define MOUSE_BUTTON7DOWN 0x0040
+#define MOUSE_BUTTON8DOWN 0x0080
+#define MOUSE_MAXBUTTON 31
+#define MOUSE_STDBUTTONS 0x0007 /* buttons 1-3 */
+#define MOUSE_EXTBUTTONS 0x7ffffff8 /* the others (28 of them!) */
+#define MOUSE_BUTTONS (MOUSE_STDBUTTONS | MOUSE_EXTBUTTONS)
+
+#define MOUSE_COPY_BUTTON MOUSE_BUTTON1DOWN
+#define MOUSE_PASTE_BUTTON MOUSE_BUTTON2DOWN
+#define MOUSE_EXTEND_BUTTON MOUSE_BUTTON3DOWN
+
+/* Motion event */
+
+struct mouse_data {
+ int x;
+ int y;
+ int z;
+ int buttons;
+};
+
+/* Click event */
+
+struct mouse_event {
+ int id; /* button clicked */
+ int value; /* number of click */
+};
+
+/* Mouse_info : either motion or click event */
+
+typedef struct mouse_info {
+ int operation;
+ /*
+ * The following operations are used to indicate the action
+ * when receiving a PCVT_MOUSECTL ioctl
+ */
+
+#define MOUSE_INIT (1 << 0) /* Init of the cursor */
+#define MOUSE_HIDE (1 << 1) /* Hide the cursor */
+#define MOUSE_MOTION_EVENT (1 << 2) /* Motion event */
+#define MOUSE_BUTTON_EVENT (1 << 3) /* Button event */
+
+ union {
+ struct mouse_data data;
+ struct mouse_event event;
+ }u;
+} mouse_info_t;
+
diff --git a/sys/arch/i386/isa/pcvt/pcvt_out.c b/sys/arch/i386/isa/pcvt/pcvt_out.c
index acf176f3dce..50ed63d20a8 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_out.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_out.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_out.c,v 1.25 2000/07/05 03:10:34 aaron Exp $ */
+/* $OpenBSD: pcvt_out.c,v 1.26 2000/09/01 05:46:02 aaron Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -153,7 +153,6 @@ sput (u_char *s, U_char kernel, int len, int page)
else
reset_screen_saver = 1; /* do it asynchronously */
#endif /* PCVT_SCREENSAVER */
-
}
attrib = kernel ? kern_attr : svsp->c_attr;
@@ -1270,6 +1269,18 @@ vt_coldmalloc(void)
printf("pcvt: scrollback memory malloc failed\n");
}
+ /*
+ * Copy buffer must be 1 character wider than the screen because we
+ * need to write '\r' characters in the buffer (carriage return
+ */
+
+ if ((Copybuffer = (char *)malloc((vs[0].maxcol + 1) *
+ vs[0].screen_rows, M_DEVBUF,
+ M_WAITOK)) == NULL)
+ {
+ printf("pcvt: copy memory malloc failed\n");
+ }
+
for(nscr = 0; nscr < PCVT_NSCREENS; nscr++)
{
if((vs[nscr].Memory =