diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2010-07-27 19:02:39 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2010-07-27 19:02:39 +0000 |
commit | 269d40cbcc43b41f621ca6d91c182952f60ec48e (patch) | |
tree | 872f2fddd3f2207e57a28595e73886713ce4a77a /xserver/hw/xfree86/ddc | |
parent | 917a2249b787451cad3f9697872aeccfd0da3324 (diff) |
Update to xserver 1.8. Tested by many. Ok oga@, todd@.
Diffstat (limited to 'xserver/hw/xfree86/ddc')
-rw-r--r-- | xserver/hw/xfree86/ddc/Makefile.am | 12 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/Makefile.in | 151 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/ddc.c (renamed from xserver/hw/xfree86/ddc/xf86DDC.c) | 326 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/ddcPriv.h | 9 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/ddcProperty.c | 53 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/edid.c | 140 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/edid.h | 114 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/interpret_edid.c | 398 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/print_edid.c | 283 | ||||
-rw-r--r-- | xserver/hw/xfree86/ddc/xf86DDC.h | 79 |
10 files changed, 998 insertions, 567 deletions
diff --git a/xserver/hw/xfree86/ddc/Makefile.am b/xserver/hw/xfree86/ddc/Makefile.am index 7cfff4763..93ea4a2a5 100644 --- a/xserver/hw/xfree86/ddc/Makefile.am +++ b/xserver/hw/xfree86/ddc/Makefile.am @@ -1,13 +1,11 @@ -sdk_HEADERS = edid.h vdif.h xf86DDC.h +sdk_HEADERS = edid.h xf86DDC.h -module_LTLIBRARIES = libddc.la +noinst_LTLIBRARIES = libddc.la -libddc_la_LDFLAGS = -avoid-version -libddc_la_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \ - interpret_vdif.c print_vdif.c ddcProperty.c +libddc_la_SOURCES = ddc.c interpret_edid.c print_edid.c ddcProperty.c INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) -EXTRA_DIST = ddcPriv.h DDC.HOWTO +EXTRA_DIST = DDC.HOWTO diff --git a/xserver/hw/xfree86/ddc/Makefile.in b/xserver/hw/xfree86/ddc/Makefile.in index fa8c7a05a..c50f4fc51 100644 --- a/xserver/hw/xfree86/ddc/Makefile.in +++ b/xserver/hw/xfree86/ddc/Makefile.in @@ -41,8 +41,8 @@ subdir = hw/xfree86/ddc DIST_COMMON = $(sdk_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ + $(top_srcdir)/m4/dolt.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(install_sh) -d @@ -52,17 +52,15 @@ CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ $(top_builddir)/include/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ - $(top_builddir)/include/kdrive-config.h + $(top_builddir)/include/kdrive-config.h \ + $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -libddc_a_AR = $(AR) $(ARFLAGS) -libddc_a_LIBADD = -am_libddc_a_OBJECTS = xf86DDC.$(OBJEXT) edid.$(OBJEXT) \ - interpret_edid.$(OBJEXT) print_edid.$(OBJEXT) \ - ddcProperty.$(OBJEXT) -libddc_a_OBJECTS = $(am_libddc_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include +LTLIBRARIES = $(noinst_LTLIBRARIES) +libddc_la_LIBADD = +am_libddc_la_OBJECTS = ddc.lo interpret_edid.lo print_edid.lo \ + ddcProperty.lo +libddc_la_OBJECTS = $(am_libddc_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -70,8 +68,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libddc_a_SOURCES) -DIST_SOURCES = $(libddc_a_SOURCES) +SOURCES = $(libddc_la_SOURCES) +DIST_SOURCES = $(libddc_la_SOURCES) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -97,12 +95,13 @@ ALPHA_VIDEO_TRUE = @ALPHA_VIDEO_TRUE@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ -APPLE_APPLICATION_ID = @APPLE_APPLICATION_ID@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ APP_MAN_DIR = @APP_MAN_DIR@ APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ AR = @AR@ +ARM_BACKTRACE_CFLAGS = @ARM_BACKTRACE_CFLAGS@ ARM_VIDEO_FALSE = @ARM_VIDEO_FALSE@ ARM_VIDEO_TRUE = @ARM_VIDEO_TRUE@ AS = @AS@ @@ -130,6 +129,7 @@ CCAS = @CCAS@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ COMPOSITE_FALSE = @COMPOSITE_FALSE@ COMPOSITE_TRUE = @COMPOSITE_TRUE@ @@ -139,8 +139,11 @@ CONFIG_HAL_FALSE = @CONFIG_HAL_FALSE@ CONFIG_HAL_TRUE = @CONFIG_HAL_TRUE@ CONFIG_NEED_DBUS_FALSE = @CONFIG_NEED_DBUS_FALSE@ CONFIG_NEED_DBUS_TRUE = @CONFIG_NEED_DBUS_TRUE@ +CONFIG_UDEV_FALSE = @CONFIG_UDEV_FALSE@ +CONFIG_UDEV_TRUE = @CONFIG_UDEV_TRUE@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CWARNFLAGS = @CWARNFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -154,6 +157,7 @@ DBUS_LIBS = @DBUS_LIBS@ DEBUG_FALSE = @DEBUG_FALSE@ DEBUG_TRUE = @DEBUG_TRUE@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFS = @DEFS@ @@ -163,7 +167,9 @@ DGA_FALSE = @DGA_FALSE@ DGA_LIBS = @DGA_LIBS@ DGA_TRUE = @DGA_TRUE@ DIX_CFLAGS = @DIX_CFLAGS@ +DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ +DLOPEN_LIBS = @DLOPEN_LIBS@ DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ @@ -179,6 +185,7 @@ DMX_BUILD_USB_TRUE = @DMX_BUILD_USB_TRUE@ DMX_FALSE = @DMX_FALSE@ DMX_TRUE = @DMX_TRUE@ DOLT_BASH = @DOLT_BASH@ +DOXYGEN = @DOXYGEN@ DPMSExtension_FALSE = @DPMSExtension_FALSE@ DPMSExtension_TRUE = @DPMSExtension_TRUE@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ @@ -191,8 +198,10 @@ DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ DRIPROTO_LIBS = @DRIPROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_CFLAGS = @DRI_CFLAGS@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DRI_FALSE = @DRI_FALSE@ +DRI_LIBS = @DRI_LIBS@ DRI_TRUE = @DRI_TRUE@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ @@ -208,8 +217,17 @@ FBDEVHW_TRUE = @FBDEVHW_TRUE@ FFLAGS = @FFLAGS@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +FONT100DPIDIR = @FONT100DPIDIR@ +FONT75DPIDIR = @FONT75DPIDIR@ +FONTMISCDIR = @FONTMISCDIR@ +FONTOTFDIR = @FONTOTFDIR@ +FONTROOTDIR = @FONTROOTDIR@ +FONTTTFDIR = @FONTTTFDIR@ +FONTTYPE1DIR = @FONTTYPE1DIR@ FREEBSD_KLDLOAD_FALSE = @FREEBSD_KLDLOAD_FALSE@ FREEBSD_KLDLOAD_TRUE = @FREEBSD_KLDLOAD_TRUE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_FALSE = @GLX_FALSE@ @@ -219,18 +237,17 @@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ -HAVE_AGL_FRAMEWORK_FALSE = @HAVE_AGL_FRAMEWORK_FALSE@ -HAVE_AGL_FRAMEWORK_TRUE = @HAVE_AGL_FRAMEWORK_TRUE@ HAVE_DBUS_FALSE = @HAVE_DBUS_FALSE@ HAVE_DBUS_TRUE = @HAVE_DBUS_TRUE@ -HAVE_XPLUGIN_FALSE = @HAVE_XPLUGIN_FALSE@ -HAVE_XPLUGIN_TRUE = @HAVE_XPLUGIN_TRUE@ +HAVE_DOXYGEN_FALSE = @HAVE_DOXYGEN_FALSE@ +HAVE_DOXYGEN_TRUE = @HAVE_DOXYGEN_TRUE@ HP300_VIDEO_FALSE = @HP300_VIDEO_FALSE@ HP300_VIDEO_TRUE = @HP300_VIDEO_TRUE@ HPPA_VIDEO_FALSE = @HPPA_VIDEO_FALSE@ HPPA_VIDEO_TRUE = @HPPA_VIDEO_TRUE@ I386_VIDEO_FALSE = @I386_VIDEO_FALSE@ I386_VIDEO_TRUE = @I386_VIDEO_TRUE@ +INSTALL_CMD = @INSTALL_CMD@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_LIBXF86CONFIG_FALSE = @INSTALL_LIBXF86CONFIG_FALSE@ INSTALL_LIBXF86CONFIG_TRUE = @INSTALL_LIBXF86CONFIG_TRUE@ @@ -239,6 +256,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SETUID_FALSE = @INSTALL_SETUID_FALSE@ INSTALL_SETUID_TRUE = @INSTALL_SETUID_TRUE@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INT10MODULE_FALSE = @INT10MODULE_FALSE@ +INT10MODULE_TRUE = @INT10MODULE_TRUE@ INT10_STUB_FALSE = @INT10_STUB_FALSE@ INT10_STUB_TRUE = @INT10_STUB_TRUE@ INT10_VM86_FALSE = @INT10_VM86_FALSE@ @@ -251,20 +270,23 @@ KDRIVELINUX_FALSE = @KDRIVELINUX_FALSE@ KDRIVELINUX_TRUE = @KDRIVELINUX_TRUE@ KDRIVEOPENBSD_FALSE = @KDRIVEOPENBSD_FALSE@ KDRIVEOPENBSD_TRUE = @KDRIVEOPENBSD_TRUE@ -KDRIVEVESA_FALSE = @KDRIVEVESA_FALSE@ -KDRIVEVESA_TRUE = @KDRIVEVESA_TRUE@ KDRIVEWSCONS_FALSE = @KDRIVEWSCONS_FALSE@ KDRIVEWSCONS_TRUE = @KDRIVEWSCONS_TRUE@ KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_EVDEV_FALSE = @KDRIVE_EVDEV_FALSE@ +KDRIVE_EVDEV_TRUE = @KDRIVE_EVDEV_TRUE@ KDRIVE_FALSE = @KDRIVE_FALSE@ -KDRIVE_HW_FALSE = @KDRIVE_HW_FALSE@ -KDRIVE_HW_TRUE = @KDRIVE_HW_TRUE@ KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_KBD_FALSE = @KDRIVE_KBD_FALSE@ +KDRIVE_KBD_TRUE = @KDRIVE_KBD_TRUE@ KDRIVE_LIBS = @KDRIVE_LIBS@ KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_MOUSE_FALSE = @KDRIVE_MOUSE_FALSE@ +KDRIVE_MOUSE_TRUE = @KDRIVE_MOUSE_TRUE@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KDRIVE_TRUE = @KDRIVE_TRUE@ +LAUNCHD_ID_PREFIX = @LAUNCHD_ID_PREFIX@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LEX = @LEX@ @@ -293,12 +315,12 @@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MAKE_HTML = @MAKE_HTML@ MAKE_PDF = @MAKE_PDF@ MAKE_PS = @MAKE_PS@ MAKE_TEXT = @MAKE_TEXT@ -MESA_SOURCE = @MESA_SOURCE@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MITSHM_FALSE = @MITSHM_FALSE@ @@ -317,6 +339,9 @@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OS_LIB = @OS_LIB@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -345,34 +370,51 @@ SCREENSAVER_TRUE = @SCREENSAVER_TRUE@ SECURE_RPC_FALSE = @SECURE_RPC_FALSE@ SECURE_RPC_TRUE = @SECURE_RPC_TRUE@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SGI_VIDEO_FALSE = @SGI_VIDEO_FALSE@ SGI_VIDEO_TRUE = @SGI_VIDEO_TRUE@ +SHA1_CFLAGS = @SHA1_CFLAGS@ +SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ SOLARIS_ASM_INLINE_FALSE = @SOLARIS_ASM_INLINE_FALSE@ SOLARIS_ASM_INLINE_TRUE = @SOLARIS_ASM_INLINE_TRUE@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ -SOLARIS_USL_CONSOLE_FALSE = @SOLARIS_USL_CONSOLE_FALSE@ -SOLARIS_USL_CONSOLE_TRUE = @SOLARIS_USL_CONSOLE_TRUE@ +SOLARIS_VT_FALSE = @SOLARIS_VT_FALSE@ +SOLARIS_VT_TRUE = @SOLARIS_VT_TRUE@ SPARC64_VIDEO_FALSE = @SPARC64_VIDEO_FALSE@ SPARC64_VIDEO_TRUE = @SPARC64_VIDEO_TRUE@ +SPECIAL_DTRACE_OBJECTS_FALSE = @SPECIAL_DTRACE_OBJECTS_FALSE@ +SPECIAL_DTRACE_OBJECTS_TRUE = @SPECIAL_DTRACE_OBJECTS_TRUE@ STANDALONE_XPBPROXY_FALSE = @STANDALONE_XPBPROXY_FALSE@ STANDALONE_XPBPROXY_TRUE = @STANDALONE_XPBPROXY_TRUE@ STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ TSLIB_CFLAGS = @TSLIB_CFLAGS@ TSLIB_FALSE = @TSLIB_FALSE@ TSLIB_LIBS = @TSLIB_LIBS@ TSLIB_TRUE = @TSLIB_TRUE@ +UDEV_CFLAGS = @UDEV_CFLAGS@ +UDEV_LIBS = @UDEV_LIBS@ +UNITTESTS_FALSE = @UNITTESTS_FALSE@ +UNITTESTS_TRUE = @UNITTESTS_TRUE@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ -VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ -VENDOR_NAME = @VENDOR_NAME@ +VBE_FALSE = @VBE_FALSE@ +VBE_TRUE = @VBE_TRUE@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ -VENDOR_RELEASE = @VENDOR_RELEASE@ VERSION = @VERSION@ +VGAHW_FALSE = @VGAHW_FALSE@ +VGAHW_TRUE = @VGAHW_TRUE@ +WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ +WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ +WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XAA_FALSE = @XAA_FALSE@ +XAA_TRUE = @XAA_TRUE@ XACE_FALSE = @XACE_FALSE@ XACE_TRUE = @XACE_TRUE@ XCALIBRATE_FALSE = @XCALIBRATE_FALSE@ @@ -397,6 +439,7 @@ XEPHYR_LIBS = @XEPHYR_LIBS@ XEPHYR_TRUE = @XEPHYR_TRUE@ XF86BIGFONT_FALSE = @XF86BIGFONT_FALSE@ XF86BIGFONT_TRUE = @XF86BIGFONT_TRUE@ +XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XF86UTILS_FALSE = @XF86UTILS_FALSE@ XF86UTILS_TRUE = @XF86UTILS_TRUE@ @@ -439,15 +482,14 @@ XORG_TRUE = @XORG_TRUE@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_FALSE = @XQUARTZ_FALSE@ +XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ +XQUARTZ_SPARKLE_FALSE = @XQUARTZ_SPARKLE_FALSE@ +XQUARTZ_SPARKLE_TRUE = @XQUARTZ_SPARKLE_TRUE@ XQUARTZ_TRUE = @XQUARTZ_TRUE@ XREGISTRY_FALSE = @XREGISTRY_FALSE@ XREGISTRY_TRUE = @XREGISTRY_TRUE@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ -XSDLSERVER_FALSE = @XSDLSERVER_FALSE@ -XSDLSERVER_TRUE = @XSDLSERVER_TRUE@ -XSDL_INCS = @XSDL_INCS@ -XSDL_LIBS = @XSDL_LIBS@ XSELINUX_FALSE = @XSELINUX_FALSE@ XSELINUX_TRUE = @XSELINUX_TRUE@ XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ @@ -495,10 +537,10 @@ X_PRIVSEP_FALSE = @X_PRIVSEP_FALSE@ X_PRIVSEP_TRUE = @X_PRIVSEP_TRUE@ YACC = @YACC@ YFLAGS = @YFLAGS@ +__XCONFIGDIR__ = @__XCONFIGDIR__@ __XCONFIGFILE__ = @__XCONFIGFILE__@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ -abi_font = @abi_font@ abi_videodrv = @abi_videodrv@ abi_xinput = @abi_xinput@ ac_ct_CC = @ac_ct_CC@ @@ -553,16 +595,16 @@ psdir = @psdir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ +symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ +sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ sdk_HEADERS = edid.h xf86DDC.h -noinst_LIBRARIES = libddc.a -libddc_a_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \ - ddcProperty.c - +noinst_LTLIBRARIES = libddc.la +libddc_la_SOURCES = ddc.c interpret_edid.c print_edid.c ddcProperty.c INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) -EXTRA_DIST = ddcPriv.h DDC.HOWTO +EXTRA_DIST = DDC.HOWTO all: all-am .SUFFIXES: @@ -597,12 +639,16 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libddc.a: $(libddc_a_OBJECTS) $(libddc_a_DEPENDENCIES) - -rm -f libddc.a - $(libddc_a_AR) libddc.a $(libddc_a_OBJECTS) $(libddc_a_LIBADD) - $(RANLIB) libddc.a +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libddc.la: $(libddc_la_OBJECTS) $(libddc_la_DEPENDENCIES) + $(LINK) $(libddc_la_LDFLAGS) $(libddc_la_OBJECTS) $(libddc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -610,11 +656,10 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddcProperty.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interpret_edid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_edid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xf86DDC.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddcProperty.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interpret_edid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_edid.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @@ -741,7 +786,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LIBRARIES) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(sdkdir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ @@ -772,7 +817,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am @@ -822,7 +867,7 @@ ps-am: uninstall-am: uninstall-info-am uninstall-sdkHEADERS .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLIBRARIES ctags distclean \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ diff --git a/xserver/hw/xfree86/ddc/xf86DDC.c b/xserver/hw/xfree86/ddc/ddc.c index 0d8677637..6fad9fbbc 100644 --- a/xserver/hw/xfree86/ddc/xf86DDC.c +++ b/xserver/hw/xfree86/ddc/ddc.c @@ -4,10 +4,10 @@ */ /* - * Note that DDC1 does not define any method for returning blocks beyond - * the first. DDC2 does, but the original implementation would only ever - * read the first block. If you want to read and parse all blocks, use - * xf86DoEEDID(). + * A note on terminology. DDC1 is the original dumb serial protocol, and + * can only do up to 128 bytes of EDID. DDC2 is I2C-encapsulated and + * introduces extension blocks. EDID is the old display identification + * block, DisplayID is the new one. */ #ifdef HAVE_XORG_CONFIG_H @@ -18,27 +18,10 @@ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86DDC.h" -#include "ddcPriv.h" #include <string.h> #define RETRIES 4 -static unsigned char *EDIDRead_DDC1( - ScrnInfoPtr pScrn, - DDC1SetSpeedProc, - unsigned int (*)(ScrnInfoPtr) -); - -static Bool TestDDC1( - ScrnInfoPtr pScrn, - unsigned int (*)(ScrnInfoPtr) -); - -static unsigned int *FetchEDID_DDC1( - ScrnInfoPtr, - register unsigned int (*)(ScrnInfoPtr) -); - typedef enum { DDCOPT_NODDC1, DDCOPT_NODDC2, @@ -52,6 +35,191 @@ static const OptionInfoRec DDCOptions[] = { { -1, NULL, OPTV_NONE, {0}, FALSE }, }; +/* DDC1 */ + +static int +find_start(unsigned int *ptr) +{ + unsigned int comp[9], test[9]; + int i,j; + + for (i=0;i<9;i++){ + comp[i] = *(ptr++); + test[i] = 1; + } + for (i=0;i<127;i++){ + for (j=0;j<9;j++){ + test[j] = test[j] & !(comp[j] ^ *(ptr++)); + } + } + for (i=0;i<9;i++) + if (test[i]) return (i+1); + return (-1); +} + +static unsigned char * +find_header(unsigned char *block) +{ + unsigned char *ptr, *head_ptr, *end; + unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + + ptr = block; + end = block + EDID1_LEN; + while (ptr<end) { + int i; + head_ptr = ptr; + for (i=0;i<8;i++){ + if (header[i] != *(head_ptr++)) break; + if (head_ptr == end) head_ptr = block; + } + if (i==8) break; + ptr++; + } + if (ptr == end) return (NULL); + return (ptr); +} + +static unsigned char * +resort(unsigned char *s_block) +{ + unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end; + unsigned char tmp; + + s_end = s_block + EDID1_LEN; + d_new = xalloc(EDID1_LEN); + if (!d_new) return NULL; + d_end = d_new + EDID1_LEN; + + s_ptr = find_header(s_block); + if (!s_ptr) return NULL; + for (d_ptr=d_new;d_ptr<d_end;d_ptr++){ + tmp = *(s_ptr++); + *d_ptr = tmp; + if (s_ptr == s_end) s_ptr = s_block; + } + xfree(s_block); + return (d_new); +} + +static int +DDC_checksum(unsigned char *block, int len) +{ + int i, result = 0; + int not_null = 0; + + for (i=0;i<len;i++) { + not_null |= block[i]; + result += block[i]; + } + +#ifdef DEBUG + if (result & 0xFF) ErrorF("DDC checksum not correct\n"); + if (!not_null) ErrorF("DDC read all Null\n"); +#endif + + /* catch the trivial case where all bytes are 0 */ + if (!not_null) return 1; + + return (result&0xFF); +} + +static unsigned char * +GetEDID_DDC1(unsigned int *s_ptr) +{ + unsigned char *d_block, *d_pos; + unsigned int *s_pos, *s_end; + int s_start; + int i,j; + s_start = find_start(s_ptr); + if (s_start==-1) return NULL; + s_end = s_ptr + NUM; + s_pos = s_ptr + s_start; + d_block=xalloc(EDID1_LEN); + if (!d_block) return NULL; + d_pos = d_block; + for (i=0;i<EDID1_LEN;i++) { + for (j=0;j<8;j++) { + *d_pos <<= 1; + if (*s_pos) { + *d_pos |= 0x01; + } + s_pos++; if (s_pos == s_end) s_pos=s_ptr; + }; + s_pos++; if (s_pos == s_end) s_pos=s_ptr; + d_pos++; + } + xfree(s_ptr); + if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL; + return (resort(d_block)); +} + +/* fetch entire EDID record; DDC bit needs to be masked */ +static unsigned int * +FetchEDID_DDC1(register ScrnInfoPtr pScrn, + register unsigned int (*read_DDC)(ScrnInfoPtr)) +{ + int count = NUM; + unsigned int *ptr, *xp; + + ptr=xp=xalloc(sizeof(int)*NUM); + + if (!ptr) return NULL; + do { + /* wait for next retrace */ + *xp = read_DDC(pScrn); + xp++; + } while(--count); + return (ptr); +} + +/* test if DDC1 return 0 if not */ +static Bool +TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC)(ScrnInfoPtr)) +{ + int old, count; + + old = read_DDC(pScrn); + count = HEADER * BITS_PER_BYTE; + do { + /* wait for next retrace */ + if (old != read_DDC(pScrn)) break; + } while(count--); + return (count); +} + +/* + * read EDID record , pass it to callback function to interpret. + * callback function will store it for further use by calling + * function; it will also decide if we need to reread it + */ +static unsigned char * +EDIDRead_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDCSpeed, + unsigned int (*read_DDC)(ScrnInfoPtr)) +{ + unsigned char *EDID_block = NULL; + int count = RETRIES; + + if (!read_DDC) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "chipset doesn't support DDC1\n"); + return NULL; + }; + + if (TestDDC1(pScrn,read_DDC)==-1) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n"); + return NULL; + }; + + if (DDCSpeed) DDCSpeed(pScrn,DDC_FAST); + do { + EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn,read_DDC)); + count --; + } while (!EDID_block && count); + if (DDCSpeed) DDCSpeed(pScrn,DDC_SLOW); + + return EDID_block; +} + /** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 are * unset. EDID information blocks are interpreted and the results returned in @@ -63,7 +231,7 @@ static const OptionInfoRec DDCOptions[] = { * @return pointer to a new xf86MonPtr containing the EDID information. * @return NULL if no monitor attached or failure to interpret the EDID. */ -xf86MonPtr +xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed, unsigned int (*DDC1Read)(ScrnInfoPtr) @@ -103,6 +271,8 @@ xf86DoEDID_DDC1( return tmp; } +/* DDC2 */ + static I2CDevPtr DDC2MakeDevice(I2CBusPtr pBus, int address, char *name) { @@ -138,8 +308,13 @@ DDC2Init(int scrnIndex, I2CBusPtr pBus) */ pBus->RiseFallTime = 20; - DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register"); dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2"); + if (xf86I2CProbeAddress(pBus, 0x0060)) + DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register"); + if (xf86I2CProbeAddress(pBus, 0x0062)) + DDC2MakeDevice(pBus, 0x0062, "EDID EEPROM interface"); + if (xf86I2CProbeAddress(pBus, 0x006E)) + DDC2MakeDevice(pBus, 0x006E, "DDC control interface"); return dev; } @@ -251,7 +426,7 @@ xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool complete) } if (tmp && complete) - tmp->flags |= EDID_COMPLETE_RAWDATA; + tmp->flags |= MONITOR_EDID_COMPLETE_RAWDATA; return tmp; } @@ -273,69 +448,60 @@ xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) return xf86DoEEDID(scrnIndex, pBus, FALSE); } -/* - * read EDID record , pass it to callback function to interpret. - * callback function will store it for further use by calling - * function; it will also decide if we need to reread it - */ -static unsigned char * -EDIDRead_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDCSpeed, - unsigned int (*read_DDC)(ScrnInfoPtr)) +/* XXX write me */ +static void * +DDC2ReadDisplayID(void) { - unsigned char *EDID_block = NULL; - int count = RETRIES; - - if (!read_DDC) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "chipset doesn't support DDC1\n"); - return NULL; - }; + return FALSE; +} - if (TestDDC1(pScrn,read_DDC)==-1) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n"); - return NULL; - }; +/** + * Attempts to probe the monitor for DisplayID information, if NoDDC and + * NoDDC2 are unset. DisplayID blocks are interpreted and the results + * returned in an xf86MonPtr. + * + * This function does not affect the list of modes used by drivers -- it is up + * to the driver to decide policy on what to do with DisplayID information. + * + * @return pointer to a new xf86MonPtr containing the DisplayID information. + * @return NULL if no monitor attached or failure to interpret the DisplayID. + */ +xf86MonPtr +xf86DoDisplayID(int scrnIndex, I2CBusPtr pBus) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + unsigned char *did = NULL; + xf86MonPtr tmp = NULL; + I2CDevPtr dev = NULL; + /* Default DDC and DDC2 to enabled. */ + Bool noddc = FALSE, noddc2 = FALSE; + OptionInfoPtr options; - if (DDCSpeed) DDCSpeed(pScrn,DDC_FAST); - do { - EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn,read_DDC)); - count --; - } while (!EDID_block && count); - if (DDCSpeed) DDCSpeed(pScrn,DDC_SLOW); + options = xalloc(sizeof(DDCOptions)); + if (!options) + return NULL; + memcpy(options, DDCOptions, sizeof(DDCOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - return EDID_block; -} + xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); + xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); + xfree(options); -/* test if DDC1 return 0 if not */ -static Bool -TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC)(ScrnInfoPtr)) -{ - int old, count; + if (noddc || noddc2) + return NULL; - old = read_DDC(pScrn); - count = HEADER * BITS_PER_BYTE; - do { - /* wait for next retrace */ - if (old != read_DDC(pScrn)) break; - } while(count--); - return (count); -} + if (!(dev = DDC2Init(scrnIndex, pBus))) + return NULL; -/* fetch entire EDID record; DDC bit needs to be masked */ -static unsigned int * -FetchEDID_DDC1(register ScrnInfoPtr pScrn, - register unsigned int (*read_DDC)(ScrnInfoPtr)) -{ - int count = NUM; - unsigned int *ptr, *xp; + if ((did = DDC2ReadDisplayID())) { + tmp = xcalloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; - ptr=xp=xalloc(sizeof(int)*NUM); + tmp->scrnIndex = scrnIndex; + tmp->flags |= MONITOR_DISPLAYID; + tmp->rawData = did; + } - if (!ptr) return NULL; - do { - /* wait for next retrace */ - *xp = read_DDC(pScrn); - xp++; - } while(--count); - return (ptr); + return tmp; } diff --git a/xserver/hw/xfree86/ddc/ddcPriv.h b/xserver/hw/xfree86/ddc/ddcPriv.h deleted file mode 100644 index b5cb9b836..000000000 --- a/xserver/hw/xfree86/ddc/ddcPriv.h +++ /dev/null @@ -1,9 +0,0 @@ -extern unsigned char *GetEDID_DDC1( - unsigned int * -); - -extern int DDC_checksum( - unsigned char *, - int -); - diff --git a/xserver/hw/xfree86/ddc/ddcProperty.c b/xserver/hw/xfree86/ddc/ddcProperty.c index a4384f1d3..329a63964 100644 --- a/xserver/hw/xfree86/ddc/ddcProperty.c +++ b/xserver/hw/xfree86/ddc/ddcProperty.c @@ -31,21 +31,36 @@ #include "property.h" #include "propertyst.h" #include "xf86DDC.h" +#include <string.h> #define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA" #define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA" static void +edidMakeAtom(int i, const char *name, CARD8 *data, int size) +{ + Atom atom; + unsigned char *atom_data; + + if (!(atom_data = xalloc(size*sizeof(CARD8)))) + return; + + atom = MakeAtom(name, strlen(name), TRUE); + memcpy(atom_data, data, size); + xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data); +} + +static void addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) { - Atom EDID1Atom=-1, EDID2Atom=-1; - CARD8 *EDID1rawdata = NULL; - CARD8 *EDID2rawdata = NULL; int i, scrnIndex = pScrn->scrnIndex; Bool makeEDID1prop = FALSE; Bool makeEDID2prop = FALSE; - if (DDC->ver.version == 1) { + if (DDC->flags & MONITOR_DISPLAYID) { + /* Don't bother, use RANDR already */ + return; + } else if (DDC->ver.version == 1) { makeEDID1prop = TRUE; } else if (DDC->ver.version == 2) { int checksum1; @@ -83,29 +98,14 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) } if (makeEDID1prop) { - int size = 128; - - if (DDC->flags & EDID_COMPLETE_RAWDATA) - size += DDC->no_sections * 128; + int size = 128 + + (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0); - if ((EDID1rawdata = xalloc(size*sizeof(CARD8)))==NULL) - return; - - EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME) - 1, TRUE); - memcpy(EDID1rawdata, DDC->rawData, size); - xf86RegisterRootWindowProperty(scrnIndex, EDID1Atom, XA_INTEGER, 8, - size, (unsigned char *)EDID1rawdata); + edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size); } - if (makeEDID2prop) { - if ((EDID2rawdata = xalloc(256*sizeof(CARD8)))==NULL) - return; - - memcpy(EDID2rawdata, DDC->rawData, 256); - EDID2Atom = MakeAtom(EDID2_ATOM_NAME, sizeof(EDID2_ATOM_NAME) - 1, TRUE); - xf86RegisterRootWindowProperty(scrnIndex, EDID2Atom, XA_INTEGER, 8, - 256, (unsigned char *)EDID2rawdata); - } + if (makeEDID2prop) + edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256); } Bool @@ -114,7 +114,10 @@ xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) if (!pScrn || !pScrn->monitor || !DDC) return FALSE; - xf86DDCMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC); + if (DDC->flags & MONITOR_DISPLAYID) + ; + else + xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC); addRootWindowProperties(pScrn, DDC); diff --git a/xserver/hw/xfree86/ddc/edid.c b/xserver/hw/xfree86/ddc/edid.c deleted file mode 100644 index 3ebafbbba..000000000 --- a/xserver/hw/xfree86/ddc/edid.c +++ /dev/null @@ -1,140 +0,0 @@ - -/* edid.c: retrieve EDID record from raw DDC1 data stream: data - * is contained in an array of unsigned int each unsigned int - * contains one bit if bit is 0 unsigned int has to be zero else - * unsigned int > 0 - * - * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> - */ -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#include "misc.h" -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86DDC.h" -#include "ddcPriv.h" -#include <string.h> - -static int find_start(unsigned int *); -static unsigned char * find_header(unsigned char *); -static unsigned char * resort(unsigned char *); - -unsigned char * -GetEDID_DDC1(unsigned int *s_ptr) -{ - unsigned char *d_block, *d_pos; - unsigned int *s_pos, *s_end; - int s_start; - int i,j; - s_start = find_start(s_ptr); - if (s_start==-1) return NULL; - s_end = s_ptr + NUM; - s_pos = s_ptr + s_start; - d_block=xalloc(EDID1_LEN); - if (!d_block) return NULL; - d_pos = d_block; - for (i=0;i<EDID1_LEN;i++) { - for (j=0;j<8;j++) { - *d_pos <<= 1; - if (*s_pos) { - *d_pos |= 0x01; - } - s_pos++; if (s_pos == s_end) s_pos=s_ptr; - }; - s_pos++; if (s_pos == s_end) s_pos=s_ptr; - d_pos++; - } - xfree(s_ptr); - if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL; - return (resort(d_block)); -} - -int -DDC_checksum(unsigned char *block, int len) -{ - int i, result = 0; - int not_null = 0; - - for (i=0;i<len;i++) { - not_null |= block[i]; - result += block[i]; - } - -#ifdef DEBUG - if (result & 0xFF) ErrorF("DDC checksum not correct\n"); - if (!not_null) ErrorF("DDC read all Null\n"); -#endif - - /* catch the trivial case where all bytes are 0 */ - if (!not_null) return 1; - - return (result&0xFF); -} - -static int -find_start(unsigned int *ptr) -{ - unsigned int comp[9], test[9]; - int i,j; - - for (i=0;i<9;i++){ - comp[i] = *(ptr++); - test[i] = 1; - } - for (i=0;i<127;i++){ - for (j=0;j<9;j++){ - test[j] = test[j] & !(comp[j] ^ *(ptr++)); - } - } - for (i=0;i<9;i++) - if (test[i]) return (i+1); - return (-1); -} - -static unsigned char * -find_header(unsigned char *block) -{ - unsigned char *ptr, *head_ptr, *end; - unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; - - ptr = block; - end = block + EDID1_LEN; - while (ptr<end) { - int i; - head_ptr = ptr; - for (i=0;i<8;i++){ - if (header[i] != *(head_ptr++)) break; - if (head_ptr == end) head_ptr = block; - } - if (i==8) break; - ptr++; - } - if (ptr == end) return (NULL); - return (ptr); -} - -static unsigned char * -resort(unsigned char *s_block) -{ - unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end; - unsigned char tmp; - - s_end = s_block + EDID1_LEN; - d_new = xalloc(EDID1_LEN); - if (!d_new) return NULL; - d_end = d_new + EDID1_LEN; - - s_ptr = find_header(s_block); - if (!s_ptr) return NULL; - for (d_ptr=d_new;d_ptr<d_end;d_ptr++){ - tmp = *(s_ptr++); - *d_ptr = tmp; - if (s_ptr == s_end) s_ptr = s_block; - } - xfree(s_block); - return (d_new); -} - - diff --git a/xserver/hw/xfree86/ddc/edid.h b/xserver/hw/xfree86/ddc/edid.h index 3ca402f57..cc4bd02ea 100644 --- a/xserver/hw/xfree86/ddc/edid.h +++ b/xserver/hw/xfree86/ddc/edid.h @@ -12,6 +12,12 @@ #ifndef _EDID_H_ #define _EDID_H_ +#include <X11/Xmd.h> + +#ifndef _X_EXPORT +# include <X11/Xfuncproto.h> +#endif + /* read complete EDID record */ #define EDID1_LEN 128 #define BITS_PER_BYTE 9 @@ -532,8 +538,15 @@ struct detailed_monitor_section { }; /* flags */ -#define EDID_COMPLETE_RAWDATA 0x1 +#define MONITOR_EDID_COMPLETE_RAWDATA 0x01 +/* old, don't use */ +#define EDID_COMPLETE_RAWDATA 0x01 +#define MONITOR_DISPLAYID 0x02 +/* + * For DisplayID devices, only the scrnIndex, flags, and rawData fields + * are meaningful. For EDID, they all are. + */ typedef struct { int scrnIndex; struct vendor vendor; @@ -547,6 +560,103 @@ typedef struct { Uchar *rawData; } xf86Monitor, *xf86MonPtr; -extern xf86MonPtr ConfiguredMonitor; +extern _X_EXPORT xf86MonPtr ConfiguredMonitor; + +#define EXT_TAG 0 +#define EXT_REV 1 +#define CEA_EXT 0x02 +#define VTB_EXT 0x10 +#define DI_EXT 0x40 +#define LS_EXT 0x50 +#define MI_EXT 0x60 + +#define CEA_EXT_MIN_DATA_OFFSET 4 +#define CEA_EXT_MAX_DATA_OFFSET 127 +#define CEA_EXT_DET_TIMING_NUM 6 + +#define IEEE_ID_HDMI 0x000C03 +#define CEA_AUDIO_BLK 1 +#define CEA_VIDEO_BLK 2 +#define CEA_VENDOR_BLK 3 +#define CEA_SPEAKER_ALLOC_BLK 4 +#define CEA_VESA_DTC_BLK 5 +#define VENDOR_SUPPORT_AI(x) ((x) >> 7) +#define VENDOR_SUPPORT_DC_48bit(x) ( ( (x) >> 6) & 0x01) +#define VENDOR_SUPPORT_DC_36bit(x) ( ( (x) >> 5) & 0x01) +#define VENDOR_SUPPORT_DC_30bit(x) ( ( (x) >> 4) & 0x01) +#define VENDOR_SUPPORT_DC_Y444(x) ( ( (x) >> 3) & 0x01) +#define VENDOR_LATENCY_PRESENT(x) ( (x) >> 7) +#define VENDOR_LATENCY_PRESENT_I(x) ( ( (x) >> 6) & 0x01) +#define HDMI_MAX_TMDS_UNIT (5000) + +struct cea_video_block { + Uchar video_code; +}; + +struct cea_audio_block_descriptor { + Uchar audio_code[3]; +}; + +struct cea_audio_block { + struct cea_audio_block_descriptor descriptor[10]; +}; + +struct cea_vendor_block_hdmi { + Uchar portB:4; + Uchar portA:4; + Uchar portD:4; + Uchar portC:4; + Uchar support_flags; + Uchar max_tmds_clock; + Uchar latency_present; + Uchar video_latency; + Uchar audio_latency; + Uchar interlaced_video_latency; + Uchar interlaced_audio_latency; +}; + +struct cea_vendor_block { + unsigned char ieee_id[3]; + union { + struct cea_vendor_block_hdmi hdmi; + /* any other vendor blocks we know about */ + }; +}; + +struct cea_speaker_block +{ + Uchar FLR:1; + Uchar LFE:1; + Uchar FC:1; + Uchar RLR:1; + Uchar RC:1; + Uchar FLRC:1; + Uchar RLRC:1; + Uchar FLRW:1; + Uchar FLRH:1; + Uchar TC:1; + Uchar FCH:1; + Uchar Resv:5; + Uchar ResvByte; +}; + +struct cea_data_block { + Uchar len:5; + Uchar tag:3; + union{ + struct cea_video_block video; + struct cea_audio_block audio; + struct cea_vendor_block vendor; + struct cea_speaker_block speaker; + }u; +}; + +struct cea_ext_body { + Uchar tag; + Uchar rev; + Uchar dt_offset; + Uchar flags; + struct cea_data_block data_collection; +}; #endif /* _EDID_H_ */ diff --git a/xserver/hw/xfree86/ddc/interpret_edid.c b/xserver/hw/xfree86/ddc/interpret_edid.c index 310606c7c..f3e593aec 100644 --- a/xserver/hw/xfree86/ddc/interpret_edid.c +++ b/xserver/hw/xfree86/ddc/interpret_edid.c @@ -3,22 +3,23 @@ * Copyright 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software") - * to deal in the software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * them Software is furnished to do so, subject to the following conditions: + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * interpret_edid.c: interpret a primary EDID block */ @@ -41,6 +42,8 @@ static void get_display_section(Uchar*, struct disp_features *, static void get_established_timing_section(Uchar*, struct established_timings *); static void get_std_timing_section(Uchar*, struct std_timings *, struct edid_version *); +static void fetch_detailed_block(Uchar *c, struct edid_version *ver, + struct detailed_monitor_section *det_mon); static void get_dt_md_section(Uchar *, struct edid_version *, struct detailed_monitor_section *det_mon); static void copy_string(Uchar *, Uchar *); @@ -52,11 +55,25 @@ static void get_detailed_timing_section(Uchar*, struct detailed_timings *); static Bool validate_version(int scrnIndex, struct edid_version *); static void +find_ranges_section(struct detailed_monitor_section *det, void *ranges) +{ + if (det->type == DS_RANGES && det->section.ranges.max_clock) + *(struct monitor_ranges **)ranges = &det->section.ranges; +} + +static void +find_max_detailed_clock(struct detailed_monitor_section *det, void *ret) +{ + if (det->type == DT) { + *(int *)ret = max(*((int *)ret), + det->section.d_timings.clock); + } +} + +static void handle_edid_quirks(xf86MonPtr m) { - int i, j; - struct detailed_timings *preferred_timing; - struct monitor_ranges *ranges; + struct monitor_ranges *ranges = NULL; /* * max_clock is only encoded in EDID in tens of MHz, so occasionally we @@ -64,28 +81,49 @@ handle_edid_quirks(xf86MonPtr m) * similar. Strictly we should refuse to round up too far, but let's * see how well this works. */ - for (i = 0; i < 4; i++) { - if (m->det_mon[i].type == DS_RANGES) { - ranges = &m->det_mon[i].section.ranges; - for (j = 0; j < 4; j++) { - if (m->det_mon[j].type == DT) { - preferred_timing = &m->det_mon[j].section.d_timings; - if (!ranges->max_clock) continue; /* zero is legal */ - if (ranges->max_clock * 1000000 < preferred_timing->clock) { - xf86Msg(X_WARNING, - "EDID preferred timing clock %.2fMHz exceeds " - "claimed max %dMHz, fixing\n", - preferred_timing->clock / 1.0e6, - ranges->max_clock); - ranges->max_clock = - (preferred_timing->clock+999999)/1000000; - return; - } - } - } - } + + /* Try to find Monitor Range and max clock, then re-set range value*/ + xf86ForEachDetailedBlock(m, find_ranges_section, &ranges); + if (ranges && ranges->max_clock) { + int clock = 0; + xf86ForEachDetailedBlock(m, find_max_detailed_clock, &clock); + if (clock && (ranges->max_clock * 1e6 < clock)) { + xf86Msg(X_WARNING, "EDID timing clock %.2f exceeds claimed max " + "%dMHz, fixing\n", clock / 1.0e6, ranges->max_clock); + ranges->max_clock = (clock+999999)/1e6; + } + } +} + +struct det_hv_parameter { + int real_hsize; + int real_vsize; + float target_aspect; +}; + +static void handle_detailed_hvsize(struct detailed_monitor_section *det_mon, + void *data) +{ + struct det_hv_parameter *p = (struct det_hv_parameter *)data; + float timing_aspect; + + if (det_mon->type == DT) { + struct detailed_timings *timing; + timing = &det_mon->section.d_timings; + + if (!timing->v_size) + return; + + timing_aspect = (float)timing->h_size / timing->v_size; + if (fabs(1 - (timing_aspect / p->target_aspect)) < 0.05) { + p->real_hsize = max(p->real_hsize, timing->h_size); + p->real_vsize = max(p->real_vsize, timing->v_size); + } } +} +static void encode_aspect_ratio(xf86MonPtr m) +{ /* * some monitors encode the aspect ratio instead of the physical size. * try to find the largest detailed timing that matches that aspect @@ -95,38 +133,26 @@ handle_edid_quirks(xf86MonPtr m) (m->features.hsize == 16 && m->features.vsize == 10) || (m->features.hsize == 4 && m->features.vsize == 3) || (m->features.hsize == 5 && m->features.vsize == 4)) { - int real_hsize = 0, real_vsize = 0; - float target_aspect, timing_aspect; - - target_aspect = (float)m->features.hsize / (float)m->features.vsize; - for (i = 0; i < 4; i++) { - if (m->det_mon[i].type == DT) { - struct detailed_timings *timing; - timing = &m->det_mon[i].section.d_timings; - - if (!timing->v_size) - continue; - - timing_aspect = (float)timing->h_size / (float)timing->v_size; - if (fabs(1 - (timing_aspect / target_aspect)) < 0.05) { - real_hsize = max(real_hsize, timing->h_size); - real_vsize = max(real_vsize, timing->v_size); - } - } - } - if (!real_hsize || !real_vsize) { + struct det_hv_parameter p; + p.real_hsize = 0; + p.real_vsize = 0; + p.target_aspect = (float)m->features.hsize /m->features.vsize; + + xf86ForEachDetailedBlock(m, handle_detailed_hvsize, &p); + + if (!p.real_hsize || !p.real_vsize) { m->features.hsize = m->features.vsize = 0; - } else if ((m->features.hsize * 10 == real_hsize) && - (m->features.vsize * 10 == real_vsize)) { + } else if ((m->features.hsize * 10 == p.real_hsize) && + (m->features.vsize * 10 == p.real_vsize)) { /* exact match is just unlikely, should do a better check though */ m->features.hsize = m->features.vsize = 0; } else { /* convert mm to cm */ - m->features.hsize = (real_hsize + 5) / 10; - m->features.vsize = (real_vsize + 5) / 10; + m->features.hsize = (p.real_hsize + 5) / 10; + m->features.vsize = (p.real_vsize + 5) / 10; } - + xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n", m->features.hsize, m->features.vsize); } @@ -155,6 +181,7 @@ xf86InterpretEDID(int scrnIndex, Uchar *block) m->no_sections = (int)*(char *)SECTION(NO_EDID,block); handle_edid_quirks(m); + encode_aspect_ratio(m); return (m); @@ -163,6 +190,141 @@ xf86InterpretEDID(int scrnIndex, Uchar *block) return NULL; } +static int get_cea_detail_timing(Uchar *blk, xf86MonPtr mon, + struct detailed_monitor_section *det_mon) +{ + int dt_num; + int dt_offset = ((struct cea_ext_body *)blk)->dt_offset; + + dt_num = 0; + + if (dt_offset < CEA_EXT_MIN_DATA_OFFSET) + return dt_num; + + for (; dt_offset < (CEA_EXT_MAX_DATA_OFFSET - DET_TIMING_INFO_LEN) && + dt_num < CEA_EXT_DET_TIMING_NUM; + _NEXT_DT_MD_SECTION(dt_offset)) { + + fetch_detailed_block(blk + dt_offset, &mon->ver, det_mon + dt_num); + dt_num = dt_num + 1 ; + } + + return dt_num; +} + +static void handle_cea_detail_block(Uchar *ext, xf86MonPtr mon, + handle_detailed_fn fn, + void *data) +{ + int i; + struct detailed_monitor_section det_mon[CEA_EXT_DET_TIMING_NUM]; + int det_mon_num; + + det_mon_num = get_cea_detail_timing(ext, mon, det_mon); + + for (i = 0; i < det_mon_num; i++) + fn(det_mon + i, data); +} + +void xf86ForEachDetailedBlock(xf86MonPtr mon, + handle_detailed_fn fn, + void *data) +{ + int i; + Uchar *ext; + + if (mon == NULL) + return; + + for (i = 0; i < DET_TIMINGS; i++) + fn(mon->det_mon + i, data); + + for (i = 0; i < mon->no_sections; i++) { + ext = mon->rawData + EDID1_LEN * (i + 1); + switch (ext[EXT_TAG]){ + case CEA_EXT: + handle_cea_detail_block(ext, mon, fn, data); + break; + case VTB_EXT: + case DI_EXT: + case LS_EXT: + case MI_EXT: + break; + } + } +} + +static struct cea_data_block * +extract_cea_data_block(Uchar *ext, int data_type) +{ + struct cea_ext_body *cea; + struct cea_data_block *data_collection; + struct cea_data_block *data_end; + + cea = (struct cea_ext_body *)ext; + + if (cea->dt_offset <= CEA_EXT_MIN_DATA_OFFSET) + return NULL; + + data_collection = &cea->data_collection; + data_end = (struct cea_data_block *)(cea->dt_offset + ext); + + for ( ;data_collection < data_end;) { + + if (data_type == data_collection->tag) { + return data_collection; + } + data_collection = (void *)((unsigned char *)data_collection + + data_collection->len + 1); + } + + return NULL; +} + +static void handle_cea_video_block(Uchar *ext, handle_video_fn fn, void *data) +{ + struct cea_video_block *video; + struct cea_video_block *video_end; + struct cea_data_block *data_collection; + + data_collection = extract_cea_data_block(ext, CEA_VIDEO_BLK); + if (data_collection == NULL) + return; + + video = &data_collection->u.video; + video_end = (struct cea_video_block *) + ((Uchar *)video + data_collection->len); + + for (; video < video_end; video = video + 1) { + fn(video, data); + } +} + +void xf86ForEachVideoBlock(xf86MonPtr mon, + handle_video_fn fn, + void *data) +{ + int i; + Uchar *ext; + + if (mon == NULL) + return; + + for (i = 0; i < mon->no_sections; i++) { + ext = mon->rawData + EDID1_LEN * (i + 1); + switch (ext[EXT_TAG]) { + case CEA_EXT: + handle_cea_video_block(ext, fn, data); + break; + case VTB_EXT: + case DI_EXT: + case LS_EXT: + case MI_EXT: + break; + } + } +} + xf86MonPtr xf86InterpretEEDID(int scrnIndex, Uchar *block) { @@ -287,66 +449,72 @@ get_std_timing_section(Uchar *c, struct std_timings *r, static const unsigned char empty_block[18]; static void -get_dt_md_section(Uchar *c, struct edid_version *ver, - struct detailed_monitor_section *det_mon) +fetch_detailed_block(Uchar *c, struct edid_version *ver, + struct detailed_monitor_section *det_mon) { - int i; - - for (i=0;i<DET_TIMINGS;i++) { if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) { - - switch (MONITOR_DESC_TYPE) { - case SERIAL_NUMBER: - det_mon[i].type = DS_SERIAL; - copy_string(c,det_mon[i].section.serial); - break; - case ASCII_STR: - det_mon[i].type = DS_ASCII_STR; - copy_string(c,det_mon[i].section.ascii_data); - break; - case MONITOR_RANGES: - det_mon[i].type = DS_RANGES; - get_monitor_ranges(c,&det_mon[i].section.ranges); - break; - case MONITOR_NAME: - det_mon[i].type = DS_NAME; - copy_string(c,det_mon[i].section.name); - break; - case ADD_COLOR_POINT: - det_mon[i].type = DS_WHITE_P; - get_whitepoint_section(c,det_mon[i].section.wp); - break; - case ADD_STD_TIMINGS: - det_mon[i].type = DS_STD_TIMINGS; - get_dst_timing_section(c,det_mon[i].section.std_t, ver); - break; - case COLOR_MANAGEMENT_DATA: - det_mon[i].type = DS_CMD; - break; - case CVT_3BYTE_DATA: - det_mon[i].type = DS_CVT; - get_cvt_timing_section(c, det_mon[i].section.cvt); - break; - case ADD_EST_TIMINGS: - det_mon[i].type = DS_EST_III; - memcpy(det_mon[i].section.est_iii, c + 6, 6); - break; - case ADD_DUMMY: - det_mon[i].type = DS_DUMMY; - break; - default: - det_mon[i].type = DS_UNKOWN; - break; - } - if (c[3] <= 0x0F && memcmp(c, empty_block, sizeof(empty_block))) { - det_mon[i].type = DS_VENDOR + c[3]; - } + switch (MONITOR_DESC_TYPE) { + case SERIAL_NUMBER: + det_mon->type = DS_SERIAL; + copy_string(c,det_mon->section.serial); + break; + case ASCII_STR: + det_mon->type = DS_ASCII_STR; + copy_string(c,det_mon->section.ascii_data); + break; + case MONITOR_RANGES: + det_mon->type = DS_RANGES; + get_monitor_ranges(c,&det_mon->section.ranges); + break; + case MONITOR_NAME: + det_mon->type = DS_NAME; + copy_string(c,det_mon->section.name); + break; + case ADD_COLOR_POINT: + det_mon->type = DS_WHITE_P; + get_whitepoint_section(c,det_mon->section.wp); + break; + case ADD_STD_TIMINGS: + det_mon->type = DS_STD_TIMINGS; + get_dst_timing_section(c,det_mon->section.std_t, ver); + break; + case COLOR_MANAGEMENT_DATA: + det_mon->type = DS_CMD; + break; + case CVT_3BYTE_DATA: + det_mon->type = DS_CVT; + get_cvt_timing_section(c, det_mon->section.cvt); + break; + case ADD_EST_TIMINGS: + det_mon->type = DS_EST_III; + memcpy(det_mon->section.est_iii, c + 6, 6); + break; + case ADD_DUMMY: + det_mon->type = DS_DUMMY; + break; + default: + det_mon->type = DS_UNKOWN; + break; + } + if (c[3] <= 0x0F && memcmp(c, empty_block, sizeof(empty_block))) { + det_mon->type = DS_VENDOR + c[3]; + } } else { - det_mon[i].type = DT; - get_detailed_timing_section(c,&det_mon[i].section.d_timings); + det_mon->type = DT; + get_detailed_timing_section(c, &det_mon->section.d_timings); + } +} + +static void +get_dt_md_section(Uchar *c, struct edid_version *ver, + struct detailed_monitor_section *det_mon) +{ + int i; + + for (i=0; i < DET_TIMINGS; i++) { + fetch_detailed_block(c, ver, det_mon + i); + NEXT_DT_MD_SECTION; } - NEXT_DT_MD_SECTION; - } } static void @@ -466,7 +634,7 @@ validate_version(int scrnIndex, struct edid_version *r) /* * Returns true if HDMI, false if definitely not or unknown. */ -_X_EXPORT Bool +Bool xf86MonitorIsHDMI(xf86MonPtr mon) { int i = 0, version, offset; diff --git a/xserver/hw/xfree86/ddc/print_edid.c b/xserver/hw/xfree86/ddc/print_edid.c index e9c8cbdf7..1faae1e33 100644 --- a/xserver/hw/xfree86/ddc/print_edid.c +++ b/xserver/hw/xfree86/ddc/print_edid.c @@ -3,22 +3,23 @@ * Copyright 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software") - * to deal in the software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * them Software is furnished to do so, subject to the following conditions: + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * print_edid.c: print out all information retrieved from display device */ @@ -250,7 +251,7 @@ print_established_timings(int scrnIndex, struct established_timings *t) if (c&0x02) xf86DrvMsg(scrnIndex,X_INFO,"1024x768@75Hz\n"); if (c&0x01) xf86DrvMsg(scrnIndex,X_INFO,"1280x1024@75Hz\n"); c=t->t_manu; - if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"1152x870@75Hz\n"); + if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"1152x864@75Hz\n"); xf86DrvMsg(scrnIndex,X_INFO,"Manufacturer's mask: %X\n",c&0x7F); } @@ -333,125 +334,147 @@ print_detailed_timings(int scrnIndex, struct detailed_timings *t) } } +/* This function handle all detailed patchs, + * including EDID and EDID-extension + */ +struct det_print_parameter{ + xf86MonPtr m; + int index; + ddc_quirk_t quirks; +}; + static void -print_detailed_monitor_section(int scrnIndex, - struct detailed_monitor_section *m) +handle_detailed_print(struct detailed_monitor_section *det_mon, + void *data) { - int i,j; - - for (i=0;i<DET_TIMINGS;i++) { - switch (m[i].type) { - case DT: - print_detailed_timings(scrnIndex,&m[i].section.d_timings); - break; - case DS_SERIAL: - xf86DrvMsg(scrnIndex,X_INFO,"Serial No: %s\n",m[i].section.serial); - break; - case DS_ASCII_STR: - xf86DrvMsg(scrnIndex,X_INFO," %s\n",m[i].section.ascii_data); - break; - case DS_NAME: - xf86DrvMsg(scrnIndex,X_INFO,"Monitor name: %s\n",m[i].section.name); - break; - case DS_RANGES: - { - struct monitor_ranges *r = &m[i].section.ranges; + int j, scrnIndex; + struct det_print_parameter *p; + + p = (struct det_print_parameter *)data; + scrnIndex = p->m->scrnIndex; + xf86DetTimingApplyQuirks(det_mon,p->quirks, + p->m->features.hsize, + p->m->features.vsize); + + switch (det_mon->type) { + case DT: + print_detailed_timings(scrnIndex,&det_mon->section.d_timings); + break; + case DS_SERIAL: + xf86DrvMsg(scrnIndex,X_INFO,"Serial No: %s\n",det_mon->section.serial); + break; + case DS_ASCII_STR: + xf86DrvMsg(scrnIndex,X_INFO," %s\n",det_mon->section.ascii_data); + break; + case DS_NAME: + xf86DrvMsg(scrnIndex,X_INFO,"Monitor name: %s\n",det_mon->section.name); + break; + case DS_RANGES: + { + struct monitor_ranges *r = &det_mon->section.ranges; + xf86DrvMsg(scrnIndex,X_INFO, + "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,", + r->min_v, r->max_v, r->min_h, r->max_h); + if (r->max_clock_khz != 0) { + xf86ErrorF(" PixClock max %i kHz\n", r->max_clock_khz); + if (r->maxwidth) + xf86DrvMsg(scrnIndex, X_INFO, "Maximum pixel width: %d\n", + r->maxwidth); + xf86DrvMsg(scrnIndex, X_INFO, "Supported aspect ratios:"); + if (r->supported_aspect & SUPPORTED_ASPECT_4_3) + xf86ErrorF(" 4:3%s", + r->preferred_aspect == PREFERRED_ASPECT_4_3?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_16_9) + xf86ErrorF(" 16:9%s", + r->preferred_aspect == PREFERRED_ASPECT_16_9?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_16_10) + xf86ErrorF(" 16:10%s", + r->preferred_aspect == PREFERRED_ASPECT_16_10?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_5_4) + xf86ErrorF(" 5:4%s", + r->preferred_aspect == PREFERRED_ASPECT_5_4?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_15_9) + xf86ErrorF(" 15:9%s", + r->preferred_aspect == PREFERRED_ASPECT_15_9?"*":""); + xf86ErrorF("\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Supported blankings:"); + if (r->supported_blanking & CVT_STANDARD) + xf86ErrorF(" standard"); + if (r->supported_blanking & CVT_REDUCED) + xf86ErrorF(" reduced"); + xf86ErrorF("\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Supported scalings:"); + if (r->supported_scaling & SCALING_HSHRINK) + xf86ErrorF(" hshrink"); + if (r->supported_scaling & SCALING_HSTRETCH) + xf86ErrorF(" hstretch"); + if (r->supported_scaling & SCALING_VSHRINK) + xf86ErrorF(" vshrink"); + if (r->supported_scaling & SCALING_VSTRETCH) + xf86ErrorF(" vstretch"); + xf86ErrorF("\n"); + if (r->preferred_refresh) + xf86DrvMsg(scrnIndex, X_INFO, "Preferred refresh rate: %d\n", + r->preferred_refresh); + else + xf86DrvMsg(scrnIndex, X_INFO, "Buggy monitor, no preferred " + "refresh rate given\n"); + } else if (r->max_clock != 0) { + xf86ErrorF(" PixClock max %i MHz\n", r->max_clock); + } else { + xf86ErrorF("\n"); + } + if (r->gtf_2nd_f > 0) + xf86DrvMsg(scrnIndex,X_INFO," 2nd GTF parameters: f: %i kHz " + "c: %i m: %i k %i j %i\n", r->gtf_2nd_f, + r->gtf_2nd_c, r->gtf_2nd_m, r->gtf_2nd_k, + r->gtf_2nd_j); + break; + } + case DS_STD_TIMINGS: + for (j = 0; j<5; j++) xf86DrvMsg(scrnIndex,X_INFO, - "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,", - r->min_v, r->max_v, r->min_h, r->max_h); - if (r->max_clock_khz != 0) { - xf86ErrorF(" PixClock max %i kHz\n", r->max_clock_khz); - if (r->maxwidth) - xf86DrvMsg(scrnIndex, X_INFO, "Maximum pixel width: %d\n", - r->maxwidth); - xf86DrvMsg(scrnIndex, X_INFO, "Supported aspect ratios:"); - if (r->supported_aspect & SUPPORTED_ASPECT_4_3) - xf86ErrorF(" 4:3%s", - r->preferred_aspect == PREFERRED_ASPECT_4_3?"*":""); - if (r->supported_aspect & SUPPORTED_ASPECT_16_9) - xf86ErrorF(" 16:9%s", - r->preferred_aspect == PREFERRED_ASPECT_16_9?"*":""); - if (r->supported_aspect & SUPPORTED_ASPECT_16_10) - xf86ErrorF(" 16:10%s", - r->preferred_aspect == PREFERRED_ASPECT_16_10?"*":""); - if (r->supported_aspect & SUPPORTED_ASPECT_5_4) - xf86ErrorF(" 5:4%s", - r->preferred_aspect == PREFERRED_ASPECT_5_4?"*":""); - if (r->supported_aspect & SUPPORTED_ASPECT_15_9) - xf86ErrorF(" 15:9%s", - r->preferred_aspect == PREFERRED_ASPECT_15_9?"*":""); - xf86ErrorF("\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Supported blankings:"); - if (r->supported_blanking & CVT_STANDARD) - xf86ErrorF(" standard"); - if (r->supported_blanking & CVT_REDUCED) - xf86ErrorF(" reduced"); - xf86ErrorF("\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Supported scalings:"); - if (r->supported_scaling & SCALING_HSHRINK) - xf86ErrorF(" hshrink"); - if (r->supported_scaling & SCALING_HSTRETCH) - xf86ErrorF(" hstretch"); - if (r->supported_scaling & SCALING_VSHRINK) - xf86ErrorF(" vshrink"); - if (r->supported_scaling & SCALING_VSTRETCH) - xf86ErrorF(" vstretch"); - xf86ErrorF("\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Preferred refresh rate: %d\n", - r->preferred_refresh); - } else if (r->max_clock != 0) { - xf86ErrorF(" PixClock max %i MHz\n", r->max_clock); - } else { - xf86ErrorF("\n"); - } - if (r->gtf_2nd_f > 0) - xf86DrvMsg(scrnIndex,X_INFO," 2nd GTF parameters: f: %i kHz " - "c: %i m: %i k %i j %i\n", r->gtf_2nd_f, - r->gtf_2nd_c, r->gtf_2nd_m, r->gtf_2nd_k, - r->gtf_2nd_j); - break; - } - case DS_STD_TIMINGS: - for (j = 0; j<5; j++) - xf86DrvMsg(scrnIndex,X_INFO,"#%i: hsize: %i vsize %i refresh: %i " - "vid: %i\n",i,m[i].section.std_t[i].hsize, - m[i].section.std_t[j].vsize,m[i].section.std_t[j].refresh, - m[i].section.std_t[j].id); - break; - case DS_WHITE_P: - for (j = 0; j<2; j++) - if (m[i].section.wp[j].index != 0) - xf86DrvMsg(scrnIndex,X_INFO, - "White point %i: whiteX: %f, whiteY: %f; gamma: %f\n", - m[i].section.wp[j].index,m[i].section.wp[j].white_x, - m[i].section.wp[j].white_y, - m[i].section.wp[j].white_gamma); - break; - case DS_CMD: - xf86DrvMsg(scrnIndex, X_INFO, - "Color management data: (not decoded)\n"); - break; - case DS_CVT: - xf86DrvMsg(scrnIndex, X_INFO, - "CVT 3-byte-code modes:\n"); - print_cvt_timings(scrnIndex, m[i].section.cvt); - break; - case DS_EST_III: - xf86DrvMsg(scrnIndex, X_INFO, - "Established timings III: (not decoded)\n"); - break; - case DS_DUMMY: - default: - break; - } - if (m[i].type >= DS_VENDOR && m[i].type <= DS_VENDOR_MAX) { - xf86DrvMsg(scrnIndex, X_WARNING, - "Unknown vendor-specific block %hx\n", - m[i].type - DS_VENDOR); - } + "#%i: hsize: %i vsize %i refresh: %i " + "vid: %i\n",p->index ,det_mon->section.std_t[j].hsize, + det_mon->section.std_t[j].vsize, + det_mon->section.std_t[j].refresh, + det_mon->section.std_t[j].id); + break; + case DS_WHITE_P: + for (j = 0; j<2; j++) + if (det_mon->section.wp[j].index != 0) + xf86DrvMsg(scrnIndex,X_INFO, + "White point %i: whiteX: %f, whiteY: %f; gamma: %f\n", + det_mon->section.wp[j].index,det_mon->section.wp[j].white_x, + det_mon->section.wp[j].white_y, + det_mon->section.wp[j].white_gamma); + break; + case DS_CMD: + xf86DrvMsg(scrnIndex, X_INFO, + "Color management data: (not decoded)\n"); + break; + case DS_CVT: + xf86DrvMsg(scrnIndex, X_INFO, + "CVT 3-byte-code modes:\n"); + print_cvt_timings(scrnIndex, det_mon->section.cvt); + break; + case DS_EST_III: + xf86DrvMsg(scrnIndex, X_INFO, + "Established timings III: (not decoded)\n"); + break; + case DS_DUMMY: + default: + break; + } + if (det_mon->type >= DS_VENDOR && det_mon->type <= DS_VENDOR_MAX) { + xf86DrvMsg(scrnIndex, X_INFO, + "Unknown vendor-specific block %hx\n", + det_mon->type - DS_VENDOR); } + + p->index = p->index + 1; } - + static void print_number_sections(int scrnIndex, int num) { @@ -465,6 +488,7 @@ xf86PrintEDID(xf86MonPtr m) { CARD16 i, j, n; char buf[EDID_WIDTH * 2 + 1]; + struct det_print_parameter p; if (!m) return NULL; @@ -473,7 +497,12 @@ xf86PrintEDID(xf86MonPtr m) print_display(m->scrnIndex, &m->features, &m->ver); print_established_timings(m->scrnIndex, &m->timings1); print_std_timings(m->scrnIndex, m->timings2); - print_detailed_monitor_section(m->scrnIndex, m->det_mon); + p.m = m; + p.index = 0; + p.quirks = xf86DDCDetectQuirks(m->scrnIndex, m, FALSE); + xf86ForEachDetailedBlock(m, + handle_detailed_print , + &p); print_number_sections(m->scrnIndex, m->no_sections); /* extension block section stuff */ @@ -490,6 +519,6 @@ xf86PrintEDID(xf86MonPtr m) } xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf); } - + return m; } diff --git a/xserver/hw/xfree86/ddc/xf86DDC.h b/xserver/hw/xfree86/ddc/xf86DDC.h index 3172b555d..af3ba06a5 100644 --- a/xserver/hw/xfree86/ddc/xf86DDC.h +++ b/xserver/hw/xfree86/ddc/xf86DDC.h @@ -24,42 +24,103 @@ typedef enum { typedef void (* DDC1SetSpeedProc)(ScrnInfoPtr, xf86ddcSpeed); -extern xf86MonPtr xf86DoEDID_DDC1( +extern _X_EXPORT xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed, unsigned int (*DDC1Read)(ScrnInfoPtr) ); -extern xf86MonPtr xf86DoEDID_DDC2( +extern _X_EXPORT xf86MonPtr xf86DoEDID_DDC2( int scrnIndex, I2CBusPtr pBus ); -extern xf86MonPtr xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool); +extern _X_EXPORT xf86MonPtr xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool); -extern xf86MonPtr xf86PrintEDID( +extern _X_EXPORT xf86MonPtr xf86PrintEDID( xf86MonPtr monPtr ); -extern xf86MonPtr xf86InterpretEDID( +extern _X_EXPORT xf86MonPtr xf86InterpretEDID( int screenIndex, Uchar *block ); -extern xf86MonPtr xf86InterpretEEDID( +extern _X_EXPORT xf86MonPtr xf86InterpretEEDID( int screenIndex, Uchar *block ); -extern void -xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC); +extern _X_EXPORT void +xf86EdidMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC); -extern Bool xf86SetDDCproperties( +extern _X_EXPORT Bool xf86SetDDCproperties( ScrnInfoPtr pScreen, xf86MonPtr DDC ); +extern _X_EXPORT DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); + +extern _X_EXPORT Bool +xf86MonitorIsHDMI(xf86MonPtr mon); + +extern _X_EXPORT xf86MonPtr +xf86DoDisplayID(int scrnIndex, I2CBusPtr pBus); + +extern _X_EXPORT void +xf86DisplayIDMonitorSet(int scrnIndex, MonPtr mon, xf86MonPtr DDC); + +extern _X_EXPORT DisplayModePtr +FindDMTMode(int hsize, int vsize, int refresh, Bool rb); + +extern _X_EXPORT const DisplayModeRec DMTModes[]; + +/* + * Quirks to work around broken EDID data from various monitors. + */ +typedef enum { + DDC_QUIRK_NONE = 0, + /* First detailed mode is bogus, prefer largest mode at 60hz */ + DDC_QUIRK_PREFER_LARGE_60 = 1 << 0, + /* 135MHz clock is too high, drop a bit */ + DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1, + /* Prefer the largest mode at 75 Hz */ + DDC_QUIRK_PREFER_LARGE_75 = 1 << 2, + /* Convert detailed timing's horizontal from units of cm to mm */ + DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3, + /* Convert detailed timing's vertical from units of cm to mm */ + DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4, + /* Detailed timing descriptors have bogus size values, so just take the + * maximum size and use that. + */ + DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, + /* Monitor forgot to set the first detailed is preferred bit. */ + DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6, + /* use +hsync +vsync for detailed mode */ + DDC_QUIRK_DETAILED_SYNC_PP = 1 << 7, + /* Force single-link DVI bandwidth limit */ + DDC_QUIRK_DVI_SINGLE_LINK = 1 << 8, +} ddc_quirk_t; + DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); extern Bool xf86MonitorIsHDMI(xf86MonPtr mon); +typedef void (* handle_detailed_fn)(struct detailed_monitor_section *,void *); + +void xf86ForEachDetailedBlock(xf86MonPtr mon, + handle_detailed_fn, + void *data); + +ddc_quirk_t +xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose); + +void xf86DetTimingApplyQuirks(struct detailed_monitor_section *det_mon, + ddc_quirk_t quirks, int hsize, int vsize); + +typedef void (* handle_video_fn)(struct cea_video_block *, void *); + +void xf86ForEachVideoBlock(xf86MonPtr, + handle_video_fn, + void *); + #endif |