2004-08-13 08:03:38 +04:00
|
|
|
/* $NetBSD: vga.c,v 1.80 2004/08/13 04:03:38 mycroft Exp $ */
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Author: Chris G. Demetriou
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify and distribute this software and
|
|
|
|
* its documentation is hereby granted, provided that both the copyright
|
|
|
|
* notice and this permission notice appear in all copies of the
|
|
|
|
* software, derivative works or modified versions, and any portions
|
|
|
|
* thereof, and that both notices appear in supporting documentation.
|
|
|
|
*
|
|
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
|
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
|
|
|
|
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
* Carnegie Mellon requests users of this software to return to
|
|
|
|
*
|
|
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
|
|
|
* School of Computer Science
|
|
|
|
* Carnegie Mellon University
|
|
|
|
* Pittsburgh PA 15213-3890
|
|
|
|
*
|
|
|
|
* any improvements or extensions that they make and grant Carnegie the
|
|
|
|
* rights to redistribute these changes.
|
|
|
|
*/
|
|
|
|
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
/* for WSCONS_SUPPORT_PCVTFONTS and WSDISPLAY_CHARFUNCS */
|
|
|
|
#include "opt_wsdisplay_compat.h"
|
Implement border color customization in wscons(4), only available for vga(4)
at the moment.
This includes the addition of two new wsdisplay ioctls, WSDISPLAY_{G,S}BORDER,
one to get the actual color and one to set it, respectively. Possible colors
match those defined by ANSI (and listed in wsdisplayvar.h).
It also adds two accessops to the underlying graphics device, getborder and
setborder, which mach their ioctl counterparts.
Two kernel options are added: WSDISPLAY_CUSTOM_BORDER, which enables the
ioctls described above (to customize the border color from userland after
boot), and WSDISPLAY_BORDER_COLOR, which sets the color at boot time.
The former is enabled by default on the GENERIC kernel, but not on INSTALL
(among others). The later is always commented out, leaving the usual black
border as a default.
wsconsctl is modified to allow accessing this value easily. For example,
'wsconsctl -d -w border=blue'.
2004-07-30 02:29:35 +04:00
|
|
|
/* for WSDISPLAY_CUSTOM_BORDER */
|
|
|
|
#include "opt_wsdisplay_border.h"
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
/* for WSDISPLAY_CUSTOM_OUTPUT */
|
|
|
|
#include "opt_wsmsgattrs.h"
|
|
|
|
|
2001-11-13 16:14:31 +03:00
|
|
|
#include <sys/cdefs.h>
|
2004-08-13 08:03:38 +04:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.80 2004/08/13 04:03:38 mycroft Exp $");
|
2001-11-13 16:14:31 +03:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
2000-03-23 10:01:25 +03:00
|
|
|
#include <sys/callout.h>
|
1998-03-22 18:11:49 +03:00
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/device.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/queue.h>
|
|
|
|
#include <machine/bus.h>
|
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
#include <dev/ic/mc6845reg.h>
|
|
|
|
#include <dev/ic/pcdisplayvar.h>
|
|
|
|
#include <dev/ic/vgareg.h>
|
|
|
|
#include <dev/ic/vgavar.h>
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
#include <dev/wscons/wsdisplayvar.h>
|
|
|
|
#include <dev/wscons/wsconsio.h>
|
1999-02-20 21:27:53 +03:00
|
|
|
#include <dev/wscons/unicode.h>
|
2001-09-03 21:34:07 +04:00
|
|
|
#include <dev/wsfont/wsfont.h>
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1998-05-15 00:49:55 +04:00
|
|
|
#include <dev/ic/pcdisplay.h>
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2003-02-01 00:57:23 +03:00
|
|
|
int vga_no_builtinfont = 0;
|
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
static struct wsdisplay_font _vga_builtinfont = {
|
2003-01-27 17:46:10 +03:00
|
|
|
"builtin", /* typeface name */
|
|
|
|
0, /* firstchar */
|
|
|
|
256, /* numbers */
|
|
|
|
WSDISPLAY_FONTENC_IBM, /* encoding */
|
|
|
|
8, /* width */
|
|
|
|
16, /* height */
|
|
|
|
1, /* stride */
|
|
|
|
WSDISPLAY_FONTORDER_L2R, /* bit order */
|
|
|
|
0, /* byte order */
|
|
|
|
NULL /* data */
|
1999-01-13 19:48:58 +03:00
|
|
|
};
|
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
struct egavga_font {
|
|
|
|
struct wsdisplay_font *wsfont;
|
2002-07-01 20:56:09 +04:00
|
|
|
int cookie; /* wsfont handle, -1 invalid */
|
2001-09-03 21:34:07 +04:00
|
|
|
int slot; /* in adapter RAM */
|
|
|
|
int usecount;
|
|
|
|
TAILQ_ENTRY(egavga_font) next; /* LRU queue */
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct egavga_font vga_builtinfont = {
|
|
|
|
&_vga_builtinfont,
|
2002-07-01 20:56:09 +04:00
|
|
|
-1, 0
|
2001-09-03 21:34:07 +04:00
|
|
|
};
|
|
|
|
|
2001-09-04 19:32:22 +04:00
|
|
|
#ifdef VGA_CONSOLE_SCREENTYPE
|
|
|
|
static struct egavga_font vga_consolefont;
|
|
|
|
#endif
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
struct vgascreen {
|
1998-05-28 20:48:40 +04:00
|
|
|
struct pcdisplayscreen pcs;
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
LIST_ENTRY(vgascreen) next;
|
|
|
|
|
|
|
|
struct vga_config *cfg;
|
|
|
|
|
|
|
|
/* videostate */
|
2001-09-03 21:34:07 +04:00
|
|
|
struct egavga_font *fontset1, *fontset2;
|
1998-03-22 18:11:49 +03:00
|
|
|
/* font data */
|
|
|
|
/* palette */
|
1998-07-24 20:20:14 +04:00
|
|
|
|
|
|
|
int mindispoffset, maxdispoffset;
|
2004-05-29 01:42:29 +04:00
|
|
|
int vga_rollover;
|
|
|
|
int visibleoffset;
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static int vgaconsole, vga_console_type, vga_console_attached;
|
|
|
|
static struct vgascreen vga_console_screen;
|
|
|
|
static struct vga_config vga_console_vc;
|
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
struct egavga_font *egavga_getfont(struct vga_config *, struct vgascreen *,
|
2003-02-09 13:29:35 +03:00
|
|
|
const char *, int);
|
2001-09-03 21:34:07 +04:00
|
|
|
void egavga_unreffont(struct vga_config *, struct egavga_font *);
|
|
|
|
|
2003-02-09 13:29:35 +03:00
|
|
|
int vga_selectfont(struct vga_config *, struct vgascreen *, const char *,
|
|
|
|
const char *);
|
2001-12-13 11:31:39 +03:00
|
|
|
void vga_init_screen(struct vga_config *, struct vgascreen *,
|
|
|
|
const struct wsscreen_descr *, int, long *);
|
|
|
|
void vga_init(struct vga_config *, bus_space_tag_t, bus_space_tag_t);
|
|
|
|
static void vga_setfont(struct vga_config *, struct vgascreen *);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2001-12-13 11:31:39 +03:00
|
|
|
static int vga_mapchar(void *, int, unsigned int *);
|
2004-05-29 01:42:29 +04:00
|
|
|
void vga_putchar(void *, int, int, u_int, long);
|
2002-07-04 18:37:10 +04:00
|
|
|
static int vga_allocattr(void *, int, int, int, long *);
|
2001-12-13 11:31:39 +03:00
|
|
|
static void vga_copyrows(void *, int, int, int);
|
2004-05-29 06:04:56 +04:00
|
|
|
#ifdef WSDISPLAY_SCROLLSUPPORT
|
2004-05-29 01:42:29 +04:00
|
|
|
void vga_scroll (void *, void *, int);
|
2004-05-29 06:04:56 +04:00
|
|
|
#endif
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
const struct wsdisplay_emulops vga_emulops = {
|
1998-05-28 20:48:40 +04:00
|
|
|
pcdisplay_cursor,
|
1999-01-13 19:48:58 +03:00
|
|
|
vga_mapchar,
|
2004-05-29 01:42:29 +04:00
|
|
|
vga_putchar,
|
1998-05-28 20:48:40 +04:00
|
|
|
pcdisplay_copycols,
|
|
|
|
pcdisplay_erasecols,
|
1998-07-24 20:20:14 +04:00
|
|
|
vga_copyrows,
|
1998-05-28 20:48:40 +04:00
|
|
|
pcdisplay_eraserows,
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
vga_allocattr,
|
|
|
|
#ifdef WSDISPLAY_CUSTOM_OUTPUT
|
|
|
|
pcdisplay_replaceattr,
|
|
|
|
#else
|
|
|
|
NULL,
|
|
|
|
#endif
|
1998-05-15 00:49:55 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* translate WS(=ANSI) color codes to standard pc ones
|
|
|
|
*/
|
2001-01-18 23:28:15 +03:00
|
|
|
static const unsigned char fgansitopc[] = {
|
1998-05-15 00:49:55 +04:00
|
|
|
#ifdef __alpha__
|
|
|
|
/*
|
|
|
|
* XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
|
|
|
|
* XXX We should probably not bother with this
|
|
|
|
* XXX (reinitialize the palette registers).
|
|
|
|
*/
|
|
|
|
FG_BLACK, FG_BLUE, FG_GREEN, FG_CYAN, FG_RED,
|
|
|
|
FG_MAGENTA, FG_BROWN, FG_LIGHTGREY
|
|
|
|
#else
|
|
|
|
FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
|
|
|
|
FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
|
|
|
|
#endif
|
|
|
|
}, bgansitopc[] = {
|
|
|
|
#ifdef __alpha__
|
|
|
|
BG_BLACK, BG_BLUE, BG_GREEN, BG_CYAN, BG_RED,
|
|
|
|
BG_MAGENTA, BG_BROWN, BG_LIGHTGREY
|
|
|
|
#else
|
|
|
|
BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
|
|
|
|
BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
|
|
|
|
#endif
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
2000-09-10 15:44:13 +04:00
|
|
|
const struct wsscreen_descr vga_25lscreen = {
|
1998-03-22 18:11:49 +03:00
|
|
|
"80x25", 80, 25,
|
|
|
|
&vga_emulops,
|
1998-05-15 00:49:55 +04:00
|
|
|
8, 16,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
|
2000-09-10 15:44:13 +04:00
|
|
|
}, vga_25lscreen_mono = {
|
1998-05-15 00:49:55 +04:00
|
|
|
"80x25", 80, 25,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 16,
|
|
|
|
WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
|
2000-09-10 15:44:13 +04:00
|
|
|
}, vga_25lscreen_bf = {
|
1999-01-13 19:48:58 +03:00
|
|
|
"80x25bf", 80, 25,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 16,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_BLINK
|
1999-04-10 18:02:11 +04:00
|
|
|
}, vga_40lscreen = {
|
|
|
|
"80x40", 80, 40,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 10,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
|
|
|
|
}, vga_40lscreen_mono = {
|
|
|
|
"80x40", 80, 40,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 10,
|
|
|
|
WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
|
|
|
|
}, vga_40lscreen_bf = {
|
|
|
|
"80x40bf", 80, 40,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 10,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_BLINK
|
1999-01-13 19:48:58 +03:00
|
|
|
}, vga_50lscreen = {
|
1998-03-22 18:11:49 +03:00
|
|
|
"80x50", 80, 50,
|
|
|
|
&vga_emulops,
|
1998-05-15 00:49:55 +04:00
|
|
|
8, 8,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
|
|
|
|
}, vga_50lscreen_mono = {
|
|
|
|
"80x50", 80, 50,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 8,
|
|
|
|
WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
|
1999-01-13 19:48:58 +03:00
|
|
|
}, vga_50lscreen_bf = {
|
|
|
|
"80x50bf", 80, 50,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 8,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_BLINK
|
2000-07-15 22:47:54 +04:00
|
|
|
}, vga_24lscreen = {
|
|
|
|
"80x24", 80, 24,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 16,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
|
|
|
|
}, vga_24lscreen_mono = {
|
|
|
|
"80x24", 80, 24,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 16,
|
|
|
|
WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
|
|
|
|
}, vga_24lscreen_bf = {
|
|
|
|
"80x24bf", 80, 24,
|
|
|
|
&vga_emulops,
|
|
|
|
8, 16,
|
|
|
|
WSSCREEN_WSCOLORS | WSSCREEN_BLINK
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
1999-01-13 19:48:58 +03:00
|
|
|
#define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT))
|
|
|
|
|
1998-04-07 20:35:42 +04:00
|
|
|
const struct wsscreen_descr *_vga_scrlist[] = {
|
2000-09-10 15:44:13 +04:00
|
|
|
&vga_25lscreen,
|
|
|
|
&vga_25lscreen_bf,
|
1999-04-10 18:02:11 +04:00
|
|
|
&vga_40lscreen,
|
|
|
|
&vga_40lscreen_bf,
|
1998-03-22 18:11:49 +03:00
|
|
|
&vga_50lscreen,
|
1999-01-13 19:48:58 +03:00
|
|
|
&vga_50lscreen_bf,
|
2000-07-15 22:47:54 +04:00
|
|
|
&vga_24lscreen,
|
|
|
|
&vga_24lscreen_bf,
|
1998-03-22 18:11:49 +03:00
|
|
|
/* XXX other formats, graphics screen? */
|
1998-05-15 00:49:55 +04:00
|
|
|
}, *_vga_scrlist_mono[] = {
|
2000-09-10 15:44:13 +04:00
|
|
|
&vga_25lscreen_mono,
|
1999-04-10 18:02:11 +04:00
|
|
|
&vga_40lscreen_mono,
|
1998-05-15 00:49:55 +04:00
|
|
|
&vga_50lscreen_mono,
|
2000-07-15 22:47:54 +04:00
|
|
|
&vga_24lscreen_mono,
|
1998-05-15 00:49:55 +04:00
|
|
|
/* XXX other formats, graphics screen? */
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
1998-05-15 00:49:55 +04:00
|
|
|
const struct wsscreen_list vga_screenlist = {
|
|
|
|
sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *),
|
|
|
|
_vga_scrlist
|
|
|
|
}, vga_screenlist_mono = {
|
|
|
|
sizeof(_vga_scrlist_mono) / sizeof(struct wsscreen_descr *),
|
|
|
|
_vga_scrlist_mono
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
2003-06-30 02:28:00 +04:00
|
|
|
static int vga_ioctl(void *, u_long, caddr_t, int, struct proc *);
|
2001-12-13 11:31:39 +03:00
|
|
|
static paddr_t vga_mmap(void *, off_t, int);
|
|
|
|
static int vga_alloc_screen(void *, const struct wsscreen_descr *,
|
|
|
|
void **, int *, int *, long *);
|
|
|
|
static void vga_free_screen(void *, void *);
|
|
|
|
static int vga_show_screen(void *, void *, int,
|
|
|
|
void (*)(void *, int, int), void *);
|
|
|
|
static int vga_load_font(void *, void *, struct wsdisplay_font *);
|
2002-07-01 17:17:48 +04:00
|
|
|
#ifdef WSDISPLAY_CHARFUNCS
|
2002-06-27 03:05:33 +04:00
|
|
|
static int vga_getwschar(void *, struct wsdisplay_char *);
|
|
|
|
static int vga_putwschar(void *, struct wsdisplay_char *);
|
2002-07-01 17:17:48 +04:00
|
|
|
#endif /* WSDISPLAY_CHARFUNCS */
|
Implement border color customization in wscons(4), only available for vga(4)
at the moment.
This includes the addition of two new wsdisplay ioctls, WSDISPLAY_{G,S}BORDER,
one to get the actual color and one to set it, respectively. Possible colors
match those defined by ANSI (and listed in wsdisplayvar.h).
It also adds two accessops to the underlying graphics device, getborder and
setborder, which mach their ioctl counterparts.
Two kernel options are added: WSDISPLAY_CUSTOM_BORDER, which enables the
ioctls described above (to customize the border color from userland after
boot), and WSDISPLAY_BORDER_COLOR, which sets the color at boot time.
The former is enabled by default on the GENERIC kernel, but not on INSTALL
(among others). The later is always commented out, leaving the usual black
border as a default.
wsconsctl is modified to allow accessing this value easily. For example,
'wsconsctl -d -w border=blue'.
2004-07-30 02:29:35 +04:00
|
|
|
#ifdef WSDISPLAY_CUSTOM_BORDER
|
|
|
|
static u_int vga_getborder(void *);
|
|
|
|
static int vga_setborder(void *, u_int);
|
|
|
|
#endif /* WSDISPLAY_CUSTOM_BORDER */
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2001-12-13 11:31:39 +03:00
|
|
|
void vga_doswitch(struct vga_config *);
|
1999-12-06 21:54:50 +03:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
const struct wsdisplay_accessops vga_accessops = {
|
|
|
|
vga_ioctl,
|
|
|
|
vga_mmap,
|
|
|
|
vga_alloc_screen,
|
|
|
|
vga_free_screen,
|
|
|
|
vga_show_screen,
|
2002-06-27 03:05:33 +04:00
|
|
|
vga_load_font,
|
|
|
|
NULL,
|
2002-07-01 17:17:48 +04:00
|
|
|
#ifdef WSDISPLAY_CHARFUNCS
|
2002-06-27 03:05:33 +04:00
|
|
|
vga_getwschar,
|
2004-05-29 02:38:28 +04:00
|
|
|
vga_putwschar,
|
2002-07-01 17:17:48 +04:00
|
|
|
#else /* WSDISPLAY_CHARFUNCS */
|
|
|
|
NULL,
|
2004-05-29 02:38:28 +04:00
|
|
|
NULL,
|
2002-07-01 17:17:48 +04:00
|
|
|
#endif /* WSDISPLAY_CHARFUNCS */
|
2004-05-29 02:38:28 +04:00
|
|
|
#ifdef WSDISPLAY_SCROLLSUPPORT
|
|
|
|
vga_scroll,
|
|
|
|
#else
|
|
|
|
NULL,
|
|
|
|
#endif
|
Implement border color customization in wscons(4), only available for vga(4)
at the moment.
This includes the addition of two new wsdisplay ioctls, WSDISPLAY_{G,S}BORDER,
one to get the actual color and one to set it, respectively. Possible colors
match those defined by ANSI (and listed in wsdisplayvar.h).
It also adds two accessops to the underlying graphics device, getborder and
setborder, which mach their ioctl counterparts.
Two kernel options are added: WSDISPLAY_CUSTOM_BORDER, which enables the
ioctls described above (to customize the border color from userland after
boot), and WSDISPLAY_BORDER_COLOR, which sets the color at boot time.
The former is enabled by default on the GENERIC kernel, but not on INSTALL
(among others). The later is always commented out, leaving the usual black
border as a default.
wsconsctl is modified to allow accessing this value easily. For example,
'wsconsctl -d -w border=blue'.
2004-07-30 02:29:35 +04:00
|
|
|
#ifdef WSDISPLAY_CUSTOM_BORDER
|
|
|
|
vga_getborder,
|
|
|
|
vga_setborder,
|
|
|
|
#else /* WSDISPLAY_CUSTOM_BORDER */
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
#endif /* WSDISPLAY_CUSTOM_BORDER */
|
1998-03-22 18:11:49 +03:00
|
|
|
};
|
|
|
|
|
1999-01-13 19:48:58 +03:00
|
|
|
/*
|
1999-03-22 21:24:23 +03:00
|
|
|
* We want at least ASCII 32..127 be present in the
|
|
|
|
* first font slot.
|
1999-01-13 19:48:58 +03:00
|
|
|
*/
|
|
|
|
#define vga_valid_primary_font(f) \
|
2001-09-03 21:34:07 +04:00
|
|
|
(f->wsfont->encoding == WSDISPLAY_FONTENC_IBM || \
|
|
|
|
f->wsfont->encoding == WSDISPLAY_FONTENC_ISO || \
|
|
|
|
f->wsfont->encoding == WSDISPLAY_FONTENC_ISO7)
|
|
|
|
|
|
|
|
struct egavga_font *
|
2003-02-09 13:29:35 +03:00
|
|
|
egavga_getfont(struct vga_config *vc, struct vgascreen *scr, const char *name,
|
2001-12-13 11:31:39 +03:00
|
|
|
int primary)
|
2001-09-03 21:34:07 +04:00
|
|
|
{
|
|
|
|
struct egavga_font *f;
|
|
|
|
int cookie;
|
|
|
|
struct wsdisplay_font *wf;
|
|
|
|
|
|
|
|
TAILQ_FOREACH(f, &vc->vc_fontlist, next) {
|
|
|
|
if (wsfont_matches(f->wsfont, name,
|
2003-01-27 17:46:10 +03:00
|
|
|
8, scr->pcs.type->fontheight, 0) &&
|
2001-09-03 21:34:07 +04:00
|
|
|
(!primary || vga_valid_primary_font(f))) {
|
|
|
|
#ifdef VGAFONTDEBUG
|
|
|
|
if (scr != &vga_console_screen || vga_console_attached)
|
|
|
|
printf("vga_getfont: %s already present\n",
|
2003-01-27 17:46:10 +03:00
|
|
|
name ? name : "<default>");
|
2001-09-03 21:34:07 +04:00
|
|
|
#endif
|
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-14 02:17:18 +03:00
|
|
|
cookie = wsfont_find(name, 8, scr->pcs.type->fontheight, 0,
|
2003-01-27 17:46:10 +03:00
|
|
|
WSDISPLAY_FONTORDER_L2R, 0);
|
2001-09-03 21:34:07 +04:00
|
|
|
/* XXX obey "primary" */
|
|
|
|
if (cookie == -1) {
|
|
|
|
#ifdef VGAFONTDEBUG
|
|
|
|
if (scr != &vga_console_screen || vga_console_attached)
|
2002-06-26 01:07:42 +04:00
|
|
|
printf("vga_getfont: %s not found\n",
|
2003-01-27 17:46:10 +03:00
|
|
|
name ? name : "<default>");
|
2001-09-03 21:34:07 +04:00
|
|
|
#endif
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2002-03-13 18:05:13 +03:00
|
|
|
if (wsfont_lock(cookie, &wf))
|
2001-09-03 21:34:07 +04:00
|
|
|
return (0);
|
|
|
|
|
2001-09-04 19:32:22 +04:00
|
|
|
#ifdef VGA_CONSOLE_SCREENTYPE
|
|
|
|
if (scr == &vga_console_screen)
|
|
|
|
f = &vga_consolefont;
|
|
|
|
else
|
|
|
|
#endif
|
2001-09-03 21:34:07 +04:00
|
|
|
f = malloc(sizeof(struct egavga_font), M_DEVBUF, M_NOWAIT);
|
|
|
|
if (!f) {
|
|
|
|
wsfont_unlock(cookie);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
f->wsfont = wf;
|
|
|
|
f->cookie = cookie;
|
|
|
|
f->slot = -1; /* not yet loaded */
|
|
|
|
f->usecount = 0; /* incremented below */
|
|
|
|
TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
|
|
|
|
|
|
|
|
found:
|
|
|
|
f->usecount++;
|
|
|
|
#ifdef VGAFONTDEBUG
|
|
|
|
if (scr != &vga_console_screen || vga_console_attached)
|
|
|
|
printf("vga_getfont: usecount=%d\n", f->usecount);
|
|
|
|
#endif
|
|
|
|
return (f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
egavga_unreffont(struct vga_config *vc, struct egavga_font *f)
|
2001-09-03 21:34:07 +04:00
|
|
|
{
|
|
|
|
|
|
|
|
f->usecount--;
|
|
|
|
#ifdef VGAFONTDEBUG
|
|
|
|
printf("vga_unreffont: usecount=%d\n", f->usecount);
|
|
|
|
#endif
|
2002-07-01 20:56:09 +04:00
|
|
|
if (f->usecount == 0 && f->cookie != -1) {
|
2001-09-03 21:34:07 +04:00
|
|
|
TAILQ_REMOVE(&vc->vc_fontlist, f, next);
|
2001-09-10 11:29:54 +04:00
|
|
|
if (f->slot != -1) {
|
|
|
|
KASSERT(vc->vc_fonts[f->slot] == f);
|
|
|
|
vc->vc_fonts[f->slot] = 0;
|
|
|
|
}
|
2001-09-03 21:34:07 +04:00
|
|
|
wsfont_unlock(f->cookie);
|
2001-09-04 19:32:22 +04:00
|
|
|
#ifdef VGA_CONSOLE_SCREENTYPE
|
|
|
|
if (f != &vga_consolefont)
|
|
|
|
#endif
|
2001-09-03 21:34:07 +04:00
|
|
|
free(f, M_DEVBUF);
|
|
|
|
}
|
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
int
|
2003-02-09 13:29:35 +03:00
|
|
|
vga_selectfont(struct vga_config *vc, struct vgascreen *scr, const char *name1,
|
|
|
|
const char *name2)
|
1999-01-13 19:48:58 +03:00
|
|
|
{
|
|
|
|
const struct wsscreen_descr *type = scr->pcs.type;
|
2001-09-03 21:34:07 +04:00
|
|
|
struct egavga_font *f1, *f2;
|
1999-01-13 19:48:58 +03:00
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
f1 = egavga_getfont(vc, scr, name1, 1);
|
|
|
|
if (!f1)
|
|
|
|
return (ENXIO);
|
|
|
|
|
|
|
|
if (VGA_SCREEN_CANTWOFONTS(type) && name2) {
|
|
|
|
f2 = egavga_getfont(vc, scr, name2, 0);
|
|
|
|
if (!f2) {
|
|
|
|
egavga_unreffont(vc, f1);
|
|
|
|
return (ENXIO);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
2001-09-03 21:34:07 +04:00
|
|
|
} else
|
|
|
|
f2 = 0;
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
#ifdef VGAFONTDEBUG
|
2001-09-03 21:34:07 +04:00
|
|
|
if (scr != &vga_console_screen || vga_console_attached) {
|
|
|
|
printf("vga (%s): font1=%s (slot %d)", type->name,
|
2003-01-27 17:46:10 +03:00
|
|
|
f1->wsfont->name, f1->slot);
|
2001-09-03 21:34:07 +04:00
|
|
|
if (f2)
|
|
|
|
printf(", font2=%s (slot %d)",
|
2003-01-27 17:46:10 +03:00
|
|
|
f2->wsfont->name, f2->slot);
|
2001-09-03 21:34:07 +04:00
|
|
|
printf("\n");
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
2001-09-03 21:34:07 +04:00
|
|
|
#endif
|
|
|
|
if (scr->fontset1)
|
|
|
|
egavga_unreffont(vc, scr->fontset1);
|
|
|
|
scr->fontset1 = f1;
|
|
|
|
if (scr->fontset2)
|
|
|
|
egavga_unreffont(vc, scr->fontset2);
|
|
|
|
scr->fontset2 = f2;
|
|
|
|
return (0);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_init_screen(struct vga_config *vc, struct vgascreen *scr,
|
|
|
|
const struct wsscreen_descr *type, int existing, long *attrp)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
1998-07-24 20:20:14 +04:00
|
|
|
int cpos;
|
1998-05-15 00:49:55 +04:00
|
|
|
int res;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
scr->cfg = vc;
|
|
|
|
scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl;
|
|
|
|
scr->pcs.type = type;
|
2001-09-04 21:06:54 +04:00
|
|
|
scr->pcs.active = existing;
|
1998-07-24 20:20:14 +04:00
|
|
|
scr->mindispoffset = 0;
|
2002-07-08 23:45:28 +04:00
|
|
|
if (vc->vc_quirks & VGA_QUIRK_NOFASTSCROLL)
|
|
|
|
scr->maxdispoffset = 0;
|
|
|
|
else
|
|
|
|
scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
if (existing) {
|
2001-09-04 21:06:54 +04:00
|
|
|
vc->active = scr;
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
|
|
|
|
cpos |= vga_6845_read(&vc->hdl, cursorl);
|
|
|
|
|
|
|
|
/* make sure we have a valid cursor position */
|
|
|
|
if (cpos < 0 || cpos >= type->nrows * type->ncols)
|
|
|
|
cpos = 0;
|
1998-07-24 20:20:14 +04:00
|
|
|
|
|
|
|
scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9;
|
|
|
|
scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1;
|
|
|
|
|
|
|
|
/* make sure we have a valid memory offset */
|
|
|
|
if (scr->pcs.dispoffset < scr->mindispoffset ||
|
|
|
|
scr->pcs.dispoffset > scr->maxdispoffset)
|
|
|
|
scr->pcs.dispoffset = scr->mindispoffset;
|
2001-09-07 21:10:13 +04:00
|
|
|
|
|
|
|
if (type != vc->currenttype) {
|
|
|
|
vga_setscreentype(&vc->hdl, type);
|
|
|
|
vc->currenttype = type;
|
|
|
|
}
|
1998-07-24 20:20:14 +04:00
|
|
|
} else {
|
|
|
|
cpos = 0;
|
|
|
|
scr->pcs.dispoffset = scr->mindispoffset;
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
2004-05-29 01:42:29 +04:00
|
|
|
scr->pcs.visibleoffset = scr->pcs.dispoffset;
|
|
|
|
scr->vga_rollover = 0;
|
|
|
|
|
2002-07-07 10:36:32 +04:00
|
|
|
scr->pcs.cursorrow = cpos / type->ncols;
|
|
|
|
scr->pcs.cursorcol = cpos % type->ncols;
|
2000-01-25 05:44:03 +03:00
|
|
|
pcdisplay_cursor_init(&scr->pcs, existing);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
#ifdef __alpha__
|
1998-05-28 20:48:40 +04:00
|
|
|
if (!vc->hdl.vh_mono)
|
1998-05-15 00:49:55 +04:00
|
|
|
/*
|
|
|
|
* DEC firmware uses a blue background.
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
* XXX These should be specified as kernel options for
|
|
|
|
* XXX alpha only, not hardcoded here (which is wrong
|
|
|
|
* XXX anyway because the emulation layer will assume
|
|
|
|
* XXX the default attribute is white on black).
|
1998-05-15 00:49:55 +04:00
|
|
|
*/
|
2002-07-04 18:37:10 +04:00
|
|
|
res = vga_allocattr(scr, WSCOL_WHITE, WSCOL_BLUE,
|
2003-01-27 17:46:10 +03:00
|
|
|
WSATTR_WSCOLORS, attrp);
|
1998-05-15 00:49:55 +04:00
|
|
|
else
|
|
|
|
#endif
|
2002-07-04 18:37:10 +04:00
|
|
|
res = vga_allocattr(scr, 0, 0, 0, attrp);
|
1998-05-15 00:49:55 +04:00
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
if (res)
|
|
|
|
panic("vga_init_screen: attribute botch");
|
1998-03-22 18:11:49 +03:00
|
|
|
#endif
|
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
scr->pcs.mem = NULL;
|
1999-03-22 21:24:23 +03:00
|
|
|
|
|
|
|
scr->fontset1 = scr->fontset2 = 0;
|
1999-01-13 19:48:58 +03:00
|
|
|
if (vga_selectfont(vc, scr, 0, 0)) {
|
|
|
|
if (scr == &vga_console_screen)
|
|
|
|
panic("vga_init_screen: no font");
|
|
|
|
else
|
|
|
|
printf("vga_init_screen: no font\n");
|
|
|
|
}
|
2001-09-07 21:10:13 +04:00
|
|
|
if (existing)
|
|
|
|
vga_setfont(vc, scr);
|
1999-03-22 21:24:23 +03:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
vc->nscreens++;
|
|
|
|
LIST_INSERT_HEAD(&vc->screens, scr, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_init(struct vga_config *vc, bus_space_tag_t iot, bus_space_tag_t memt)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
|
|
|
struct vga_handle *vh = &vc->hdl;
|
|
|
|
u_int8_t mor;
|
1999-01-13 19:48:58 +03:00
|
|
|
int i;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2003-01-27 17:46:10 +03:00
|
|
|
vh->vh_iot = iot;
|
|
|
|
vh->vh_memt = memt;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2003-01-27 17:46:10 +03:00
|
|
|
if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
|
|
|
|
panic("vga_init: couldn't map vga io");
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
/* read "misc output register" */
|
2003-01-27 18:16:10 +03:00
|
|
|
mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_MISC_DATAR);
|
1998-05-28 20:48:40 +04:00
|
|
|
vh->vh_mono = !(mor & 1);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
|
2003-01-27 17:46:10 +03:00
|
|
|
&vh->vh_ioh_6845))
|
|
|
|
panic("vga_init: couldn't map 6845 io");
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2003-01-27 17:46:10 +03:00
|
|
|
if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
|
|
|
|
panic("vga_init: couldn't map memory");
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2003-01-27 17:46:10 +03:00
|
|
|
if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
|
|
|
|
(vh->vh_mono ? 0x10000 : 0x18000), 0x8000, &vh->vh_memh))
|
|
|
|
panic("vga_init: mem subrange failed");
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1998-06-12 22:41:01 +04:00
|
|
|
/* should only reserve the space (no need to map - save KVM) */
|
|
|
|
vc->vc_biostag = memt;
|
2003-01-27 17:46:10 +03:00
|
|
|
if (bus_space_map(vc->vc_biostag, 0xc0000, 0x8000, 0, &vc->vc_bioshdl))
|
1998-06-12 22:41:01 +04:00
|
|
|
vc->vc_biosmapped = 0;
|
|
|
|
else
|
|
|
|
vc->vc_biosmapped = 1;
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
vc->nscreens = 0;
|
|
|
|
LIST_INIT(&vc->screens);
|
|
|
|
vc->active = NULL;
|
2000-09-15 18:13:01 +04:00
|
|
|
vc->currenttype = vh->vh_mono ? &vga_25lscreen_mono : &vga_25lscreen;
|
2000-03-23 10:01:25 +03:00
|
|
|
callout_init(&vc->vc_switch_callout);
|
1999-01-13 19:48:58 +03:00
|
|
|
|
2003-02-01 00:57:23 +03:00
|
|
|
wsfont_init();
|
|
|
|
if (vga_no_builtinfont) {
|
|
|
|
struct wsdisplay_font *wf;
|
|
|
|
int cookie;
|
|
|
|
|
|
|
|
cookie = wsfont_find(NULL, 8, 16, 0,
|
|
|
|
WSDISPLAY_FONTORDER_L2R, 0);
|
|
|
|
if (cookie == -1 || wsfont_lock(cookie, &wf))
|
|
|
|
panic("vga_init: can't load console font");
|
|
|
|
vga_loadchars(&vc->hdl, 0, wf->firstchar, wf->numchars,
|
|
|
|
wf->fontheight, wf->data);
|
|
|
|
vga_builtinfont.wsfont = wf;
|
|
|
|
vga_builtinfont.cookie = cookie;
|
|
|
|
vga_builtinfont.slot = 0;
|
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
vc->vc_fonts[0] = &vga_builtinfont;
|
1999-12-13 17:04:06 +03:00
|
|
|
for (i = 1; i < 8; i++)
|
1999-01-13 19:48:58 +03:00
|
|
|
vc->vc_fonts[i] = 0;
|
2001-09-03 21:34:07 +04:00
|
|
|
TAILQ_INIT(&vc->vc_fontlist);
|
|
|
|
TAILQ_INSERT_HEAD(&vc->vc_fontlist, &vga_builtinfont, next);
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
vc->currentfontset1 = vc->currentfontset2 = 0;
|
Implement border color customization in wscons(4), only available for vga(4)
at the moment.
This includes the addition of two new wsdisplay ioctls, WSDISPLAY_{G,S}BORDER,
one to get the actual color and one to set it, respectively. Possible colors
match those defined by ANSI (and listed in wsdisplayvar.h).
It also adds two accessops to the underlying graphics device, getborder and
setborder, which mach their ioctl counterparts.
Two kernel options are added: WSDISPLAY_CUSTOM_BORDER, which enables the
ioctls described above (to customize the border color from userland after
boot), and WSDISPLAY_BORDER_COLOR, which sets the color at boot time.
The former is enabled by default on the GENERIC kernel, but not on INSTALL
(among others). The later is always commented out, leaving the usual black
border as a default.
wsconsctl is modified to allow accessing this value easily. For example,
'wsconsctl -d -w border=blue'.
2004-07-30 02:29:35 +04:00
|
|
|
|
2004-07-30 14:47:20 +04:00
|
|
|
if (!vh->vh_mono && (u_int)WSDISPLAY_BORDER_COLOR < sizeof(fgansitopc))
|
|
|
|
_vga_attr_write(vh, VGA_ATC_OVERSCAN,
|
|
|
|
fgansitopc[WSDISPLAY_BORDER_COLOR]);
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_common_attach(struct vga_softc *sc, bus_space_tag_t iot,
|
2002-06-29 02:24:11 +04:00
|
|
|
bus_space_tag_t memt, int type, int quirks,
|
|
|
|
const struct vga_funcs *vf)
|
2000-06-17 11:11:50 +04:00
|
|
|
{
|
1998-03-22 18:11:49 +03:00
|
|
|
int console;
|
|
|
|
struct vga_config *vc;
|
|
|
|
struct wsemuldisplaydev_attach_args aa;
|
|
|
|
|
|
|
|
console = vga_is_console(iot, type);
|
|
|
|
|
|
|
|
if (console) {
|
|
|
|
vc = &vga_console_vc;
|
|
|
|
vga_console_attached = 1;
|
|
|
|
} else {
|
|
|
|
vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK);
|
|
|
|
vga_init(vc, iot, memt);
|
|
|
|
}
|
|
|
|
|
2002-06-29 02:24:11 +04:00
|
|
|
if (quirks & VGA_QUIRK_ONEFONT) {
|
|
|
|
vc->vc_nfontslots = 1;
|
2002-07-01 20:56:09 +04:00
|
|
|
#ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
|
|
|
|
/*
|
|
|
|
* XXX maybe invalidate font in slot > 0, but this can
|
|
|
|
* only be happen with VGA_CONSOLE_SCREENTYPE, and then
|
|
|
|
* we require VGA_CONSOLE_ATI_BROKEN_FONTSEL anyway.
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
} else {
|
2002-06-29 02:24:11 +04:00
|
|
|
vc->vc_nfontslots = 8;
|
2002-07-01 20:56:09 +04:00
|
|
|
#ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
|
|
|
|
/*
|
|
|
|
* XXX maybe validate builtin font shifted to slot 1 if
|
|
|
|
* slot 0 got overwritten because of VGA_CONSOLE_SCREENTYPE,
|
|
|
|
* but it will be reloaded anyway if needed.
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Save the builtin font to memory. In case it got overwritten
|
|
|
|
* in console initialization, use the copy in slot 1.
|
|
|
|
*/
|
|
|
|
#ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
|
|
|
|
#define BUILTINFONTLOC (vga_builtinfont.slot == -1 ? 1 : 0)
|
|
|
|
#else
|
|
|
|
KASSERT(vga_builtinfont.slot == 0);
|
|
|
|
#define BUILTINFONTLOC (0)
|
|
|
|
#endif
|
2003-02-01 00:57:23 +03:00
|
|
|
if (!vga_no_builtinfont) {
|
2003-02-09 13:29:35 +03:00
|
|
|
char *data =
|
2003-02-01 00:57:23 +03:00
|
|
|
malloc(256 * vga_builtinfont.wsfont->fontheight,
|
|
|
|
M_DEVBUF, M_WAITOK);
|
|
|
|
vga_readoutchars(&vc->hdl, BUILTINFONTLOC, 0, 256,
|
2003-02-09 13:29:35 +03:00
|
|
|
vga_builtinfont.wsfont->fontheight, data);
|
|
|
|
vga_builtinfont.wsfont->data = data;
|
2003-02-01 00:57:23 +03:00
|
|
|
}
|
2002-07-01 20:56:09 +04:00
|
|
|
|
2001-09-14 05:10:11 +04:00
|
|
|
vc->vc_type = type;
|
|
|
|
vc->vc_funcs = vf;
|
2002-07-08 23:45:28 +04:00
|
|
|
vc->vc_quirks = quirks;
|
2001-09-14 05:10:11 +04:00
|
|
|
|
|
|
|
sc->sc_vc = vc;
|
|
|
|
vc->softc = sc;
|
2000-06-17 11:11:50 +04:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
aa.console = console;
|
1998-05-28 20:48:40 +04:00
|
|
|
aa.scrdata = (vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist);
|
1998-03-22 18:11:49 +03:00
|
|
|
aa.accessops = &vga_accessops;
|
|
|
|
aa.accesscookie = vc;
|
|
|
|
|
2003-01-27 17:46:10 +03:00
|
|
|
config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, int type, int check)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
1998-05-15 00:49:55 +04:00
|
|
|
long defattr;
|
|
|
|
const struct wsscreen_descr *scr;
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
if (check && !vga_common_probe(iot, memt))
|
|
|
|
return (ENXIO);
|
|
|
|
|
|
|
|
/* set up bus-independent VGA configuration */
|
|
|
|
vga_init(&vga_console_vc, iot, memt);
|
2000-09-15 18:13:01 +04:00
|
|
|
#ifdef VGA_CONSOLE_SCREENTYPE
|
|
|
|
scr = wsdisplay_screentype_pick(vga_console_vc.hdl.vh_mono ?
|
2003-01-27 17:46:10 +03:00
|
|
|
&vga_screenlist_mono : &vga_screenlist, VGA_CONSOLE_SCREENTYPE);
|
2000-09-15 18:13:01 +04:00
|
|
|
if (!scr)
|
|
|
|
panic("vga_cnattach: invalid screen type");
|
|
|
|
#else
|
1999-01-09 18:29:26 +03:00
|
|
|
scr = vga_console_vc.currenttype;
|
2002-06-29 02:24:11 +04:00
|
|
|
#endif
|
|
|
|
#ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
|
|
|
|
/*
|
|
|
|
* On some (most/all?) ATI cards, only font slot 0 is usable.
|
|
|
|
* vga_init_screen() might need font slot 0 for a non-default
|
2002-07-01 20:56:09 +04:00
|
|
|
* console font, so save the builtin VGA font to another font slot.
|
|
|
|
* The attach() code will take care later.
|
2002-06-29 02:24:11 +04:00
|
|
|
*/
|
2002-07-08 23:45:28 +04:00
|
|
|
vga_console_vc.vc_quirks |= VGA_QUIRK_ONEFONT; /* redundant */
|
2002-06-29 02:24:11 +04:00
|
|
|
vga_copyfont01(&vga_console_vc.hdl);
|
|
|
|
vga_console_vc.vc_nfontslots = 1;
|
|
|
|
#else
|
|
|
|
vga_console_vc.vc_nfontslots = 8;
|
2000-09-15 18:13:01 +04:00
|
|
|
#endif
|
2004-08-08 23:21:27 +04:00
|
|
|
#ifdef notdef
|
2002-07-08 23:45:28 +04:00
|
|
|
/* until we know better, assume "fast scrolling" does not work */
|
|
|
|
vga_console_vc.vc_quirks |= VGA_QUIRK_NOFASTSCROLL;
|
2004-08-08 23:21:27 +04:00
|
|
|
#endif
|
2002-07-08 23:45:28 +04:00
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1998-05-15 00:49:55 +04:00
|
|
|
wsdisplay_cnattach(scr, &vga_console_screen,
|
2003-01-27 17:46:10 +03:00
|
|
|
vga_console_screen.pcs.cursorcol,
|
|
|
|
vga_console_screen.pcs.cursorrow, defattr);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
vgaconsole = 1;
|
|
|
|
vga_console_type = type;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_is_console(bus_space_tag_t iot, int type)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
|
|
|
if (vgaconsole &&
|
|
|
|
!vga_console_attached &&
|
|
|
|
iot == vga_console_vc.hdl.vh_iot &&
|
|
|
|
(vga_console_type == -1 || (type == vga_console_type)))
|
|
|
|
return (1);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:11:38 +03:00
|
|
|
static int
|
|
|
|
vga_get_video(struct vga_config *vc)
|
|
|
|
{
|
2003-01-27 18:16:10 +03:00
|
|
|
|
|
|
|
return (vga_ts_read(&vc->hdl, mode) & VGA_TS_MODE_BLANK) == 0;
|
2002-01-23 20:11:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vga_set_video(struct vga_config *vc, int state)
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
|
|
|
|
vga_ts_write(&vc->hdl, syncreset, 0x01);
|
|
|
|
if (state) { /* unblank screen */
|
|
|
|
val = vga_ts_read(&vc->hdl, mode);
|
2003-01-27 18:16:10 +03:00
|
|
|
vga_ts_write(&vc->hdl, mode, val & ~VGA_TS_MODE_BLANK);
|
2002-01-23 20:11:38 +03:00
|
|
|
#ifndef VGA_NO_VBLANK
|
|
|
|
val = vga_6845_read(&vc->hdl, mode);
|
|
|
|
vga_6845_write(&vc->hdl, mode, val | 0x80);
|
|
|
|
#endif
|
|
|
|
} else { /* blank screen */
|
|
|
|
val = vga_ts_read(&vc->hdl, mode);
|
2003-01-27 18:16:10 +03:00
|
|
|
vga_ts_write(&vc->hdl, mode, val | VGA_TS_MODE_BLANK);
|
2002-01-23 20:11:38 +03:00
|
|
|
#ifndef VGA_NO_VBLANK
|
|
|
|
val = vga_6845_read(&vc->hdl, mode);
|
|
|
|
vga_6845_write(&vc->hdl, mode, val & ~0x80);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
vga_ts_write(&vc->hdl, syncreset, 0x03);
|
|
|
|
}
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
int
|
2003-06-30 02:28:00 +04:00
|
|
|
vga_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
|
|
|
struct vga_config *vc = v;
|
2001-09-14 05:10:11 +04:00
|
|
|
const struct vga_funcs *vf = vc->vc_funcs;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case WSDISPLAYIO_GTYPE:
|
|
|
|
*(int *)data = vc->vc_type;
|
|
|
|
return 0;
|
1999-01-13 19:48:58 +03:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
case WSDISPLAYIO_GINFO:
|
2001-09-14 05:10:11 +04:00
|
|
|
/* XXX should get detailed hardware information here */
|
2002-03-17 22:40:26 +03:00
|
|
|
return EPASSTHROUGH;
|
2001-09-14 05:10:11 +04:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
case WSDISPLAYIO_GVIDEO:
|
2003-01-27 17:46:10 +03:00
|
|
|
*(int *)data = (vga_get_video(vc) ?
|
|
|
|
WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF);
|
2002-01-23 20:11:38 +03:00
|
|
|
return 0;
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
case WSDISPLAYIO_SVIDEO:
|
2002-01-23 20:11:38 +03:00
|
|
|
vga_set_video(vc, *(int *)data == WSDISPLAYIO_VIDEO_ON);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WSDISPLAYIO_GETCMAP:
|
|
|
|
case WSDISPLAYIO_PUTCMAP:
|
1998-03-22 18:11:49 +03:00
|
|
|
case WSDISPLAYIO_GCURPOS:
|
|
|
|
case WSDISPLAYIO_SCURPOS:
|
|
|
|
case WSDISPLAYIO_GCURMAX:
|
|
|
|
case WSDISPLAYIO_GCURSOR:
|
|
|
|
case WSDISPLAYIO_SCURSOR:
|
|
|
|
/* NONE of these operations are by the generic VGA driver. */
|
2002-03-17 22:40:26 +03:00
|
|
|
return EPASSTHROUGH;
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
|
2001-09-14 05:10:11 +04:00
|
|
|
if (vc->vc_funcs == NULL)
|
2002-03-17 22:40:26 +03:00
|
|
|
return (EPASSTHROUGH);
|
2001-09-14 05:10:11 +04:00
|
|
|
|
|
|
|
if (vf->vf_ioctl == NULL)
|
2002-03-17 22:40:26 +03:00
|
|
|
return (EPASSTHROUGH);
|
2001-09-14 05:10:11 +04:00
|
|
|
|
2003-06-30 02:28:00 +04:00
|
|
|
return ((*vf->vf_ioctl)(v, cmd, data, flag, p));
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
2000-06-26 08:55:19 +04:00
|
|
|
static paddr_t
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_mmap(void *v, off_t offset, int prot)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
2000-06-17 11:11:50 +04:00
|
|
|
struct vga_config *vc = v;
|
2001-09-14 05:10:11 +04:00
|
|
|
const struct vga_funcs *vf = vc->vc_funcs;
|
|
|
|
|
|
|
|
if (vc->vc_funcs == NULL)
|
|
|
|
return (-1);
|
2000-06-17 11:11:50 +04:00
|
|
|
|
2001-09-14 05:10:11 +04:00
|
|
|
if (vf->vf_mmap == NULL)
|
|
|
|
return (-1);
|
2000-08-15 00:14:50 +04:00
|
|
|
|
2001-09-14 05:10:11 +04:00
|
|
|
return ((*vf->vf_mmap)(v, offset, prot));
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
|
|
|
|
int *curxp, int *curyp, long *defattrp)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
|
|
|
struct vga_config *vc = v;
|
|
|
|
struct vgascreen *scr;
|
|
|
|
|
|
|
|
if (vc->nscreens == 1) {
|
2001-09-04 19:32:22 +04:00
|
|
|
struct vgascreen *scr1 = vc->screens.lh_first;
|
1998-03-22 18:11:49 +03:00
|
|
|
/*
|
|
|
|
* When allocating the second screen, get backing store
|
|
|
|
* for the first one too.
|
|
|
|
* XXX We could be more clever and use video RAM.
|
|
|
|
*/
|
2001-09-04 19:32:22 +04:00
|
|
|
scr1->pcs.mem =
|
2003-01-27 17:46:10 +03:00
|
|
|
malloc(scr1->pcs.type->ncols * scr1->pcs.type->nrows * 2,
|
|
|
|
M_DEVBUF, M_WAITOK);
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
|
1998-05-28 20:48:40 +04:00
|
|
|
vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp);
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2001-09-04 21:06:54 +04:00
|
|
|
if (vc->nscreens > 1) {
|
1998-05-28 20:48:40 +04:00
|
|
|
scr->pcs.mem = malloc(type->ncols * type->nrows * 2,
|
2003-01-27 17:46:10 +03:00
|
|
|
M_DEVBUF, M_WAITOK);
|
1998-05-28 20:48:40 +04:00
|
|
|
pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp);
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
*cookiep = scr;
|
2002-07-07 10:36:32 +04:00
|
|
|
*curxp = scr->pcs.cursorcol;
|
|
|
|
*curyp = scr->pcs.cursorrow;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_free_screen(void *v, void *cookie)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
|
|
|
struct vgascreen *vs = cookie;
|
1999-01-09 18:29:26 +03:00
|
|
|
struct vga_config *vc = vs->cfg;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
LIST_REMOVE(vs, next);
|
2001-09-04 19:32:22 +04:00
|
|
|
if (vs->fontset1)
|
|
|
|
egavga_unreffont(vc, vs->fontset1);
|
|
|
|
if (vs->fontset2)
|
|
|
|
egavga_unreffont(vc, vs->fontset2);
|
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
if (vs != &vga_console_screen)
|
|
|
|
free(vs, M_DEVBUF);
|
|
|
|
else
|
|
|
|
panic("vga_free_screen: console");
|
1999-01-09 18:29:26 +03:00
|
|
|
|
|
|
|
if (vc->active == vs)
|
|
|
|
vc->active = 0;
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
2001-09-07 21:10:13 +04:00
|
|
|
static void vga_usefont(struct vga_config *, struct egavga_font *);
|
2001-09-03 21:34:07 +04:00
|
|
|
|
2001-09-07 21:10:13 +04:00
|
|
|
static void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_usefont(struct vga_config *vc, struct egavga_font *f)
|
2001-09-03 21:34:07 +04:00
|
|
|
{
|
|
|
|
int slot;
|
|
|
|
struct egavga_font *of;
|
|
|
|
|
|
|
|
if (f->slot != -1)
|
|
|
|
goto toend;
|
|
|
|
|
2002-06-26 01:07:42 +04:00
|
|
|
for (slot = 0; slot < vc->vc_nfontslots; slot++) {
|
2001-09-03 21:34:07 +04:00
|
|
|
if (!vc->vc_fonts[slot])
|
|
|
|
goto loadit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* have to kick out another one */
|
|
|
|
TAILQ_FOREACH(of, &vc->vc_fontlist, next) {
|
|
|
|
if (of->slot != -1) {
|
|
|
|
KASSERT(vc->vc_fonts[of->slot] == of);
|
|
|
|
slot = of->slot;
|
|
|
|
of->slot = -1;
|
|
|
|
goto loadit;
|
|
|
|
}
|
|
|
|
}
|
2002-06-27 10:26:51 +04:00
|
|
|
panic("vga_usefont");
|
2001-09-03 21:34:07 +04:00
|
|
|
|
|
|
|
loadit:
|
2002-06-26 20:33:18 +04:00
|
|
|
vga_loadchars(&vc->hdl, slot, f->wsfont->firstchar,
|
2003-01-27 17:46:10 +03:00
|
|
|
f->wsfont->numchars, f->wsfont->fontheight, f->wsfont->data);
|
2001-09-03 21:34:07 +04:00
|
|
|
f->slot = slot;
|
|
|
|
vc->vc_fonts[slot] = f;
|
|
|
|
|
|
|
|
toend:
|
|
|
|
TAILQ_REMOVE(&vc->vc_fontlist, f, next);
|
|
|
|
TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
|
|
|
|
}
|
|
|
|
|
1999-01-13 19:48:58 +03:00
|
|
|
static void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_setfont(struct vga_config *vc, struct vgascreen *scr)
|
1999-01-13 19:48:58 +03:00
|
|
|
{
|
|
|
|
int fontslot1, fontslot2;
|
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
if (scr->fontset1)
|
|
|
|
vga_usefont(vc, scr->fontset1);
|
|
|
|
if (scr->fontset2)
|
|
|
|
vga_usefont(vc, scr->fontset2);
|
|
|
|
|
1999-01-13 19:48:58 +03:00
|
|
|
fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0);
|
|
|
|
fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1);
|
|
|
|
if (vc->currentfontset1 != fontslot1 ||
|
|
|
|
vc->currentfontset2 != fontslot2) {
|
|
|
|
vga_setfontset(&vc->hdl, fontslot1, fontslot2);
|
|
|
|
vc->currentfontset1 = fontslot1;
|
|
|
|
vc->currentfontset2 = fontslot2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-06 21:54:50 +03:00
|
|
|
int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_show_screen(void *v, void *cookie, int waitok,
|
|
|
|
void (*cb)(void *, int, int), void *cbarg)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
1998-05-28 20:48:40 +04:00
|
|
|
struct vgascreen *scr = cookie, *oldscr;
|
1998-03-22 18:11:49 +03:00
|
|
|
struct vga_config *vc = scr->cfg;
|
1999-12-06 21:54:50 +03:00
|
|
|
|
|
|
|
oldscr = vc->active; /* can be NULL! */
|
|
|
|
if (scr == oldscr) {
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
vc->wantedscreen = cookie;
|
|
|
|
vc->switchcb = cb;
|
|
|
|
vc->switchcbarg = cbarg;
|
|
|
|
if (cb) {
|
2000-03-23 10:01:25 +03:00
|
|
|
callout_reset(&vc->vc_switch_callout, 0,
|
|
|
|
(void(*)(void *))vga_doswitch, vc);
|
1999-12-06 21:54:50 +03:00
|
|
|
return (EAGAIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
vga_doswitch(vc);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_doswitch(struct vga_config *vc)
|
1999-12-06 21:54:50 +03:00
|
|
|
{
|
|
|
|
struct vgascreen *scr, *oldscr;
|
1998-03-22 18:11:49 +03:00
|
|
|
struct vga_handle *vh = &vc->hdl;
|
1999-12-06 21:54:50 +03:00
|
|
|
const struct wsscreen_descr *type;
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1999-12-06 21:54:50 +03:00
|
|
|
scr = vc->wantedscreen;
|
|
|
|
if (!scr) {
|
|
|
|
printf("vga_doswitch: disappeared\n");
|
|
|
|
(*vc->switchcb)(vc->switchcbarg, EIO, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
type = scr->pcs.type;
|
1999-01-09 18:29:26 +03:00
|
|
|
oldscr = vc->active; /* can be NULL! */
|
1998-05-28 20:48:40 +04:00
|
|
|
#ifdef DIAGNOSTIC
|
1999-01-09 18:29:26 +03:00
|
|
|
if (oldscr) {
|
|
|
|
if (!oldscr->pcs.active)
|
|
|
|
panic("vga_show_screen: not active");
|
|
|
|
if (oldscr->pcs.type != vc->currenttype)
|
|
|
|
panic("vga_show_screen: bad type");
|
|
|
|
}
|
1998-05-28 20:48:40 +04:00
|
|
|
#endif
|
|
|
|
if (scr == oldscr) {
|
1998-03-22 18:11:49 +03:00
|
|
|
return;
|
1998-05-28 20:48:40 +04:00
|
|
|
}
|
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
if (scr->pcs.active)
|
|
|
|
panic("vga_show_screen: active");
|
|
|
|
#endif
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1999-01-09 18:29:26 +03:00
|
|
|
if (oldscr) {
|
|
|
|
const struct wsscreen_descr *oldtype = oldscr->pcs.type;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
1999-01-09 18:29:26 +03:00
|
|
|
oldscr->pcs.active = 0;
|
|
|
|
bus_space_read_region_2(vh->vh_memt, vh->vh_memh,
|
2003-01-27 17:46:10 +03:00
|
|
|
oldscr->pcs.dispoffset, oldscr->pcs.mem,
|
|
|
|
oldtype->ncols * oldtype->nrows);
|
1999-01-09 18:29:26 +03:00
|
|
|
}
|
1998-03-22 18:11:49 +03:00
|
|
|
|
1999-01-09 18:29:26 +03:00
|
|
|
if (vc->currenttype != type) {
|
1998-05-28 20:48:40 +04:00
|
|
|
vga_setscreentype(vh, type);
|
1999-01-09 18:29:26 +03:00
|
|
|
vc->currenttype = type;
|
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
vga_setfont(vc, scr);
|
1999-01-09 18:29:26 +03:00
|
|
|
/* XXX swich colours! */
|
1998-03-22 18:11:49 +03:00
|
|
|
|
2004-08-13 08:03:38 +04:00
|
|
|
scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
|
1999-01-09 18:29:26 +03:00
|
|
|
if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
|
1998-07-24 20:20:14 +04:00
|
|
|
vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9);
|
|
|
|
vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1);
|
|
|
|
}
|
|
|
|
|
1999-01-09 18:29:26 +03:00
|
|
|
bus_space_write_region_2(vh->vh_memt, vh->vh_memh,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.dispoffset, scr->pcs.mem, type->ncols * type->nrows);
|
1998-05-28 20:48:40 +04:00
|
|
|
scr->pcs.active = 1;
|
1999-01-09 18:29:26 +03:00
|
|
|
|
1998-03-22 18:11:49 +03:00
|
|
|
vc->active = scr;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
|
|
|
pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.cursorrow, scr->pcs.cursorcol);
|
1999-12-06 21:54:50 +03:00
|
|
|
|
|
|
|
vc->wantedscreen = 0;
|
|
|
|
if (vc->switchcb)
|
|
|
|
(*vc->switchcb)(vc->switchcbarg, 0, 0);
|
1998-03-22 18:11:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_load_font(void *v, void *cookie, struct wsdisplay_font *data)
|
1998-03-22 18:11:49 +03:00
|
|
|
{
|
1999-01-13 19:48:58 +03:00
|
|
|
struct vga_config *vc = v;
|
1998-03-22 18:11:49 +03:00
|
|
|
struct vgascreen *scr = cookie;
|
1999-01-13 19:48:58 +03:00
|
|
|
char *name2;
|
2001-09-03 21:34:07 +04:00
|
|
|
int res;
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
if (scr) {
|
2002-04-04 17:08:35 +04:00
|
|
|
name2 = NULL;
|
|
|
|
if (data->name) {
|
|
|
|
name2 = strchr(data->name, ',');
|
|
|
|
if (name2)
|
|
|
|
*name2++ = '\0';
|
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
res = vga_selectfont(vc, scr, data->name, name2);
|
2002-06-26 20:33:18 +04:00
|
|
|
if (!res && scr->pcs.active)
|
1999-01-13 19:48:58 +03:00
|
|
|
vga_setfont(vc, scr);
|
|
|
|
return (res);
|
|
|
|
}
|
1998-03-22 18:11:49 +03:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
1998-05-15 00:49:55 +04:00
|
|
|
static int
|
2002-07-04 18:37:10 +04:00
|
|
|
vga_allocattr(void *id, int fg, int bg, int flags, long *attrp)
|
1998-05-15 00:49:55 +04:00
|
|
|
{
|
|
|
|
struct vgascreen *scr = id;
|
|
|
|
struct vga_config *vc = scr->cfg;
|
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
if (vc->hdl.vh_mono) {
|
1998-05-15 00:49:55 +04:00
|
|
|
if (flags & WSATTR_WSCOLORS)
|
|
|
|
return (EINVAL);
|
|
|
|
if (flags & WSATTR_REVERSE)
|
|
|
|
*attrp = 0x70;
|
|
|
|
else
|
|
|
|
*attrp = 0x07;
|
|
|
|
if (flags & WSATTR_UNDERLINE)
|
|
|
|
*attrp |= FG_UNDERLINE;
|
|
|
|
if (flags & WSATTR_HILIT)
|
|
|
|
*attrp |= FG_INTENSE;
|
|
|
|
} else {
|
|
|
|
if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
|
|
|
|
return (EINVAL);
|
|
|
|
if (flags & WSATTR_WSCOLORS)
|
|
|
|
*attrp = fgansitopc[fg] | bgansitopc[bg];
|
|
|
|
else
|
|
|
|
*attrp = 7;
|
|
|
|
if (flags & WSATTR_HILIT)
|
|
|
|
*attrp += 8;
|
|
|
|
}
|
|
|
|
if (flags & WSATTR_BLINK)
|
|
|
|
*attrp |= FG_BLINK;
|
|
|
|
return (0);
|
|
|
|
}
|
1998-07-24 20:20:14 +04:00
|
|
|
|
2001-12-13 11:31:39 +03:00
|
|
|
static void
|
|
|
|
vga_copyrows(void *id, int srcrow, int dstrow, int nrows)
|
1998-07-24 20:20:14 +04:00
|
|
|
{
|
|
|
|
struct vgascreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->pcs.hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->pcs.hdl->ph_memh;
|
|
|
|
int ncols = scr->pcs.type->ncols;
|
|
|
|
bus_size_t srcoff, dstoff;
|
|
|
|
|
|
|
|
srcoff = srcrow * ncols + 0;
|
|
|
|
dstoff = dstrow * ncols + 0;
|
|
|
|
|
|
|
|
if (scr->pcs.active) {
|
|
|
|
if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) {
|
1999-09-20 01:48:08 +04:00
|
|
|
#ifdef PCDISPLAY_SOFTCURSOR
|
1999-09-29 21:29:24 +04:00
|
|
|
int cursoron = scr->pcs.cursoron;
|
|
|
|
|
1999-11-03 18:55:27 +03:00
|
|
|
if (cursoron)
|
|
|
|
pcdisplay_cursor(&scr->pcs, 0,
|
2002-07-07 10:36:32 +04:00
|
|
|
scr->pcs.cursorrow, scr->pcs.cursorcol);
|
1999-09-20 01:48:08 +04:00
|
|
|
#endif
|
1998-07-24 20:20:14 +04:00
|
|
|
/* scroll up whole screen */
|
|
|
|
if ((scr->pcs.dispoffset + srcrow * ncols * 2)
|
|
|
|
<= scr->maxdispoffset) {
|
|
|
|
scr->pcs.dispoffset += srcrow * ncols * 2;
|
|
|
|
} else {
|
|
|
|
bus_space_copy_region_2(memt, memh,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.dispoffset + srcoff * 2,
|
|
|
|
memh, scr->mindispoffset, nrows * ncols);
|
1998-07-24 20:20:14 +04:00
|
|
|
scr->pcs.dispoffset = scr->mindispoffset;
|
|
|
|
}
|
|
|
|
vga_6845_write(&scr->cfg->hdl, startadrh,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.dispoffset >> 9);
|
1998-07-24 20:20:14 +04:00
|
|
|
vga_6845_write(&scr->cfg->hdl, startadrl,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.dispoffset >> 1);
|
1999-09-20 01:48:08 +04:00
|
|
|
#ifdef PCDISPLAY_SOFTCURSOR
|
1999-11-03 18:55:27 +03:00
|
|
|
if (cursoron)
|
|
|
|
pcdisplay_cursor(&scr->pcs, 1,
|
2002-07-07 10:36:32 +04:00
|
|
|
scr->pcs.cursorrow, scr->pcs.cursorcol);
|
1999-09-20 01:48:08 +04:00
|
|
|
#endif
|
1998-07-24 20:20:14 +04:00
|
|
|
} else {
|
|
|
|
bus_space_copy_region_2(memt, memh,
|
2003-01-27 17:46:10 +03:00
|
|
|
scr->pcs.dispoffset + srcoff * 2,
|
|
|
|
memh, scr->pcs.dispoffset + dstoff * 2,
|
|
|
|
nrows * ncols);
|
1998-07-24 20:20:14 +04:00
|
|
|
}
|
|
|
|
} else
|
2001-07-07 19:53:13 +04:00
|
|
|
memcpy(&scr->pcs.mem[dstoff], &scr->pcs.mem[srcoff],
|
2003-01-27 17:46:10 +03:00
|
|
|
nrows * ncols * 2);
|
1998-07-24 20:20:14 +04:00
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
#ifdef WSCONS_SUPPORT_PCVTFONTS
|
|
|
|
|
|
|
|
#define NOTYET 0xffff
|
2001-01-18 23:28:15 +03:00
|
|
|
static const u_int16_t pcvt_unichars[0xa0] = {
|
2001-12-02 15:46:32 +03:00
|
|
|
/* 0 */ _e006U, /* N/L control */
|
1999-02-20 21:27:53 +03:00
|
|
|
NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
1999-01-13 19:48:58 +03:00
|
|
|
NOTYET,
|
|
|
|
0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */
|
|
|
|
0x240a, /* SYMBOL FOR LINE FEED */
|
|
|
|
0x240b, /* SYMBOL FOR VERTICAL TABULATION */
|
|
|
|
0x240c, /* SYMBOL FOR FORM FEED */
|
|
|
|
0x240d, /* SYMBOL FOR CARRIAGE RETURN */
|
|
|
|
NOTYET, NOTYET,
|
1999-02-20 21:27:53 +03:00
|
|
|
/* 1 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
1999-01-13 19:48:58 +03:00
|
|
|
NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
|
|
|
/* 2 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
|
|
|
NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
1999-02-20 21:27:53 +03:00
|
|
|
/* 3 */ NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
1999-01-13 19:48:58 +03:00
|
|
|
NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
|
|
|
|
/* 4 */ 0x03c1, /* GREEK SMALL LETTER RHO */
|
|
|
|
0x03c8, /* GREEK SMALL LETTER PSI */
|
|
|
|
0x2202, /* PARTIAL DIFFERENTIAL */
|
|
|
|
0x03bb, /* GREEK SMALL LETTER LAMDA */
|
|
|
|
0x03b9, /* GREEK SMALL LETTER IOTA */
|
|
|
|
0x03b7, /* GREEK SMALL LETTER ETA */
|
|
|
|
0x03b5, /* GREEK SMALL LETTER EPSILON */
|
|
|
|
0x03c7, /* GREEK SMALL LETTER CHI */
|
|
|
|
0x2228, /* LOGICAL OR */
|
|
|
|
0x2227, /* LOGICAL AND */
|
|
|
|
0x222a, /* UNION */
|
|
|
|
0x2283, /* SUPERSET OF */
|
|
|
|
0x2282, /* SUBSET OF */
|
|
|
|
0x03a5, /* GREEK CAPITAL LETTER UPSILON */
|
|
|
|
0x039e, /* GREEK CAPITAL LETTER XI */
|
|
|
|
0x03a8, /* GREEK CAPITAL LETTER PSI */
|
1999-02-20 21:27:53 +03:00
|
|
|
/* 5 */ 0x03a0, /* GREEK CAPITAL LETTER PI */
|
1999-01-13 19:48:58 +03:00
|
|
|
0x21d2, /* RIGHTWARDS DOUBLE ARROW */
|
|
|
|
0x21d4, /* LEFT RIGHT DOUBLE ARROW */
|
|
|
|
0x039b, /* GREEK CAPITAL LETTER LAMDA */
|
|
|
|
0x0398, /* GREEK CAPITAL LETTER THETA */
|
|
|
|
0x2243, /* ASYMPTOTICALLY EQUAL TO */
|
|
|
|
0x2207, /* NABLA */
|
|
|
|
0x2206, /* INCREMENT */
|
|
|
|
0x221d, /* PROPORTIONAL TO */
|
|
|
|
0x2234, /* THEREFORE */
|
|
|
|
0x222b, /* INTEGRAL */
|
|
|
|
0x2215, /* DIVISION SLASH */
|
|
|
|
0x2216, /* SET MINUS */
|
2001-12-02 15:46:32 +03:00
|
|
|
_e00eU, /* angle? */
|
|
|
|
_e00dU, /* inverted angle? */
|
|
|
|
_e00bU, /* braceleftmid */
|
|
|
|
/* 6 */ _e00cU, /* bracerightmid */
|
|
|
|
_e007U, /* bracelefttp */
|
|
|
|
_e008U, /* braceleftbt */
|
|
|
|
_e009U, /* bracerighttp */
|
|
|
|
_e00aU, /* bracerightbt */
|
1999-01-13 19:48:58 +03:00
|
|
|
0x221a, /* SQUARE ROOT */
|
|
|
|
0x03c9, /* GREEK SMALL LETTER OMEGA */
|
|
|
|
0x00a5, /* YEN SIGN */
|
|
|
|
0x03be, /* GREEK SMALL LETTER XI */
|
|
|
|
0x00fd, /* LATIN SMALL LETTER Y WITH ACUTE */
|
|
|
|
0x00fe, /* LATIN SMALL LETTER THORN */
|
|
|
|
0x00f0, /* LATIN SMALL LETTER ETH */
|
|
|
|
0x00de, /* LATIN CAPITAL LETTER THORN */
|
|
|
|
0x00dd, /* LATIN CAPITAL LETTER Y WITH ACUTE */
|
|
|
|
0x00d7, /* MULTIPLICATION SIGN */
|
|
|
|
0x00d0, /* LATIN CAPITAL LETTER ETH */
|
1999-02-20 21:27:53 +03:00
|
|
|
/* 7 */ 0x00be, /* VULGAR FRACTION THREE QUARTERS */
|
1999-01-13 19:48:58 +03:00
|
|
|
0x00b8, /* CEDILLA */
|
|
|
|
0x00b4, /* ACUTE ACCENT */
|
|
|
|
0x00af, /* MACRON */
|
|
|
|
0x00ae, /* REGISTERED SIGN */
|
|
|
|
0x00ad, /* SOFT HYPHEN */
|
|
|
|
0x00ac, /* NOT SIGN */
|
|
|
|
0x00a8, /* DIAERESIS */
|
|
|
|
0x2260, /* NOT EQUAL TO */
|
2001-12-02 15:46:32 +03:00
|
|
|
_e005U, /* scan 9 */
|
|
|
|
_e004U, /* scan 7 */
|
|
|
|
_e003U, /* scan 5 */
|
|
|
|
_e002U, /* scan 3 */
|
|
|
|
_e001U, /* scan 1 */
|
1999-01-13 19:48:58 +03:00
|
|
|
0x03c5, /* GREEK SMALL LETTER UPSILON */
|
|
|
|
0x00f8, /* LATIN SMALL LETTER O WITH STROKE */
|
|
|
|
/* 8 */ 0x0153, /* LATIN SMALL LIGATURE OE */
|
|
|
|
0x00f5, /* LATIN SMALL LETTER O WITH TILDE !!!doc bug */
|
|
|
|
0x00e3, /* LATIN SMALL LETTER A WITH TILDE */
|
|
|
|
0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
|
|
|
|
0x00db, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
|
|
|
|
0x00da, /* LATIN CAPITAL LETTER U WITH ACUTE */
|
|
|
|
0x00d9, /* LATIN CAPITAL LETTER U WITH GRAVE */
|
|
|
|
0x00d8, /* LATIN CAPITAL LETTER O WITH STROKE */
|
|
|
|
0x0152, /* LATIN CAPITAL LIGATURE OE */
|
|
|
|
0x00d5, /* LATIN CAPITAL LETTER O WITH TILDE */
|
|
|
|
0x00d4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
|
|
|
|
0x00d3, /* LATIN CAPITAL LETTER O WITH ACUTE */
|
|
|
|
0x00d2, /* LATIN CAPITAL LETTER O WITH GRAVE */
|
|
|
|
0x00cf, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
|
|
|
|
0x00ce, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
|
|
|
|
0x00cd, /* LATIN CAPITAL LETTER I WITH ACUTE */
|
1999-02-20 21:27:53 +03:00
|
|
|
/* 9 */ 0x00cc, /* LATIN CAPITAL LETTER I WITH GRAVE */
|
1999-01-13 19:48:58 +03:00
|
|
|
0x00cb, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
|
|
|
|
0x00ca, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
|
|
|
|
0x00c8, /* LATIN CAPITAL LETTER E WITH GRAVE */
|
|
|
|
0x00c3, /* LATIN CAPITAL LETTER A WITH TILDE */
|
|
|
|
0x00c2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
|
|
|
|
0x00c1, /* LATIN CAPITAL LETTER A WITH ACUTE */
|
|
|
|
0x00c0, /* LATIN CAPITAL LETTER A WITH GRAVE */
|
|
|
|
0x00b9, /* SUPERSCRIPT ONE */
|
|
|
|
0x00b7, /* MIDDLE DOT */
|
|
|
|
0x03b6, /* GREEK SMALL LETTER ZETA */
|
|
|
|
0x00b3, /* SUPERSCRIPT THREE */
|
|
|
|
0x00a9, /* COPYRIGHT SIGN */
|
|
|
|
0x00a4, /* CURRENCY SIGN */
|
|
|
|
0x03ba, /* GREEK SMALL LETTER KAPPA */
|
2001-12-02 15:46:32 +03:00
|
|
|
_e000U /* mirrored question mark? */
|
1999-01-13 19:48:58 +03:00
|
|
|
};
|
|
|
|
|
2001-12-13 11:31:39 +03:00
|
|
|
static int vga_pcvt_mapchar(int, u_int *);
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
static int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_pcvt_mapchar(int uni, u_int *index)
|
1999-01-13 19:48:58 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 0xa0; i++) /* 0xa0..0xff are reserved */
|
1999-02-12 14:25:23 +03:00
|
|
|
if (uni == pcvt_unichars[i]) {
|
|
|
|
*index = i;
|
|
|
|
return (5);
|
|
|
|
}
|
|
|
|
*index = 0x99; /* middle dot */
|
|
|
|
return (0);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WSCONS_SUPPORT_PCVTFONTS */
|
|
|
|
|
2000-09-15 18:13:01 +04:00
|
|
|
#ifdef WSCONS_SUPPORT_ISO7FONTS
|
|
|
|
|
|
|
|
static int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_iso7_mapchar(int uni, u_int *index)
|
2000-09-15 18:13:01 +04:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* U+0384 (GREEK TONOS) to
|
|
|
|
* U+03ce (GREEK SMALL LETTER OMEGA WITH TONOS)
|
|
|
|
* map directly to the iso-9 font
|
|
|
|
*/
|
|
|
|
if (uni >= 0x0384 && uni <= 0x03ce) {
|
|
|
|
/* U+0384 is at offset 0xb4 in the font */
|
|
|
|
*index = uni - 0x0384 + 0xb4;
|
|
|
|
return (5);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX more chars in the iso-9 font */
|
|
|
|
|
|
|
|
*index = 0xa4; /* shaded rectangle */
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WSCONS_SUPPORT_ISO7FONTS */
|
|
|
|
|
2001-12-13 11:31:39 +03:00
|
|
|
static int _vga_mapchar(void *, const struct egavga_font *, int, u_int *);
|
1999-01-13 19:48:58 +03:00
|
|
|
|
|
|
|
static int
|
2001-12-13 11:31:39 +03:00
|
|
|
_vga_mapchar(void *id, const struct egavga_font *font, int uni, u_int *index)
|
1999-01-13 19:48:58 +03:00
|
|
|
{
|
|
|
|
|
2001-09-03 21:34:07 +04:00
|
|
|
switch (font->wsfont->encoding) {
|
1999-01-13 19:48:58 +03:00
|
|
|
case WSDISPLAY_FONTENC_ISO:
|
1999-02-12 14:25:23 +03:00
|
|
|
if (uni < 256) {
|
|
|
|
*index = uni;
|
|
|
|
return (5);
|
|
|
|
} else {
|
|
|
|
*index = ' ';
|
|
|
|
return (0);
|
|
|
|
}
|
1999-01-13 19:48:58 +03:00
|
|
|
case WSDISPLAY_FONTENC_IBM:
|
1999-02-12 14:25:23 +03:00
|
|
|
return (pcdisplay_mapchar(id, uni, index));
|
1999-01-13 19:48:58 +03:00
|
|
|
#ifdef WSCONS_SUPPORT_PCVTFONTS
|
|
|
|
case WSDISPLAY_FONTENC_PCVT:
|
1999-02-12 14:25:23 +03:00
|
|
|
return (vga_pcvt_mapchar(uni, index));
|
2000-09-15 18:13:01 +04:00
|
|
|
#endif
|
|
|
|
#ifdef WSCONS_SUPPORT_ISO7FONTS
|
|
|
|
case WSDISPLAY_FONTENC_ISO7:
|
|
|
|
return (vga_iso7_mapchar(uni, index));
|
1999-01-13 19:48:58 +03:00
|
|
|
#endif
|
1999-02-12 14:25:23 +03:00
|
|
|
default:
|
1999-04-01 15:52:42 +04:00
|
|
|
#ifdef VGAFONTDEBUG
|
2001-09-03 21:34:07 +04:00
|
|
|
printf("_vga_mapchar: encoding=%d\n", font->wsfont->encoding);
|
1999-04-01 15:52:42 +04:00
|
|
|
#endif
|
1999-02-12 14:25:23 +03:00
|
|
|
*index = ' ';
|
|
|
|
return (0);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-12 14:25:23 +03:00
|
|
|
static int
|
2001-12-13 11:31:39 +03:00
|
|
|
vga_mapchar(void *id, int uni, u_int *index)
|
1999-01-13 19:48:58 +03:00
|
|
|
{
|
|
|
|
struct vgascreen *scr = id;
|
2001-12-13 11:31:39 +03:00
|
|
|
u_int idx1, idx2;
|
1999-02-12 14:25:23 +03:00
|
|
|
int res1, res2;
|
|
|
|
|
|
|
|
res1 = 0;
|
|
|
|
idx1 = ' '; /* space */
|
|
|
|
if (scr->fontset1)
|
|
|
|
res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1);
|
|
|
|
res2 = -1;
|
1999-01-13 19:48:58 +03:00
|
|
|
if (scr->fontset2) {
|
|
|
|
KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type));
|
1999-02-12 14:25:23 +03:00
|
|
|
res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
1999-02-12 14:25:23 +03:00
|
|
|
if (res2 > res1) {
|
1999-02-20 21:27:53 +03:00
|
|
|
*index = idx2 | 0x0800; /* attribute bit 3 */
|
|
|
|
return (res2);
|
1999-02-12 14:25:23 +03:00
|
|
|
}
|
|
|
|
*index = idx1;
|
|
|
|
return (res1);
|
1999-01-13 19:48:58 +03:00
|
|
|
}
|
2002-06-27 03:05:33 +04:00
|
|
|
|
2004-05-29 01:42:29 +04:00
|
|
|
#ifdef WSDISPLAY_SCROLLSUPPORT
|
|
|
|
void
|
|
|
|
vga_scroll(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);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
vga_putchar(void *c, int row, int col, u_int uc, long attr)
|
|
|
|
{
|
|
|
|
|
|
|
|
pcdisplay_putchar(c, row, col, uc, attr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-01 17:17:48 +04:00
|
|
|
#ifdef WSDISPLAY_CHARFUNCS
|
2002-06-27 03:05:33 +04:00
|
|
|
int
|
|
|
|
vga_getwschar(void *cookie, struct wsdisplay_char *wschar)
|
|
|
|
{
|
|
|
|
struct vgascreen *scr = cookie;
|
|
|
|
|
|
|
|
if (scr == NULL) return 0;
|
|
|
|
return (pcdisplay_getwschar(&scr->pcs, wschar));
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vga_putwschar(void *cookie, struct wsdisplay_char *wschar)
|
|
|
|
{
|
|
|
|
struct vgascreen *scr = cookie;
|
|
|
|
|
|
|
|
if (scr == NULL) return 0;
|
|
|
|
return (pcdisplay_putwschar(&scr->pcs, wschar));
|
|
|
|
}
|
2002-07-01 17:17:48 +04:00
|
|
|
#endif /* WSDISPLAY_CHARFUNCS */
|
Implement border color customization in wscons(4), only available for vga(4)
at the moment.
This includes the addition of two new wsdisplay ioctls, WSDISPLAY_{G,S}BORDER,
one to get the actual color and one to set it, respectively. Possible colors
match those defined by ANSI (and listed in wsdisplayvar.h).
It also adds two accessops to the underlying graphics device, getborder and
setborder, which mach their ioctl counterparts.
Two kernel options are added: WSDISPLAY_CUSTOM_BORDER, which enables the
ioctls described above (to customize the border color from userland after
boot), and WSDISPLAY_BORDER_COLOR, which sets the color at boot time.
The former is enabled by default on the GENERIC kernel, but not on INSTALL
(among others). The later is always commented out, leaving the usual black
border as a default.
wsconsctl is modified to allow accessing this value easily. For example,
'wsconsctl -d -w border=blue'.
2004-07-30 02:29:35 +04:00
|
|
|
|
|
|
|
#ifdef WSDISPLAY_CUSTOM_BORDER
|
|
|
|
static u_int
|
|
|
|
vga_getborder(void *cookie)
|
|
|
|
{
|
|
|
|
struct vgascreen *scr = cookie;
|
|
|
|
struct vga_handle *vh;
|
|
|
|
u_int idx;
|
|
|
|
u_int8_t value;
|
|
|
|
|
|
|
|
if (scr == NULL) return EINVAL;
|
|
|
|
vh = &scr->cfg->hdl;
|
|
|
|
if (vh->vh_mono) return ENODEV;
|
|
|
|
|
|
|
|
value = _vga_attr_read(vh, VGA_ATC_OVERSCAN);
|
|
|
|
for (idx = 0; idx < sizeof(fgansitopc); idx++)
|
|
|
|
if (fgansitopc[idx] == value)
|
|
|
|
break;
|
|
|
|
return idx == sizeof(fgansitopc) ? 0 : idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vga_setborder(void *cookie, u_int value)
|
|
|
|
{
|
|
|
|
struct vgascreen *scr = cookie;
|
|
|
|
struct vga_handle *vh;
|
|
|
|
|
|
|
|
if (scr == NULL) return EINVAL;
|
|
|
|
vh = &scr->cfg->hdl;
|
|
|
|
if (vh->vh_mono) return ENODEV;
|
|
|
|
if (value >= sizeof(fgansitopc)) return EINVAL;
|
|
|
|
|
|
|
|
_vga_attr_write(vh, VGA_ATC_OVERSCAN, fgansitopc[value]);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
#endif /* WSDISPLAY_CUSTOM_BORDER */
|