xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

vbeModes.c (16335B)


      1 #define DEBUG_VERB 2
      2 /*
      3  * Copyright © 2002 David Dawes
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included in
     13  * all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  *
     23  * Except as contained in this notice, the name of the author(s) shall
     24  * not be used in advertising or otherwise to promote the sale, use or other
     25  * dealings in this Software without prior written authorization from
     26  * the author(s).
     27  *
     28  * Authors: David Dawes <dawes@xfree86.org>
     29  *
     30  */
     31 
     32 #ifdef HAVE_XORG_CONFIG_H
     33 #include <xorg-config.h>
     34 #endif
     35 
     36 #include <stdio.h>
     37 #include <string.h>
     38 
     39 #include "xf86.h"
     40 #include "vbe.h"
     41 #include "vbeModes.h"
     42 
     43 static int
     44 GetDepthFlag(vbeInfoPtr pVbe, int id)
     45 {
     46     VbeModeInfoBlock *mode;
     47     int bpp;
     48 
     49     if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
     50         return 0;
     51 
     52     if (VBE_MODE_USABLE(mode, 0)) {
     53         int depth;
     54 
     55         if (VBE_MODE_COLOR(mode)) {
     56             depth = mode->RedMaskSize + mode->GreenMaskSize +
     57                 mode->BlueMaskSize;
     58         }
     59         else {
     60             depth = 1;
     61         }
     62         bpp = mode->BitsPerPixel;
     63         VBEFreeModeInfo(mode);
     64         mode = NULL;
     65         switch (depth) {
     66         case 1:
     67             return V_DEPTH_1;
     68         case 4:
     69             return V_DEPTH_4;
     70         case 8:
     71             return V_DEPTH_8;
     72         case 15:
     73             return V_DEPTH_15;
     74         case 16:
     75             return V_DEPTH_16;
     76         case 24:
     77             switch (bpp) {
     78             case 24:
     79                 return V_DEPTH_24_24;
     80             case 32:
     81                 return V_DEPTH_24_32;
     82             }
     83         }
     84     }
     85     if (mode)
     86         VBEFreeModeInfo(mode);
     87     return 0;
     88 }
     89 
     90 /*
     91  * Find supported mode depths.
     92  */
     93 int
     94 VBEFindSupportedDepths(vbeInfoPtr pVbe, VbeInfoBlock * vbe, int *flags24,
     95                        int modeTypes)
     96 {
     97     int i = 0;
     98     int depths = 0;
     99 
    100     if (modeTypes & V_MODETYPE_VBE) {
    101         while (vbe->VideoModePtr[i] != 0xffff) {
    102             depths |= GetDepthFlag(pVbe, vbe->VideoModePtr[i++]);
    103         }
    104     }
    105 
    106     /*
    107      * XXX This possibly only works with VBE 3.0 and later.
    108      */
    109     if (modeTypes & V_MODETYPE_VGA) {
    110         for (i = 0; i < 0x7F; i++) {
    111             depths |= GetDepthFlag(pVbe, i);
    112         }
    113     }
    114 
    115     if (flags24) {
    116         if (depths & V_DEPTH_24_24)
    117             *flags24 |= Support24bppFb;
    118         if (depths & V_DEPTH_24_32)
    119             *flags24 |= Support32bppFb;
    120     }
    121 
    122     return depths;
    123 }
    124 
    125 static DisplayModePtr
    126 CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock * vbe, int id,
    127           int flags)
    128 {
    129     CARD16 major;
    130     VbeModeInfoBlock *mode;
    131     DisplayModePtr pMode;
    132     VbeModeInfoData *data;
    133     Bool modeOK = FALSE;
    134 
    135     major = (unsigned) (vbe->VESAVersion >> 8);
    136 
    137     if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
    138         return NULL;
    139 
    140     /* Does the mode match the depth/bpp? */
    141     /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
    142     if (VBE_MODE_USABLE(mode, flags) &&
    143         ((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) ||
    144          (mode->BitsPerPixel > 8 &&
    145           (mode->RedMaskSize + mode->GreenMaskSize +
    146            mode->BlueMaskSize) == pScrn->depth &&
    147           mode->BitsPerPixel == pScrn->bitsPerPixel) ||
    148          (mode->BitsPerPixel == 15 && pScrn->depth == 15) ||
    149          (mode->BitsPerPixel <= 8 &&
    150           mode->BitsPerPixel == pScrn->bitsPerPixel))) {
    151         modeOK = TRUE;
    152         xf86ErrorFVerb(DEBUG_VERB, "*");
    153     }
    154 
    155     xf86ErrorFVerb(DEBUG_VERB,
    156                    "Mode: %x (%dx%d)\n", id, mode->XResolution,
    157                    mode->YResolution);
    158     xf86ErrorFVerb(DEBUG_VERB, "	ModeAttributes: 0x%x\n",
    159                    mode->ModeAttributes);
    160     xf86ErrorFVerb(DEBUG_VERB, "	WinAAttributes: 0x%x\n",
    161                    mode->WinAAttributes);
    162     xf86ErrorFVerb(DEBUG_VERB, "	WinBAttributes: 0x%x\n",
    163                    mode->WinBAttributes);
    164     xf86ErrorFVerb(DEBUG_VERB, "	WinGranularity: %d\n",
    165                    mode->WinGranularity);
    166     xf86ErrorFVerb(DEBUG_VERB, "	WinSize: %d\n", mode->WinSize);
    167     xf86ErrorFVerb(DEBUG_VERB,
    168                    "	WinASegment: 0x%x\n", mode->WinASegment);
    169     xf86ErrorFVerb(DEBUG_VERB,
    170                    "	WinBSegment: 0x%x\n", mode->WinBSegment);
    171     xf86ErrorFVerb(DEBUG_VERB,
    172                    "	WinFuncPtr: 0x%lx\n", (unsigned long) mode->WinFuncPtr);
    173     xf86ErrorFVerb(DEBUG_VERB,
    174                    "	BytesPerScanline: %d\n", mode->BytesPerScanline);
    175     xf86ErrorFVerb(DEBUG_VERB, "	XResolution: %d\n", mode->XResolution);
    176     xf86ErrorFVerb(DEBUG_VERB, "	YResolution: %d\n", mode->YResolution);
    177     xf86ErrorFVerb(DEBUG_VERB, "	XCharSize: %d\n", mode->XCharSize);
    178     xf86ErrorFVerb(DEBUG_VERB, "	YCharSize: %d\n", mode->YCharSize);
    179     xf86ErrorFVerb(DEBUG_VERB,
    180                    "	NumberOfPlanes: %d\n", mode->NumberOfPlanes);
    181     xf86ErrorFVerb(DEBUG_VERB,
    182                    "	BitsPerPixel: %d\n", mode->BitsPerPixel);
    183     xf86ErrorFVerb(DEBUG_VERB,
    184                    "	NumberOfBanks: %d\n", mode->NumberOfBanks);
    185     xf86ErrorFVerb(DEBUG_VERB, "	MemoryModel: %d\n", mode->MemoryModel);
    186     xf86ErrorFVerb(DEBUG_VERB, "	BankSize: %d\n", mode->BankSize);
    187     xf86ErrorFVerb(DEBUG_VERB,
    188                    "	NumberOfImages: %d\n", mode->NumberOfImages);
    189     xf86ErrorFVerb(DEBUG_VERB, "	RedMaskSize: %d\n", mode->RedMaskSize);
    190     xf86ErrorFVerb(DEBUG_VERB,
    191                    "	RedFieldPosition: %d\n", mode->RedFieldPosition);
    192     xf86ErrorFVerb(DEBUG_VERB,
    193                    "	GreenMaskSize: %d\n", mode->GreenMaskSize);
    194     xf86ErrorFVerb(DEBUG_VERB,
    195                    "	GreenFieldPosition: %d\n", mode->GreenFieldPosition);
    196     xf86ErrorFVerb(DEBUG_VERB,
    197                    "	BlueMaskSize: %d\n", mode->BlueMaskSize);
    198     xf86ErrorFVerb(DEBUG_VERB,
    199                    "	BlueFieldPosition: %d\n", mode->BlueFieldPosition);
    200     xf86ErrorFVerb(DEBUG_VERB,
    201                    "	RsvdMaskSize: %d\n", mode->RsvdMaskSize);
    202     xf86ErrorFVerb(DEBUG_VERB,
    203                    "	RsvdFieldPosition: %d\n", mode->RsvdFieldPosition);
    204     xf86ErrorFVerb(DEBUG_VERB,
    205                    "	DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
    206     if (major >= 2) {
    207         xf86ErrorFVerb(DEBUG_VERB,
    208                        "	PhysBasePtr: 0x%lx\n",
    209                        (unsigned long) mode->PhysBasePtr);
    210         if (major >= 3) {
    211             xf86ErrorFVerb(DEBUG_VERB,
    212                            "	LinBytesPerScanLine: %d\n",
    213                            mode->LinBytesPerScanLine);
    214             xf86ErrorFVerb(DEBUG_VERB, "	BnkNumberOfImagePages: %d\n",
    215                            mode->BnkNumberOfImagePages);
    216             xf86ErrorFVerb(DEBUG_VERB, "	LinNumberOfImagePages: %d\n",
    217                            mode->LinNumberOfImagePages);
    218             xf86ErrorFVerb(DEBUG_VERB, "	LinRedMaskSize: %d\n",
    219                            mode->LinRedMaskSize);
    220             xf86ErrorFVerb(DEBUG_VERB, "	LinRedFieldPosition: %d\n",
    221                            mode->LinRedFieldPosition);
    222             xf86ErrorFVerb(DEBUG_VERB, "	LinGreenMaskSize: %d\n",
    223                            mode->LinGreenMaskSize);
    224             xf86ErrorFVerb(DEBUG_VERB, "	LinGreenFieldPosition: %d\n",
    225                            mode->LinGreenFieldPosition);
    226             xf86ErrorFVerb(DEBUG_VERB, "	LinBlueMaskSize: %d\n",
    227                            mode->LinBlueMaskSize);
    228             xf86ErrorFVerb(DEBUG_VERB, "	LinBlueFieldPosition: %d\n",
    229                            mode->LinBlueFieldPosition);
    230             xf86ErrorFVerb(DEBUG_VERB, "	LinRsvdMaskSize: %d\n",
    231                            mode->LinRsvdMaskSize);
    232             xf86ErrorFVerb(DEBUG_VERB, "	LinRsvdFieldPosition: %d\n",
    233                            mode->LinRsvdFieldPosition);
    234             xf86ErrorFVerb(DEBUG_VERB, "	MaxPixelClock: %ld\n",
    235                            (unsigned long) mode->MaxPixelClock);
    236         }
    237     }
    238 
    239     if (!modeOK) {
    240         VBEFreeModeInfo(mode);
    241         return NULL;
    242     }
    243     pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
    244 
    245     pMode->status = MODE_OK;
    246     pMode->type = M_T_BUILTIN;
    247 
    248     /* for adjust frame */
    249     pMode->HDisplay = mode->XResolution;
    250     pMode->VDisplay = mode->YResolution;
    251 
    252     data = xnfcalloc(sizeof(VbeModeInfoData), 1);
    253     data->mode = id;
    254     data->data = mode;
    255     pMode->PrivSize = sizeof(VbeModeInfoData);
    256     pMode->Private = (INT32 *) data;
    257     pMode->next = NULL;
    258     return pMode;
    259 }
    260 
    261 /*
    262  * Check the available BIOS modes, and extract those that match the
    263  * requirements into the modePool.  Note: modePool is a NULL-terminated
    264  * list.
    265  */
    266 
    267 DisplayModePtr
    268 VBEGetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock * vbe,
    269                int modeTypes)
    270 {
    271     DisplayModePtr pMode, p = NULL, modePool = NULL;
    272     int i = 0;
    273 
    274     if (modeTypes & V_MODETYPE_VBE) {
    275         while (vbe->VideoModePtr[i] != 0xffff) {
    276             int id = vbe->VideoModePtr[i++];
    277 
    278             if ((pMode = CheckMode(pScrn, pVbe, vbe, id, modeTypes)) != NULL) {
    279                 ModeStatus status = MODE_OK;
    280 
    281                 /* Check the mode against a specified virtual size (if any) */
    282                 if (pScrn->display->virtualX > 0 &&
    283                     pMode->HDisplay > pScrn->display->virtualX) {
    284                     status = MODE_VIRTUAL_X;
    285                 }
    286                 if (pScrn->display->virtualY > 0 &&
    287                     pMode->VDisplay > pScrn->display->virtualY) {
    288                     status = MODE_VIRTUAL_Y;
    289                 }
    290                 if (status != MODE_OK) {
    291                     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    292                                "Not using mode \"%dx%d\" (%s)\n",
    293                                pMode->HDisplay, pMode->VDisplay,
    294                                xf86ModeStatusToString(status));
    295                 }
    296                 else {
    297                     if (p == NULL) {
    298                         modePool = pMode;
    299                     }
    300                     else {
    301                         p->next = pMode;
    302                     }
    303                     pMode->prev = NULL;
    304                     p = pMode;
    305                 }
    306             }
    307         }
    308     }
    309     if (modeTypes & V_MODETYPE_VGA) {
    310         for (i = 0; i < 0x7F; i++) {
    311             if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) {
    312                 ModeStatus status = MODE_OK;
    313 
    314                 /* Check the mode against a specified virtual size (if any) */
    315                 if (pScrn->display->virtualX > 0 &&
    316                     pMode->HDisplay > pScrn->display->virtualX) {
    317                     status = MODE_VIRTUAL_X;
    318                 }
    319                 if (pScrn->display->virtualY > 0 &&
    320                     pMode->VDisplay > pScrn->display->virtualY) {
    321                     status = MODE_VIRTUAL_Y;
    322                 }
    323                 if (status != MODE_OK) {
    324                     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    325                                "Not using mode \"%dx%d\" (%s)\n",
    326                                pMode->HDisplay, pMode->VDisplay,
    327                                xf86ModeStatusToString(status));
    328                 }
    329                 else {
    330                     if (p == NULL) {
    331                         modePool = pMode;
    332                     }
    333                     else {
    334                         p->next = pMode;
    335                     }
    336                     pMode->prev = NULL;
    337                     p = pMode;
    338                 }
    339             }
    340         }
    341     }
    342     return modePool;
    343 }
    344 
    345 void
    346 VBESetModeNames(DisplayModePtr pMode)
    347 {
    348     if (!pMode)
    349         return;
    350 
    351     do {
    352         if (!pMode->name) {
    353             /* Catch "bad" modes. */
    354             if (pMode->HDisplay > 10000 || pMode->HDisplay < 0 ||
    355                 pMode->VDisplay > 10000 || pMode->VDisplay < 0) {
    356                 pMode->name = strdup("BADMODE");
    357             }
    358             else {
    359                 char *tmp;
    360                 XNFasprintf(&tmp, "%dx%d",
    361                             pMode->HDisplay, pMode->VDisplay);
    362                 pMode->name = tmp;
    363             }
    364         }
    365         pMode = pMode->next;
    366     } while (pMode);
    367 }
    368 
    369 /*
    370  * Go through the monitor modes and selecting the best set of
    371  * parameters for each BIOS mode.  Note: This is only supported in
    372  * VBE version 3.0 or later.
    373  */
    374 void
    375 VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
    376 {
    377     DisplayModePtr pMode;
    378     VbeModeInfoData *data;
    379 
    380     pMode = pScrn->modes;
    381     do {
    382         DisplayModePtr p, best = NULL;
    383         ModeStatus status;
    384 
    385         for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
    386             if ((p->HDisplay != pMode->HDisplay) ||
    387                 (p->VDisplay != pMode->VDisplay) ||
    388                 (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
    389                 continue;
    390             /* XXX could support the various V_ flags */
    391             status = xf86CheckModeForMonitor(p, pScrn->monitor);
    392             if (status != MODE_OK)
    393                 continue;
    394             if (!best || (p->Clock > best->Clock))
    395                 best = p;
    396         }
    397 
    398         if (best) {
    399             int clock;
    400 
    401             data = (VbeModeInfoData *) pMode->Private;
    402             pMode->HSync = (float) best->Clock * 1000.0 / best->HTotal + 0.5;
    403             pMode->VRefresh = pMode->HSync / best->VTotal + 0.5;
    404             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    405                        "Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
    406                        (int) pMode->VRefresh, pMode->name, data->mode);
    407             data->block = calloc(sizeof(VbeCRTCInfoBlock), 1);
    408             data->block->HorizontalTotal = best->HTotal;
    409             data->block->HorizontalSyncStart = best->HSyncStart;
    410             data->block->HorizontalSyncEnd = best->HSyncEnd;
    411             data->block->VerticalTotal = best->VTotal;
    412             data->block->VerticalSyncStart = best->VSyncStart;
    413             data->block->VerticalSyncEnd = best->VSyncEnd;
    414             data->block->Flags = ((best->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
    415                 ((best->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
    416             data->block->PixelClock = best->Clock * 1000;
    417             /* XXX May not have this. */
    418             clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
    419             DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n",
    420                    (double) data->block->PixelClock / 1000000.0,
    421                    (double) clock / 1000000.0);
    422             if (clock)
    423                 data->block->PixelClock = clock;
    424             data->mode |= (1 << 11);
    425             data->block->RefreshRate = ((double) (data->block->PixelClock) /
    426                                         (double) (best->HTotal *
    427                                                   best->VTotal)) * 100;
    428         }
    429         pMode = pMode->next;
    430     } while (pMode != pScrn->modes);
    431 }
    432 
    433 /*
    434  * These wrappers are to allow (temporary) functionality divergences.
    435  */
    436 int
    437 VBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
    438                  const char **modeNames, ClockRangePtr clockRanges,
    439                  int *linePitches, int minPitch, int maxPitch, int pitchInc,
    440                  int minHeight, int maxHeight, int virtualX, int virtualY,
    441                  int apertureSize, LookupModeFlags strategy)
    442 {
    443     return xf86ValidateModes(scrp, availModes, modeNames, clockRanges,
    444                              linePitches, minPitch, maxPitch, pitchInc,
    445                              minHeight, maxHeight, virtualX, virtualY,
    446                              apertureSize, strategy);
    447 }
    448 
    449 void
    450 VBEPrintModes(ScrnInfoPtr scrp)
    451 {
    452     xf86PrintModes(scrp);
    453 }