xwayland: Add vidmode mode changing emulation support
Add support for fake mode changes using viewport, for apps which want to change the resolution when going fullscreen. Reviewed-by: Olivier Fourdan <ofourdan@redhat.com> Acked-by: Michel Dänzer <mdaenzer@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
		
							parent
							
								
									bcad1b813a
								
							
						
					
					
						commit
						38de626081
					
				| 
						 | 
					@ -106,26 +106,25 @@ xwlRRModeToDisplayMode(RRModePtr rrmode, DisplayModePtr mode)
 | 
				
			||||||
static RRModePtr
 | 
					static RRModePtr
 | 
				
			||||||
xwlVidModeGetRRMode(ScreenPtr pScreen, int32_t width, int32_t height)
 | 
					xwlVidModeGetRRMode(ScreenPtr pScreen, int32_t width, int32_t height)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RROutputPtr output = RRFirstOutput(pScreen);
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (output == NULL)
 | 
					    if (!xwl_output)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return xwl_output_find_mode(output->devPrivate, width, height);
 | 
					    return xwl_output_find_mode(xwl_output, width, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static RRModePtr
 | 
					static RRModePtr
 | 
				
			||||||
xwlVidModeGetCurrentRRMode(ScreenPtr pScreen)
 | 
					xwlVidModeGetCurrentRRMode(ScreenPtr pScreen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
    struct xwl_emulated_mode *emulated_mode;
 | 
					    struct xwl_emulated_mode *emulated_mode;
 | 
				
			||||||
    struct xwl_output *xwl_output;
 | 
					 | 
				
			||||||
    RROutputPtr output;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    output = RRFirstOutput(pScreen);
 | 
					    if (!xwl_output)
 | 
				
			||||||
    if (output == NULL)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    xwl_output = output->devPrivate;
 | 
					 | 
				
			||||||
    emulated_mode =
 | 
					    emulated_mode =
 | 
				
			||||||
        xwl_output_get_emulated_mode_for_client(xwl_output, GetCurrentClient());
 | 
					        xwl_output_get_emulated_mode_for_client(xwl_output, GetCurrentClient());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,39 +198,79 @@ xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
 | 
					xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RRModePtr rrmode;
 | 
					    return Clock;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    rrmode = xwlVidModeGetCurrentRRMode(pScreen);
 | 
					 | 
				
			||||||
    if (rrmode == NULL)
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return rrmode->mode.dotClock / 1000.0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 | 
					xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return 1;
 | 
					    /* We emulate a programmable clock, rather then a fixed set of clocks */
 | 
				
			||||||
 | 
					    *progClock = TRUE;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 | 
					xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *Clocks = xwlVidModeGetDotClock(pScreen, 0);
 | 
					    return FALSE; /* Programmable clock, no clock list */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GetFirstModeline and GetNextModeline are used from Xext/vidmode.c like this:
 | 
				
			||||||
 | 
					 *  if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
 | 
				
			||||||
 | 
					 *      do {
 | 
				
			||||||
 | 
					 *          ...
 | 
				
			||||||
 | 
					 *          if (...)
 | 
				
			||||||
 | 
					 *              break;
 | 
				
			||||||
 | 
					 *      } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
 | 
				
			||||||
 | 
					 *  }
 | 
				
			||||||
 | 
					 * IOW our caller basically always loops over all the modes. There never is a
 | 
				
			||||||
 | 
					 * return to the mainloop between GetFirstModeline and NextModeline calls where
 | 
				
			||||||
 | 
					 * other parts of the server may change our state so we do not need to worry
 | 
				
			||||||
 | 
					 * about xwl_output->randr_output->modes changing underneath us.
 | 
				
			||||||
 | 
					 * Thus we can simply implement these two callbacks by storing the enumeration
 | 
				
			||||||
 | 
					 * index in pVidMode->Next.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					    VidModePtr pVidMode;
 | 
				
			||||||
 | 
					    DisplayModePtr pMod;
 | 
				
			||||||
 | 
					    intptr_t index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
 | 
				
			||||||
 | 
					    pVidMode = VidModeGetPtr(pScreen);
 | 
				
			||||||
 | 
					    if (xwl_output == NULL || pMod == NULL || pVidMode == NULL)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = (intptr_t)pVidMode->Next;
 | 
				
			||||||
 | 
					    if (index >= xwl_output->randr_output->numModes)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    xwlRRModeToDisplayMode(xwl_output->randr_output->modes[index], pMod);
 | 
				
			||||||
 | 
					    index++;
 | 
				
			||||||
 | 
					    pVidMode->Next = (void *)index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *mode = pMod;
 | 
				
			||||||
 | 
					    if (dotClock != NULL)
 | 
				
			||||||
 | 
					        *dotClock = pMod->Clock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return TRUE;
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					 | 
				
			||||||
xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return FALSE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 | 
					xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return xwlVidModeGetCurrentModeline(pScreen, mode, dotClock);
 | 
					    VidModePtr pVidMode;
 | 
				
			||||||
 | 
					    intptr_t index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pVidMode = VidModeGetPtr(pScreen);
 | 
				
			||||||
 | 
					    if (pVidMode == NULL)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pVidMode->Next = (void *)index; /* 0 */
 | 
				
			||||||
 | 
					    return xwlVidModeGetNextModeline(pScreen, mode, dotClock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
| 
						 | 
					@ -251,37 +290,27 @@ xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom)
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 | 
					xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RROutputPtr output;
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
    RRCrtcPtr crtc;
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    output = RRFirstOutput(pScreen);
 | 
					    if (!xwl_output)
 | 
				
			||||||
    if (output == NULL)
 | 
					 | 
				
			||||||
        return FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    crtc = output->crtc;
 | 
					 | 
				
			||||||
    if (crtc == NULL)
 | 
					 | 
				
			||||||
        return FALSE;
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Support only default viewport */
 | 
					    /* Support only default viewport */
 | 
				
			||||||
    return (x == crtc->x && y == crtc->y);
 | 
					    return (x == xwl_output->x && y == xwl_output->y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 | 
					xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RROutputPtr output;
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
    RRCrtcPtr crtc;
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    output = RRFirstOutput(pScreen);
 | 
					    if (!xwl_output)
 | 
				
			||||||
    if (output == NULL)
 | 
					 | 
				
			||||||
        return FALSE;
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    crtc = output->crtc;
 | 
					    *x = xwl_output->x;
 | 
				
			||||||
    if (crtc == NULL)
 | 
					    *y = xwl_output->y;
 | 
				
			||||||
        return FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    *x = crtc->x;
 | 
					 | 
				
			||||||
    *y = crtc->y;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return TRUE;
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -289,8 +318,19 @@ xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 | 
					xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Unsupported for now */
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
    return FALSE;
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					    RRModePtr rrmode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!xwl_output)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rrmode = xwl_output_find_mode(xwl_output, mode->HDisplay, mode->VDisplay);
 | 
				
			||||||
 | 
					    if (rrmode == NULL)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), rrmode, TRUE);
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
| 
						 | 
					@ -344,8 +384,10 @@ xwlVidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
xwlVidModeGetNumOfModes(ScreenPtr pScreen)
 | 
					xwlVidModeGetNumOfModes(ScreenPtr pScreen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* We have only one mode */
 | 
					    struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 | 
				
			||||||
    return 1;
 | 
					    struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return xwl_output ? xwl_output->randr_output->numModes : 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue