Make libvgl mostly work without superuser privilege in direct modes by

not doing any unnecessary PIO instructions or refusing to start when the
i/o privilege needed for these instructions cannot be acquired.

This turns off useless palette management in direct modes.  Palette
management had no useful effect since the hardware palette is not used
in these modes.

This transiently acquires i/o privilege if possible as needed to give
VGLSetBorder() and VGLBlankDisplay() a chance of working.  Neither has
much chance of working.  I was going to drop support for them in direct
modes, but found that VGLBlankDisplay() still works with an old graphics
card on a not so old LCD monitor.

This has some good side effects: reduce glitches for managing the palette
for screen switches, and speed up and reduce async-signal-unsafeness in
mouse cursor drawing.
This commit is contained in:
bde 2019-04-20 20:29:03 +00:00
parent b331cfbc16
commit 35b6fb039b
3 changed files with 48 additions and 20 deletions

View File

@ -93,7 +93,8 @@ struct vt_mode smode;
size[2] = VGLOldVInfo.font_size;;
ioctl(0, KDRASTER, size);
}
ioctl(0, KDDISABIO, 0);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT)
ioctl(0, KDDISABIO, 0);
ioctl(0, KDSETMODE, KD_TEXT);
smode.mode = VT_AUTO;
ioctl(0, VT_SETMODE, &smode);
@ -176,7 +177,7 @@ VGLInit(int mode)
if (VGLDisplay == NULL)
return -2;
if (ioctl(0, KDENABIO, 0)) {
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) {
free(VGLDisplay);
return -3;
}
@ -370,7 +371,8 @@ VGLCheckSwitch()
VGLSwitchPending = 0;
if (VGLOnDisplay) {
ioctl(0, KDENABIO, 0);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT)
ioctl(0, KDENABIO, 0);
ioctl(0, KDSETMODE, KD_GRAPHICS);
ioctl(0, VGLMode, 0);
VGLCurWindow = 0;
@ -531,7 +533,8 @@ VGLCheckSwitch()
munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size);
ioctl(0, VGLOldMode, 0);
ioctl(0, KDSETMODE, KD_TEXT);
ioctl(0, KDDISABIO, 0);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT)
ioctl(0, KDDISABIO, 0);
ioctl(0, VT_RELDISP, VT_TRUE);
VGLDisplay->Bitmap = VGLBuf;
VGLDisplay->Type = MEMBUF;

View File

@ -111,10 +111,12 @@ VGLMousePointerShow()
if (!VGLMouseVisible) {
INTOFF();
VGLMouseVisible = 1;
crtcidx = inb(0x3c4);
crtcval = inb(0x3c5);
gdcidx = inb(0x3ce);
gdcval = inb(0x3cf);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
crtcidx = inb(0x3c4);
crtcval = inb(0x3c5);
gdcidx = inb(0x3ce);
gdcval = inb(0x3cf);
}
__VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
&VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
bcopy(VGLMouseSave.Bitmap, buffer.Bitmap,
@ -128,10 +130,12 @@ VGLMousePointerShow()
}
__VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
outb(0x3c4, crtcidx);
outb(0x3c5, crtcval);
outb(0x3ce, gdcidx);
outb(0x3cf, gdcval);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
outb(0x3c4, crtcidx);
outb(0x3c5, crtcval);
outb(0x3ce, gdcidx);
outb(0x3cf, gdcval);
}
INTON();
}
}
@ -144,16 +148,20 @@ VGLMousePointerHide()
if (VGLMouseVisible) {
INTOFF();
VGLMouseVisible = 0;
crtcidx = inb(0x3c4);
crtcval = inb(0x3c5);
gdcidx = inb(0x3ce);
gdcval = inb(0x3cf);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
crtcidx = inb(0x3c4);
crtcval = inb(0x3c5);
gdcidx = inb(0x3ce);
gdcval = inb(0x3cf);
}
__VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
outb(0x3c4, crtcidx);
outb(0x3c5, crtcval);
outb(0x3ce, gdcidx);
outb(0x3cf, gdcval);
if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
outb(0x3c4, crtcidx);
outb(0x3c5, crtcval);
outb(0x3ce, gdcidx);
outb(0x3cf, gdcval);
}
INTON();
}
}

View File

@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <signal.h>
#include <sys/fbio.h>
#include <sys/kbio.h>
#include <sys/endian.h>
#include "vgl.h"
@ -551,6 +552,8 @@ VGLRestorePalette()
{
int i;
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
return;
outb(0x3C6, 0xFF);
inb(0x3DA);
outb(0x3C8, 0x00);
@ -571,6 +574,8 @@ VGLSavePalette()
{
int i;
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
return;
outb(0x3C6, 0xFF);
inb(0x3DA);
outb(0x3C7, 0x00);
@ -591,6 +596,8 @@ VGLSetPalette(byte *red, byte *green, byte *blue)
{
int i;
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
return;
for (i=0; i<256; i++) {
VGLSavePaletteRed[i] = red[i];
VGLSavePaletteGreen[i] = green[i];
@ -615,6 +622,8 @@ VGLSetPalette(byte *red, byte *green, byte *blue)
void
VGLSetPaletteIndex(byte color, byte red, byte green, byte blue)
{
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
return;
VGLSavePaletteRed[color] = red;
VGLSavePaletteGreen[color] = green;
VGLSavePaletteBlue[color] = blue;
@ -630,11 +639,15 @@ VGLSetPaletteIndex(byte color, byte red, byte green, byte blue)
void
VGLSetBorder(byte color)
{
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0))
return;
VGLCheckSwitch();
inb(0x3DA);
outb(0x3C0,0x11); outb(0x3C0, color);
inb(0x3DA);
outb(0x3C0, 0x20);
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
ioctl(0, KDDISABIO, 0);
}
void
@ -642,7 +655,11 @@ VGLBlankDisplay(int blank)
{
byte val;
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0))
return;
VGLCheckSwitch();
outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01);
outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF)));
if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT)
ioctl(0, KDDISABIO, 0);
}