2
Copyright (c) 2000 by Juliusz Chroboczek
4
Permission is hereby granted, free of charge, to any person obtaining a copy
5
of this software and associated documentation files (the "Software"), to deal
6
in the Software without restriction, including without limitation the rights
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
copies of the Software, and to permit persons to whom the Software is
9
furnished to do so, subject to the following conditions:
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
/* $Id: vesa.c,v 1.36 2005/12/27 08:29:50 ajax Exp $ */
25
#include <kdrive-config.h>
34
int vesa_video_mode = 0;
35
Bool vesa_force_mode = FALSE;
36
Bool vesa_swap_rgb = FALSE;
37
Bool vesa_shadow = FALSE;
38
Bool vesa_linear_fb = TRUE;
39
Bool vesa_restore = FALSE;
40
Bool vesa_verbose = FALSE;
41
Bool vesa_force_text = FALSE;
42
Bool vesa_restore_font = TRUE;
43
Bool vesa_map_holes = TRUE;
44
Bool vesa_boot = FALSE;
46
#define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver)
48
#define vesaWidth(scr,vmib) ((vmib)->XResolution)
49
#define vesaHeight(scr,vmib) ((vmib)->YResolution)
52
vesaComputeFramebufferMapping (KdScreenInfo *screen);
55
vesaMapFramebuffer (KdScreenInfo *screen);
58
vesaModeSupportable (VesaModePtr mode, Bool complain)
60
if((mode->ModeAttributes & 0x10) == 0) {
62
ErrorF("Text mode specified.\n");
65
if(mode->MemoryModel != 0x06 && mode->MemoryModel != 0x04 && mode->MemoryModel != 0x03) {
67
ErrorF("Unsupported memory model 0x%X\n", mode->MemoryModel);
70
if((mode->ModeAttributes & 0x80) == 0) {
71
if ((mode->ModeAttributes & 0x40) != 0) {
73
ErrorF("Neither linear nor windowed framebuffer available in this mode\n");
77
if(!(mode->ModeAttributes & 1)) {
79
ErrorF("Mode not supported on this hardware\n");
86
vesaModeSupported (VesaCardPrivPtr priv, VesaModePtr mode, Bool complain)
88
if (!priv->vbeInfo && mode->vbe) {
90
ErrorF("VBE bios mode not usable.\n");
93
return vesaModeSupportable (mode, complain);
97
vesaReportMode (VesaModePtr mode)
99
int supported = (mode->ModeAttributes&MODE_SUPPORTED)?1:0;
100
int colour = (mode->ModeAttributes&MODE_COLOUR)?1:0;
101
int graphics = (mode->ModeAttributes&MODE_GRAPHICS)?1:0;
102
int vga_compatible = !((mode->ModeAttributes&MODE_VGA)?1:0);
103
int linear_fb = (mode->ModeAttributes&MODE_LINEAR)?1:0;
105
ErrorF("0x%04X: %dx%dx%d%s%s",
106
(unsigned)mode->mode,
107
(int)mode->XResolution, (int)mode->YResolution,
109
colour?"":" (monochrome)",
110
graphics?"":" (graphics)",
111
vga_compatible?"":" (vga compatible)",
112
linear_fb?"":" (linear frame buffer)");
113
switch(mode->MemoryModel) {
115
ErrorF(" text mode");
118
ErrorF(" CGA graphics");
120
case MEMORY_HERCULES:
121
ErrorF(" Hercules graphics");
124
ErrorF(" Planar (%d planes)", mode->NumberOfPlanes);
127
ErrorF(" PseudoColor");
129
case MEMORY_NONCHAIN:
130
ErrorF(" Non-chain 4, 256 colour");
133
if(mode->DirectColorModeInfo & MODE_DIRECT)
134
ErrorF(" DirectColor");
136
ErrorF(" TrueColor");
137
ErrorF(" [%d:%d:%d:%d]",
138
mode->RedMaskSize, mode->GreenMaskSize, mode->BlueMaskSize,
140
if(mode->DirectColorModeInfo & 2)
141
ErrorF(" (reserved bits are reserved)");
147
ErrorF("unknown MemoryModel 0x%X ", mode->MemoryModel);
150
ErrorF(" (unsupported)");
152
ErrorF(" (no linear framebuffer)");
157
vesaGetModes (Vm86InfoPtr vi, int *ret_nmode)
160
int nmode, nmodeVbe, nmodeVga;
163
code = VgaGetNmode (vi);
169
code = VbeGetNmode (vi);
175
nmode = nmodeVga + nmodeVbe;
179
modes = xalloc (nmode * sizeof (VesaModeRec));
181
memset (modes, '\0', nmode * sizeof (VesaModeRec));
185
code = VgaGetModes (vi, modes, nmodeVga);
194
code = VbeGetModes (vi, modes + nmodeVga, nmodeVbe);
201
nmode = nmodeVga + nmodeVbe;
214
vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
216
priv->vi = Vm86Setup(vesa_map_holes);
223
priv->modes = vesaGetModes (priv->vi, &priv->nmode);
228
priv->vbeInfo = VbeInit (priv->vi);
236
Vm86Cleanup(priv->vi);
248
vi = Vm86Setup (vesa_map_holes);
251
ErrorF ("Can't setup vm86\n");
255
modes = vesaGetModes (vi, &nmode);
258
ErrorF ("No modes available\n");
263
for (n = 0; n < nmode; n++)
265
if (vesa_force_mode || vesaModeSupportable (modes+n, 0))
266
vesaReportMode (modes+n);
284
vi = Vm86Setup (vesa_map_holes);
287
ErrorF ("Can't setup vm86\n");
290
modes = vesaGetModes (vi, &nmode);
293
ErrorF ("No modes available\n");
297
vbeInfo = VbeInit (vi);
298
for (n = 0; n < nmode; n++)
300
if (modes[n].mode == vesa_video_mode)
305
ErrorF ("no mode specified\n");
311
ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
312
VbeSetMode(vi, vbeInfo, mode->mode, FALSE, FALSE);
316
ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
317
VgaSetMode (vi, mode->mode);
320
ErrorF ("Restore BIOS mode 0x%x\n", 3);
327
vesaCardInit(KdCardInfo *card)
329
VesaCardPrivPtr priv;
331
priv = xalloc(sizeof(VesaCardPrivRec));
335
if (!vesaInitialize (card, priv))
345
vesaDepth (VesaModePtr mode)
347
if (mode->MemoryModel == MEMORY_DIRECT)
348
return (mode->RedMaskSize +
349
mode->GreenMaskSize +
352
return mode->BitsPerPixel;
356
vesaModeGood (KdScreenInfo *screen,
359
if (vesaWidth(screen,a) <= screen->width &&
360
vesaHeight(screen,a) <= screen->height &&
361
vesaDepth (a) >= screen->fb[0].depth)
368
#define vabs(a) ((a) >= 0 ? (a) : -(a))
371
vesaSizeError (KdScreenInfo *screen,
375
xdist = vabs (screen->width - vesaWidth(screen,a));
376
ydist = vabs (screen->height - vesaHeight(screen,a));
377
return xdist * xdist + ydist * ydist;
381
vesaModeBetter (KdScreenInfo *screen,
387
if (vesaModeGood (screen, a))
389
if (!vesaModeGood (screen, b))
394
if (vesaModeGood (screen, b))
397
aerr = vesaSizeError (screen, a);
398
berr = vesaSizeError (screen, b);
403
if (vabs (screen->fb[0].depth - vesaDepth (a)) <
404
vabs (screen->fb[0].depth - vesaDepth (b)))
406
if (a->BitsPerPixel == 32 && b->BitsPerPixel == 24)
412
vesaSelectMode (KdScreenInfo *screen)
414
VesaCardPrivPtr priv = screen->card->driver;
419
for (best = 0; best < priv->nmode; best++)
420
if (priv->modes[best].mode == vesa_video_mode &&
421
(vesaModeSupported (priv, &priv->modes[best], FALSE) ||
423
return &priv->modes[best];
425
for (best = 0; best < priv->nmode; best++)
427
if (vesaModeSupported (priv, &priv->modes[best], FALSE))
430
if (best == priv->nmode)
432
for (i = best + 1; i < priv->nmode; i++)
433
if (vesaModeSupported (priv, &priv->modes[i], FALSE) &&
434
vesaModeBetter (screen, &priv->modes[i],
437
return &priv->modes[best];
441
vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
445
screen->driver = pscr;
447
if (!screen->width || !screen->height)
450
screen->height = 480;
452
if (!screen->fb[0].depth)
453
screen->fb[0].depth = 4;
456
ErrorF ("Mode requested %dx%dx%d\n",
457
screen->width, screen->height, screen->fb[0].depth);
459
mode = vesaSelectMode (screen);
464
ErrorF ("No selectable mode\n");
472
vesaReportMode (&pscr->mode);
475
pscr->randr = screen->randr;
476
pscr->shadow = vesa_shadow;
477
pscr->origDepth = screen->fb[0].depth;
479
* Compute visual support for the selected depth
482
switch (pscr->mode.MemoryModel) {
484
/* TrueColor or DirectColor */
485
screen->fb[0].visuals = (1 << TrueColor);
486
screen->fb[0].redMask =
487
FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize);
488
screen->fb[0].greenMask =
489
FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize);
490
screen->fb[0].blueMask =
491
FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize);
495
screen->fb[0].visuals = ((1 << StaticGray) |
501
screen->fb[0].blueMask = 0x00;
502
screen->fb[0].greenMask = 0x00;
503
screen->fb[0].redMask = 0x00;
507
if (pscr->mode.ModeAttributes & MODE_COLOUR)
508
screen->fb[0].visuals = (1 << StaticColor);
510
screen->fb[0].visuals = (1 << StaticGray);
511
screen->fb[0].blueMask = 0x00;
512
screen->fb[0].greenMask = 0x00;
513
screen->fb[0].redMask = 0x00;
516
ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
517
pscr->mode.MemoryModel);
522
if (!vesaComputeFramebufferMapping (screen))
524
if (!vesaMapFramebuffer (screen))
530
vesaScreenInit(KdScreenInfo *screen)
532
VesaScreenPrivPtr pscr;
534
pscr = xcalloc (1, sizeof (VesaScreenPrivRec));
537
if (!vesaScreenInitialize (screen, pscr))
543
vesaSetWindowPlanar(ScreenPtr pScreen,
549
KdScreenPriv(pScreen);
550
VesaCardPrivPtr priv = pScreenPriv->card->driver;
551
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
557
VgaSetWritePlaneMask (priv->vi, (1 << plane));
558
offset = offset >> 2;
561
base = VbeSetWindow (priv->vi,
563
pscr->mode.BytesPerScanLine * row + offset,
569
base = VgaSetWindow (priv->vi,
571
pscr->mode.BytesPerScanLine * row + offset,
575
*size = (CARD32) winSize;
580
vesaSetWindowLinear (ScreenPtr pScreen,
586
KdScreenPriv(pScreen);
587
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
589
*size = pscr->mode.BytesPerScanLine;
590
return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset;
594
vesaSetWindowWindowed (ScreenPtr pScreen,
600
KdScreenPriv(pScreen);
601
VesaCardPrivPtr priv = pScreenPriv->card->driver;
602
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
608
base = VbeSetWindow (priv->vi,
610
pscr->mode.BytesPerScanLine * row + offset,
616
base = VgaSetWindow (priv->vi,
618
pscr->mode.BytesPerScanLine * row + offset,
622
*size = (CARD32) winSize;
627
vesaWindowPlanar (ScreenPtr pScreen,
634
KdScreenPriv(pScreen);
636
if (!pScreenPriv->enabled)
638
return vesaSetWindowPlanar (pScreen, row, offset, mode, size);
642
vesaWindowLinear (ScreenPtr pScreen,
649
KdScreenPriv(pScreen);
651
if (!pScreenPriv->enabled)
653
return vesaSetWindowLinear (pScreen, row, offset, mode, size);
657
vesaWindowWindowed (ScreenPtr pScreen,
664
KdScreenPriv(pScreen);
666
if (!pScreenPriv->enabled)
668
return vesaSetWindowWindowed (pScreen, row, offset, mode, size);
671
#define vesaInvertBits32(v) { \
672
v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
673
v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
674
v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
678
vesaWindowCga (ScreenPtr pScreen,
685
KdScreenPriv(pScreen);
686
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
689
if (!pScreenPriv->enabled)
691
*size = pscr->mode.BytesPerScanLine;
692
line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine;
693
return (CARD8 *) pscr->fb + line + offset;
697
vesaUpdateMono (ScreenPtr pScreen,
700
RegionPtr damage = shadowDamage(pBuf);
701
PixmapPtr pShadow = pBuf->pPixmap;
702
int nbox = REGION_NUM_RECTS (damage);
703
BoxPtr pbox = REGION_RECTS (damage);
704
FbBits *shaBase, *shaLine, *sha;
706
int scrBase, scrLine, scr;
708
int shaXoff, shaYoff; /* XXX assumed to be zero */
709
int x, y, w, h, width;
711
FbBits *winBase = 0, *win;
715
fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
718
x = pbox->x1 * shaBpp;
720
w = (pbox->x2 - pbox->x1) * shaBpp;
721
h = pbox->y2 - pbox->y1;
723
scrLine = (x >> FB_SHIFT);
724
shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
727
w = (w + x + FB_MASK) >> FB_SHIFT;
737
/* how much remains in this window */
738
i = scrBase + winSize - scr;
739
if (i <= 0 || scr < scrBase)
741
winBase = (FbBits *) (*pBuf->window) (pScreen,
743
scr * sizeof (FbBits),
750
winSize /= sizeof (FbBits);
753
win = winBase + (scr - scrBase);
761
vesaInvertBits32(bits);
765
shaLine += shaStride;
772
static const CARD16 vga16Colors[16][3] = {
773
{ 0, 0, 0, }, /* 0 */
774
{ 0, 0, 0xAA,}, /* 1 */
775
{ 0, 0xAA,0, }, /* 2 */
776
{ 0, 0xAA,0xAA,}, /* 3 */
777
{ 0xAA,0, 0, }, /* 4 */
778
{ 0xAA,0, 0xAA,}, /* 5 */
779
{ 0xAA,0x55,0, }, /* 6 */
780
{ 0xAA,0xAA,0xAA,}, /* 7 */
781
{ 0x55,0x55,0x55,}, /* 8 */
782
{ 0x55,0x55,0xFF,}, /* 9 */
783
{ 0x55,0xFF,0x55,}, /* 10 */
784
{ 0x55,0xFF,0xFF,}, /* 11 */
785
{ 0xFF,0x55,0x55,}, /* 12 */
786
{ 0xFF,0x55,0xFF,}, /* 13 */
787
{ 0xFF,0xFF,0x55,}, /* 14 */
788
{ 0xFF,0xFF,0xFF,}, /* 15 */
792
vesaCreateColormap16 (ColormapPtr pmap)
796
if (pmap->pVisual->ColormapEntries == 16)
797
for (i = 0; i < pmap->pVisual->ColormapEntries; i++)
800
pmap->red[i].co.local.red = (vga16Colors[j][0]<<8)|vga16Colors[j][0];
801
pmap->red[i].co.local.green = (vga16Colors[j][1]<<8)|vga16Colors[j][1];
802
pmap->red[i].co.local.blue = (vga16Colors[j][2]<<8)|vga16Colors[j][2];
808
vesaSetScreenSizes (ScreenPtr pScreen)
810
KdScreenPriv(pScreen);
811
KdScreenInfo *screen = pScreenPriv->screen;
812
VesaScreenPrivPtr pscr = screen->driver;
814
if (pscr->randr & (RR_Rotate_0|RR_Rotate_180))
816
pScreen->width = pscr->mode.XResolution;
817
pScreen->height = pscr->mode.YResolution;
818
pScreen->mmWidth = screen->width_mm;
819
pScreen->mmHeight = screen->height_mm;
823
pScreen->width = pscr->mode.YResolution;
824
pScreen->height = pscr->mode.XResolution;
825
pScreen->mmWidth = screen->height_mm;
826
pScreen->mmHeight = screen->width_mm;
831
vesaSetShadow (ScreenPtr pScreen)
833
KdScreenPriv(pScreen);
834
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
835
ShadowUpdateProc update;
836
ShadowWindowProc window = 0;
838
if (pscr->randr != RR_Rotate_0)
839
update = shadowUpdateRotatePacked;
841
update = shadowUpdatePacked;
842
switch (pscr->mapping) {
844
window = vesaWindowLinear;
847
window = vesaWindowWindowed;
850
if (pScreenPriv->screen->fb[0].bitsPerPixel == 8)
851
update = shadowUpdatePlanar4x8;
853
update = shadowUpdatePlanar4;
854
window = vesaWindowPlanar;
857
update = vesaUpdateMono;
858
if (pscr->mode.mode < 8)
859
window = vesaWindowCga;
861
window = vesaWindowLinear;
865
return KdShadowSet (pScreen, pscr->randr, update, window);
869
vesaComputeFramebufferMapping (KdScreenInfo *screen)
871
VesaScreenPrivPtr pscr = screen->driver;
872
int depth, bpp, fbbpp;
878
pscr->mapping = VESA_LINEAR;
879
pscr->shadow = FALSE;
883
pscr->mapping = VESA_WINDOWED;
887
depth = vesaDepth (&pscr->mode);
888
bpp = pscr->mode.BitsPerPixel;
904
switch (pscr->mode.MemoryModel) {
906
allbits = (screen->fb[0].redMask |
907
screen->fb[0].greenMask |
908
screen->fb[0].blueMask);
910
while (depth && !(allbits & (1 << (depth - 1))))
913
ErrorF ("\tTrue Color %d/%d red 0x%x green 0x%x blue 0x%x\n",
915
screen->fb[0].redMask,
916
screen->fb[0].greenMask,
917
screen->fb[0].blueMask);
921
ErrorF ("\tPseudo Color bpp %d depth %d\n",
927
bpp = screen->fb[0].bitsPerPixel;
934
pscr->mapping = VESA_MONO;
936
ErrorF ("\tMonochrome\n");
940
pscr->mapping = VESA_PLANAR;
942
ErrorF ("\tStatic color bpp %d depth %d\n",
945
pscr->randr = RR_Rotate_0;
958
pscr->randr = RR_Rotate_0;
962
if (pscr->randr != RR_Rotate_0)
966
pscr->shadow = vesa_shadow;
968
if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR))
970
pscr->mapping = VESA_WINDOWED;
973
KdComputeMouseMatrix (&m, pscr->randr,
974
pscr->mode.XResolution, pscr->mode.YResolution);
976
KdSetMouseMatrix (&m);
978
screen->width = pscr->mode.XResolution;
979
screen->height = pscr->mode.YResolution;
980
screen->fb[0].depth = depth;
981
screen->fb[0].bitsPerPixel = bpp;
987
vesaMapFramebuffer (KdScreenInfo *screen)
989
VesaCardPrivPtr priv = screen->card->driver;
990
VesaScreenPrivPtr pscr = screen->driver;
994
switch (pscr->mapping) {
998
pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
1003
pscr->fb = VgaMapFramebuffer (priv->vi,
1018
screen->memory_base = pscr->fb;
1019
screen->memory_size = pscr->fb_size;
1023
if (!KdShadowFbAlloc (screen, 0,
1024
pscr->randr & (RR_Rotate_90|RR_Rotate_270)))
1026
screen->off_screen_base = screen->memory_size;
1030
screen->fb[0].frameBuffer = (CARD8 *) (pscr->fb);
1031
screen->fb[0].byteStride = pscr->mode.BytesPerScanLine;
1032
screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) /
1033
screen->fb[0].bitsPerPixel);
1034
screen->off_screen_base = screen->fb[0].byteStride * screen->height;
1036
pscr->mapped = TRUE;
1042
vesaUnmapFramebuffer (KdScreenInfo *screen)
1044
VesaCardPrivPtr priv = screen->card->driver;
1045
VesaScreenPrivPtr pscr = screen->driver;
1050
pscr->mapped = FALSE;
1051
KdShadowFbFree (screen, 0);
1055
VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb);
1057
VgaUnmapFramebuffer (priv->vi);
1064
vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
1066
KdScreenPriv(pScreen);
1067
VesaModePtr modes, mode;
1068
KdScreenInfo *screen = pScreenPriv->screen;
1069
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1070
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1073
RRScreenSizePtr pSize;
1075
*rotations = (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270|
1076
RR_Reflect_X|RR_Reflect_Y);
1078
* Get mode information from BIOS -- every time in case
1079
* something changes, like an external monitor is plugged in
1081
modes = vesaGetModes (priv->vi, &nmode);
1085
xfree (priv->modes);
1086
priv->modes = modes;
1087
priv->nmode = nmode;
1088
for (n = 0; n < nmode; n++)
1090
mode = &priv->modes[n];
1091
if (vesaModeSupported (priv, mode, FALSE))
1094
* XXX limit reported modes to those matching the current
1097
if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
1098
mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
1099
mode->MemoryModel == pscr->mode.MemoryModel &&
1100
mode->RedMaskSize == pscr->mode.RedMaskSize &&
1101
mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
1102
mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
1103
mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
1104
mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
1105
mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
1107
int width, height, width_mm, height_mm;
1108
if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
1110
width = mode->XResolution;
1111
height = mode->YResolution;
1112
width_mm = screen->width_mm;
1113
height_mm = screen->height_mm;
1117
width = mode->YResolution;
1118
height = mode->XResolution;
1119
width_mm = screen->height_mm;
1120
height_mm = screen->width_mm;
1122
pSize = RRRegisterSize (pScreen,
1124
width_mm, height_mm);
1125
if (mode->XResolution == screen->width &&
1126
mode->YResolution == screen->height)
1128
int randr = KdSubRotation (pscr->randr, screen->randr);
1129
RRSetCurrentConfig (pScreen, randr, 0, pSize);
1138
vesaRandRSetConfig (ScreenPtr pScreen,
1141
RRScreenSizePtr pSize)
1143
KdScreenPriv(pScreen);
1144
VesaModePtr mode = 0;
1145
KdScreenInfo *screen = pScreenPriv->screen;
1146
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1147
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1149
Bool wasEnabled = pScreenPriv->enabled;
1151
VesaScreenPrivRec oldscr;
1156
int newwidth, newheight;
1158
if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
1160
newwidth = pSize->width;
1161
newheight = pSize->height;
1165
newwidth = pSize->height;
1166
newheight = pSize->width;
1168
for (n = 0; n < priv->nmode; n++)
1170
mode = &priv->modes[n];
1171
if (vesaModeSupported (priv, mode, FALSE))
1174
* XXX all we have to match is the size
1176
if (mode->XResolution == newwidth &&
1177
mode->YResolution == newheight &&
1178
mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
1179
mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
1180
mode->RedMaskSize == pscr->mode.RedMaskSize &&
1181
mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
1182
mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
1183
mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
1184
mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
1185
mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
1189
if (n == priv->nmode)
1193
KdDisableScreen (pScreen);
1195
if (mode->mode != pscr->mode.mode)
1197
ret = vesaSetMode (pScreen, mode);
1204
oldwidth = screen->width;
1205
oldheight = screen->height;
1206
oldmmwidth = pScreen->mmWidth;
1207
oldmmheight = pScreen->mmHeight;
1210
* Set new configuration
1214
pscr->randr = KdAddRotation (screen->randr, randr);
1217
* Can't rotate some formats
1219
switch (screen->fb[0].bitsPerPixel) {
1230
KdOffscreenSwapOut (screen->pScreen);
1232
vesaUnmapFramebuffer (screen);
1234
if (!vesaComputeFramebufferMapping (screen))
1237
if (!vesaMapFramebuffer (screen))
1240
vesaSetScreenSizes (screen->pScreen);
1242
if (!vesaSetShadow (screen->pScreen))
1246
* Set frame buffer mapping
1248
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
1251
screen->fb[0].depth,
1252
screen->fb[0].bitsPerPixel,
1253
screen->fb[0].byteStride,
1254
screen->fb[0].frameBuffer);
1256
/* set the subpixel order */
1257
KdSetSubpixelOrder (pScreen, pscr->randr);
1260
KdEnableScreen (pScreen);
1265
vesaUnmapFramebuffer (screen);
1267
(void) vesaComputeFramebufferMapping (screen);
1268
(void) vesaMapFramebuffer (screen);
1271
pScreen->width = oldwidth;
1272
pScreen->height = oldheight;
1273
pScreen->mmWidth = oldmmwidth;
1274
pScreen->mmHeight = oldmmheight;
1279
(void) vesaSetMode (pScreen, &pscr->mode);
1282
KdEnableScreen (pScreen);
1289
vesaRandRInit (ScreenPtr pScreen)
1291
rrScrPrivPtr pScrPriv;
1293
if (!RRScreenInit (pScreen))
1296
pScrPriv = rrGetScrPriv(pScreen);
1297
pScrPriv->rrGetInfo = vesaRandRGetInfo;
1298
pScrPriv->rrSetConfig = vesaRandRSetConfig;
1304
vesaInitScreen(ScreenPtr pScreen)
1306
KdScreenPriv(pScreen);
1307
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1308
switch (pscr->mapping) {
1310
pScreen->CreateColormap = vesaCreateColormap16;
1317
vesaFinishInitScreen (ScreenPtr pScreen)
1319
if (!shadowSetup (pScreen))
1323
if (!vesaRandRInit (pScreen))
1331
vesaCreateResources (ScreenPtr pScreen)
1333
return vesaSetShadow (pScreen);
1337
vesaSetMode (ScreenPtr pScreen,
1340
KdScreenPriv(pScreen);
1341
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1342
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1348
ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
1349
code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode,
1350
pscr->mapping == VESA_LINEAR,
1351
mode->MemoryModel == MEMORY_DIRECT);
1356
ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
1357
code = VgaSetMode (priv->vi, mode->mode);
1367
vesaEnable(ScreenPtr pScreen)
1369
KdScreenPriv(pScreen);
1370
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1371
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1372
KdScreenInfo *screen = pScreenPriv->screen;
1376
Bool was_mapped = pscr->mapped;
1378
if (!vesaMapFramebuffer (screen))
1381
if (!vesaSetMode (pScreen, &pscr->mode))
1384
switch (pscr->mapping) {
1386
VgaSetWritePlaneMask (priv->vi, 0x1);
1388
if (vesa_restore_font)
1389
memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
1392
if (vesa_restore_font)
1394
for (i = 0; i < VESA_TEXT_SAVE;)
1396
p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_READ, &size);
1398
ErrorF("Couldn't set window for saving VGA font\n");
1401
if(i + size > VESA_TEXT_SAVE)
1402
size = VESA_TEXT_SAVE - i;
1403
memcpy(((char*)priv->text) + i, p, size);
1409
if (vesa_restore_font)
1411
for (i = 0; i < 4; i++)
1413
p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_READ, &size);
1414
memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p,
1415
(VESA_TEXT_SAVE/4));
1422
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
1425
screen->fb[0].depth,
1426
screen->fb[0].bitsPerPixel,
1427
screen->fb[0].byteStride,
1428
screen->fb[0].frameBuffer);
1436
# define TOSHIBA_SMM 1
1439
# ifndef TOSHIBA_SMM
1440
# define TOSHIBA_SMM 0
1447
* Toshiba laptops use a special interface to operate the backlight
1449
#include <sys/ioctl.h>
1450
#define TOSH_PROC "/proc/toshiba"
1451
#define TOSH_DEVICE "/dev/toshiba"
1452
#define TOSH_SMM _IOWR('t', 0x90, SMMRegisters)
1456
unsigned int ebx __attribute__ ((packed));
1457
unsigned int ecx __attribute__ ((packed));
1458
unsigned int edx __attribute__ ((packed));
1459
unsigned int esi __attribute__ ((packed));
1460
unsigned int edi __attribute__ ((packed));
1463
#define HCI_BACKLIGHT 0x0002
1464
#define HCI_DISABLE 0x0000
1465
#define HCI_ENABLE 0x0001
1466
#define HCI_GET 0xfe00,
1467
#define HCI_SET 0xff00
1470
toshibaDPMS (ScreenPtr pScreen, int mode)
1476
fd = open (TOSH_DEVICE, 2);
1480
regs.ebx = HCI_BACKLIGHT;
1481
regs.ecx = mode ? HCI_DISABLE : HCI_ENABLE;
1482
if (ioctl (fd, TOSH_SMM, ®s) < 0)
1486
#endif /* TOSHIBA_SMM */
1489
vesaDPMS (ScreenPtr pScreen, int mode)
1491
KdScreenPriv(pScreen);
1492
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1493
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1496
if (toshibaDPMS (pScreen, mode))
1500
return VbeDPMS (priv->vi, mode);
1505
vesaDisable(ScreenPtr pScreen)
1507
KdScreenPriv(pScreen);
1508
KdScreenInfo *screen = pScreenPriv->screen;
1509
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1510
VesaScreenPrivPtr pscr = screen->driver;
1515
if (vesa_restore_font) {
1516
switch (pscr->mapping) {
1519
memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE);
1522
while(i < VESA_TEXT_SAVE) {
1523
p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
1525
ErrorF("Couldn't set window for restoring VGA font\n");
1528
if(i + size > VESA_TEXT_SAVE)
1529
size = VESA_TEXT_SAVE - i;
1530
memcpy(p, ((char*)priv->text) + i, size);
1535
for (i = 0; i < 4; i++)
1537
p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
1539
((char *)priv->text) + i * (VESA_TEXT_SAVE/4),
1540
(VESA_TEXT_SAVE/4));
1545
vesaUnmapFramebuffer (screen);
1549
vesaPreserve(KdCardInfo *card)
1551
VesaCardPrivPtr priv = card->driver;
1553
/* The framebuffer might not be valid at this point, so we cannot
1554
save the VGA fonts now; we do it in vesaEnable. */
1556
if (VbeGetMode (priv->vi, &priv->old_vbe_mode) < 0)
1557
priv->old_vbe_mode = -1;
1559
if (VgaGetMode (priv->vi, &priv->old_vga_mode) < 0)
1560
priv->old_vga_mode = -1;
1563
ErrorF ("Previous modes: VBE 0x%x BIOS 0x%x\n",
1564
priv->old_vbe_mode, priv->old_vga_mode);
1568
vesaRestore(KdCardInfo *card)
1570
VesaCardPrivPtr priv = card->driver;
1573
if (vesa_force_text)
1576
ErrorF ("Forcing switch back to mode 3 text\n");
1577
priv->old_vbe_mode = -1;
1578
priv->old_vga_mode = 3;
1580
for (n = 0; n < priv->nmode; n++)
1581
if (priv->modes[n].vbe && priv->modes[n].mode == (priv->old_vbe_mode&0x3fff))
1584
if (n < priv->nmode)
1587
ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode);
1588
VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0);
1593
ErrorF ("Restore BIOS mode 0x%x\n", priv->old_vga_mode);
1594
VgaSetMode (priv->vi, priv->old_vga_mode);
1599
vesaCardFini(KdCardInfo *card)
1601
VesaCardPrivPtr priv = card->driver;
1604
VbeCleanup (priv->vi, priv->vbeInfo);
1606
xfree (priv->modes);
1607
Vm86Cleanup(priv->vi);
1611
vesaScreenFini(KdScreenInfo *screen)
1613
VesaScreenPrivPtr pscr = screen->driver;
1615
KdShadowFbFree (screen, 0);
1616
vesaUnmapFramebuffer (screen);
1617
screen->fb[0].depth = pscr->origDepth;
1621
vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
1623
if (priv->vga_palette)
1624
return VgaSetPalette (priv->vi, first, number, entries);
1626
return VbeSetPalette (priv->vi, priv->vbeInfo, first, number, entries);
1631
vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
1635
if (priv->vga_palette)
1636
code = VgaGetPalette (priv->vi, first, number, entries);
1639
code = VbeGetPalette (priv->vi, priv->vbeInfo, first, number, entries);
1642
priv->vga_palette = 1;
1643
code = VgaGetPalette (priv->vi, first, number, entries);
1650
vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
1652
KdScreenPriv(pScreen);
1653
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1654
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1657
int red, green, blue;
1682
scratch = priv->cmap + (p * 4);
1683
scratch[red] = pdefs->red >> 8;
1684
scratch[green] = pdefs->green >> 8;
1685
scratch[blue] = pdefs->blue >> 8;
1688
if (pscr->mapping == VESA_PLANAR)
1691
* VGA modes are strange; this code covers all
1692
* possible modes by duplicating the color information
1693
* however the attribute registers might be set
1697
vesaSetPalette (priv, p, 1, scratch);
1699
vesaSetPalette (priv, p+0x30, 1, scratch);
1701
vesaSetPalette (priv, 0x14, 1, scratch);
1705
if (pscr->mapping != VESA_PLANAR)
1706
vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4);
1710
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
1712
KdScreenPriv(pScreen);
1713
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1714
VesaCardPrivPtr priv = pScreenPriv->card->driver;
1716
int red, green, blue;
1736
for(i = 0; i < n; i++)
1743
if (pscr->mapping == VESA_PLANAR)
1744
vesaGetPalette (priv, p, 1, priv->cmap + p * 4);
1746
if (pscr->mapping != VESA_PLANAR)
1747
vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4);
1748
for (i = 0; i < n; i++)
1751
scratch = priv->cmap + p * 4;
1752
pdefs[i].red = scratch[red]<<8;
1753
pdefs[i].green = scratch[green]<<8;
1754
pdefs[i].blue = scratch[blue]<<8;
1761
ErrorF("\nTinyX VESA Usage:\n");
1762
ErrorF("-mode VESA video mode to use (Be careful!)\n");
1763
ErrorF("-listmodes List supported video modes\n");
1764
ErrorF("-force Attempt even unsupported modes\n");
1765
ErrorF("-shadow Always use shadow framebuffer (May increase performance)\n");
1766
ErrorF("-nolinear Never use linear framebuffer (Not useful)\n");
1767
ErrorF("-swaprgb Use if colors are wrong in PseudoColor and 16 color modes\n");
1768
ErrorF("-map-holes Use contiguous memory map (For seg fault with rare BIOS)\n");
1769
ErrorF("-verbose Emit diagnostic messages during BIOS initialization\n");
1770
ErrorF("-force-text Always use standard 25x80 text mode on server exit or VT switch\n");
1771
ErrorF("-boot Soft boot video card\n");
1772
/* XXX: usage for -vesatest, -no-map-holes (don't need?),
1773
* XXX: and -trash-font. Also in man page. */
1777
vesaProcessArgument (int argc, char **argv, int i)
1779
if(!strcmp(argv[i], "-mode")) {
1781
vesa_video_mode = strtol(argv[i+1], NULL, 0);
1785
} else if(!strcmp(argv[i], "-force")) {
1786
vesa_force_mode = TRUE;
1788
} else if(!strcmp(argv[i], "-listmodes")) {
1791
} else if(!strcmp(argv[i], "-vesatest")) {
1794
} else if(!strcmp(argv[i], "-swaprgb")) {
1795
vesa_swap_rgb = TRUE;
1797
} else if(!strcmp(argv[i], "-shadow")) {
1800
} else if(!strcmp(argv[i], "-nolinear")) {
1801
vesa_linear_fb = FALSE;
1803
} else if(!strcmp(argv[i], "-verbose")) {
1804
vesa_verbose = TRUE;
1806
} else if(!strcmp(argv[i], "-force-text")) {
1807
vesa_force_text = TRUE;
1809
} else if(!strcmp(argv[i], "-map-holes")) {
1810
vesa_map_holes = TRUE;
1812
} else if(!strcmp(argv[i], "-no-map-holes")) {
1813
vesa_map_holes = FALSE;
1815
} else if(!strcmp(argv[i], "-trash-font")) {
1816
vesa_restore_font = FALSE;
1818
} else if(!strcmp(argv[i], "-boot")) {