xwayland: Use libxcvt
Xwayland is using a copy of the CVT generator found in Xorg. Rather than duplicating the code within the xserver tree, use the libxcvt implementation instead. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
		
							parent
							
								
									a4ab57cb74
								
							
						
					
					
						commit
						6ea2c001f9
					
				|  | @ -12,7 +12,8 @@ Xwayland_CFLAGS =				\ | ||||||
| 	$(XWAYLANDMODULES_CFLAGS)		\
 | 	$(XWAYLANDMODULES_CFLAGS)		\
 | ||||||
| 	$(DIX_CFLAGS)				\
 | 	$(DIX_CFLAGS)				\
 | ||||||
| 	$(GLAMOR_CFLAGS)			\
 | 	$(GLAMOR_CFLAGS)			\
 | ||||||
| 	$(GBM_CFLAGS) | 	$(GBM_CFLAGS)				\
 | ||||||
|  | 	$(LIBXCVT_CFLAGS) | ||||||
| 
 | 
 | ||||||
| Xwayland_SOURCES =				\
 | Xwayland_SOURCES =				\
 | ||||||
| 	xwayland.c				\
 | 	xwayland.c				\
 | ||||||
|  | @ -60,7 +61,8 @@ Xwayland_LDADD =				\ | ||||||
| 	$(GLXVND_LIB)				\
 | 	$(GLXVND_LIB)				\
 | ||||||
| 	$(XWAYLAND_SYS_LIBS)			\
 | 	$(XWAYLAND_SYS_LIBS)			\
 | ||||||
| 	$(top_builddir)/Xext/libXvidmode.la	\
 | 	$(top_builddir)/Xext/libXvidmode.la	\
 | ||||||
| 	$(XSERVER_SYS_LIBS) | 	$(XSERVER_SYS_LIBS)			\
 | ||||||
|  | 	$(LIBXCVT_LIBS) | ||||||
| Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) | Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) | ||||||
| 
 | 
 | ||||||
| Xwayland_built_sources = | Xwayland_built_sources = | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| /* Copied from hw/xfree86/modes/xf86cvt.c into xwayland DDX and
 |  | ||||||
|  * changed to generate an RRMode */ |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Copyright 2005-2006 Luc Verhaegen. |  * Copyright 2005-2006 Luc Verhaegen. | ||||||
|  |  * Copyright © 2021 Red Hat, Inc. | ||||||
|  * |  * | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a |  * Permission is hereby granted, free of charge, to any person obtaining a | ||||||
|  * copy of this software and associated documentation files (the "Software"), |  * copy of this software and associated documentation files (the "Software"), | ||||||
|  | @ -23,284 +21,38 @@ | ||||||
|  * OTHER DEALINGS IN THE SOFTWARE. |  * OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * The reason for having this function in a file of its own is |  | ||||||
|  * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode |  | ||||||
|  * code is shared directly. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <xwayland-config.h> | #include <xwayland-config.h> | ||||||
| 
 | 
 | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <randrstr.h> | #include <randrstr.h> | ||||||
|  | #include <libxcvt/libxcvt.h> | ||||||
| 
 | 
 | ||||||
| #include "xwayland-cvt.h" | #include "xwayland-cvt.h" | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh. |  | ||||||
|  * |  | ||||||
|  * These calculations are stolen from the CVT calculation spreadsheet written |  | ||||||
|  * by Graham Loveridge. He seems to be claiming no copyright and there seems to |  | ||||||
|  * be no license attached to this. He apparently just wants to see his name |  | ||||||
|  * mentioned. |  | ||||||
|  * |  | ||||||
|  * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
 |  | ||||||
|  * |  | ||||||
|  * Comments and structure corresponds to the comments and structure of the xls. |  | ||||||
|  * This should ease importing of future changes to the standard (not very |  | ||||||
|  * likely though). |  | ||||||
|  * |  | ||||||
|  * About margins; i'm sure that they are to be the bit between HDisplay and |  | ||||||
|  * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and |  | ||||||
|  * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking |  | ||||||
|  * outside sync "margin" for some reason. Since we prefer seeing proper |  | ||||||
|  * blanking instead of the overscan colour, and since the Crtc* values will |  | ||||||
|  * probably get altered after us, we will disable margins altogether. With |  | ||||||
|  * these calculations, Margins will plainly expand H/VDisplay, and we don't |  | ||||||
|  * want that. -- libv |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| RRModePtr | RRModePtr | ||||||
| xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, | xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced, | ||||||
|              Bool Interlaced) |              Bool interlaced) | ||||||
| { | { | ||||||
|     /* 1) top/bottom margin size (% of height) - default: 1.8 */ |     struct libxcvt_mode_info *libxcvt_mode_info; | ||||||
| #define CVT_MARGIN_PERCENTAGE 1.8 |  | ||||||
| 
 |  | ||||||
|     /* 2) character cell horizontal granularity (pixels) - default 8 */ |  | ||||||
| #define CVT_H_GRANULARITY 8 |  | ||||||
| 
 |  | ||||||
|     /* 4) Minimum vertical porch (lines) - default 3 */ |  | ||||||
| #define CVT_MIN_V_PORCH 3 |  | ||||||
| 
 |  | ||||||
|     /* 4) Minimum number of vertical back porch lines - default 6 */ |  | ||||||
| #define CVT_MIN_V_BPORCH 6 |  | ||||||
| 
 |  | ||||||
|     /* Pixel Clock step (kHz) */ |  | ||||||
| #define CVT_CLOCK_STEP 250 |  | ||||||
| 
 |  | ||||||
|     Bool Margins = FALSE; |  | ||||||
|     float VFieldRate, HPeriod; |  | ||||||
|     int HDisplayRnd, HMargin; |  | ||||||
|     int VDisplayRnd, VMargin, VSync; |  | ||||||
|     float Interlace;            /* Please rename this */ |  | ||||||
|     char name[128]; |     char name[128]; | ||||||
|     xRRModeInfo modeinfo; |     xRRModeInfo modeinfo; | ||||||
| 
 | 
 | ||||||
|  |     libxcvt_mode_info = | ||||||
|  |         libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced); | ||||||
|  | 
 | ||||||
|     memset(&modeinfo, 0, sizeof modeinfo); |     memset(&modeinfo, 0, sizeof modeinfo); | ||||||
|  |     modeinfo.width      = libxcvt_mode_info->hdisplay; | ||||||
|  |     modeinfo.height     = libxcvt_mode_info->vdisplay; | ||||||
|  |     modeinfo.dotClock   = libxcvt_mode_info->dot_clock * 1000.0; | ||||||
|  |     modeinfo.hSyncStart = libxcvt_mode_info->hsync_start; | ||||||
|  |     modeinfo.hSyncEnd   = libxcvt_mode_info->hsync_end; | ||||||
|  |     modeinfo.hTotal     = libxcvt_mode_info->htotal; | ||||||
|  |     modeinfo.vSyncStart = libxcvt_mode_info->vsync_start; | ||||||
|  |     modeinfo.vSyncEnd   = libxcvt_mode_info->vsync_end; | ||||||
|  |     modeinfo.vTotal     = libxcvt_mode_info->vtotal; | ||||||
|  |     modeinfo.modeFlags  = libxcvt_mode_info->mode_flags; | ||||||
| 
 | 
 | ||||||
|     /* CVT default is 60.0Hz */ |     free(libxcvt_mode_info); | ||||||
|     if (!VRefresh) |  | ||||||
|         VRefresh = 60.0; |  | ||||||
| 
 |  | ||||||
|     /* 1. Required field rate */ |  | ||||||
|     if (Interlaced) |  | ||||||
|         VFieldRate = VRefresh * 2; |  | ||||||
|     else |  | ||||||
|         VFieldRate = VRefresh; |  | ||||||
| 
 |  | ||||||
|     /* 2. Horizontal pixels */ |  | ||||||
|     HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); |  | ||||||
| 
 |  | ||||||
|     /* 3. Determine left and right borders */ |  | ||||||
|     if (Margins) { |  | ||||||
|         /* right margin is actually exactly the same as left */ |  | ||||||
|         HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); |  | ||||||
|         HMargin -= HMargin % CVT_H_GRANULARITY; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|         HMargin = 0; |  | ||||||
| 
 |  | ||||||
|     /* 4. Find total active pixels */ |  | ||||||
|     modeinfo.width = HDisplayRnd + 2 * HMargin; |  | ||||||
| 
 |  | ||||||
|     /* 5. Find number of lines per field */ |  | ||||||
|     if (Interlaced) |  | ||||||
|         VDisplayRnd = VDisplay / 2; |  | ||||||
|     else |  | ||||||
|         VDisplayRnd = VDisplay; |  | ||||||
| 
 |  | ||||||
|     /* 6. Find top and bottom margins */ |  | ||||||
|     /* nope. */ |  | ||||||
|     if (Margins) |  | ||||||
|         /* top and bottom margins are equal again. */ |  | ||||||
|         VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); |  | ||||||
|     else |  | ||||||
|         VMargin = 0; |  | ||||||
| 
 |  | ||||||
|     modeinfo.height = VDisplay + 2 * VMargin; |  | ||||||
| 
 |  | ||||||
|     /* 7. Interlace */ |  | ||||||
|     if (Interlaced) |  | ||||||
|         Interlace = 0.5; |  | ||||||
|     else |  | ||||||
|         Interlace = 0.0; |  | ||||||
| 
 |  | ||||||
|     /* Determine VSync Width from aspect ratio */ |  | ||||||
|     if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) |  | ||||||
|         VSync = 4; |  | ||||||
|     else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) |  | ||||||
|         VSync = 5; |  | ||||||
|     else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) |  | ||||||
|         VSync = 6; |  | ||||||
|     else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) |  | ||||||
|         VSync = 7; |  | ||||||
|     else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) |  | ||||||
|         VSync = 7; |  | ||||||
|     else                        /* Custom */ |  | ||||||
|         VSync = 10; |  | ||||||
| 
 |  | ||||||
|     if (!Reduced) {             /* simplified GTF calculation */ |  | ||||||
| 
 |  | ||||||
|         /* 4) Minimum time of vertical sync + back porch interval (µs)
 |  | ||||||
|          * default 550.0 */ |  | ||||||
| #define CVT_MIN_VSYNC_BP 550.0 |  | ||||||
| 
 |  | ||||||
|         /* 3) Nominal HSync width (% of line period) - default 8 */ |  | ||||||
| #define CVT_HSYNC_PERCENTAGE 8 |  | ||||||
| 
 |  | ||||||
|         float HBlankPercentage; |  | ||||||
|         int VSyncAndBackPorch, VBackPorch; |  | ||||||
|         int HBlank; |  | ||||||
| 
 |  | ||||||
|         /* 8. Estimated Horizontal period */ |  | ||||||
|         HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / |  | ||||||
|             (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); |  | ||||||
| 
 |  | ||||||
|         /* 9. Find number of lines in sync + backporch */ |  | ||||||
|         if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) < |  | ||||||
|             (VSync + CVT_MIN_V_PORCH)) |  | ||||||
|             VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; |  | ||||||
|         else |  | ||||||
|             VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1; |  | ||||||
| 
 |  | ||||||
|         /* 10. Find number of lines in back porch */ |  | ||||||
|         VBackPorch = VSyncAndBackPorch - VSync; |  | ||||||
|         (void) VBackPorch; |  | ||||||
| 
 |  | ||||||
|         /* 11. Find total number of lines in vertical field */ |  | ||||||
|         modeinfo.vTotal = |  | ||||||
|             VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace + |  | ||||||
|             CVT_MIN_V_PORCH; |  | ||||||
| 
 |  | ||||||
|         /* 5) Definition of Horizontal blanking time limitation */ |  | ||||||
|         /* Gradient (%/kHz) - default 600 */ |  | ||||||
| #define CVT_M_FACTOR 600 |  | ||||||
| 
 |  | ||||||
|         /* Offset (%) - default 40 */ |  | ||||||
| #define CVT_C_FACTOR 40 |  | ||||||
| 
 |  | ||||||
|         /* Blanking time scaling factor - default 128 */ |  | ||||||
| #define CVT_K_FACTOR 128 |  | ||||||
| 
 |  | ||||||
|         /* Scaling factor weighting - default 20 */ |  | ||||||
| #define CVT_J_FACTOR 20 |  | ||||||
| 
 |  | ||||||
| #define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 |  | ||||||
| #define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ |  | ||||||
|         CVT_J_FACTOR |  | ||||||
| 
 |  | ||||||
|         /* 12. Find ideal blanking duty cycle from formula */ |  | ||||||
|         HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0; |  | ||||||
| 
 |  | ||||||
|         /* 13. Blanking time */ |  | ||||||
|         if (HBlankPercentage < 20) |  | ||||||
|             HBlankPercentage = 20; |  | ||||||
| 
 |  | ||||||
|         HBlank = modeinfo.width * HBlankPercentage / (100.0 - HBlankPercentage); |  | ||||||
|         HBlank -= HBlank % (2 * CVT_H_GRANULARITY); |  | ||||||
| 
 |  | ||||||
|         /* 14. Find total number of pixels in a line. */ |  | ||||||
|         modeinfo.hTotal = modeinfo.width + HBlank; |  | ||||||
| 
 |  | ||||||
|         /* Fill in HSync values */ |  | ||||||
|         modeinfo.hSyncEnd = modeinfo.width + HBlank / 2; |  | ||||||
| 
 |  | ||||||
|         modeinfo.hSyncStart = modeinfo.hSyncEnd - |  | ||||||
|             (modeinfo.hTotal * CVT_HSYNC_PERCENTAGE) / 100; |  | ||||||
|         modeinfo.hSyncStart += CVT_H_GRANULARITY - |  | ||||||
|             modeinfo.hSyncStart % CVT_H_GRANULARITY; |  | ||||||
| 
 |  | ||||||
|         /* Fill in VSync values */ |  | ||||||
|         modeinfo.vSyncStart = modeinfo.height + CVT_MIN_V_PORCH; |  | ||||||
|         modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
|     else {                      /* Reduced blanking */ |  | ||||||
|         /* Minimum vertical blanking interval time (µs) - default 460 */ |  | ||||||
| #define CVT_RB_MIN_VBLANK 460.0 |  | ||||||
| 
 |  | ||||||
|         /* Fixed number of clocks for horizontal sync */ |  | ||||||
| #define CVT_RB_H_SYNC 32.0 |  | ||||||
| 
 |  | ||||||
|         /* Fixed number of clocks for horizontal blanking */ |  | ||||||
| #define CVT_RB_H_BLANK 160.0 |  | ||||||
| 
 |  | ||||||
|         /* Fixed number of lines for vertical front porch - default 3 */ |  | ||||||
| #define CVT_RB_VFPORCH 3 |  | ||||||
| 
 |  | ||||||
|         int VBILines; |  | ||||||
| 
 |  | ||||||
|         /* 8. Estimate Horizontal period. */ |  | ||||||
|         HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / |  | ||||||
|             (VDisplayRnd + 2 * VMargin); |  | ||||||
| 
 |  | ||||||
|         /* 9. Find number of lines in vertical blanking */ |  | ||||||
|         VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; |  | ||||||
| 
 |  | ||||||
|         /* 10. Check if vertical blanking is sufficient */ |  | ||||||
|         if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) |  | ||||||
|             VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; |  | ||||||
| 
 |  | ||||||
|         /* 11. Find total number of lines in vertical field */ |  | ||||||
|         modeinfo.vTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; |  | ||||||
| 
 |  | ||||||
|         /* 12. Find total number of pixels in a line */ |  | ||||||
|         modeinfo.hTotal = modeinfo.width + CVT_RB_H_BLANK; |  | ||||||
| 
 |  | ||||||
|         /* Fill in HSync values */ |  | ||||||
|         modeinfo.hSyncEnd = modeinfo.width + CVT_RB_H_BLANK / 2; |  | ||||||
|         modeinfo.hSyncStart = modeinfo.hSyncEnd - CVT_RB_H_SYNC; |  | ||||||
| 
 |  | ||||||
|         /* Fill in VSync values */ |  | ||||||
|         modeinfo.vSyncStart = modeinfo.height + CVT_RB_VFPORCH; |  | ||||||
|         modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* 15/13. Find pixel clock frequency (kHz for xf86) */ |  | ||||||
|     modeinfo.dotClock = modeinfo.hTotal * 1000.0 / HPeriod; |  | ||||||
|     modeinfo.dotClock -= modeinfo.dotClock % CVT_CLOCK_STEP; |  | ||||||
|     modeinfo.dotClock *= 1000.0; |  | ||||||
| #if 0 |  | ||||||
|     /* 16/14. Find actual Horizontal Frequency (kHz) */ |  | ||||||
|     modeinfo.hSync = ((float) modeinfo.dotClock) / ((float) modeinfo.hTotal); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #if 0 |  | ||||||
|     /* 17/15. Find actual Field rate */ |  | ||||||
|     modeinfo.vRefresh = (1000.0 * ((float) modeinfo.dotClock)) / |  | ||||||
|         ((float) (modeinfo.hTotal * modeinfo.vTotal)); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|     /* 18/16. Find actual vertical frame frequency */ |  | ||||||
|     /* ignore - just set the mode flag for interlaced */ |  | ||||||
|     if (Interlaced) |  | ||||||
|         modeinfo.vTotal *= 2; |  | ||||||
| 
 |  | ||||||
|     if (Reduced) |  | ||||||
|         modeinfo.modeFlags |= RR_HSyncPositive | RR_VSyncNegative; |  | ||||||
|     else |  | ||||||
|         modeinfo.modeFlags |= RR_HSyncNegative | RR_VSyncPositive; |  | ||||||
| 
 |  | ||||||
|     if (Interlaced) |  | ||||||
|         modeinfo.modeFlags |= RR_Interlace; |  | ||||||
| 
 |  | ||||||
|     /* FWXGA hack adapted from hw/xfree86/modes/xf86EdidModes.c, because you can't say 1366 */ |  | ||||||
|     if (HDisplay == 1366 && VDisplay == 768) { |  | ||||||
|          modeinfo.width = 1366; |  | ||||||
|          modeinfo.hSyncStart--; |  | ||||||
|          modeinfo.hSyncEnd--; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     snprintf(name, sizeof name, "%dx%d", |     snprintf(name, sizeof name, "%dx%d", | ||||||
|              modeinfo.width, modeinfo.height); |              modeinfo.width, modeinfo.height); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue