xserver

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

rrinfo.c (9007B)


      1 /*
      2  * Copyright © 2006 Keith Packard
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that copyright
      7  * notice and this permission notice appear in supporting documentation, and
      8  * that the name of the copyright holders not be used in advertising or
      9  * publicity pertaining to distribution of the software without specific,
     10  * written prior permission.  The copyright holders make no representations
     11  * about the suitability of this software for any purpose.  It is provided "as
     12  * is" without express or implied warranty.
     13  *
     14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     20  * OF THIS SOFTWARE.
     21  */
     22 
     23 #include "randrstr.h"
     24 
     25 #ifdef RANDR_10_INTERFACE
     26 static RRModePtr
     27 RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
     28 {
     29     ScreenPtr pScreen = output->pScreen;
     30 
     31     rrScrPriv(pScreen);
     32     xRRModeInfo modeInfo;
     33     char name[100];
     34     RRModePtr mode;
     35     int i;
     36     RRModePtr *modes;
     37 
     38     memset(&modeInfo, '\0', sizeof(modeInfo));
     39     snprintf(name, sizeof(name), "%dx%d", size->width, size->height);
     40 
     41     modeInfo.width = size->width;
     42     modeInfo.height = size->height;
     43     modeInfo.hTotal = size->width;
     44     modeInfo.vTotal = size->height;
     45     modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height *
     46                          (CARD32) refresh);
     47     modeInfo.nameLength = strlen(name);
     48     mode = RRModeGet(&modeInfo, name);
     49     if (!mode)
     50         return NULL;
     51     for (i = 0; i < output->numModes; i++)
     52         if (output->modes[i] == mode) {
     53             RRModeDestroy(mode);
     54             return mode;
     55         }
     56 
     57     if (output->numModes)
     58         modes = reallocarray(output->modes,
     59                              output->numModes + 1, sizeof(RRModePtr));
     60     else
     61         modes = malloc(sizeof(RRModePtr));
     62     if (!modes) {
     63         RRModeDestroy(mode);
     64         FreeResource(mode->mode.id, 0);
     65         return NULL;
     66     }
     67     modes[output->numModes++] = mode;
     68     output->modes = modes;
     69     output->changed = TRUE;
     70     pScrPriv->changed = TRUE;
     71     pScrPriv->configChanged = TRUE;
     72     return mode;
     73 }
     74 
     75 static void
     76 RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
     77 {
     78     rrScrPriv(pScreen);
     79     RROutputPtr output;
     80     RRCrtcPtr crtc;
     81     RRModePtr mode, newMode = NULL;
     82     int i;
     83     CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT;
     84     CARD16 maxWidth = 0, maxHeight = 0;
     85     CARD16 width, height;
     86 
     87     /*
     88      * First time through, create a crtc and output and hook
     89      * them together
     90      */
     91     if (pScrPriv->numOutputs == 0 && pScrPriv->numCrtcs == 0) {
     92         crtc = RRCrtcCreate(pScreen, NULL);
     93         if (!crtc)
     94             return;
     95         output = RROutputCreate(pScreen, "default", 7, NULL);
     96         if (!output)
     97             return;
     98         RROutputSetCrtcs(output, &crtc, 1);
     99         RROutputSetConnection(output, RR_Connected);
    100         RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
    101     }
    102 
    103     output = pScrPriv->outputs[0];
    104     if (!output)
    105         return;
    106     crtc = pScrPriv->crtcs[0];
    107     if (!crtc)
    108         return;
    109 
    110     /* check rotations */
    111     if (rotations != crtc->rotations) {
    112         crtc->rotations = rotations;
    113         crtc->changed = TRUE;
    114         pScrPriv->changed = TRUE;
    115     }
    116 
    117     /* regenerate mode list */
    118     for (i = 0; i < pScrPriv->nSizes; i++) {
    119         RRScreenSizePtr size = &pScrPriv->pSizes[i];
    120         int r;
    121 
    122         if (size->nRates) {
    123             for (r = 0; r < size->nRates; r++) {
    124                 mode = RROldModeAdd(output, size, size->pRates[r].rate);
    125                 if (i == pScrPriv->size &&
    126                     size->pRates[r].rate == pScrPriv->rate) {
    127                     newMode = mode;
    128                 }
    129             }
    130             free(size->pRates);
    131         }
    132         else {
    133             mode = RROldModeAdd(output, size, 0);
    134             if (i == pScrPriv->size)
    135                 newMode = mode;
    136         }
    137     }
    138     if (pScrPriv->nSizes)
    139         free(pScrPriv->pSizes);
    140     pScrPriv->pSizes = NULL;
    141     pScrPriv->nSizes = 0;
    142 
    143     /* find size bounds */
    144     for (i = 0; i < output->numModes + output->numUserModes; i++) {
    145         mode = (i < output->numModes ?
    146                           output->modes[i] :
    147                           output->userModes[i - output->numModes]);
    148         width = mode->mode.width;
    149         height = mode->mode.height;
    150 
    151         if (width < minWidth)
    152             minWidth = width;
    153         if (width > maxWidth)
    154             maxWidth = width;
    155         if (height < minHeight)
    156             minHeight = height;
    157         if (height > maxHeight)
    158             maxHeight = height;
    159     }
    160 
    161     RRScreenSetSizeRange(pScreen, minWidth, minHeight, maxWidth, maxHeight);
    162 
    163     /* notice current mode */
    164     if (newMode)
    165         RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, NULL, 1, &output);
    166 }
    167 #endif
    168 
    169 /*
    170  * Poll the driver for changed information
    171  */
    172 Bool
    173 RRGetInfo(ScreenPtr pScreen, Bool force_query)
    174 {
    175     rrScrPriv(pScreen);
    176     Rotation rotations;
    177     int i;
    178 
    179     /* Return immediately if we don't need to re-query and we already have the
    180      * information.
    181      */
    182     if (!force_query) {
    183         if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0)
    184             return TRUE;
    185     }
    186 
    187     for (i = 0; i < pScrPriv->numOutputs; i++)
    188         pScrPriv->outputs[i]->changed = FALSE;
    189     for (i = 0; i < pScrPriv->numCrtcs; i++)
    190         pScrPriv->crtcs[i]->changed = FALSE;
    191 
    192     rotations = 0;
    193     pScrPriv->changed = FALSE;
    194     pScrPriv->configChanged = FALSE;
    195 
    196     if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
    197         return FALSE;
    198 
    199 #if RANDR_10_INTERFACE
    200     if (pScrPriv->nSizes)
    201         RRScanOldConfig(pScreen, rotations);
    202 #endif
    203     RRTellChanged(pScreen);
    204     return TRUE;
    205 }
    206 
    207 /*
    208  * Register the range of sizes for the screen
    209  */
    210 void
    211 RRScreenSetSizeRange(ScreenPtr pScreen,
    212                      CARD16 minWidth,
    213                      CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight)
    214 {
    215     rrScrPriv(pScreen);
    216 
    217     if (!pScrPriv)
    218         return;
    219     if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight &&
    220         pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) {
    221         return;
    222     }
    223 
    224     pScrPriv->minWidth = minWidth;
    225     pScrPriv->minHeight = minHeight;
    226     pScrPriv->maxWidth = maxWidth;
    227     pScrPriv->maxHeight = maxHeight;
    228     RRSetChanged(pScreen);
    229     pScrPriv->configChanged = TRUE;
    230 }
    231 
    232 #ifdef RANDR_10_INTERFACE
    233 static Bool
    234 RRScreenSizeMatches(RRScreenSizePtr a, RRScreenSizePtr b)
    235 {
    236     if (a->width != b->width)
    237         return FALSE;
    238     if (a->height != b->height)
    239         return FALSE;
    240     if (a->mmWidth != b->mmWidth)
    241         return FALSE;
    242     if (a->mmHeight != b->mmHeight)
    243         return FALSE;
    244     return TRUE;
    245 }
    246 
    247 RRScreenSizePtr
    248 RRRegisterSize(ScreenPtr pScreen,
    249                short width, short height, short mmWidth, short mmHeight)
    250 {
    251     rrScrPriv(pScreen);
    252     int i;
    253     RRScreenSize tmp;
    254     RRScreenSizePtr pNew;
    255 
    256     if (!pScrPriv)
    257         return 0;
    258 
    259     tmp.id = 0;
    260     tmp.width = width;
    261     tmp.height = height;
    262     tmp.mmWidth = mmWidth;
    263     tmp.mmHeight = mmHeight;
    264     tmp.pRates = 0;
    265     tmp.nRates = 0;
    266     for (i = 0; i < pScrPriv->nSizes; i++)
    267         if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
    268             return &pScrPriv->pSizes[i];
    269     pNew = reallocarray(pScrPriv->pSizes,
    270                         pScrPriv->nSizes + 1, sizeof(RRScreenSize));
    271     if (!pNew)
    272         return 0;
    273     pNew[pScrPriv->nSizes++] = tmp;
    274     pScrPriv->pSizes = pNew;
    275     return &pNew[pScrPriv->nSizes - 1];
    276 }
    277 
    278 Bool
    279 RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
    280 {
    281     rrScrPriv(pScreen);
    282     int i;
    283     RRScreenRatePtr pNew, pRate;
    284 
    285     if (!pScrPriv)
    286         return FALSE;
    287 
    288     for (i = 0; i < pSize->nRates; i++)
    289         if (pSize->pRates[i].rate == rate)
    290             return TRUE;
    291 
    292     pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate));
    293     if (!pNew)
    294         return FALSE;
    295     pRate = &pNew[pSize->nRates++];
    296     pRate->rate = rate;
    297     pSize->pRates = pNew;
    298     return TRUE;
    299 }
    300 
    301 Rotation
    302 RRGetRotation(ScreenPtr pScreen)
    303 {
    304     RROutputPtr output = RRFirstOutput(pScreen);
    305 
    306     if (!output)
    307         return RR_Rotate_0;
    308 
    309     return output->crtc->rotation;
    310 }
    311 
    312 void
    313 RRSetCurrentConfig(ScreenPtr pScreen,
    314                    Rotation rotation, int rate, RRScreenSizePtr pSize)
    315 {
    316     rrScrPriv(pScreen);
    317 
    318     if (!pScrPriv)
    319         return;
    320     pScrPriv->size = pSize - pScrPriv->pSizes;
    321     pScrPriv->rotation = rotation;
    322     pScrPriv->rate = rate;
    323 }
    324 #endif