Subject: kern/17445: second wsscroll patch
To: None <gnats-bugs@gnats.netbsd.org>
From: None <krp@freeshell.org>
List: netbsd-bugs
Date: 06/30/2002 22:18:30
>Number: 17445
>Category: kern
>Synopsis: allow scrolling on wscons terminals
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jun 30 13:23:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: David Ferlier
>Release: NetBSD 1.6A
>Organization:
None
Run NetBSD - www.NetBSD.org
David Ferlier - krp@freeshell.org
>Environment:
netbsd/i386
System: NetBSD hell 1.6A NetBSD 1.6A (LARGE_CHUNKS) #70: Sun Jun 21:56:52 PDT 2002 root@hell:/usr/src/sys/arch/i386/compile/LARGE_CHUNKS i386
Architecture: i386
Machine: i386
>Description:
Feel the lack of scrolling functions on wscons terminals
Attached patch works on 1.6A
>How-To-Repeat:
none
>Fix:
Index: sys/dev/wscons/wsdisplay.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/wscons/wsdisplay.c,v
retrieving revision 1.63
diff -u -r1.63 wsdisplay.c
--- wsdisplay.c 2002/04/07 09:25:47 1.63
+++ wsdisplay.c 2002/06/30 20:05:27
@@ -114,6 +114,9 @@
void *sc_accesscookie;
const struct wsscreen_list *sc_scrdata;
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ struct wsdisplay_scroll_data sc_scroll_values;
+#endif
struct wsscreen *sc_scr[WSDISPLAY_MAXSCREEN];
int sc_focusidx; /* available only if sc_focus isn't null */
@@ -152,6 +155,13 @@
wsdisplay_noemul_match,
wsdisplay_noemul_attach,
};
+
+struct wsdisplay_scroll_data wsdisplay_default_scroll_values = {
+ WSDISPLAY_SCROLL_DOALL,
+ 25,
+ 2,
+};
+
/* Exported tty- and cdevsw-related functions. */
cdev_decl(wsdisplay);
@@ -397,6 +407,32 @@
vdevgone(maj, mn, mn, VCHR);
}
+#ifdef WSDISPLAY_SCROLLSUPPORT
+
+void
+wsdisplay_scroll(arg, op)
+ void *arg;
+ int op;
+{
+ struct wsdisplay_softc *sc = arg;
+ int lines;
+
+ if (op == WSDISPLAY_SCROLL_RESET)
+ lines = 0;
+ else {
+ lines = (op & WSDISPLAY_SCROLL_LOW) ? sc->sc_scroll_values.slowlines : sc->sc_scroll_values.fastlines;
+ if (op & WSDISPLAY_SCROLL_BACKWARD)
+ lines = -(lines);
+ }
+
+ if (sc->sc_accessops->scroll) {
+ (*sc->sc_accessops->scroll)(sc->sc_accesscookie,
+ sc->sc_focus->scr_dconf->emulcookie, lines);
+ }
+}
+
+#endif
+
int
wsdisplay_delscreen(struct wsdisplay_softc *sc, int idx, int flags)
{
@@ -615,6 +651,7 @@
sc->sc_accessops = accessops;
sc->sc_accesscookie = accesscookie;
sc->sc_scrdata = scrdata;
+ sc->sc_scroll_values = wsdisplay_default_scroll_values;
/*
* Set up a number of virtual screens if wanted. The
@@ -916,6 +953,9 @@
int error;
char namebuf[16];
struct wsdisplay_font fd;
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ struct wsdisplay_scroll_data *ksdp, *usdp;
+#endif
#if NWSKBD > 0
struct wsevsrc *inp;
@@ -964,6 +1004,32 @@
return (0);
#undef d
+
+#ifdef WSDISPLAY_SCROLLSUPPORT
+
+#define SETSCROLLLINES(dstp, srcp, dfltp) \
+ do { \
+ (dstp)->fastlines = ((srcp)->which & WSDISPLAY_SCROLL_DOFASTLINES) ? \
+ (srcp)->fastlines : (dfltp)->fastlines; \
+ (dstp)->slowlines = ((srcp)->which & WSDISPLAY_SCROLL_DOSLOWLINES) ? \
+ (srcp)->slowlines : (dfltp)->slowlines; \
+ (dstp)->which = WSDISPLAY_SCROLL_DOALL; \
+ } while (0)
+
+
+ case WSDISPLAYIO_DSSCROLL:
+ usdp = (struct wsdisplay_scroll_data *)data;
+ ksdp = &sc->sc_scroll_values;
+ SETSCROLLLINES(ksdp, usdp, ksdp);
+ return (0);
+
+ case WSDISPLAYIO_DGSCROLL:
+ usdp = (struct wsdisplay_scroll_data *)data;
+ ksdp = &sc->sc_scroll_values;
+ SETSCROLLLINES(usdp, ksdp, ksdp);
+ return (0);
+
+#endif
case WSDISPLAYIO_SFONT:
#define d ((struct wsdisplay_usefontdata *)data)
Index: sys/dev/wscons/wsdisplayvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/wscons/wsdisplayvar.h,v
retrieving revision 1.20
diff -u -r1.20 wsdisplayvar.h
--- wsdisplayvar.h 2001/10/13 15:56:15 1.20
+++ wsdisplayvar.h 2002/06/30 20:05:29
@@ -106,6 +106,7 @@
int (*show_screen)(void *, void *, int,
void (*) (void *, int, int), void *);
int (*load_font)(void *, void *, struct wsdisplay_font *);
+ void (*scroll) __P((void *, void *, int));
void (*pollc)(void *, int);
};
@@ -188,6 +189,15 @@
int wsdisplay_cfg_ioctl(struct wsdisplay_softc *sc, u_long cmd, caddr_t data,
int flag, struct proc *p);
+
+#ifdef WSDISPLAY_SCROLLSUPPORT
+void wsdisplay_scroll __P((void *v, int op));
+#endif
+
+#define WSDISPLAY_SCROLL_BACKWARD 1
+#define WSDISPLAY_SCROLL_FORWARD (1 << 1)
+#define WSDISPLAY_SCROLL_RESET (1 << 2)
+#define WSDISPLAY_SCROLL_LOW (1 << 3)
/*
* for general use
Index: sys/dev/wscons/wskbd.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/wscons/wskbd.c,v
retrieving revision 1.61
diff -u -r1.61 wskbd.c
--- wskbd.c 2002/03/17 19:41:06 1.61
+++ wskbd.c 2002/06/30 20:05:44
@@ -113,6 +113,7 @@
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>
+#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wseventvar.h>
#include <dev/wscons/wscons_callbacks.h>
@@ -162,6 +163,9 @@
struct wskbd_bell_data sc_bell_data;
struct wskbd_keyrepeat_data sc_keyrepeat_data;
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ struct wskbd_scroll_data sc_scroll_data;
+#endif
int sc_repeating; /* we've called timeout() */
struct callout sc_repeat_ch;
@@ -199,6 +203,16 @@
#define MOD_ONESET(id, mask) (((id)->t_modifiers & (mask)) != 0)
#define MOD_ALLSET(id, mask) (((id)->t_modifiers & (mask)) == (mask))
+#define GETMODSTATE(src, dst) \
+ do { \
+ dst |= (src & MOD_SHIFT_L) ? MOD_SHIFT_L : 0; \
+ dst |= (src & MOD_SHIFT_R) ? MOD_SHIFT_R : 0; \
+ dst |= (src & MOD_CONTROL_L) ? MOD_CONTROL_L : 0; \
+ dst |= (src & MOD_CONTROL_R) ? MOD_CONTROL_R : 0; \
+ dst |= (src & MOD_META_L) ? MOD_META_L : 0; \
+ dst |= (src & MOD_META_R) ? MOD_META_R : 0; \
+ } while (0)
+
static int wskbd_match(struct device *, struct cfdata *, void *);
static void wskbd_attach(struct device *, struct device *, void *);
static int wskbd_detach(struct device *, int);
@@ -273,6 +287,16 @@
WSKBD_DEFAULT_KEYREPEAT_DELN,
};
+struct wskbd_scroll_data wskbd_default_scroll_data = {
+ WSKBD_SCROLL_DOALL,
+ WSKBD_SCROLL_MODE_NORMAL,
+#ifdef WSDISPLAY_SCROLLCOMBO
+ WSDISPLAY_SCROLLCOMBO,
+#else
+ MOD_SHIFT_L,
+#endif
+};
+
cdev_decl(wskbd);
#if NWSDISPLAY > 0 || NWSMUX > 0
@@ -398,6 +422,7 @@
/* set default bell and key repeat data */
sc->sc_bell_data = wskbd_default_bell_data;
sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;
+ sc->sc_scroll_data = wskbd_default_scroll_data;
if (ap->console) {
KASSERT(wskbd_console_initted);
@@ -570,7 +595,7 @@
sc->sc_repeating = 0;
callout_stop(&sc->sc_repeat_ch);
}
-
+
/*
* If /dev/wskbdN is not connected in event mode translate and
* send upstream.
@@ -579,6 +604,9 @@
num = wskbd_translate(sc->id, type, value);
if (num > 0) {
if (sc->sc_base.me_dispdv != NULL) {
+ if (sc->id->t_symbols [0] != KS_Print_Screen) {
+ wsdisplay_scroll (sc->sc_base.me_dispdv, WSDISPLAY_SCROLL_RESET);
+ }
for (i = 0; i < num; i++)
wsdisplay_kbdinput(
sc->sc_base.me_dispdv,
@@ -887,6 +915,9 @@
wskbd_displayioctl(struct device *dev, u_long cmd, caddr_t data, int flag,
struct proc *p)
{
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ struct wskbd_scroll_data *usdp, *ksdp;
+#endif
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
struct wskbd_bell_data *ubdp, *kbdp;
struct wskbd_keyrepeat_data *ukdp, *kkdp;
@@ -987,6 +1018,30 @@
kkdp = &wskbd_default_keyrepeat_data;
goto getkeyrepeat;
+#ifdef WSDISPLAY_SCROLLSUPPORT
+
+#define SETSCROLLMOD(dstp, srcp, dfltp) \
+ do { \
+ (dstp)->mode = ((srcp)->which & WSKBD_SCROLL_DOMODE) ? \
+ (srcp)->mode : (dfltp)->mode; \
+ (dstp)->modifier = ((srcp)->which & WSKBD_SCROLL_DOMODIFIER) ? \
+ (srcp)->modifier : (dfltp)->modifier; \
+ (dstp)->which = WSKBD_SCROLL_DOALL; \
+ } while (0)
+
+ case WSKBDIO_SETSCROLL:
+ usdp = (struct wskbd_scroll_data *)data;
+ ksdp = &sc->sc_scroll_data;
+ SETSCROLLMOD(ksdp, usdp, ksdp);
+ return (0);
+
+ case WSKBDIO_GETSCROLL:
+ usdp = (struct wskbd_scroll_data *)data;
+ ksdp = &sc->sc_scroll_data;
+ SETSCROLLMOD(usdp, ksdp, ksdp);
+ return (0);
+#endif
+
#undef SETKEYREPEAT
case WSKBDIO_SETMAP:
@@ -1306,7 +1361,48 @@
internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym,
keysym_t ksym2)
{
+ u_int state=0;
switch (ksym) {
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ case KS_Cmd_ScrollFastUp:
+ case KS_Cmd_ScrollFastDown:
+ if (*type == WSCONS_EVENT_KEY_DOWN) {
+ GETMODSTATE(sc->id->t_modifiers, state);
+ if ((sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_HOLD
+ && MOD_ONESET(sc->id, MOD_HOLDSCREEN))
+ || (sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_NORMAL
+ && sc->sc_scroll_data.modifier == state)) {
+ update_modifier(sc->id, *type, 0, MOD_COMMAND);
+ wsdisplay_scroll(sc->sc_base.me_dispdv,
+ (ksym == KS_Cmd_ScrollFastUp) ?
+ WSDISPLAY_SCROLL_BACKWARD :
+ WSDISPLAY_SCROLL_FORWARD);
+ return (1);
+ } else {
+ return (0);
+ }
+ }
+
+ case KS_Cmd_ScrollSlowUp:
+ case KS_Cmd_ScrollSlowDown:
+ if (*type == WSCONS_EVENT_KEY_DOWN) {
+ GETMODSTATE(sc->id->t_modifiers, state);
+ if ((sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_HOLD
+ && MOD_ONESET(sc->id, MOD_HOLDSCREEN))
+ || (sc->sc_scroll_data.mode == WSKBD_SCROLL_MODE_NORMAL
+ && sc->sc_scroll_data.modifier == state)) {
+ update_modifier(sc->id, *type, 0, MOD_COMMAND);
+ wsdisplay_scroll(sc->sc_base.me_dispdv,
+ (ksym == KS_Cmd_ScrollSlowUp) ?
+ WSDISPLAY_SCROLL_BACKWARD | WSDISPLAY_SCROLL_LOW:
+ WSDISPLAY_SCROLL_FORWARD | WSDISPLAY_SCROLL_LOW);
+ return (1);
+ } else {
+ return (0);
+ }
+ }
+#endif
+
case KS_Cmd:
update_modifier(sc->id, *type, 0, MOD_COMMAND);
ksym = ksym2;
@@ -1327,6 +1423,7 @@
return (0);
switch (ksym) {
+
#if defined(DDB) || defined(KGDB)
case KS_Cmd_Debugger:
if (sc->sc_isconsole) {
Index: sys/dev/wscons/wsconsio.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/wscons/wsconsio.h,v
retrieving revision 1.50
diff -u -r1.50 wsconsio.h
--- wsconsio.h 2002/04/07 09:25:47 1.50
+++ wsconsio.h 2002/06/30 20:05:50
@@ -99,6 +99,21 @@
u_int period; /* period, in milliseconds */
u_int volume; /* percentage of max volume */
};
+/* Manipulate the scrolling modifiers and mode */
+struct wskbd_scroll_data {
+ u_int which;
+ u_int mode;
+ u_int modifier;
+};
+
+/* Manipulate the scrolling values (how many lines to scroll) */
+
+struct wsdisplay_scroll_data {
+ u_int which;
+ u_int fastlines;
+ u_int slowlines;
+};
+
#define WSKBD_BELL_DOPITCH 0x1 /* get/set pitch */
#define WSKBD_BELL_DOPERIOD 0x2 /* get/set period */
#define WSKBD_BELL_DOVOLUME 0x4 /* get/set volume */
@@ -157,6 +172,15 @@
#define WSKBDIO_SETKEYCLICK _IOW('W', 21, int)
#define WSKBDIO_GETKEYCLICK _IOR('W', 22, int)
+#define WSKBDIO_GETSCROLL _IOR('W', 23, struct wskbd_scroll_data)
+#define WSKBDIO_SETSCROLL _IOW('W', 24, struct wskbd_scroll_data)
+
+#define WSKBD_SCROLL_MODE_NORMAL 0x00
+#define WSKBD_SCROLL_MODE_HOLD 0x01
+#define WSKBD_SCROLL_DOMODIFIER 0x01
+#define WSKBD_SCROLL_DOMODE 0x02
+#define WSKBD_SCROLL_DOALL 0x03
+
/*
* Mouse ioctls (32 - 63)
*/
@@ -294,6 +318,11 @@
#define WSDISPLAY_CURSOR_DOSHAPE 0x10 /* get/set img/mask */
#define WSDISPLAY_CURSOR_DOALL 0x1f /* all of the above */
+#define WSDISPLAY_SCROLL_DOFASTLINES 0x01
+#define WSDISPLAY_SCROLL_DOSLOWLINES 0x02
+#define WSDISPLAY_SCROLL_DOALL 0x03
+
+
/* Cursor control: get and set position */
#define WSDISPLAYIO_GCURPOS _IOR('W', 70, struct wsdisplay_curpos)
#define WSDISPLAYIO_SCURPOS _IOW('W', 71, struct wsdisplay_curpos)
@@ -374,6 +403,9 @@
};
#define WSDISPLAYIO_GETPARAM _IOWR('W', 82, struct wsdisplay_param)
#define WSDISPLAYIO_SETPARAM _IOWR('W', 83, struct wsdisplay_param)
+
+#define WSDISPLAYIO_DGSCROLL _IOR('W', 84, struct wsdisplay_scroll_data)
+#define WSDISPLAYIO_DSSCROLL _IOW('W', 85, struct wsdisplay_scroll_data)
/* XXX NOT YET DEFINED */
/* Mapping information retrieval. */
Index: sys/dev/wscons/wsksymdef.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/wscons/wsksymdef.h,v
retrieving revision 1.45
diff -u -r1.45 wsksymdef.h
--- wsksymdef.h 2002/04/23 13:42:46 1.45
+++ wsksymdef.h 2002/06/30 20:05:55
@@ -434,7 +434,10 @@
#define KS_Cmd_ContrastUp 0xf429
#define KS_Cmd_ContrastDown 0xf42a
#define KS_Cmd_ContrastRotate 0xf42b
-
+#define KS_Cmd_ScrollFastUp 0xf42c
+#define KS_Cmd_ScrollFastDown 0xf42d
+#define KS_Cmd_ScrollSlowUp 0xf42e
+#define KS_Cmd_ScrollSlowDown 0xf42f
/*
* Group 5 (internal)
Index: sbin/wsconsctl/display.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/wsconsctl/display.c,v
retrieving revision 1.2
diff -u -r1.2 display.c
--- display.c 2002/04/07 10:40:04 1.2
+++ display.c 2002/06/30 20:05:57
@@ -37,6 +37,7 @@
*/
#include <sys/ioctl.h>
+#include <stdio.h>
#include <sys/time.h>
#include <dev/wscons/wsconsio.h>
#include <err.h>
@@ -44,10 +45,13 @@
static int dpytype;
static struct wsdisplay_usefontdata font;
+static struct wsdisplay_scroll_data scroll_l;
struct field display_field_tab[] = {
- { "type", &dpytype, FMT_DPYTYPE, FLG_RDONLY },
- { "font", &font.name, FMT_STRING, FLG_WRONLY },
+ { "type", &dpytype, FMT_DPYTYPE, FLG_RDONLY },
+ { "font", &font.name, FMT_STRING, FLG_WRONLY },
+ { "scroll.fastlines", &scroll_l.fastlines, FMT_UINT, FLG_MODIFY },
+ { "scroll.slowlines", &scroll_l.slowlines, FMT_UINT, FLG_MODIFY },
};
int display_field_tab_len = sizeof(display_field_tab)/
@@ -60,6 +64,15 @@
if (field_by_value(&dpytype)->flags & FLG_GET)
if (ioctl(fd, WSDISPLAYIO_GTYPE, &dpytype) < 0)
err(1, "WSDISPLAYIO_GTYPE");
+
+ scroll_l.which = 0;
+ if (field_by_value(&scroll_l.fastlines)->flags & FLG_GET)
+ scroll_l.which |= WSDISPLAY_SCROLL_DOFASTLINES;
+ if (field_by_value(&scroll_l.slowlines)->flags & FLG_GET)
+ scroll_l.which |= WSDISPLAY_SCROLL_DOSLOWLINES;
+ if (scroll_l.which != 0 &&
+ ioctl(fd, WSDISPLAYIO_DGSCROLL, &scroll_l) < 0)
+ err(1, "WSDISPLAYIO_GSCROLL");
}
void
@@ -71,4 +84,19 @@
err(1, "WSDISPLAYIO_SFONT");
pr_field(field_by_value(&font.name), " -> ");
}
+
+ scroll_l.which = 0;
+ if (field_by_value(&scroll_l.fastlines)->flags & FLG_SET)
+ scroll_l.which |= WSDISPLAY_SCROLL_DOFASTLINES;
+ if (field_by_value(&scroll_l.slowlines)->flags & FLG_SET)
+ scroll_l.which |= WSDISPLAY_SCROLL_DOSLOWLINES;
+
+ if (scroll_l.which & WSDISPLAY_SCROLL_DOFASTLINES)
+ pr_field(field_by_value(&scroll_l.fastlines), " -> ");
+ if (scroll_l.which & WSDISPLAY_SCROLL_DOSLOWLINES)
+ pr_field(field_by_value(&scroll_l.slowlines), " -> ");
+ if (scroll_l.which != 0 &&
+ ioctl(fd, WSDISPLAYIO_DSSCROLL, &scroll_l) < 0)
+ err (1, "WSDISPLAYIO_SSCROLL");
+
}
Index: sbin/wsconsctl/keyboard.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/wsconsctl/keyboard.c,v
retrieving revision 1.3
diff -u -r1.3 keyboard.c
--- keyboard.c 2001/09/19 12:45:24 1.3
+++ keyboard.c 2002/06/30 20:06:00
@@ -52,6 +52,7 @@
and in util.c */
static struct wskbd_keyrepeat_data repeat;
static struct wskbd_keyrepeat_data dfrepeat;
+static struct wskbd_scroll_data scroll;
static int ledstate;
static kbd_t kbdencoding;
@@ -71,6 +72,8 @@
{ "ledstate", &ledstate, FMT_UINT, 0 },
{ "encoding", &kbdencoding, FMT_KBDENC, FLG_MODIFY },
{ "keyclick", &keyclick, FMT_UINT, FLG_MODIFY },
+ { "scroll.mode", &scroll.mode, FMT_UINT, FLG_MODIFY },
+ { "scroll.modifier", &scroll.modifier, FMT_UINT, FLG_MODIFY },
};
int keyboard_field_tab_len = sizeof(keyboard_field_tab)/
@@ -141,6 +144,15 @@
ioctl(fd, WSKBDIO_GETKEYCLICK, &keyclick);
/* Optional; don't complain. */
}
+
+ scroll.which = 0;
+ if (field_by_value(&scroll.mode)->flags & FLG_GET)
+ scroll.which |= WSKBD_SCROLL_DOMODE;
+ if (field_by_value(&scroll.modifier)->flags & FLG_GET)
+ scroll.which |= WSKBD_SCROLL_DOMODIFIER;
+ if (scroll.which != 0 &&
+ ioctl(fd, WSKBDIO_GETSCROLL, &scroll) < 0)
+ err(1, "WSKBDIO_GETSCROLL");
}
void
@@ -229,4 +241,20 @@
err(1, "WSKBDIO_SETKEYCLICK");
pr_field(field_by_value(&keyclick), " -> ");
}
+
+
+ scroll.which = 0;
+ if (field_by_value(&scroll.mode)->flags & FLG_SET)
+ scroll.which |= WSKBD_SCROLL_DOMODE;
+ if (field_by_value(&scroll.modifier)->flags & FLG_SET)
+ scroll.which |= WSKBD_SCROLL_DOMODIFIER;
+
+ if (scroll.which & WSKBD_SCROLL_DOMODE)
+ pr_field(field_by_value(&scroll.mode), " -> ");
+ if (scroll.which & WSKBD_SCROLL_DOMODIFIER)
+ pr_field(field_by_value(&scroll.modifier), " -> ");
+ if (scroll.which != 0 &&
+ ioctl(fd, WSKBDIO_SETSCROLL, &scroll) < 0)
+ err (1, "WSKBDIO_SETSCROLL");
}
+
Index: sys/dev/ic/vga.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/vga.c,v
retrieving revision 1.50
diff -u -r1.50 vga.c
--- vga.c 2002/04/04 13:08:35 1.50
+++ vga.c 2002/06/30 20:06:15
@@ -92,6 +92,8 @@
/* palette */
int mindispoffset, maxdispoffset;
+ int vga_rollover;
+ int visibleoffset;
};
static int vgaconsole, vga_console_type, vga_console_attached;
@@ -111,6 +113,7 @@
static int vga_mapchar(void *, int, unsigned int *);
static int vga_alloc_attr(void *, int, int, int, long *);
static void vga_copyrows(void *, int, int, int);
+void vga_scroll __P((void *, void *, int));
const struct wsdisplay_emulops vga_emulops = {
pcdisplay_cursor,
@@ -256,7 +259,12 @@
vga_alloc_screen,
vga_free_screen,
vga_show_screen,
- vga_load_font
+ vga_load_font,
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ vga_scroll
+#else
+ NULL
+#endif
};
/*
@@ -501,6 +509,9 @@
scr->pcs.dispoffset = scr->mindispoffset;
}
+ scr->pcs.visibleoffset = scr->pcs.dispoffset;
+ scr->vga_rollover = 0;
+
scr->pcs.vc_crow = cpos / type->ncols;
scr->pcs.vc_ccol = cpos % type->ncols;
pcdisplay_cursor_init(&scr->pcs, existing);
@@ -1290,3 +1301,48 @@
*index = idx1;
return (res1);
}
+
+void
+vga_scroll(v, cookie, lines)
+ void *v;
+ void *cookie;
+ int lines;
+{
+ struct vga_config *vc = v;
+ struct vgascreen *scr = cookie;
+ struct vga_handle *vh = &vc->hdl;
+
+ if (lines == 0) {
+ if (scr->pcs.visibleoffset == scr->pcs.dispoffset)
+ return;
+
+ scr->pcs.visibleoffset = scr->pcs.dispoffset;
+ }
+ else {
+ int vga_scr_end;
+ int margin = scr->pcs.type->ncols * 2;
+ int ul, we, p, st;
+
+ vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols *
+ scr->pcs.type->nrows * 2);
+ if (scr->vga_rollover > vga_scr_end + margin) {
+ ul = vga_scr_end;
+ we = scr->vga_rollover + scr->pcs.type->ncols * 2;
+ } else {
+ ul = 0;
+ we = 0x8000;
+ }
+ p = (scr->pcs.visibleoffset - ul + we) % we + lines *
+ (scr->pcs.type->ncols * 2);
+ st = (scr->pcs.dispoffset - ul + we) % we;
+ if (p < margin)
+ p = 0;
+ if (p > st - margin)
+ p = st;
+ scr->pcs.visibleoffset = (p + ul) % we;
+ }
+
+ vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9);
+ vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1);
+}
+
Index: sys/dev/ic/pcdisplay_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/pcdisplay_subr.c,v
retrieving revision 1.20
diff -u -r1.20 pcdisplay_subr.c
--- pcdisplay_subr.c 2001/11/13 13:14:43 1.20
+++ pcdisplay_subr.c 2002/06/30 20:06:18
@@ -173,6 +173,8 @@
c | (attr << 8));
else
scr->mem[off] = c | (attr << 8);
+
+ scr->visibleoffset = scr->dispoffset;
}
void
Index: sys/dev/ic/pcdisplayvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/pcdisplayvar.h,v
retrieving revision 1.8
diff -u -r1.8 pcdisplayvar.h
--- pcdisplayvar.h 2000/01/25 02:44:03 1.8
+++ pcdisplayvar.h 2002/06/30 20:06:19
@@ -49,6 +49,7 @@
int vc_ccol, vc_crow; /* current cursor position */
int dispoffset; /* offset of displayed area in video mem */
+ int visibleoffset;
};
struct pcdisplay_handle {
>Release-Note:
>Audit-Trail:
>Unformatted: