Snap for 8426163 from b3dedeaa7107178b3f577cc986c91113c92e8edd to mainline-tzdata2-release

Change-Id: Iae767d4eed80a5d5770ef67dc173a55600d47ee6
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index b6d3117..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,79 +0,0 @@
----
-AccessModifierOffset: -8
-AlignAfterOpenBracket: Align
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignOperands: true
-AlignTrailingComments: false
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: InlineOnly
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLambdasOnASingleLine: All
-AllowShortLoopsOnASingleLine: false
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: false
-BinPackArguments: true
-BinPackParameters: true
-BraceWrapping:
-  AfterClass: true
-  AfterControlStatement: false
-  AfterEnum: false
-  AfterFunction: true
-  AfterNamespace: true
-  AfterStruct: false
-  AfterUnion: false
-  BeforeCatch: false
-  BeforeElse: false
-  IndentBraces: false
-BreakAfterJavaFieldAnnotations: false
-BreakBeforeBinaryOperators: None
-BreakBeforeBraces: Custom
-BreakBeforeTernaryOperators: true
-BreakStringLiterals: false
-ColumnLimit: 0
-CommentPragmas: '^ IWYU pragma:'
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
-ConstructorInitializerIndentWidth: 8
-ContinuationIndentWidth: 8
-Cpp11BracedListStyle: false
-DerivePointerAlignment: false
-DisableFormat: false
-ExperimentalAutoDetectBinPacking: false
-IncludeCategories:
-  - Regex: '.*'
-    Priority: 1
-IncludeIsMainRegex: '(_test)?$'
-IndentCaseLabels: false
-IndentWidth: 8
-IndentWrappedFunctionNames: false
-KeepEmptyLinesAtTheStartOfBlocks: false
-MacroBlockBegin: ''
-MacroBlockEnd: ''
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
-PenaltyBreakBeforeFirstCallParameter: 30
-PenaltyBreakComment: 10
-PenaltyBreakFirstLessLess: 0
-PenaltyBreakString: 10
-PenaltyExcessCharacter: 100
-PenaltyReturnTypeOnItsOwnLine: 60
-PointerAlignment: Left
-ReflowComments: false
-SortIncludes: false
-SpaceAfterCStyleCast: false
-SpaceAfterTemplateKeyword: false
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeParens: ControlStatements
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
-SpacesInAngles: false
-SpacesInCStyleCastParentheses: false
-SpacesInContainerLiterals: false
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-Standard: Cpp11
-TabWidth: 8
-UseTab: Always
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644
index 4c47fa8..0000000
--- a/.clang-tidy
+++ /dev/null
@@ -1,3 +0,0 @@
-Checks:		-clang-diagnostic-c99-designator
-FormatStyle:	file
-
diff --git a/.gitignore b/.gitignore
index 35f030e..7efae50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,3 @@
 *.txt.user
 *.patch
 py/__pycache__
-*.pyc
-meson.build.user
-subprojects/packagecache/
-subprojects/pybind11-*/
diff --git a/.gitmodules b/.gitmodules
index e69de29..c6d1083 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "ext/pybind11"]
+	path = ext/pybind11
+	url = https://github.com/pybind/pybind11.git
diff --git a/.travis.yml b/.travis.yml
index b311750..353026a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
-# Ubuntu 20.04
-dist: focal
-os: linux
+# Ubuntu 14.04 Trusty support
+sudo: required
+dist: trusty
 
 # Only build test master & travis
 branches:
@@ -13,81 +13,68 @@
 
 addons:
   apt:
+    sources: &sources
+      - ubuntu-toolchain-r-test
     packages: &packages
-      - libdrm-dev
       - libegl1-mesa-dev
       - libgles2-mesa-dev
       - libwayland-dev
       - libx11-xcb-dev
       - libx11-dev
       - libgbm-dev
-      - libevdev-dev
-      - meson
-      - ninja-build
-      - libfmt-dev
 
 # Need MYCC and MYCXX as travis overwrites CC and CXX
 
-jobs:
+matrix:
   include:
     - compiler: gcc
       addons:
         apt:
+          sources: *sources
+          packages: [*packages, 'g++-4.8']
+      env: MYCC=gcc-4.8 MYCXX=g++-4.8
+
+    - compiler: gcc
+      addons:
+        apt:
+          sources: *sources
+          packages: [*packages, 'g++-4.9']
+      # g++-4.9 gives a warning, disable it
+      env: MYCC=gcc-4.9 MYCXX=g++-4.9 CXXFLAGS=-Wno-maybe-uninitialized
+
+    - compiler: gcc
+      addons:
+        apt:
+          sources: *sources
+          packages: [*packages, 'g++-5']
+      env: MYCC=gcc-5 MYCXX=g++-5
+
+    - compiler: gcc
+      addons:
+        apt:
+          sources: *sources
+          packages: [*packages, 'g++-6']
+      env: MYCC=gcc-6 MYCXX=g++-6
+
+    - compiler: gcc
+      addons:
+        apt:
+          sources: *sources
           packages: [*packages, 'g++-7']
       env: MYCC=gcc-7 MYCXX=g++-7
 
-    - compiler: gcc
-      addons:
-        apt:
-          packages: [*packages, 'g++-8']
-      env: MYCC=gcc-8 MYCXX=g++-8
-
-    - compiler: gcc
-      addons:
-        apt:
-          packages: [*packages, 'g++-9']
-      env: MYCC=gcc-9 MYCXX=g++-9
-
-    - compiler: gcc
-      addons:
-        apt:
-          packages: [*packages, 'g++-10']
-      env: MYCC=gcc-10 MYCXX=g++-10
-
     - compiler: clang
       addons:
         apt:
-          packages: [*packages, 'clang-6.0', 'llvm-6.0-dev']
-      env: MYCC=clang-6.0 MYCXX=clang++-6.0
-
-    - compiler: clang
-      addons:
-        apt:
-          packages: [*packages, 'clang-7', 'llvm-7-dev']
-      env: MYCC=clang-7 MYCXX=clang++-7
-
-    - compiler: clang
-      addons:
-        apt:
-          packages: [*packages, 'clang-8', 'llvm-8-dev']
-      env: MYCC=clang-8 MYCXX=clang++-8
-
-    - compiler: clang
-      addons:
-        apt:
-          packages: [*packages, 'clang-9', 'llvm-9-dev']
-      env: MYCC=clang-9 MYCXX=clang++-9
-
-    - compiler: clang
-      addons:
-        apt:
-          packages: [*packages, 'clang-10', 'llvm-10-dev']
-      env: MYCC=clang-10 MYCXX=clang++-10
+          sources: [*sources, 'llvm-toolchain-precise-3.8']
+          packages: [*packages, 'clang-3.8']
+      env: MYCC=clang-3.8 MYCXX=clang++-3.8
 
 # Build steps
 script:
-  - CC=$MYCC CXX=$MYCXX meson -Dkmscube=true -Dpykms=enabled -Dwerror=true -Db_lto=true build
-  - ninja -v -C build
+  - mkdir build
+  - cd build
+  - CC=$MYCC CXX=$MYCXX cmake -DTREAT_WARNINGS_AS_ERRORS=1 -DKMSXX_ENABLE_KMSCUBE=1 -DKMSXX_ENABLE_PYTHON=1 .. && make VERBOSE=1
 
 notifications:
   email:
diff --git a/Android.bp b/Android.bp
index 10dc301..e62650e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,38 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["external_libkmsxx_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
-    name: "external_libkmsxx_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-BSD",
-        "SPDX-license-identifier-MIT",
-        "SPDX-license-identifier-MPL",
-        "SPDX-license-identifier-MPL-2.0",
-    ],
-    license_text: [
-        "LICENSE",
-    ],
-}
-
 cc_library_shared {
     name: "libkmsxx",
 
@@ -51,20 +19,37 @@
     rtti: true,
 
     srcs: [
-        "kms++/src/*.cpp",
+        "kms++/src/atomicreq.cpp",
+        "kms++/src/card.cpp",
+        "kms++/src/crtc.cpp",
+        "kms++/src/drmpropobject.cpp",
+        "kms++/src/encoder.cpp",
+        "kms++/src/framebuffer.cpp",
+        "kms++/src/modedb_cea.cpp",
+        "kms++/src/modedb_dmt.cpp",
+        "kms++/src/pixelformats.cpp",
+        "kms++/src/property.cpp",
+        "kms++/src/blob.cpp",
+        "kms++/src/connector.cpp",
+        "kms++/src/drmobject.cpp",
+        "kms++/src/dumbframebuffer.cpp",
+        "kms++/src/extframebuffer.cpp",
+        "kms++/src/helpers.cpp",
+        "kms++/src/mode_cvt.cpp",
+        "kms++/src/modedb.cpp",
+        "kms++/src/plane.cpp",
+        "kms++/src/videomode.cpp",
     ],
 
     cflags: [
-        "-DFMT_EXCEPTIONS=0",  // fmtlib is not built with exception.
+        "-std=c++11",
         "-Wall",
         "-Wextra",
         "-Wno-unused-parameter",
         "-fexceptions",
-        "-include array",
     ],
 
     shared_libs: [
-        "libbase",  // for fmtlib
         "libdrm",
     ],
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f2f24fe
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,90 @@
+cmake_minimum_required(VERSION 2.8)
+project(kms++)
+
+include(LTO.cmake)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include(CheckCXXCompilerFlag)
+
+IF(NOT CMAKE_BUILD_TYPE)
+    message(STATUS "Setting build type to 'Release' as none was specified.")
+    SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
+    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
+ENDIF()
+
+string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
+
+option(BUILD_SHARED_LIBS "Build shared libs" FALSE)
+option(TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" FALSE)
+
+set(KMSXX_ENABLE_PYTHON ON CACHE BOOL "Enable Python wrappers")
+set(KMSXX_PYTHON_VERSION "python3;python2" CACHE STRING "Python pkgconfig package")
+
+set(KMSXX_ENABLE_KMSCUBE OFF CACHE BOOL "Enable kmscube")
+
+set(KMSXX_ENABLE_THREADING ON CACHE BOOL "Enable threading for parallelized drawing")
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra -Wno-unused-parameter")
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wno-unused-parameter")
+
+if (CMAKE_COMPILER_IS_GNUCC)
+    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+        # GCC 4.x seems to warn too much
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers")
+    endif()
+endif()
+
+# HACK: cmake always adds "-rdynamic", this removes it
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+
+if (TREAT_WARNINGS_AS_ERRORS)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+endif()
+
+# static link libc
+# set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
+
+check_lto()
+
+if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+    if (LTO_WORKS)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
+        set(CMAKE_AR "${LTO_AR}")
+        set(CMAKE_RANLIB "${LTO_RANLIB}")
+    endif()
+endif()
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(LIBDRM libdrm>=2.4.64 REQUIRED)
+
+pkg_check_modules(LIBDRM_OMAP libdrm_omap)
+if(LIBDRM_OMAP_FOUND)
+    add_definitions(-DHAS_LIBDRM_OMAP)
+endif()
+
+enable_testing()
+
+add_subdirectory(kms++)
+add_subdirectory(kms++util)
+add_subdirectory(utils)
+
+if(KMSXX_ENABLE_KMSCUBE)
+	add_subdirectory(kmscube)
+endif()
+
+if(KMSXX_ENABLE_PYTHON)
+        add_subdirectory(py)
+endif()
+
+add_custom_target(docs SOURCES "README.md")
diff --git a/LTO.cmake b/LTO.cmake
new file mode 100644
index 0000000..9a18d77
--- /dev/null
+++ b/LTO.cmake
@@ -0,0 +1,32 @@
+function(check_lto)
+    if (DEFINED LTO_WORKS)
+        return()
+    endif()
+
+    set(LTO_WORKS FALSE CACHE INTERNAL "LTO works")
+
+    CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
+
+    if (NOT HAS_LTO_FLAG)
+        return()
+    endif()
+
+    find_program(LTO_AR NAMES "${CMAKE_C_COMPILER}-ar" gcc-ar)
+    find_program(LTO_RANLIB NAMES "${CMAKE_C_COMPILER}-ranlib" gcc-ranlib)
+
+    if (NOT LTO_AR OR NOT LTO_RANLIB)
+        return()
+    endif()
+
+    EXECUTE_PROCESS(COMMAND "${LTO_AR}" --version RESULT_VARIABLE ret OUTPUT_QUIET ERROR_QUIET)
+    if (ret)
+        return()
+    endif()
+
+    EXECUTE_PROCESS(COMMAND "${LTO_RANLIB}" --version RESULT_VARIABLE ret OUTPUT_QUIET ERROR_QUIET)
+    if (ret)
+        return()
+    endif()
+
+    set(LTO_WORKS TRUE CACHE INTERNAL "LTO works")
+endfunction()
diff --git a/METADATA b/METADATA
index f2c8934..e098fe8 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/tomba/kmsxx"
   }
-  version: "b12aab5d4bb45e77934d9838576a817bc8defe4b"
+  version: "a5545df02b40414c2bf3abc60cf629c5f59d00ec"
   license_type: RECIPROCAL
   last_upgrade_date {
-    year: 2021
-    month: 1
-    day: 5
+    year: 2019
+    month: 7
+    day: 30
   }
 }
diff --git a/NOTICE b/NOTICE
new file mode 120000
index 0000000..7a694c9
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+LICENSE
\ No newline at end of file
diff --git a/OWNERS b/OWNERS
index f3c79cc..17d23e7 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,3 @@
 # Default code reviewers picked from top 3 or more developers.
 # Please update this list if you find better candidates.
-adelva@google.com
+astrachan@google.com
diff --git a/README.md b/README.md
index 9e465ed..feb43d7 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 # kms++ - C++ library for kernel mode setting
 
-kms++ is a C++17 library for kernel mode setting.
+kms++ is a C++11 library for kernel mode setting.
 
 Also included are some simple utilities for KMS and python bindings for kms++.
 
@@ -30,51 +30,55 @@
 And to compile:
 
 ```
-meson build
-ninja -C build
+$ mkdir build
+$ cd build
+$ cmake ..
+$ make -j4
 ```
 
 ## Cross compiling instructions:
 
-```
-meson build --cross-file=<path-to-meson-cross-file>
-ninja -C build
-```
+Directions for cross compiling depend on your environment.
 
-Here is my cross file for arm32 (where ${BROOT} is path to my buildroot output dir):
+These are for mine with buildroot:
 
 ```
-[binaries]
-c = ['ccache', '${BROOT}/host/bin/arm-buildroot-linux-gnueabihf-gcc']
-cpp = ['ccache', '${BROOT}/host/bin/arm-buildroot-linux-gnueabihf-g++']
-ar = '${BROOT}/host/bin/arm-buildroot-linux-gnueabihf-ar'
-strip = '${BROOT}/host/bin/arm-buildroot-linux-gnueabihf-strip'
-pkgconfig = '${BROOT}/host/bin/pkg-config'
+$ mkdir build
+$ cd build
+$ cmake -DCMAKE_TOOLCHAIN_FILE=<buildrootpath>/output/host/usr/share/buildroot/toolchainfile.cmake ..
+$ make -j4
+```
 
-[host_machine]
-system = 'linux'
-cpu_family = 'arm'
-cpu = 'arm'
-endian = 'little'
+Your environment may provide similar toolchainfile. If not, you can create a toolchainfile of your own, something along these lines:
+
+```
+SET(CMAKE_SYSTEM_NAME Linux)
+
+SET(BROOT "<buildroot>/output/")
+
+# specify the cross compiler
+SET(CMAKE_C_COMPILER   ${BROOT}/host/usr/bin/arm-buildroot-linux-gnueabihf-gcc)
+SET(CMAKE_CXX_COMPILER ${BROOT}/host/usr/bin/arm-buildroot-linux-gnueabihf-g++)
+
+# where is the target environment
+SET(CMAKE_FIND_ROOT_PATH ${BROOT}/target ${BROOT}/host)
+
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 ```
 
 ## Build options
 
-You can use meson options to configure the build. E.g.
+You can use the following cmake flags to control the build. Use `-DFLAG=VALUE` to set them.
 
-```
-meson build -Dbuildtype=debug -Dkmscube=true
-```
-
-Use `meson configure build` to see all the configuration options and their current values.
-
-kms++ specific build options are:
-
-Option name      | Values                  | Default         | Notes
----------------- | -------------           | --------------- | --------
-pykms            | true, false             | true            | Python bindings
-kmscube          | true, false             | false           | GLES kmscube
-omap             | enabled, disabled, auto | auto            | libdrm-omap support
+Option name           | Values          | Default         | Notes
+--------------------- | -------------   | --------------- | --------
+CMAKE_BUILD_TYPE      | Release/Debug   | Release         |
+BUILD_SHARED_LIBS     | ON/OFF          | OFF             |
+KMSXX_ENABLE_PYTHON   | ON/OFF          | ON              |
+KMSXX_ENABLE_KMSCUBE  | ON/OFF          | OFF             |
+KMSXX_PYTHON_VERSION  | python3/python2 | python3;python2 | Name of the python pkgconfig file
 
 ## Env variables
 
@@ -93,4 +97,5 @@
 
 ```
 PYTHONPATH=build/py py/tests/hpd.py
+
 ```
diff --git a/ext/pybind11 b/ext/pybind11
new file mode 160000
index 0000000..9a19306
--- /dev/null
+++ b/ext/pybind11
@@ -0,0 +1 @@
+Subproject commit 9a19306fbf30642ca331d0ec88e7da54a96860f9
diff --git a/kms++/CMakeLists.txt b/kms++/CMakeLists.txt
new file mode 100644
index 0000000..10352a2
--- /dev/null
+++ b/kms++/CMakeLists.txt
@@ -0,0 +1,33 @@
+include_directories(${LIBDRM_INCLUDE_DIRS})
+link_directories(${LIBDRM_LIBRARY_DIRS})
+
+include_directories(${LIBDRM_OMAP_INCLUDE_DIRS})
+link_directories(${LIBDRM_OMAP_LIBRARY_DIRS})
+
+file(GLOB SRCS "src/*.cpp" "src/*.h")
+file(GLOB PUB_HDRS "inc/kms++/*.h")
+
+if(LIBDRM_OMAP_FOUND)
+    file(GLOB OMAP_SRCS "src/omap/*.cpp" "src/omap/*.h")
+    file(GLOB OMAP_PUB_HDRS "inc/kms++/omap/*.h")
+
+    set(SRCS ${SRCS} ${OMAP_SRCS})
+    set(PUB_HDRS ${PUB_HDRS} ${OMAP_PUB_HDRS})
+endif()
+
+add_library(kms++ ${SRCS} ${PUB_HDRS})
+
+target_include_directories(kms++ PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
+    $<INSTALL_INTERFACE:include>
+    PRIVATE src)
+
+target_link_libraries(kms++ ${LIBDRM_LIBRARIES} ${LIBDRM_OMAP_LIBRARIES})
+
+set_target_properties(kms++ PROPERTIES
+    PUBLIC_HEADER "${PUB_HDRS}")
+
+install(TARGETS kms++
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib
+    PUBLIC_HEADER DESTINATION include/kms++)
diff --git a/kms++/inc/kms++/atomicreq.h b/kms++/inc/kms++/atomicreq.h
index 780cc8f..a678b54 100644
--- a/kms++/inc/kms++/atomicreq.h
+++ b/kms++/inc/kms++/atomicreq.h
@@ -20,9 +20,9 @@
 	AtomicReq& operator=(const AtomicReq& other) = delete;
 
 	void add(uint32_t ob_id, uint32_t prop_id, uint64_t value);
-	void add(DrmPropObject* ob, Property* prop, uint64_t value);
-	void add(DrmPropObject* ob, const std::string& prop, uint64_t value);
-	void add(DrmPropObject* ob, const std::map<std::string, uint64_t>& values);
+	void add(DrmPropObject *ob, Property *prop, uint64_t value);
+	void add(DrmPropObject *ob, const std::string& prop, uint64_t value);
+	void add(DrmPropObject *ob, const std::map<std::string, uint64_t>& values);
 
 	void add_display(Connector* conn, Crtc* crtc, Blob* videomode,
 			 Plane* primary, Framebuffer* fb);
@@ -36,4 +36,4 @@
 	_drmModeAtomicReq* m_req;
 };
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/blob.h b/kms++/inc/kms++/blob.h
index 011613d..fd872f1 100644
--- a/kms++/inc/kms++/blob.h
+++ b/kms++/inc/kms++/blob.h
@@ -5,12 +5,13 @@
 
 namespace kms
 {
+
 class Blob : public DrmObject
 {
 public:
 	Blob(Card& card, uint32_t blob_id);
 	Blob(Card& card, void* data, size_t len);
-	~Blob() override;
+	virtual ~Blob();
 
 	std::vector<uint8_t> data();
 
@@ -18,4 +19,4 @@
 	bool m_created;
 };
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/card.h b/kms++/inc/kms++/card.h
index bf6f9bf..099d5b5 100644
--- a/kms++/inc/kms++/card.h
+++ b/kms++/inc/kms++/card.h
@@ -4,39 +4,24 @@
 #include <vector>
 #include <map>
 #include <memory>
-#include <string>
 
 #include "decls.h"
 #include "pipeline.h"
 
 namespace kms
 {
-struct CardVersion {
-	int major;
-	int minor;
-	int patchlevel;
-	std::string name;
-	std::string date;
-	std::string desc;
-};
-
 class Card
 {
 	friend class Framebuffer;
-
 public:
-	static std::unique_ptr<Card> open_named_card(const std::string& name);
-
 	Card(const std::string& dev_path = "");
 	Card(const std::string& driver, uint32_t idx);
-	Card(int fd, bool take_ownership);
 	virtual ~Card();
 
 	Card(const Card& other) = delete;
 	Card& operator=(const Card& other) = delete;
 
 	int fd() const { return m_fd; }
-	unsigned int dev_minor() const { return m_minor; }
 
 	void drop_master();
 
@@ -51,17 +36,17 @@
 
 	bool is_master() const { return m_is_master; }
 	bool has_atomic() const { return m_has_atomic; }
-	bool has_universal_planes() const { return m_has_universal_planes; }
+	bool has_has_universal_planes() const { return m_has_universal_planes; }
 	bool has_dumb_buffers() const { return m_has_dumb; }
 	bool has_kms() const;
 
-	std::vector<Connector*> get_connectors() const { return m_connectors; }
-	std::vector<Encoder*> get_encoders() const { return m_encoders; }
-	std::vector<Crtc*> get_crtcs() const { return m_crtcs; }
-	std::vector<Plane*> get_planes() const { return m_planes; }
-	std::vector<Property*> get_properties() const { return m_properties; }
+	const std::vector<Connector*> get_connectors() const { return m_connectors; }
+	const std::vector<Encoder*> get_encoders() const { return m_encoders; }
+	const std::vector<Crtc*> get_crtcs() const { return m_crtcs; }
+	const std::vector<Plane*> get_planes() const { return m_planes; }
+	const std::vector<Property*> get_properties() const { return m_properties; }
 
-	std::vector<DrmObject*> get_objects() const;
+	const std::vector<DrmObject*> get_objects() const;
 
 	std::vector<Pipeline> get_connected_pipelines();
 
@@ -69,8 +54,7 @@
 
 	int disable_all();
 
-	const std::string& version_name() const { return m_version.name; }
-	const CardVersion& version() const { return m_version; }
+	const std::string& version_name() const { return m_version_name; }
 
 private:
 	void setup();
@@ -86,13 +70,17 @@
 	std::vector<Framebuffer*> m_framebuffers;
 
 	int m_fd;
-	unsigned int m_minor;
 	bool m_is_master;
 
 	bool m_has_atomic;
 	bool m_has_universal_planes;
 	bool m_has_dumb;
 
-	CardVersion m_version;
+	int m_version_major;
+	int m_version_minor;
+	int m_version_patchlevel;
+	std::string m_version_name;
+	std::string m_version_date;
+	std::string m_version_desc;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/connector.h b/kms++/inc/kms++/connector.h
index f45a487..155f916 100644
--- a/kms++/inc/kms++/connector.h
+++ b/kms++/inc/kms++/connector.h
@@ -7,9 +7,11 @@
 
 namespace kms
 {
+
 struct ConnectorPriv;
 
-enum class ConnectorStatus {
+enum class ConnectorStatus
+{
 	Unknown,
 	Connected,
 	Disconnected,
@@ -18,7 +20,6 @@
 class Connector : public DrmPropObject
 {
 	friend class Card;
-
 public:
 	void refresh();
 
@@ -43,12 +44,11 @@
 	const std::string& subpixel_str() const;
 	std::vector<Videomode> get_modes() const;
 	std::vector<Encoder*> get_encoders() const;
-
 private:
 	Connector(Card& card, uint32_t id, uint32_t idx);
-	~Connector() override;
+	~Connector();
 
-	void setup() override;
+	void setup();
 	void restore_mode();
 
 	ConnectorPriv* m_priv;
@@ -59,4 +59,4 @@
 
 	Crtc* m_saved_crtc;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/crtc.h b/kms++/inc/kms++/crtc.h
index cf64a86..ea20ef8 100644
--- a/kms++/inc/kms++/crtc.h
+++ b/kms++/inc/kms++/crtc.h
@@ -6,13 +6,13 @@
 
 namespace kms
 {
+
 struct CrtcPriv;
 
 class Crtc : public DrmPropObject
 {
 	friend class Card;
 	friend class Connector;
-
 public:
 	void refresh();
 
@@ -21,7 +21,7 @@
 	int set_mode(Connector* conn, const Videomode& mode);
 	int set_mode(Connector* conn, Framebuffer& fb, const Videomode& mode);
 
-	int set_plane(Plane* plane, Framebuffer& fb,
+	int set_plane(Plane *plane, Framebuffer &fb,
 		      int32_t dst_x, int32_t dst_y, uint32_t dst_w, uint32_t dst_h,
 		      float src_x, float src_y, float src_w, float src_h);
 	int disable_mode();
@@ -30,7 +30,7 @@
 
 	Plane* get_primary_plane();
 
-	int page_flip(Framebuffer& fb, void* data);
+	int page_flip(Framebuffer& fb, void *data);
 
 	uint32_t buffer_id() const;
 	uint32_t x() const;
@@ -39,18 +39,16 @@
 	uint32_t height() const;
 	int mode_valid() const;
 	Videomode mode() const;
-	int legacy_gamma_size() const;
-	void legacy_gamma_set(std::vector<std::tuple<uint16_t, uint16_t, uint16_t>> v);
-
+	int gamma_size() const;
 private:
 	Crtc(Card& card, uint32_t id, uint32_t idx);
-	~Crtc() override;
+	~Crtc();
 
-	void setup() override;
-	void restore_mode(Connector* conn);
+	void setup();
+	void restore_mode(Connector *conn);
 
 	CrtcPriv* m_priv;
 
 	std::vector<Plane*> m_possible_planes;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/decls.h b/kms++/inc/kms++/decls.h
index a4b5631..91bce13 100644
--- a/kms++/inc/kms++/decls.h
+++ b/kms++/inc/kms++/decls.h
@@ -12,10 +12,9 @@
 class DumbFramebuffer;
 class Encoder;
 class ExtFramebuffer;
-class DmabufFramebuffer;
 class Framebuffer;
 class PageFlipHandlerBase;
 class Plane;
 class Property;
 struct Videomode;
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/dmabufframebuffer.h b/kms++/inc/kms++/dmabufframebuffer.h
deleted file mode 100644
index 6643a81..0000000
--- a/kms++/inc/kms++/dmabufframebuffer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <array>
-#include <vector>
-
-#include "framebuffer.h"
-#include "pixelformats.h"
-
-namespace kms
-{
-class DmabufFramebuffer : public Framebuffer
-{
-public:
-	DmabufFramebuffer(Card& card, uint32_t width, uint32_t height, const std::string& format,
-			  std::vector<int> fds, std::vector<uint32_t> pitches, std::vector<uint32_t> offsets, std::vector<uint64_t> modifiers = {});
-	DmabufFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
-			  std::vector<int> fds, std::vector<uint32_t> pitches, std::vector<uint32_t> offsets, std::vector<uint64_t> modifiers = {});
-	~DmabufFramebuffer() override;
-
-	uint32_t width() const override { return Framebuffer::width(); }
-	uint32_t height() const override { return Framebuffer::height(); }
-
-	PixelFormat format() const override { return m_format; }
-	unsigned num_planes() const override { return m_num_planes; }
-
-	uint32_t handle(unsigned plane) const { return m_planes.at(plane).handle; }
-	uint32_t stride(unsigned plane) const override { return m_planes.at(plane).stride; }
-	uint32_t size(unsigned plane) const override { return m_planes.at(plane).size; }
-	uint32_t offset(unsigned plane) const override { return m_planes.at(plane).offset; }
-	uint8_t* map(unsigned plane) override;
-	int prime_fd(unsigned plane) override;
-
-	void begin_cpu_access(CpuAccess access) override;
-	void end_cpu_access() override;
-
-private:
-	struct FramebufferPlane {
-		uint32_t handle;
-		int prime_fd;
-		uint32_t size;
-		uint32_t stride;
-		uint32_t offset;
-		uint64_t modifier;
-		uint8_t* map;
-	};
-
-	unsigned m_num_planes;
-	std::array<FramebufferPlane, 4> m_planes;
-
-	PixelFormat m_format;
-
-	uint32_t m_sync_flags = 0;
-};
-
-} // namespace kms
diff --git a/kms++/inc/kms++/drmobject.h b/kms++/inc/kms++/drmobject.h
index e15ed4c..a939aa7 100644
--- a/kms++/inc/kms++/drmobject.h
+++ b/kms++/inc/kms++/drmobject.h
@@ -6,10 +6,10 @@
 
 namespace kms
 {
+
 class DrmObject
 {
 	friend class Card;
-
 public:
 	DrmObject(const DrmObject& other) = delete;
 	DrmObject& operator=(const DrmObject& other) = delete;
@@ -26,7 +26,7 @@
 
 	virtual ~DrmObject();
 
-	virtual void setup() {}
+	virtual void setup() { }
 
 	virtual void set_id(uint32_t id);
 
@@ -37,4 +37,4 @@
 	uint32_t m_object_type;
 	uint32_t m_idx;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/drmpropobject.h b/kms++/inc/kms++/drmpropobject.h
index dc3a806..d9ba58e 100644
--- a/kms++/inc/kms++/drmpropobject.h
+++ b/kms++/inc/kms++/drmpropobject.h
@@ -8,15 +8,13 @@
 
 namespace kms
 {
+
 class DrmPropObject : public DrmObject
 {
 	friend class Card;
-
 public:
 	void refresh_props();
 
-	bool has_prop(const std::string& name) const { return !!get_prop(name); }
-
 	Property* get_prop(const std::string& name) const;
 
 	uint64_t get_prop_value(uint32_t id) const;
@@ -33,9 +31,9 @@
 	DrmPropObject(Card& card, uint32_t object_type);
 	DrmPropObject(Card& card, uint32_t id, uint32_t object_type, uint32_t idx = 0);
 
-	~DrmPropObject() override;
+	virtual ~DrmPropObject();
 
 private:
 	std::map<uint32_t, uint64_t> m_prop_values;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/dumbframebuffer.h b/kms++/inc/kms++/dumbframebuffer.h
index af5fe42..fb99d0e 100644
--- a/kms++/inc/kms++/dumbframebuffer.h
+++ b/kms++/inc/kms++/dumbframebuffer.h
@@ -1,31 +1,30 @@
 #pragma once
 
-#include <array>
-
 #include "framebuffer.h"
 #include "pixelformats.h"
 
 namespace kms
 {
+
 class DumbFramebuffer : public Framebuffer
 {
 public:
 	DumbFramebuffer(Card& card, uint32_t width, uint32_t height, const std::string& fourcc);
 	DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format);
-	~DumbFramebuffer() override;
+	virtual ~DumbFramebuffer();
 
-	uint32_t width() const override { return Framebuffer::width(); }
-	uint32_t height() const override { return Framebuffer::height(); }
+	uint32_t width() const { return Framebuffer::width(); }
+	uint32_t height() const { return Framebuffer::height(); }
 
-	PixelFormat format() const override { return m_format; }
-	unsigned num_planes() const override { return m_num_planes; }
+	PixelFormat format() const { return m_format; }
+	unsigned num_planes() const { return m_num_planes; }
 
-	uint32_t handle(unsigned plane) const { return m_planes.at(plane).handle; }
-	uint32_t stride(unsigned plane) const override { return m_planes.at(plane).stride; }
-	uint32_t size(unsigned plane) const override { return m_planes.at(plane).size; }
-	uint32_t offset(unsigned plane) const override { return m_planes.at(plane).offset; }
-	uint8_t* map(unsigned plane) override;
-	int prime_fd(unsigned plane) override;
+	uint32_t handle(unsigned plane) const { return m_planes[plane].handle; }
+	uint32_t stride(unsigned plane) const { return m_planes[plane].stride; }
+	uint32_t size(unsigned plane) const { return m_planes[plane].size; }
+	uint32_t offset(unsigned plane) const { return m_planes[plane].offset; }
+	uint8_t* map(unsigned plane);
+	int prime_fd(unsigned plane);
 
 private:
 	struct FramebufferPlane {
@@ -34,12 +33,15 @@
 		uint32_t size;
 		uint32_t stride;
 		uint32_t offset;
-		uint8_t* map;
+		uint8_t *map;
 	};
 
+	void Create();
+	void Destroy();
+
 	unsigned m_num_planes;
-	std::array<FramebufferPlane, 4> m_planes;
+	struct FramebufferPlane m_planes[4];
 
 	PixelFormat m_format;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/encoder.h b/kms++/inc/kms++/encoder.h
index 9476d80..1d36adc 100644
--- a/kms++/inc/kms++/encoder.h
+++ b/kms++/inc/kms++/encoder.h
@@ -5,12 +5,12 @@
 
 namespace kms
 {
+
 struct EncoderPriv;
 
 class Encoder : public DrmPropObject
 {
 	friend class Card;
-
 public:
 	void refresh();
 
@@ -18,11 +18,10 @@
 	std::vector<Crtc*> get_possible_crtcs() const;
 
 	const std::string& get_encoder_type() const;
-
 private:
 	Encoder(Card& card, uint32_t id, uint32_t idx);
-	~Encoder() override;
+	~Encoder();
 
 	EncoderPriv* m_priv;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/extframebuffer.h b/kms++/inc/kms++/extframebuffer.h
index 00dc9bf..5f0660c 100644
--- a/kms++/inc/kms++/extframebuffer.h
+++ b/kms++/inc/kms++/extframebuffer.h
@@ -1,45 +1,47 @@
 #pragma once
 
-#include <array>
-#include <vector>
-
 #include "framebuffer.h"
 #include "pixelformats.h"
 
 namespace kms
 {
+
 class ExtFramebuffer : public Framebuffer
 {
 public:
 	ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
-		       std::vector<uint32_t> handles, std::vector<uint32_t> pitches, std::vector<uint32_t> offsets, std::vector<uint64_t> modifiers = {});
-	~ExtFramebuffer() override;
+		       std::vector<uint32_t> handles, std::vector<uint32_t> pitches, std::vector<uint32_t> offsets);
+	ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
+		       std::vector<int> fds, std::vector<uint32_t> pitches, std::vector<uint32_t> offsets);
+	virtual ~ExtFramebuffer();
 
-	uint32_t width() const override { return Framebuffer::width(); }
-	uint32_t height() const override { return Framebuffer::height(); }
+	uint32_t width() const { return Framebuffer::width(); }
+	uint32_t height() const { return Framebuffer::height(); }
 
-	PixelFormat format() const override { return m_format; }
-	unsigned num_planes() const override { return m_num_planes; }
+	PixelFormat format() const { return m_format; }
+	unsigned num_planes() const { return m_num_planes; }
 
-	uint32_t handle(unsigned plane) const { return m_planes.at(plane).handle; }
-	uint32_t stride(unsigned plane) const override { return m_planes.at(plane).stride; }
-	uint32_t size(unsigned plane) const override { return m_planes.at(plane).size; }
-	uint32_t offset(unsigned plane) const override { return m_planes.at(plane).offset; }
+	uint32_t handle(unsigned plane) const { return m_planes[plane].handle; }
+	uint32_t stride(unsigned plane) const { return m_planes[plane].stride; }
+	uint32_t size(unsigned plane) const { return m_planes[plane].size; }
+	uint32_t offset(unsigned plane) const { return m_planes[plane].offset; }
+	uint8_t* map(unsigned plane);
+	int prime_fd(unsigned plane);
 
 private:
 	struct FramebufferPlane {
 		uint32_t handle;
+		int prime_fd;
 		uint32_t size;
 		uint32_t stride;
 		uint32_t offset;
-		uint64_t modifier;
-		uint8_t* map;
+		uint8_t *map;
 	};
 
 	unsigned m_num_planes;
-	std::array<FramebufferPlane, 4> m_planes;
+	struct FramebufferPlane m_planes[4];
 
 	PixelFormat m_format;
 };
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/framebuffer.h b/kms++/inc/kms++/framebuffer.h
index 6f77b98..3d43d08 100644
--- a/kms++/inc/kms++/framebuffer.h
+++ b/kms++/inc/kms++/framebuffer.h
@@ -5,16 +5,9 @@
 
 namespace kms
 {
-enum class CpuAccess {
-	Read,
-	Write,
-	ReadWrite,
-};
-
-class IFramebuffer
-{
+class IFramebuffer {
 public:
-	virtual ~IFramebuffer() {}
+	virtual ~IFramebuffer() { }
 
 	virtual uint32_t width() const = 0;
 	virtual uint32_t height() const = 0;
@@ -27,22 +20,18 @@
 	virtual uint32_t offset(unsigned plane) const { throw std::runtime_error("not implemented"); }
 	virtual uint8_t* map(unsigned plane) { throw std::runtime_error("not implemented"); }
 	virtual int prime_fd(unsigned plane) { throw std::runtime_error("not implemented"); }
-
-	virtual void begin_cpu_access(CpuAccess access) {}
-	virtual void end_cpu_access() {}
 };
 
 class Framebuffer : public DrmObject, public IFramebuffer
 {
 public:
 	Framebuffer(Card& card, uint32_t id);
-	~Framebuffer() override;
+	virtual ~Framebuffer();
 
-	uint32_t width() const override { return m_width; }
-	uint32_t height() const override { return m_height; }
+	uint32_t width() const { return m_width; }
+	uint32_t height() const { return m_height; }
 
 	void flush();
-
 protected:
 	Framebuffer(Card& card, uint32_t width, uint32_t height);
 
@@ -51,4 +40,4 @@
 	uint32_t m_height;
 };
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/kms++.h b/kms++/inc/kms++/kms++.h
index a97505a..3365ef7 100644
--- a/kms++/inc/kms++/kms++.h
+++ b/kms++/inc/kms++/kms++.h
@@ -8,7 +8,6 @@
 #include "framebuffer.h"
 #include "dumbframebuffer.h"
 #include "extframebuffer.h"
-#include "dmabufframebuffer.h"
 #include "plane.h"
 #include "property.h"
 #include "blob.h"
diff --git a/kms++/inc/kms++/mode_cvt.h b/kms++/inc/kms++/mode_cvt.h
index 3fa8a07..8902e4a 100644
--- a/kms++/inc/kms++/mode_cvt.h
+++ b/kms++/inc/kms++/mode_cvt.h
@@ -4,6 +4,7 @@
 
 namespace kms
 {
+
 Videomode videomode_from_cvt(uint32_t hact, uint32_t vact, uint32_t refresh, bool ilace, bool reduced_v2, bool video_optimized);
 
 }
diff --git a/kms++/inc/kms++/modedb.h b/kms++/inc/kms++/modedb.h
index 0650442..b6447c6 100644
--- a/kms++/inc/kms++/modedb.h
+++ b/kms++/inc/kms++/modedb.h
@@ -13,4 +13,4 @@
 const Videomode& find_dmt(uint32_t width, uint32_t height, float vrefresh, bool ilace);
 const Videomode& find_cea(uint32_t width, uint32_t height, float vrefresh, bool ilace);
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/omap/omapcard.h b/kms++/inc/kms++/omap/omapcard.h
index 123205b..2f1f528 100644
--- a/kms++/inc/kms++/omap/omapcard.h
+++ b/kms++/inc/kms++/omap/omapcard.h
@@ -17,4 +17,4 @@
 private:
 	struct omap_device* m_omap_dev;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/omap/omapframebuffer.h b/kms++/inc/kms++/omap/omapframebuffer.h
index b102a76..70bf946 100644
--- a/kms++/inc/kms++/omap/omapframebuffer.h
+++ b/kms++/inc/kms++/omap/omapframebuffer.h
@@ -12,7 +12,8 @@
 class OmapFramebuffer : public Framebuffer
 {
 public:
-	enum Flags {
+	enum Flags
+	{
 		None = 0,
 		Tiled = 1 << 0,
 		MemContig = 1 << 1,
@@ -50,7 +51,7 @@
 		uint8_t* map;
 	};
 
-	void Create(uint32_t width, uint32_t height, PixelFormat format, Flags buffer_flags);
+	void Create(Flags buffer_flags);
 	void Destroy();
 
 	unsigned m_num_planes;
@@ -58,4 +59,4 @@
 
 	PixelFormat m_format;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/pagefliphandler.h b/kms++/inc/kms++/pagefliphandler.h
index 2f5fdcd..79cda0d 100644
--- a/kms++/inc/kms++/pagefliphandler.h
+++ b/kms++/inc/kms++/pagefliphandler.h
@@ -1,12 +1,11 @@
 #pragma once
 
-namespace kms
-{
+namespace kms {
 class PageFlipHandlerBase
 {
 public:
-	PageFlipHandlerBase() {}
-	virtual ~PageFlipHandlerBase() {}
+	PageFlipHandlerBase() { }
+	virtual ~PageFlipHandlerBase() { }
 	virtual void handle_page_flip(uint32_t frame, double time) = 0;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/pipeline.h b/kms++/inc/kms++/pipeline.h
index 236e582..ef04ec1 100644
--- a/kms++/inc/kms++/pipeline.h
+++ b/kms++/inc/kms++/pipeline.h
@@ -8,4 +8,4 @@
 	Crtc* crtc;
 	Connector* connector;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/pixelformats.h b/kms++/inc/kms++/pixelformats.h
index 6f2671b..15fee7f 100644
--- a/kms++/inc/kms++/pixelformats.h
+++ b/kms++/inc/kms++/pixelformats.h
@@ -2,29 +2,20 @@
 
 #include <cstdint>
 #include <string>
-#include <stdexcept>
 
 namespace kms
 {
-constexpr uint32_t MakeFourCC(const char* fourcc)
+constexpr uint32_t MakeFourCC(const char *fourcc)
 {
 	return fourcc[0] | (fourcc[1] << 8) | (fourcc[2] << 16) | (fourcc[3] << 24);
 }
 
-enum class PixelFormat : uint32_t {
+enum class PixelFormat : uint32_t
+{
 	Undefined = 0,
 
 	NV12 = MakeFourCC("NV12"),
 	NV21 = MakeFourCC("NV21"),
-	NV16 = MakeFourCC("NV16"),
-	NV61 = MakeFourCC("NV61"),
-
-	YUV420 = MakeFourCC("YU12"),
-	YVU420 = MakeFourCC("YV12"),
-	YUV422 = MakeFourCC("YU16"),
-	YVU422 = MakeFourCC("YV16"),
-	YUV444 = MakeFourCC("YU24"),
-	YVU444 = MakeFourCC("YV24"),
 
 	UYVY = MakeFourCC("UYVY"),
 	YUYV = MakeFourCC("YUYV"),
@@ -44,14 +35,9 @@
 	RGB888 = MakeFourCC("RG24"),
 	BGR888 = MakeFourCC("BG24"),
 
-	RGB332 = MakeFourCC("RGB8"),
-
 	RGB565 = MakeFourCC("RG16"),
 	BGR565 = MakeFourCC("BG16"),
 
-	XRGB4444 = MakeFourCC("XR12"),
-	XRGB1555 = MakeFourCC("XR15"),
-
 	ARGB4444 = MakeFourCC("AR12"),
 	ARGB1555 = MakeFourCC("AR15"),
 
@@ -73,26 +59,29 @@
 
 static inline std::string PixelFormatToFourCC(PixelFormat f)
 {
-	char buf[5] = { (char)(((uint32_t)f >> 0) & 0xff),
-			(char)(((uint32_t)f >> 8) & 0xff),
-			(char)(((uint32_t)f >> 16) & 0xff),
-			(char)(((uint32_t)f >> 24) & 0xff),
+	char buf[5] = { (char)(((int)f >> 0) & 0xff),
+			(char)(((int)f >> 8) & 0xff),
+			(char)(((int)f >> 16) & 0xff),
+			(char)(((int)f >> 24) & 0xff),
 			0 };
 	return std::string(buf);
 }
 
-enum class PixelColorType {
+enum class PixelColorType
+{
 	RGB,
 	YUV,
 };
 
-struct PixelFormatPlaneInfo {
+struct PixelFormatPlaneInfo
+{
 	uint8_t bitspp;
 	uint8_t xsub;
 	uint8_t ysub;
 };
 
-struct PixelFormatInfo {
+struct PixelFormatInfo
+{
 	PixelColorType type;
 	uint8_t num_planes;
 	struct PixelFormatPlaneInfo planes[4];
@@ -100,4 +89,4 @@
 
 const struct PixelFormatInfo& get_pixel_format_info(PixelFormat format);
 
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/plane.h b/kms++/inc/kms++/plane.h
index d3cfde5..27e819b 100644
--- a/kms++/inc/kms++/plane.h
+++ b/kms++/inc/kms++/plane.h
@@ -4,7 +4,9 @@
 
 namespace kms
 {
-enum class PlaneType {
+
+enum class PlaneType
+{
 	Overlay = 1 << 0,
 	Primary = 1 << 1,
 	Cursor = 1 << 2,
@@ -15,7 +17,6 @@
 class Plane : public DrmPropObject
 {
 	friend class Card;
-
 public:
 	bool supports_crtc(Crtc* crtc) const;
 	bool supports_format(PixelFormat fmt) const;
@@ -32,11 +33,10 @@
 	uint32_t x() const;
 	uint32_t y() const;
 	uint32_t gamma_size() const;
-
 private:
 	Plane(Card& card, uint32_t id, uint32_t idx);
-	~Plane() override;
+	~Plane();
 
 	PlanePriv* m_priv;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/property.h b/kms++/inc/kms++/property.h
index 7c7b834..b9097ff 100644
--- a/kms++/inc/kms++/property.h
+++ b/kms++/inc/kms++/property.h
@@ -6,9 +6,11 @@
 
 namespace kms
 {
+
 struct PropertyPriv;
 
-enum class PropertyType {
+enum class PropertyType
+{
 	Range,
 	Enum,
 	Blob,
@@ -20,7 +22,6 @@
 class Property : public DrmObject
 {
 	friend class Card;
-
 public:
 	const std::string& name() const;
 
@@ -31,14 +32,13 @@
 	std::map<uint64_t, std::string> get_enums() const;
 	std::vector<uint64_t> get_values() const;
 	std::vector<uint32_t> get_blob_ids() const;
-
 private:
 	Property(Card& card, uint32_t id);
-	~Property() override;
+	~Property();
 
 	PropertyType m_type;
 
 	PropertyPriv* m_priv;
 	std::string m_name;
 };
-} // namespace kms
+}
diff --git a/kms++/inc/kms++/videomode.h b/kms++/inc/kms++/videomode.h
index 7209ea9..d7f5258 100644
--- a/kms++/inc/kms++/videomode.h
+++ b/kms++/inc/kms++/videomode.h
@@ -8,13 +8,16 @@
 
 namespace kms
 {
-enum class SyncPolarity {
+
+enum class SyncPolarity
+{
 	Undefined,
 	Positive,
 	Negative,
 };
 
-struct Videomode {
+struct Videomode
+{
 	std::string name;
 
 	uint32_t clock;
@@ -23,8 +26,8 @@
 
 	uint32_t vrefresh;
 
-	uint32_t flags; // DRM_MODE_FLAG_*
-	uint32_t type; // DRM_MODE_TYPE_*
+	uint32_t flags;		// DRM_MODE_FLAG_*
+	uint32_t type;		// DRM_MODE_TYPE_*
 
 	std::unique_ptr<Blob> to_blob(Card& card) const;
 
@@ -46,14 +49,10 @@
 	void set_hsync(SyncPolarity pol);
 	void set_vsync(SyncPolarity pol);
 
-	std::string to_string_short() const;
-	std::string to_string_long() const;
-	std::string to_string_long_padded() const;
-
-	bool valid() const;
+	std::string to_string() const;
 };
 
 struct Videomode videomode_from_timings(uint32_t clock_khz,
 					uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp,
 					uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp);
-} // namespace kms
+}
diff --git a/kms++/meson.build b/kms++/meson.build
deleted file mode 100644
index fee1b54..0000000
--- a/kms++/meson.build
+++ /dev/null
@@ -1,87 +0,0 @@
-libkmsxx_sources = files([
-    'src/atomicreq.cpp',
-    'src/blob.cpp',
-    'src/card.cpp',
-    'src/connector.cpp',
-    'src/crtc.cpp',
-    'src/dmabufframebuffer.cpp',
-    'src/drmobject.cpp',
-    'src/drmpropobject.cpp',
-    'src/dumbframebuffer.cpp',
-    'src/encoder.cpp',
-    'src/extframebuffer.cpp',
-    'src/framebuffer.cpp',
-    'src/helpers.cpp',
-    'src/mode_cvt.cpp',
-    'src/modedb_cea.cpp',
-    'src/modedb.cpp',
-    'src/modedb_dmt.cpp',
-    'src/pixelformats.cpp',
-    'src/plane.cpp',
-    'src/property.cpp',
-    'src/videomode.cpp',
-])
-
-public_headers = [
-    'inc/kms++/dmabufframebuffer.h',
-    'inc/kms++/atomicreq.h',
-    'inc/kms++/property.h',
-    'inc/kms++/plane.h',
-    'inc/kms++/kms++.h',
-    'inc/kms++/connector.h',
-    'inc/kms++/card.h',
-    'inc/kms++/modedb.h',
-    'inc/kms++/pagefliphandler.h',
-    'inc/kms++/encoder.h',
-    'inc/kms++/decls.h',
-    'inc/kms++/videomode.h',
-    'inc/kms++/drmobject.h',
-    'inc/kms++/pixelformats.h',
-    'inc/kms++/crtc.h',
-    'inc/kms++/framebuffer.h',
-    'inc/kms++/extframebuffer.h',
-    'inc/kms++/pipeline.h',
-    'inc/kms++/drmpropobject.h',
-    'inc/kms++/mode_cvt.h',
-    'inc/kms++/blob.h',
-    'inc/kms++/dumbframebuffer.h',
-]
-
-public_headers_omap = [
-    'inc/kms++/omap/omapframebuffer.h',
-    'inc/kms++/omap/omapkms++.h',
-    'inc/kms++/omap/omapcard.h',
-]
-
-private_includes = include_directories('src', 'inc')
-public_includes = include_directories('inc')
-
-libdrm_dep = dependency('libdrm')
-
-if libdrmomap_dep.found()
-    libkmsxx_sources += files([
-        'src/omap/omapcard.cpp',
-        'src/omap/omapframebuffer.cpp',
-    ])
-endif
-
-libkmsxx_deps = [ libdrm_dep, libfmt_dep, libdrmomap_dep ]
-
-libkmsxx = library('kms++',
-                   libkmsxx_sources,
-                   install : true,
-                   include_directories : private_includes,
-                   dependencies : libkmsxx_deps)
-
-
-libkmsxx_dep = declare_dependency(include_directories : public_includes,
-                                  link_with : libkmsxx)
-
-install_headers(public_headers, subdir : 'kms++')
-
-if libdrmomap_dep.found()
-    install_headers(public_headers_omap, subdir : 'kms++/omap')
-endif
-
-pkg = import('pkgconfig')
-pkg.generate(libkmsxx)
diff --git a/kms++/src/atomicreq.cpp b/kms++/src/atomicreq.cpp
index 1ef4f7d..28128f2 100644
--- a/kms++/src/atomicreq.cpp
+++ b/kms++/src/atomicreq.cpp
@@ -14,21 +14,10 @@
 struct _drmModeAtomicReq;
 typedef struct _drmModeAtomicReq* drmModeAtomicReqPtr;
 
-static inline drmModeAtomicReqPtr drmModeAtomicAlloc()
-{
-	return 0;
-}
-static inline void drmModeAtomicFree(drmModeAtomicReqPtr)
-{
-}
-static inline int drmModeAtomicAddProperty(drmModeAtomicReqPtr, uint32_t, uint32_t, uint64_t)
-{
-	return 0;
-}
-static inline int drmModeAtomicCommit(int, drmModeAtomicReqPtr, int, void*)
-{
-	return 0;
-}
+static inline drmModeAtomicReqPtr drmModeAtomicAlloc() { return 0; }
+static inline void drmModeAtomicFree(drmModeAtomicReqPtr) { }
+static inline int drmModeAtomicAddProperty(drmModeAtomicReqPtr, uint32_t, uint32_t, uint64_t) { return 0; }
+static inline int drmModeAtomicCommit(int, drmModeAtomicReqPtr, int, void*) { return 0; }
 
 #endif // DRM_CLIENT_CAP_ATOMIC
 
@@ -55,50 +44,45 @@
 		throw std::invalid_argument("foo");
 }
 
-void AtomicReq::add(DrmPropObject* ob, Property* prop, uint64_t value)
+void AtomicReq::add(DrmPropObject* ob, Property *prop, uint64_t value)
 {
 	add(ob->id(), prop->id(), value);
 }
 
 void AtomicReq::add(kms::DrmPropObject* ob, const string& prop, uint64_t value)
 {
-	Property* p = ob->get_prop(prop);
-
-	if (!p)
-		throw runtime_error("Property not found");
-
-	add(ob, p, value);
+	add(ob, ob->get_prop(prop), value);
 }
 
 void AtomicReq::add(kms::DrmPropObject* ob, const map<string, uint64_t>& values)
 {
-	for (const auto& kvp : values)
+	for(const auto& kvp : values)
 		add(ob, kvp.first, kvp.second);
 }
 
 void AtomicReq::add_display(Connector* conn, Crtc* crtc, Blob* videomode, Plane* primary, Framebuffer* fb)
 {
 	add(conn, {
-			  { "CRTC_ID", crtc->id() },
-		  });
+		    { "CRTC_ID", crtc->id() },
+	    });
 
 	add(crtc, {
-			  { "ACTIVE", 1 },
-			  { "MODE_ID", videomode->id() },
-		  });
+		    { "ACTIVE", 1 },
+		    { "MODE_ID", videomode->id() },
+	    });
 
 	add(primary, {
-			     { "FB_ID", fb->id() },
-			     { "CRTC_ID", crtc->id() },
-			     { "SRC_X", 0 << 16 },
-			     { "SRC_Y", 0 << 16 },
-			     { "SRC_W", fb->width() << 16 },
-			     { "SRC_H", fb->height() << 16 },
-			     { "CRTC_X", 0 },
-			     { "CRTC_Y", 0 },
-			     { "CRTC_W", fb->width() },
-			     { "CRTC_H", fb->height() },
-		     });
+		    { "FB_ID", fb->id() },
+		    { "CRTC_ID", crtc->id() },
+		    { "SRC_X", 0 << 16 },
+		    { "SRC_Y", 0 << 16 },
+		    { "SRC_W", fb->width() << 16 },
+		    { "SRC_H", fb->height() << 16 },
+		    { "CRTC_X", 0 },
+		    { "CRTC_Y", 0 },
+		    { "CRTC_W", fb->width() },
+		    { "CRTC_H", fb->height() },
+	    });
 }
 
 int AtomicReq::test(bool allow_modeset)
@@ -130,4 +114,4 @@
 
 	return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0);
 }
-} // namespace kms
+}
diff --git a/kms++/src/blob.cpp b/kms++/src/blob.cpp
index 431863a..e1cd1f8 100644
--- a/kms++/src/blob.cpp
+++ b/kms++/src/blob.cpp
@@ -7,6 +7,7 @@
 
 namespace kms
 {
+
 Blob::Blob(Card& card, uint32_t blob_id)
 	: DrmObject(card, blob_id, DRM_MODE_OBJECT_BLOB), m_created(false)
 {
@@ -47,4 +48,4 @@
 	return v;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/card.cpp b/kms++/src/card.cpp
index 935969d..8de8b82 100644
--- a/kms++/src/card.cpp
+++ b/kms++/src/card.cpp
@@ -1,18 +1,14 @@
-#include <cstdio>
+#include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <utility>
 #include <stdexcept>
-#include <cstring>
+#include <string.h>
 #include <algorithm>
 #include <cerrno>
 #include <algorithm>
 #include <glob.h>
 
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
@@ -22,19 +18,20 @@
 
 namespace kms
 {
+
 static vector<string> glob(const string& pattern)
 {
 	glob_t glob_result;
 	memset(&glob_result, 0, sizeof(glob_result));
 
 	int r = glob(pattern.c_str(), 0, NULL, &glob_result);
-	if (r != 0) {
+	if(r != 0) {
 		globfree(&glob_result);
 		throw runtime_error("failed to find DRM cards");
 	}
 
 	vector<string> filenames;
-	for (size_t i = 0; i < glob_result.gl_pathc; ++i)
+	for(size_t i = 0; i < glob_result.gl_pathc; ++i)
 		filenames.push_back(string(glob_result.gl_pathv[i]));
 
 	globfree(&glob_result);
@@ -107,16 +104,6 @@
 	throw invalid_argument("Failed to find a DRM device " + name + ":" + to_string(idx));
 }
 
-std::unique_ptr<Card> Card::open_named_card(const std::string& name)
-{
-	int fd = drmOpen(name.c_str(), 0);
-
-	if (fd < 0)
-		throw invalid_argument(string(strerror(errno)) + " opening card \"" + name + "\"");
-
-	return std::unique_ptr<Card>(new Card(fd, true));
-}
-
 Card::Card(const std::string& dev_path)
 {
 	const char* drv_p = getenv("KMSXX_DRIVER");
@@ -161,40 +148,19 @@
 	setup();
 }
 
-Card::Card(int fd, bool take_ownership)
-{
-	if (take_ownership) {
-		m_fd = fd;
-	} else {
-		m_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-
-		if (m_fd < 0)
-			throw invalid_argument(string(strerror(errno)) + " duplicating fd");
-	}
-
-	setup();
-}
-
 void Card::setup()
 {
 	drmVersionPtr ver = drmGetVersion(m_fd);
-	m_version.major = ver->version_major;
-	m_version.minor = ver->version_minor;
-	m_version.patchlevel = ver->version_patchlevel;
-	m_version.name = string(ver->name, ver->name_len);
-	m_version.date = string(ver->date, ver->date_len);
-	m_version.desc = string(ver->desc, ver->desc_len);
+	m_version_major = ver->version_major;
+	m_version_minor = ver->version_minor;
+	m_version_patchlevel = ver->version_patchlevel;
+	m_version_name = string(ver->name, ver->name_len);
+	m_version_date = string(ver->date, ver->date_len);
+	m_version_desc = string(ver->desc, ver->desc_len);
 	drmFreeVersion(ver);
 
-	struct stat stats;
 	int r;
 
-	r = fstat(m_fd, &stats);
-	if (r < 0)
-		throw invalid_argument("Can't stat device (" + string(strerror(errno)) + ")");
-
-	m_minor = minor(stats.st_dev);
-
 	r = drmSetMaster(m_fd);
 	m_is_master = r == 0;
 
@@ -314,7 +280,7 @@
 
 Connector* Card::get_first_connected_connector() const
 {
-	for (auto c : m_connectors) {
+	for(auto c : m_connectors) {
 		if (c->connected())
 			return c;
 	}
@@ -330,40 +296,26 @@
 	return nullptr;
 }
 
-std::vector<kms::DrmObject*> Card::get_objects() const
+const vector<DrmObject*> Card::get_objects() const
 {
 	vector<DrmObject*> v;
-	for (auto pair : m_obmap)
+	for(auto pair : m_obmap)
 		v.push_back(pair.second);
 	return v;
 }
 
-Connector* Card::get_connector(uint32_t id) const
-{
-	return dynamic_cast<Connector*>(get_object(id));
-}
-Crtc* Card::get_crtc(uint32_t id) const
-{
-	return dynamic_cast<Crtc*>(get_object(id));
-}
-Encoder* Card::get_encoder(uint32_t id) const
-{
-	return dynamic_cast<Encoder*>(get_object(id));
-}
-Property* Card::get_prop(uint32_t id) const
-{
-	return dynamic_cast<Property*>(get_object(id));
-}
-Plane* Card::get_plane(uint32_t id) const
-{
-	return dynamic_cast<Plane*>(get_object(id));
-}
+Connector* Card::get_connector(uint32_t id) const { return dynamic_cast<Connector*>(get_object(id)); }
+Crtc* Card::get_crtc(uint32_t id) const { return dynamic_cast<Crtc*>(get_object(id)); }
+Encoder* Card::get_encoder(uint32_t id) const { return dynamic_cast<Encoder*>(get_object(id)); }
+Property* Card::get_prop(uint32_t id) const { return dynamic_cast<Property*>(get_object(id)); }
+Plane* Card::get_plane(uint32_t id) const { return dynamic_cast<Plane*>(get_object(id)); }
 
 std::vector<kms::Pipeline> Card::get_connected_pipelines()
 {
 	vector<Pipeline> outputs;
 
-	for (auto conn : get_connectors()) {
+	for (auto conn : get_connectors())
+	{
 		if (conn->connected() == false)
 			continue;
 
@@ -383,7 +335,7 @@
 					       to_string(conn->idx()) +
 					       " has no possible crtcs");
 
-		outputs.push_back(Pipeline{ crtc, conn });
+		outputs.push_back(Pipeline { crtc, conn });
 	}
 
 	return outputs;
@@ -391,7 +343,7 @@
 
 static void page_flip_handler(int fd, unsigned int frame,
 			      unsigned int sec, unsigned int usec,
-			      void* data)
+			      void *data)
 {
 	auto handler = (PageFlipHandlerBase*)data;
 	double time = sec + usec / 1000000.0;
@@ -400,7 +352,7 @@
 
 void Card::call_page_flip_handlers()
 {
-	drmEventContext ev{};
+	drmEventContext ev { };
 	ev.version = DRM_EVENT_CONTEXT_VERSION;
 	ev.page_flip_handler = page_flip_handler;
 
@@ -413,18 +365,18 @@
 
 	for (Crtc* c : m_crtcs) {
 		req.add(c, {
-				   { "ACTIVE", 0 },
-			   });
+				{ "ACTIVE", 0 },
+			});
 	}
 
 	for (Plane* p : m_planes) {
 		req.add(p, {
-				   { "FB_ID", 0 },
-				   { "CRTC_ID", 0 },
-			   });
+				{ "FB_ID", 0 },
+				{ "CRTC_ID", 0 },
+			});
 	}
 
 	return req.commit_sync(true);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/connector.cpp b/kms++/src/connector.cpp
index 92bab80..a1807da 100644
--- a/kms++/src/connector.cpp
+++ b/kms++/src/connector.cpp
@@ -1,4 +1,4 @@
-#include <cstdio>
+#include <stdio.h>
 #include <iostream>
 #include <unistd.h>
 #include <fcntl.h>
@@ -12,6 +12,7 @@
 
 namespace kms
 {
+
 #ifndef DRM_MODE_CONNECTOR_DPI
 #define DRM_MODE_CONNECTOR_DPI 17
 #endif
@@ -45,10 +46,7 @@
 };
 
 static const map<int, string> subpix_str = {
-#define DEF_SUBPIX(c)                     \
-	{                                 \
-		DRM_MODE_SUBPIXEL_##c, #c \
-	}
+#define DEF_SUBPIX(c) { DRM_MODE_SUBPIXEL_##c, #c }
 	DEF_SUBPIX(UNKNOWN),
 	DEF_SUBPIX(HORIZONTAL_RGB),
 	DEF_SUBPIX(HORIZONTAL_BGR),
@@ -58,12 +56,13 @@
 #undef DEF_SUBPIX
 };
 
-struct ConnectorPriv {
+struct ConnectorPriv
+{
 	drmModeConnectorPtr drm_connector;
 };
 
-Connector::Connector(Card& card, uint32_t id, uint32_t idx)
-	: DrmPropObject(card, id, DRM_MODE_OBJECT_CONNECTOR, idx)
+Connector::Connector(Card &card, uint32_t id, uint32_t idx)
+	:DrmPropObject(card, id, DRM_MODE_OBJECT_CONNECTOR, idx)
 {
 	m_priv = new ConnectorPriv();
 
@@ -121,8 +120,7 @@
 Videomode Connector::get_default_mode() const
 {
 	if (m_priv->drm_connector->count_modes == 0)
-		return Videomode();
-
+		throw invalid_argument("no modes available\n");
 	drmModeModeInfo drmmode = m_priv->drm_connector->modes[0];
 
 	return drm_mode_to_video_mode(drmmode);
@@ -194,7 +192,7 @@
 bool Connector::connected() const
 {
 	return m_priv->drm_connector->connection == DRM_MODE_CONNECTED ||
-	       m_priv->drm_connector->connection == DRM_MODE_UNKNOWNCONNECTION;
+			m_priv->drm_connector->connection == DRM_MODE_UNKNOWNCONNECTION;
 }
 
 ConnectorStatus Connector::connector_status() const
@@ -268,7 +266,7 @@
 
 	for (int i = 0; i < m_priv->drm_connector->count_modes; i++)
 		modes.push_back(drm_mode_to_video_mode(
-			m_priv->drm_connector->modes[i]));
+					m_priv->drm_connector->modes[i]));
 
 	return modes;
 }
@@ -284,4 +282,4 @@
 	return encoders;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/crtc.cpp b/kms++/src/crtc.cpp
index 1c1888f..f94216f 100644
--- a/kms++/src/crtc.cpp
+++ b/kms++/src/crtc.cpp
@@ -1,4 +1,4 @@
-#include <cstdio>
+#include <stdio.h>
 #include <iostream>
 #include <unistd.h>
 #include <fcntl.h>
@@ -11,12 +11,14 @@
 
 namespace kms
 {
-struct CrtcPriv {
+
+struct CrtcPriv
+{
 	drmModeCrtcPtr drm_crtc;
 };
 
-Crtc::Crtc(Card& card, uint32_t id, uint32_t idx)
-	: DrmPropObject(card, id, DRM_MODE_OBJECT_CRTC, idx)
+Crtc::Crtc(Card &card, uint32_t id, uint32_t idx)
+	:DrmPropObject(card, id, DRM_MODE_OBJECT_CRTC, idx)
 {
 	m_priv = new CrtcPriv();
 	m_priv->drm_crtc = drmModeGetCrtc(this->card().fd(), this->id());
@@ -63,13 +65,13 @@
 	unique_ptr<Blob> blob = mode.to_blob(card());
 
 	req.add(conn, {
-			      { "CRTC_ID", this->id() },
-		      });
+			{ "CRTC_ID", this->id() },
+		});
 
 	req.add(this, {
-			      { "ACTIVE", 1 },
-			      { "MODE_ID", blob->id() },
-		      });
+			{ "ACTIVE", 1 },
+			{ "MODE_ID", blob->id() },
+		});
 
 	int r = req.commit_sync(true);
 
@@ -115,7 +117,7 @@
 
 Plane* Crtc::get_primary_plane()
 {
-	Plane* primary = nullptr;
+	Plane *primary = nullptr;
 
 	for (Plane* p : get_possible_planes()) {
 		if (p->plane_type() != PlaneType::Primary)
@@ -133,7 +135,7 @@
 	throw invalid_argument(string("No primary plane for crtc ") + to_string(id()));
 }
 
-int Crtc::page_flip(Framebuffer& fb, void* data)
+int Crtc::page_flip(Framebuffer& fb, void *data)
 {
 	return drmModePageFlip(card().fd(), id(), fb.id(), DRM_MODE_PAGE_FLIP_EVENT, data);
 }
@@ -173,25 +175,9 @@
 	return drm_mode_to_video_mode(m_priv->drm_crtc->mode);
 }
 
-int Crtc::legacy_gamma_size() const
+int Crtc::gamma_size() const
 {
 	return m_priv->drm_crtc->gamma_size;
 }
 
-void Crtc::legacy_gamma_set(vector<tuple<uint16_t, uint16_t, uint16_t>> v)
-{
-	uint32_t len = v.size();
-	uint16_t red[len];
-	uint16_t green[len];
-	uint16_t blue[len];
-
-	for (uint32_t i = 0; i < len; ++i) {
-		red[i] = get<0>(v[i]);
-		green[i] = get<1>(v[i]);
-		blue[i] = get<2>(v[i]);
-	}
-
-	drmModeCrtcSetGamma(card().fd(), id(), len, red, green, blue);
 }
-
-} // namespace kms
diff --git a/kms++/src/dmabufframebuffer.cpp b/kms++/src/dmabufframebuffer.cpp
deleted file mode 100644
index cb76f09..0000000
--- a/kms++/src/dmabufframebuffer.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-
-#include <cstring>
-#include <cerrno>
-
-#include <stdexcept>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <linux/dma-buf.h>
-
-#include <kms++/kms++.h>
-
-using namespace std;
-
-namespace kms
-{
-DmabufFramebuffer::DmabufFramebuffer(Card& card, uint32_t width, uint32_t height, const string& format,
-				     vector<int> fds, vector<uint32_t> pitches, vector<uint32_t> offsets, vector<uint64_t> modifiers)
-	: DmabufFramebuffer(card, width, height, FourCCToPixelFormat(format), fds, pitches, offsets, modifiers)
-{
-}
-
-DmabufFramebuffer::DmabufFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
-				     vector<int> fds, vector<uint32_t> pitches, vector<uint32_t> offsets, vector<uint64_t> modifiers)
-	: Framebuffer(card, width, height)
-{
-	int r;
-
-	m_format = format;
-
-	const PixelFormatInfo& format_info = get_pixel_format_info(format);
-
-	m_num_planes = format_info.num_planes;
-
-	if (fds.size() != m_num_planes || pitches.size() != m_num_planes || offsets.size() != m_num_planes)
-		throw std::invalid_argument("the size of fds, pitches and offsets has to match number of planes");
-
-	for (int i = 0; i < format_info.num_planes; ++i) {
-		FramebufferPlane& plane = m_planes.at(i);
-
-		plane.prime_fd = fds[i];
-
-		r = drmPrimeFDToHandle(card.fd(), fds[i], &plane.handle);
-		if (r)
-			throw invalid_argument(string("drmPrimeFDToHandle: ") + strerror(errno));
-
-		plane.stride = pitches[i];
-		plane.offset = offsets[i];
-		plane.modifier = modifiers.empty() ? 0 : modifiers[i];
-		plane.size = plane.stride * height;
-		plane.map = 0;
-	}
-
-	uint32_t id;
-	uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle, m_planes[2].handle, m_planes[3].handle };
-	pitches.resize(4);
-	offsets.resize(4);
-
-	if (modifiers.empty()) {
-		r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format,
-				  bo_handles, pitches.data(), offsets.data(), &id, 0);
-		if (r)
-			throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
-	} else {
-		modifiers.resize(4);
-		r = drmModeAddFB2WithModifiers(card.fd(), width, height, (uint32_t)format,
-					       bo_handles, pitches.data(), offsets.data(), modifiers.data(), &id, DRM_MODE_FB_MODIFIERS);
-		if (r)
-			throw invalid_argument(string("drmModeAddFB2WithModifiers failed: ") + strerror(errno));
-	}
-
-	set_id(id);
-}
-
-DmabufFramebuffer::~DmabufFramebuffer()
-{
-	drmModeRmFB(card().fd(), id());
-}
-
-uint8_t* DmabufFramebuffer::map(unsigned plane)
-{
-	FramebufferPlane& p = m_planes.at(plane);
-
-	if (p.map)
-		return p.map;
-
-	p.map = (uint8_t*)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
-			       p.prime_fd, 0);
-	if (p.map == MAP_FAILED)
-		throw invalid_argument(string("mmap failed: ") + strerror(errno));
-
-	return p.map;
-}
-
-int DmabufFramebuffer::prime_fd(unsigned plane)
-{
-	FramebufferPlane& p = m_planes.at(plane);
-
-	return p.prime_fd;
-}
-
-void DmabufFramebuffer::begin_cpu_access(CpuAccess access)
-{
-	if (m_sync_flags != 0)
-		throw runtime_error("begin_cpu sync already started");
-
-	switch (access) {
-	case CpuAccess::Read:
-		m_sync_flags = DMA_BUF_SYNC_READ;
-		break;
-	case CpuAccess::Write:
-		m_sync_flags = DMA_BUF_SYNC_WRITE;
-		break;
-	case CpuAccess::ReadWrite:
-		m_sync_flags = DMA_BUF_SYNC_RW;
-		break;
-	}
-
-	dma_buf_sync dbs{
-		.flags = DMA_BUF_SYNC_START | m_sync_flags
-	};
-
-	for (uint32_t p = 0; p < m_num_planes; ++p) {
-		int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs);
-		if (r)
-			throw runtime_error("DMA_BUF_IOCTL_SYNC failed");
-	}
-}
-
-void DmabufFramebuffer::end_cpu_access()
-{
-	if (m_sync_flags == 0)
-		throw runtime_error("begin_cpu sync not started");
-
-	dma_buf_sync dbs{
-		.flags = DMA_BUF_SYNC_END | m_sync_flags
-	};
-
-	for (uint32_t p = 0; p < m_num_planes; ++p) {
-		int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs);
-		if (r)
-			throw runtime_error("DMA_BUF_IOCTL_SYNC failed");
-	}
-
-	m_sync_flags = 0;
-}
-
-} // namespace kms
diff --git a/kms++/src/drmobject.cpp b/kms++/src/drmobject.cpp
index f01c8af..f94fc5d 100644
--- a/kms++/src/drmobject.cpp
+++ b/kms++/src/drmobject.cpp
@@ -1,4 +1,4 @@
-#include <cstring>
+#include <string.h>
 #include <iostream>
 #include <stdexcept>
 
@@ -11,22 +11,24 @@
 
 namespace kms
 {
+
 DrmObject::DrmObject(Card& card, uint32_t object_type)
-	: m_card(card), m_id(-1), m_object_type(object_type), m_idx(0)
+	:m_card(card), m_id(-1), m_object_type(object_type), m_idx(0)
 {
 }
 
 DrmObject::DrmObject(Card& card, uint32_t id, uint32_t object_type, uint32_t idx)
-	: m_card(card), m_id(id), m_object_type(object_type), m_idx(idx)
+	:m_card(card), m_id(id), m_object_type(object_type), m_idx(idx)
 {
 }
 
 DrmObject::~DrmObject()
 {
+
 }
 
 void DrmObject::set_id(uint32_t id)
 {
 	m_id = id;
 }
-} // namespace kms
+}
diff --git a/kms++/src/drmpropobject.cpp b/kms++/src/drmpropobject.cpp
index 616aef7..f91f913 100644
--- a/kms++/src/drmpropobject.cpp
+++ b/kms++/src/drmpropobject.cpp
@@ -1,4 +1,4 @@
-#include <cstring>
+#include <string.h>
 #include <iostream>
 #include <stdexcept>
 
@@ -11,6 +11,7 @@
 
 namespace kms
 {
+
 DrmPropObject::DrmPropObject(Card& card, uint32_t object_type)
 	: DrmObject(card, object_type)
 {
@@ -24,6 +25,7 @@
 
 DrmPropObject::~DrmPropObject()
 {
+
 }
 
 void DrmPropObject::refresh_props()
@@ -52,7 +54,7 @@
 			return prop;
 	}
 
-	return nullptr;
+	throw invalid_argument(string("property ") + name + " not found");
 }
 
 uint64_t DrmPropObject::get_prop_value(uint32_t id) const
@@ -88,7 +90,7 @@
 	return drmModeObjectSetProperty(card().fd(), this->id(), this->object_type(), id, value);
 }
 
-int DrmPropObject::set_prop_value(const string& name, uint64_t value)
+int DrmPropObject::set_prop_value(const string &name, uint64_t value)
 {
 	Property* prop = get_prop(name);
 
@@ -98,4 +100,4 @@
 	return set_prop_value(prop->id(), value);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/dumbframebuffer.cpp b/kms++/src/dumbframebuffer.cpp
index fc50586..4419687 100644
--- a/kms++/src/dumbframebuffer.cpp
+++ b/kms++/src/dumbframebuffer.cpp
@@ -19,13 +19,24 @@
 
 namespace kms
 {
-DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, const string& fourcc)
-	: DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc))
+
+DumbFramebuffer::DumbFramebuffer(Card &card, uint32_t width, uint32_t height, const string& fourcc)
+	:DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc))
 {
 }
 
 DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format)
-	: Framebuffer(card, width, height), m_format(format)
+	:Framebuffer(card, width, height), m_format(format)
+{
+	Create();
+}
+
+DumbFramebuffer::~DumbFramebuffer()
+{
+	Destroy();
+}
+
+void DumbFramebuffer::Create()
 {
 	int r;
 
@@ -35,22 +46,14 @@
 
 	for (int i = 0; i < format_info.num_planes; ++i) {
 		const PixelFormatPlaneInfo& pi = format_info.planes[i];
-		FramebufferPlane& plane = m_planes.at(i);
+		FramebufferPlane& plane = m_planes[i];
 
 		/* create dumb buffer */
 		struct drm_mode_create_dumb creq = drm_mode_create_dumb();
-		creq.width = width;
-		creq.height = height / pi.ysub;
-		/*
-		 * For fully planar YUV buffers, the chroma planes don't combine
-		 * U and V components, their width must thus be divided by the
-		 * horizontal subsampling factor.
-		 */
-		if (format_info.type == PixelColorType::YUV &&
-		    format_info.num_planes == 3)
-			creq.width /= pi.xsub;
+		creq.width = width();
+		creq.height = height() / pi.ysub;
 		creq.bpp = pi.bitspp;
-		r = drmIoctl(card.fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq);
+		r = drmIoctl(card().fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq);
 		if (r)
 			throw invalid_argument(string("DRM_IOCTL_MODE_CREATE_DUMB failed: ") + strerror(errno));
 
@@ -63,26 +66,11 @@
 	}
 
 	/* create framebuffer object for the dumb-buffer */
-	uint32_t bo_handles[4] = {
-		m_planes[0].handle,
-		m_planes[1].handle,
-		m_planes[2].handle,
-		m_planes[3].handle,
-	};
-	uint32_t pitches[4] = {
-		m_planes[0].stride,
-		m_planes[1].stride,
-		m_planes[2].stride,
-		m_planes[3].stride,
-	};
-	uint32_t offsets[4] = {
-		m_planes[0].offset,
-		m_planes[1].offset,
-		m_planes[2].offset,
-		m_planes[3].offset,
-	};
+	uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
+	uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride };
+	uint32_t offsets[4] = {  m_planes[0].offset, m_planes[1].offset };
 	uint32_t id;
-	r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format,
+	r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
 			  bo_handles, pitches, offsets, &id, 0);
 	if (r)
 		throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
@@ -90,13 +78,13 @@
 	set_id(id);
 }
 
-DumbFramebuffer::~DumbFramebuffer()
+void DumbFramebuffer::Destroy()
 {
 	/* delete framebuffer */
 	drmModeRmFB(card().fd(), id());
 
 	for (uint i = 0; i < m_num_planes; ++i) {
-		FramebufferPlane& plane = m_planes.at(i);
+		FramebufferPlane& plane = m_planes[i];
 
 		/* unmap buffer */
 		if (plane.map)
@@ -113,7 +101,7 @@
 
 uint8_t* DumbFramebuffer::map(unsigned plane)
 {
-	FramebufferPlane& p = m_planes.at(plane);
+	FramebufferPlane& p = m_planes[plane];
 
 	if (p.map)
 		return p.map;
@@ -126,8 +114,8 @@
 		throw invalid_argument(string("DRM_IOCTL_MODE_MAP_DUMB failed: ") + strerror(errno));
 
 	/* perform actual memory mapping */
-	p.map = (uint8_t*)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
-			       card().fd(), mreq.offset);
+	p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
+					  card().fd(), mreq.offset);
 	if (p.map == MAP_FAILED)
 		throw invalid_argument(string("mmap failed: ") + strerror(errno));
 
@@ -136,15 +124,15 @@
 
 int DumbFramebuffer::prime_fd(unsigned int plane)
 {
-	if (m_planes.at(plane).prime_fd >= 0)
-		return m_planes.at(plane).prime_fd;
+	if (m_planes[plane].prime_fd >= 0)
+		return m_planes[plane].prime_fd;
 
-	int r = drmPrimeHandleToFD(card().fd(), m_planes.at(plane).handle,
-				   DRM_CLOEXEC | O_RDWR, &m_planes.at(plane).prime_fd);
+	int r = drmPrimeHandleToFD(card().fd(), m_planes[plane].handle,
+				   DRM_CLOEXEC | O_RDWR, &m_planes[plane].prime_fd);
 	if (r)
 		throw std::runtime_error("drmPrimeHandleToFD failed");
 
-	return m_planes.at(plane).prime_fd;
+	return m_planes[plane].prime_fd;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/encoder.cpp b/kms++/src/encoder.cpp
index 8144b9f..bfb2ea8 100644
--- a/kms++/src/encoder.cpp
+++ b/kms++/src/encoder.cpp
@@ -1,4 +1,4 @@
-#include <cstdio>
+#include <stdio.h>
 #include <iostream>
 #include <unistd.h>
 #include <fcntl.h>
@@ -12,15 +12,14 @@
 
 namespace kms
 {
-struct EncoderPriv {
+
+struct EncoderPriv
+{
 	drmModeEncoderPtr drm_encoder;
 };
 
 static const map<int, string> encoder_types = {
-#define DEF_ENC(c)                       \
-	{                                \
-		DRM_MODE_ENCODER_##c, #c \
-	}
+#define DEF_ENC(c) { DRM_MODE_ENCODER_##c, #c }
 	DEF_ENC(NONE),
 	DEF_ENC(DAC),
 	DEF_ENC(TMDS),
@@ -33,8 +32,8 @@
 #undef DEF_ENC
 };
 
-Encoder::Encoder(Card& card, uint32_t id, uint32_t idx)
-	: DrmPropObject(card, id, DRM_MODE_OBJECT_ENCODER, idx)
+Encoder::Encoder(Card &card, uint32_t id, uint32_t idx)
+	:DrmPropObject(card, id, DRM_MODE_OBJECT_ENCODER, idx)
 {
 	m_priv = new EncoderPriv();
 	m_priv->drm_encoder = drmModeGetEncoder(this->card().fd(), this->id());
@@ -84,4 +83,4 @@
 	return encoder_types.at(m_priv->drm_encoder->encoder_type);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/extframebuffer.cpp b/kms++/src/extframebuffer.cpp
index 78b6fbb..12e59b7 100644
--- a/kms++/src/extframebuffer.cpp
+++ b/kms++/src/extframebuffer.cpp
@@ -13,8 +13,9 @@
 
 namespace kms
 {
+
 ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
-			       vector<uint32_t> handles, vector<uint32_t> pitches, vector<uint32_t> offsets, vector<uint64_t> modifiers)
+			       vector<uint32_t> handles, vector<uint32_t> pitches, vector<uint32_t> offsets)
 	: Framebuffer(card, width, height)
 {
 	m_format = format;
@@ -23,42 +24,94 @@
 
 	m_num_planes = format_info.num_planes;
 
-	if (handles.size() != m_num_planes || pitches.size() != m_num_planes || offsets.size() != m_num_planes)
-		throw std::invalid_argument("the size of handles, pitches and offsets has to match number of planes");
-
 	for (int i = 0; i < format_info.num_planes; ++i) {
-		FramebufferPlane& plane = m_planes.at(i);
+		FramebufferPlane& plane = m_planes[i];
 
 		plane.handle = handles[i];
+		plane.prime_fd = 0;
+
 		plane.stride = pitches[i];
 		plane.offset = offsets[i];
-		plane.modifier = modifiers.empty() ? 0 : modifiers[i];
 		plane.size = plane.stride * height;
 		plane.map = 0;
 	}
 
 	uint32_t id;
-	handles.resize(4);
-	pitches.resize(4);
-	offsets.resize(4);
-	int r;
-
-	if (modifiers.empty()) {
-		r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, handles.data(), pitches.data(), offsets.data(), &id, 0);
-	} else {
-		modifiers.resize(4);
-		r = drmModeAddFB2WithModifiers(card.fd(), width, height, (uint32_t)format, handles.data(), pitches.data(), offsets.data(), modifiers.data(), &id, DRM_MODE_FB_MODIFIERS);
-	}
-
+	int r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, handles.data(), pitches.data(), offsets.data(), &id, 0);
 	if (r)
 		throw std::invalid_argument(string("Failed to create ExtFramebuffer: ") + strerror(r));
 
 	set_id(id);
 }
 
+ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
+			       vector<int> fds, vector<uint32_t> pitches, vector<uint32_t> offsets)
+	: Framebuffer(card, width, height)
+{
+	int r;
+
+	m_format = format;
+
+	const PixelFormatInfo& format_info = get_pixel_format_info(format);
+
+	m_num_planes = format_info.num_planes;
+
+	for (int i = 0; i < format_info.num_planes; ++i) {
+		FramebufferPlane& plane = m_planes[i];
+
+		plane.prime_fd = fds[i];
+
+		r = drmPrimeFDToHandle(card.fd(), fds[i], &plane.handle);
+		if (r)
+			throw invalid_argument(string("drmPrimeFDToHandle: ") + strerror(errno));
+
+		plane.stride = pitches[i];
+		plane.offset = offsets[i];
+		plane.size = plane.stride * height;
+		plane.map = 0;
+	}
+
+	uint32_t id;
+	uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
+	r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format,
+			  bo_handles, pitches.data(), offsets.data(), &id, 0);
+	if (r)
+		throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
+
+	set_id(id);
+}
+
 ExtFramebuffer::~ExtFramebuffer()
 {
 	drmModeRmFB(card().fd(), id());
 }
 
-} // namespace kms
+uint8_t* ExtFramebuffer::map(unsigned plane)
+{
+	FramebufferPlane& p = m_planes[plane];
+
+	if (!p.prime_fd)
+		throw invalid_argument("cannot mmap non-dmabuf fb");
+
+	if (p.map)
+		return p.map;
+
+	p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
+					  p.prime_fd, 0);
+	if (p.map == MAP_FAILED)
+		throw invalid_argument(string("mmap failed: ") + strerror(errno));
+
+	return p.map;
+}
+
+int ExtFramebuffer::prime_fd(unsigned plane)
+{
+	FramebufferPlane& p = m_planes[plane];
+
+	if (!p.prime_fd)
+		throw invalid_argument("no primefb for non-dmabuf fb");
+
+	return p.prime_fd;
+}
+
+}
diff --git a/kms++/src/framebuffer.cpp b/kms++/src/framebuffer.cpp
index f1cba3b..39c4e16 100644
--- a/kms++/src/framebuffer.cpp
+++ b/kms++/src/framebuffer.cpp
@@ -11,6 +11,7 @@
 
 namespace kms
 {
+
 Framebuffer::Framebuffer(Card& card, uint32_t width, uint32_t height)
 	: DrmObject(card, DRM_MODE_OBJECT_FB), m_width(width), m_height(height)
 {
@@ -36,7 +37,7 @@
 
 void Framebuffer::flush()
 {
-	drmModeClip clip{};
+	drmModeClip clip { };
 	clip.x1 = clip.y1 = 0;
 	clip.x2 = width();
 	clip.y2 = height();
@@ -51,4 +52,5 @@
 	card().m_framebuffers.erase(iter);
 }
 
-} // namespace kms
+
+}
diff --git a/kms++/src/helpers.cpp b/kms++/src/helpers.cpp
index 9079a23..8bd082b 100644
--- a/kms++/src/helpers.cpp
+++ b/kms++/src/helpers.cpp
@@ -9,7 +9,7 @@
 {
 Videomode drm_mode_to_video_mode(const drmModeModeInfo& drmmode)
 {
-	Videomode mode = {};
+	Videomode mode = { };
 
 	auto& src = drmmode;
 	auto& dst = mode;
@@ -40,7 +40,7 @@
 
 drmModeModeInfo video_mode_to_drm_mode(const Videomode& mode)
 {
-	drmModeModeInfo drmmode = {};
+	drmModeModeInfo drmmode = { };
 
 	auto& src = mode;
 	auto& dst = drmmode;
@@ -69,4 +69,4 @@
 
 	return drmmode;
 }
-} // namespace kms
+}
diff --git a/kms++/src/helpers.h b/kms++/src/helpers.h
index 58926bf..4eb597c 100644
--- a/kms++/src/helpers.h
+++ b/kms++/src/helpers.h
@@ -9,4 +9,4 @@
 
 Videomode drm_mode_to_video_mode(const drmModeModeInfo& drmmode);
 drmModeModeInfo video_mode_to_drm_mode(const Videomode& mode);
-} // namespace kms
+}
diff --git a/kms++/src/mode_cvt.cpp b/kms++/src/mode_cvt.cpp
index a7a10b8..41503c7 100644
--- a/kms++/src/mode_cvt.cpp
+++ b/kms++/src/mode_cvt.cpp
@@ -7,10 +7,12 @@
 
 namespace kms
 {
+
 static float CELL_GRAN = 8;
 static float CELL_GRAN_RND = round(CELL_GRAN);
 
-struct CVTConsts {
+struct CVTConsts
+{
 	float CLOCK_STEP;
 	float MIN_V_BPORCH;
 	float RB_H_BLANK;
@@ -22,28 +24,30 @@
 	float REFRESH_MULTIPLIER;
 };
 
-static const CVTConsts cvt_consts_v1 = {
-	.CLOCK_STEP = 0.25, // Fixed
-	.MIN_V_BPORCH = 6, // Min
-	.RB_H_BLANK = 160, // Fixed
-	.RB_H_FPORCH = 48, // Fixed
-	.RB_H_SYNC = 32, // Fixed
-	.RB_H_BPORCH = 80, // Fixed
-	.RB_MIN_V_BLANK = 460, // Min
-	.RB_V_FPORCH = 3, // Fixed
-	.REFRESH_MULTIPLIER = 1, // Fixed
+static const CVTConsts cvt_consts_v1 =
+{
+	.CLOCK_STEP = 0.25,	// Fixed
+	.MIN_V_BPORCH = 6,	// Min
+	.RB_H_BLANK = 160,	// Fixed
+	.RB_H_FPORCH = 48,	// Fixed
+	.RB_H_SYNC = 32,	// Fixed
+	.RB_H_BPORCH = 80,	// Fixed
+	.RB_MIN_V_BLANK = 460,	// Min
+	.RB_V_FPORCH = 3,	// Fixed
+	.REFRESH_MULTIPLIER = 1,// Fixed
 };
 
-static const CVTConsts cvt_consts_v2 = {
-	.CLOCK_STEP = 0.001, // Fixed
-	.MIN_V_BPORCH = 6, // Fixed
-	.RB_H_BLANK = 80, // Fixed
-	.RB_H_FPORCH = 8, // Fixed
-	.RB_H_SYNC = 32, // Fixed
-	.RB_H_BPORCH = 40, // Fixed
-	.RB_MIN_V_BLANK = 460, // Min
-	.RB_V_FPORCH = 1, // Min
-	.REFRESH_MULTIPLIER = 1, // or 1000/1001
+static const CVTConsts cvt_consts_v2 =
+{
+	.CLOCK_STEP = 0.001,	// Fixed
+	.MIN_V_BPORCH = 6,	// Fixed
+	.RB_H_BLANK = 80,	// Fixed
+	.RB_H_FPORCH = 8,	// Fixed
+	.RB_H_SYNC = 32,	// Fixed
+	.RB_H_BPORCH = 40,	// Fixed
+	.RB_MIN_V_BLANK = 460,	// Min
+	.RB_V_FPORCH = 1,	// Min
+	.REFRESH_MULTIPLIER = 1,// or 1000/1001
 };
 
 Videomode videomode_from_cvt(uint32_t hact, uint32_t vact, uint32_t refresh, bool ilace, bool reduced_v2, bool video_optimized)
@@ -51,7 +55,7 @@
 	CVTConsts c = reduced_v2 ? cvt_consts_v2 : cvt_consts_v1;
 
 	if (video_optimized)
-		c.REFRESH_MULTIPLIER = 1000.0 / 1001.0;
+		c.REFRESH_MULTIPLIER = 1000.0/1001.0;
 
 	bool INT_RQD = ilace;
 
@@ -147,4 +151,4 @@
 	return mode;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/modedb.cpp b/kms++/src/modedb.cpp
index 081100a..5d5d373 100644
--- a/kms++/src/modedb.cpp
+++ b/kms++/src/modedb.cpp
@@ -8,6 +8,7 @@
 
 namespace kms
 {
+
 static const Videomode& find_from_table(const Videomode* modes, uint32_t width, uint32_t height, float vrefresh, bool ilace)
 {
 	for (unsigned i = 0; modes[i].clock; ++i) {
@@ -55,4 +56,4 @@
 	return find_from_table(cea_modes, width, height, vrefresh, ilace);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/modedb_cea.cpp b/kms++/src/modedb_cea.cpp
index b09472f..a99a612 100644
--- a/kms++/src/modedb_cea.cpp
+++ b/kms++/src/modedb_cea.cpp
@@ -35,13 +35,14 @@
 
 namespace kms
 {
+
 #define DIV_ROUND(n, d) (((n) + (d) / 2) / (d))
 
-#define DRM_MODE(nm, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f)                             \
-	.name = nm, .clock = (c),                                                                   \
+#define DRM_MODE(nm, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
+	.name = nm, .clock = (c), \
 	.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), .htotal = (ht), .hskew = (hsk), \
-	.vdisplay = (vd), .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), .vscan = (vs),  \
-	.vrefresh = DIV_ROUND(c * 1000, ht * vt) * (((f)&DRM_MODE_FLAG_INTERLACE) ? 2 : 1),         \
+	.vdisplay = (vd), .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), .vscan = (vs), \
+	.vrefresh = DIV_ROUND(c * 1000, ht * vt) * (((f) & DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \
 	.flags = (f), .type = 0
 
 /*
@@ -50,416 +51,352 @@
  */
 const Videomode cea_modes[] = {
 	/* 1 - 640x480@60Hz */
-	{
-		DRM_MODE("640x480", 25175, 640, 656,
-			 752, 800, 0, 480, 490, 492, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("640x480", 25175, 640, 656,
+	  752, 800, 0, 480, 490, 492, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 2 - 720x480@60Hz */
-	{
-		DRM_MODE("720x480", 27000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 27000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 3 - 720x480@60Hz */
-	{
-		DRM_MODE("720x480", 27000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 27000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 4 - 1280x720@60Hz */
-	{
-		DRM_MODE("1280x720", 74250, 1280, 1390,
-			 1430, 1650, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 74250, 1280, 1390,
+	  1430, 1650, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 5 - 1920x1080i@60Hz */
-	{
-		DRM_MODE("1920x1080i", 74250, 1920, 2008,
-			 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("1920x1080i", 74250, 1920, 2008,
+	  2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 6 - 720(1440)x480i@60Hz */
-	{
-		DRM_MODE("720x480i", 13500, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 13500, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 7 - 720(1440)x480i@60Hz */
-	{
-		DRM_MODE("720x480i", 13500, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 13500, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 8 - 720(1440)x240@60Hz */
-	{
-		DRM_MODE("720x240", 13500, 720, 739,
-			 801, 858, 0, 240, 244, 247, 262, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x240", 13500, 720, 739,
+	  801, 858, 0, 240, 244, 247, 262, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 9 - 720(1440)x240@60Hz */
-	{
-		DRM_MODE("720x240", 13500, 720, 739,
-			 801, 858, 0, 240, 244, 247, 262, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x240", 13500, 720, 739,
+	  801, 858, 0, 240, 244, 247, 262, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 10 - 2880x480i@60Hz */
-	{
-		DRM_MODE("2880x480i", 54000, 2880, 2956,
-			 3204, 3432, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("2880x480i", 54000, 2880, 2956,
+	  3204, 3432, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 11 - 2880x480i@60Hz */
-	{
-		DRM_MODE("2880x480i", 54000, 2880, 2956,
-			 3204, 3432, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("2880x480i", 54000, 2880, 2956,
+	  3204, 3432, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 12 - 2880x240@60Hz */
-	{
-		DRM_MODE("2880x240", 54000, 2880, 2956,
-			 3204, 3432, 0, 240, 244, 247, 262, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x240", 54000, 2880, 2956,
+	  3204, 3432, 0, 240, 244, 247, 262, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 13 - 2880x240@60Hz */
-	{
-		DRM_MODE("2880x240", 54000, 2880, 2956,
-			 3204, 3432, 0, 240, 244, 247, 262, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x240", 54000, 2880, 2956,
+	  3204, 3432, 0, 240, 244, 247, 262, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 14 - 1440x480@60Hz */
-	{
-		DRM_MODE("1440x480", 54000, 1440, 1472,
-			 1596, 1716, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("1440x480", 54000, 1440, 1472,
+	  1596, 1716, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 15 - 1440x480@60Hz */
-	{
-		DRM_MODE("1440x480", 54000, 1440, 1472,
-			 1596, 1716, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("1440x480", 54000, 1440, 1472,
+	  1596, 1716, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 16 - 1920x1080@60Hz */
-	{
-		DRM_MODE("1920x1080", 148500, 1920, 2008,
-			 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 148500, 1920, 2008,
+	  2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 17 - 720x576@50Hz */
-	{
-		DRM_MODE("720x576", 27000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 27000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 18 - 720x576@50Hz */
-	{
-		DRM_MODE("720x576", 27000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 27000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 19 - 1280x720@50Hz */
-	{
-		DRM_MODE("1280x720", 74250, 1280, 1720,
-			 1760, 1980, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 74250, 1280, 1720,
+	  1760, 1980, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 20 - 1920x1080i@50Hz */
-	{
-		DRM_MODE("1920x1080i", 74250, 1920, 2448,
-			 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("1920x1080i", 74250, 1920, 2448,
+	  2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 21 - 720(1440)x576i@50Hz */
-	{
-		DRM_MODE("720x576i", 13500, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 13500, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 22 - 720(1440)x576i@50Hz */
-	{
-		DRM_MODE("720x576i", 13500, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 13500, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 23 - 720(1440)x288@50Hz */
-	{
-		DRM_MODE("720x288", 13500, 720, 732,
-			 795, 864, 0, 288, 290, 293, 312, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x288", 13500, 720, 732,
+	  795, 864, 0, 288, 290, 293, 312, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 24 - 720(1440)x288@50Hz */
-	{
-		DRM_MODE("720x288", 13500, 720, 732,
-			 795, 864, 0, 288, 290, 293, 312, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x288", 13500, 720, 732,
+	  795, 864, 0, 288, 290, 293, 312, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 25 - 2880x576i@50Hz */
-	{
-		DRM_MODE("2880x576i", 54000, 2880, 2928,
-			 3180, 3456, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("2880x576i", 54000, 2880, 2928,
+	  3180, 3456, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 26 - 2880x576i@50Hz */
-	{
-		DRM_MODE("2880x576i", 54000, 2880, 2928,
-			 3180, 3456, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("2880x576i", 54000, 2880, 2928,
+	  3180, 3456, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 27 - 2880x288@50Hz */
-	{
-		DRM_MODE("2880x288", 54000, 2880, 2928,
-			 3180, 3456, 0, 288, 290, 293, 312, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x288", 54000, 2880, 2928,
+	  3180, 3456, 0, 288, 290, 293, 312, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 28 - 2880x288@50Hz */
-	{
-		DRM_MODE("2880x288", 54000, 2880, 2928,
-			 3180, 3456, 0, 288, 290, 293, 312, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x288", 54000, 2880, 2928,
+	  3180, 3456, 0, 288, 290, 293, 312, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 29 - 1440x576@50Hz */
-	{
-		DRM_MODE("1440x576", 54000, 1440, 1464,
-			 1592, 1728, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("1440x576", 54000, 1440, 1464,
+	  1592, 1728, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 30 - 1440x576@50Hz */
-	{
-		DRM_MODE("1440x576", 54000, 1440, 1464,
-			 1592, 1728, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("1440x576", 54000, 1440, 1464,
+	  1592, 1728, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 31 - 1920x1080@50Hz */
-	{
-		DRM_MODE("1920x1080", 148500, 1920, 2448,
-			 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 148500, 1920, 2448,
+	  2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 32 - 1920x1080@24Hz */
-	{
-		DRM_MODE("1920x1080", 74250, 1920, 2558,
-			 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 74250, 1920, 2558,
+	  2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 33 - 1920x1080@25Hz */
-	{
-		DRM_MODE("1920x1080", 74250, 1920, 2448,
-			 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 74250, 1920, 2448,
+	  2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 34 - 1920x1080@30Hz */
-	{
-		DRM_MODE("1920x1080", 74250, 1920, 2008,
-			 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 74250, 1920, 2008,
+	  2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 35 - 2880x480@60Hz */
-	{
-		DRM_MODE("2880x480", 108000, 2880, 2944,
-			 3192, 3432, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x480", 108000, 2880, 2944,
+	  3192, 3432, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 36 - 2880x480@60Hz */
-	{
-		DRM_MODE("2880x480", 108000, 2880, 2944,
-			 3192, 3432, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x480", 108000, 2880, 2944,
+	  3192, 3432, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 37 - 2880x576@50Hz */
-	{
-		DRM_MODE("2880x576", 108000, 2880, 2928,
-			 3184, 3456, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x576", 108000, 2880, 2928,
+	  3184, 3456, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 38 - 2880x576@50Hz */
-	{
-		DRM_MODE("2880x576", 108000, 2880, 2928,
-			 3184, 3456, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("2880x576", 108000, 2880, 2928,
+	  3184, 3456, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 39 - 1920x1080i@50Hz */
-	{
-		DRM_MODE("1920x1080i", 72000, 1920, 1952,
-			 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("1920x1080i", 72000, 1920, 1952,
+	  2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 40 - 1920x1080i@100Hz */
-	{
-		DRM_MODE("1920x1080i", 148500, 1920, 2448,
-			 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("1920x1080i", 148500, 1920, 2448,
+	  2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 41 - 1280x720@100Hz */
-	{
-		DRM_MODE("1280x720", 148500, 1280, 1720,
-			 1760, 1980, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 148500, 1280, 1720,
+	  1760, 1980, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 42 - 720x576@100Hz */
-	{
-		DRM_MODE("720x576", 54000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 54000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 43 - 720x576@100Hz */
-	{
-		DRM_MODE("720x576", 54000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 54000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 44 - 720(1440)x576i@100Hz */
-	{
-		DRM_MODE("720x576i", 27000, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 27000, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 45 - 720(1440)x576i@100Hz */
-	{
-		DRM_MODE("720x576i", 27000, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 27000, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 46 - 1920x1080i@120Hz */
-	{
-		DRM_MODE("1920x1080i", 148500, 1920, 2008,
-			 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
-				 DRM_MODE_FLAG_INTERLACE),
+	{ DRM_MODE("1920x1080i", 148500, 1920, 2008,
+	  2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+	  DRM_MODE_FLAG_INTERLACE),
 	},
 	/* 47 - 1280x720@120Hz */
-	{
-		DRM_MODE("1280x720", 148500, 1280, 1390,
-			 1430, 1650, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 148500, 1280, 1390,
+	  1430, 1650, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 48 - 720x480@120Hz */
-	{
-		DRM_MODE("720x480", 54000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 54000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 49 - 720x480@120Hz */
-	{
-		DRM_MODE("720x480", 54000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 54000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 50 - 720(1440)x480i@120Hz */
-	{
-		DRM_MODE("720x480i", 27000, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 27000, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 51 - 720(1440)x480i@120Hz */
-	{
-		DRM_MODE("720x480i", 27000, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 27000, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 52 - 720x576@200Hz */
-	{
-		DRM_MODE("720x576", 108000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 108000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 53 - 720x576@200Hz */
-	{
-		DRM_MODE("720x576", 108000, 720, 732,
-			 796, 864, 0, 576, 581, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x576", 108000, 720, 732,
+	  796, 864, 0, 576, 581, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 54 - 720(1440)x576i@200Hz */
-	{
-		DRM_MODE("720x576i", 54000, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 54000, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 55 - 720(1440)x576i@200Hz */
-	{
-		DRM_MODE("720x576i", 54000, 720, 732,
-			 795, 864, 0, 576, 580, 586, 625, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x576i", 54000, 720, 732,
+	  795, 864, 0, 576, 580, 586, 625, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 56 - 720x480@240Hz */
-	{
-		DRM_MODE("720x480", 108000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 108000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 57 - 720x480@240Hz */
-	{
-		DRM_MODE("720x480", 108000, 720, 736,
-			 798, 858, 0, 480, 489, 495, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
+	{ DRM_MODE("720x480", 108000, 720, 736,
+	  798, 858, 0, 480, 489, 495, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 	},
 	/* 58 - 720(1440)x480i@240 */
-	{
-		DRM_MODE("720x480i", 54000, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 54000, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 59 - 720(1440)x480i@240 */
-	{
-		DRM_MODE("720x480i", 54000, 720, 739,
-			 801, 858, 0, 480, 488, 494, 525, 0,
-			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
-				 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
+	{ DRM_MODE("720x480i", 54000, 720, 739,
+	  801, 858, 0, 480, 488, 494, 525, 0,
+	  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+	  DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
 	},
 	/* 60 - 1280x720@24Hz */
-	{
-		DRM_MODE("1280x720", 59400, 1280, 3040,
-			 3080, 3300, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 59400, 1280, 3040,
+	  3080, 3300, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 61 - 1280x720@25Hz */
-	{
-		DRM_MODE("1280x720", 74250, 1280, 3700,
-			 3740, 3960, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 74250, 1280, 3700,
+	  3740, 3960, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 62 - 1280x720@30Hz */
-	{
-		DRM_MODE("1280x720", 74250, 1280, 3040,
-			 3080, 3300, 0, 720, 725, 730, 750, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1280x720", 74250, 1280, 3040,
+	  3080, 3300, 0, 720, 725, 730, 750, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 63 - 1920x1080@120Hz */
-	{
-		DRM_MODE("1920x1080", 297000, 1920, 2008,
-			 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 297000, 1920, 2008,
+	  2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* 64 - 1920x1080@100Hz */
-	{
-		DRM_MODE("1920x1080", 297000, 1920, 2448,
-			 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
-			 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+	{ DRM_MODE("1920x1080", 297000, 1920, 2448,
+	  2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+	  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
 	},
 	/* TERMINATOR */
-	{},
+	{ },
 };
 
-} // namespace kms
+}
diff --git a/kms++/src/modedb_dmt.cpp b/kms++/src/modedb_dmt.cpp
index 21fe1c2..7dee6b1 100644
--- a/kms++/src/modedb_dmt.cpp
+++ b/kms++/src/modedb_dmt.cpp
@@ -6,17 +6,18 @@
 
 namespace kms
 {
+
 #define DIV_ROUND(n, d) (((n) + (d) / 2) / (d))
 
 // hd, hss, hse, ht, vd, vss, vse, vt
 
-#define DRM_MODE(nm, c, hact, hfp, hsw, hbp, vact, vfp, vsw, vbp, f)                                                                                            \
-	{                                                                                                                                                       \
-		.name = nm, .clock = c,                                                                                                                         \
-		.hdisplay = (hact), .hsync_start = (hact) + (hfp), .hsync_end = (hact) + (hfp) + (hsw), .htotal = (hact) + (hfp) + (hsw) + (hbp), .hskew = 0,   \
-		.vdisplay = (vact), .vsync_start = (vact) + (vfp), .vsync_end = (vact) + (vfp) + (vsw), .vtotal = (vact) + (vfp) + (vsw) + (vbp), .vscan = 0,   \
-		.vrefresh = DIV_ROUND(c * 1000, ((hact) + (hfp) + (hsw) + (hbp)) * ((vact) + (vfp) + (vsw) + (vbp))) * (((f)&DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \
-		.flags = (f), .type = 0                                                                                                                         \
+#define DRM_MODE(nm, c, hact, hfp, hsw, hbp, vact, vfp, vsw, vbp, f) \
+	{ \
+	.name = nm, .clock = c, \
+	.hdisplay = (hact), .hsync_start = (hact) + (hfp), .hsync_end = (hact) + (hfp) + (hsw), .htotal = (hact) + (hfp) + (hsw) + (hbp), .hskew = 0, \
+	.vdisplay = (vact), .vsync_start = (vact) + (vfp), .vsync_end = (vact) + (vfp) + (vsw), .vtotal = (vact) + (vfp) + (vsw) + (vbp), .vscan = 0, \
+	.vrefresh = DIV_ROUND(c * 1000, ((hact) + (hfp) + (hsw) + (hbp)) * ((vact) + (vfp) + (vsw) + (vbp))) * (((f) & DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \
+	.flags = (f), .type = 0 \
 	}
 
 const Videomode dmt_modes[] = {
@@ -197,7 +198,7 @@
 	// 0x58 - 4096 x 2160 @ 59.94 Hz CVT (Reduced Blanking v2)
 	DRM_MODE("4096 x 2160 @ 59.94 Hz CVT (Reduced Blanking v2)", 556188, 4096, 8, 32, 40, 2160, 48, 8, 6, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC),
 	/* TERMINATOR */
-	{},
+	{ },
 };
 
-} // namespace kms
+}
diff --git a/kms++/src/omap/omapcard.cpp b/kms++/src/omap/omapcard.cpp
index 500bb72..5e21c75 100644
--- a/kms++/src/omap/omapcard.cpp
+++ b/kms++/src/omap/omapcard.cpp
@@ -9,6 +9,7 @@
 
 namespace kms
 {
+
 OmapCard::OmapCard(const string& device)
 	: Card(device)
 {
@@ -20,4 +21,4 @@
 	omap_device_del(m_omap_dev);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/omap/omapframebuffer.cpp b/kms++/src/omap/omapframebuffer.cpp
index 3bea13e..f33a286 100644
--- a/kms++/src/omap/omapframebuffer.cpp
+++ b/kms++/src/omap/omapframebuffer.cpp
@@ -18,22 +18,23 @@
 }
 
 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
-#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1)
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
 #define PAGE_SIZE 4096
 
 using namespace std;
 
 namespace kms
 {
+
 OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const string& fourcc, Flags flags)
 	: OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc), flags)
 {
 }
 
 OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format, Flags flags)
-	: Framebuffer(card, width, height), m_omap_card(card), m_format(format)
+	:Framebuffer(card, width, height), m_omap_card(card), m_format(format)
 {
-	Create(width, height, format, flags);
+	Create(flags);
 }
 
 OmapFramebuffer::~OmapFramebuffer()
@@ -41,9 +42,9 @@
 	Destroy();
 }
 
-void OmapFramebuffer::Create(uint32_t width, uint32_t height, PixelFormat format, Flags buffer_flags)
+void OmapFramebuffer::Create(Flags buffer_flags)
 {
-	const PixelFormatInfo& format_info = get_pixel_format_info(format);
+	const PixelFormatInfo& format_info = get_pixel_format_info(m_format);
 
 	m_num_planes = format_info.num_planes;
 
@@ -67,9 +68,9 @@
 		uint32_t stride;
 
 		if (!(buffer_flags & Flags::Tiled)) {
-			stride = width * pi.bitspp / 8;
+			stride = width() * pi.bitspp / 8;
 
-			uint32_t size = stride * height / pi.ysub;
+			uint32_t size = stride * height() / pi.ysub;
 
 			bo = omap_bo_new(m_omap_card.dev(), size, flags);
 			if (!bo)
@@ -77,46 +78,36 @@
 		} else {
 			unsigned bitspertiler;
 
-			switch (format) {
+			switch (m_format) {
 			case PixelFormat::NV12:
-				bitspertiler = i == 0 ? 8 : 16;
-				break;
+				bitspertiler = i == 0 ? 8 : 16; break;
 			case PixelFormat::YUYV:
 			case PixelFormat::UYVY:
-				bitspertiler = 32;
-				break;
+				bitspertiler = 32; break;
 			case PixelFormat::ARGB8888:
 			case PixelFormat::XRGB8888:
-				bitspertiler = 32;
-				break;
+				bitspertiler = 32; break;
 			case PixelFormat::RGB565:
-				bitspertiler = 16;
-				break;
+				bitspertiler = 16; break;
 			default:
 				throw invalid_argument("unimplemented format");
 			}
 
 			switch (bitspertiler) {
-			case 8:
-				flags |= OMAP_BO_TILED_8;
-				break;
-			case 16:
-				flags |= OMAP_BO_TILED_16;
-				break;
-			case 32:
-				flags |= OMAP_BO_TILED_32;
-				break;
+			case 8: flags |= OMAP_BO_TILED_8; break;
+			case 16: flags |= OMAP_BO_TILED_16; break;
+			case 32: flags |= OMAP_BO_TILED_32; break;
 			default:
 				throw invalid_argument("bad bitspertiler");
 			}
 
-			uint32_t width_tiler = width * pi.bitspp / bitspertiler;
+			uint32_t width_tiler = width() * pi.bitspp / bitspertiler;
 
-			bo = omap_bo_new_tiled(m_omap_card.dev(), width_tiler, height, flags);
+			bo = omap_bo_new_tiled(m_omap_card.dev(), width_tiler, height(), flags);
 			if (!bo)
 				throw invalid_argument(string("omap_bo_new_tiled failed: ") + strerror(errno));
 
-			stride = round_up(width * pi.bitspp / 8, PAGE_SIZE);
+			stride = round_up(width() * pi.bitspp / 8, PAGE_SIZE);
 		}
 
 		plane.omap_bo = bo;
@@ -133,8 +124,8 @@
 	uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride };
 	uint32_t offsets[4] = { m_planes[0].offset, m_planes[1].offset };
 	uint32_t id;
-	int r = drmModeAddFB2(card().fd(), width, height, (uint32_t)format,
-			      bo_handles, pitches, offsets, &id, 0);
+	int r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
+			  bo_handles, pitches, offsets, &id, 0);
 	if (r)
 		throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
 
@@ -190,4 +181,4 @@
 	return fd;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/pixelformats.cpp b/kms++/src/pixelformats.cpp
index d739efd..ecca41d 100644
--- a/kms++/src/pixelformats.cpp
+++ b/kms++/src/pixelformats.cpp
@@ -8,266 +8,42 @@
 {
 static const map<PixelFormat, PixelFormatInfo> format_info_array = {
 	/* YUV packed */
-	{ PixelFormat::UYVY, {
-				     PixelColorType::YUV,
-				     1,
-				     { { 16, 2, 1 } },
-			     } },
-	{ PixelFormat::YUYV, {
-				     PixelColorType::YUV,
-				     1,
-				     { { 16, 2, 1 } },
-			     } },
-	{ PixelFormat::YVYU, {
-				     PixelColorType::YUV,
-				     1,
-				     { { 16, 2, 1 } },
-			     } },
-	{ PixelFormat::VYUY, {
-				     PixelColorType::YUV,
-				     1,
-				     { { 16, 2, 1 } },
-			     } },
+	{ PixelFormat::UYVY, { PixelColorType::YUV, 1, { { 16, 2, 1 } }, } },
+	{ PixelFormat::YUYV, { PixelColorType::YUV, 1, { { 16, 2, 1 } }, } },
+	{ PixelFormat::YVYU, { PixelColorType::YUV, 1, { { 16, 2, 1 } }, } },
+	{ PixelFormat::VYUY, { PixelColorType::YUV, 1, { { 16, 2, 1 } }, } },
 	/* YUV semi-planar */
-	{ PixelFormat::NV12, {
-				     PixelColorType::YUV,
-				     2,
-				     { {
-					       8,
-					       1,
-					       1,
-				       },
-				       { 8, 2, 2 } },
-			     } },
-	{ PixelFormat::NV21, {
-				     PixelColorType::YUV,
-				     2,
-				     { {
-					       8,
-					       1,
-					       1,
-				       },
-				       { 8, 2, 2 } },
-			     } },
-	{ PixelFormat::NV16, {
-				     PixelColorType::YUV,
-				     2,
-				     { {
-					       8,
-					       1,
-					       1,
-				       },
-				       { 8, 2, 1 } },
-			     } },
-	{ PixelFormat::NV61, {
-				     PixelColorType::YUV,
-				     2,
-				     { {
-					       8,
-					       1,
-					       1,
-				       },
-				       { 8, 2, 1 } },
-			     } },
-	/* YUV planar */
-	{ PixelFormat::YUV420, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 2, 2 },
-					 { 8, 2, 2 } },
-			       } },
-	{ PixelFormat::YVU420, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 2, 2 },
-					 { 8, 2, 2 } },
-			       } },
-	{ PixelFormat::YUV422, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 2, 1 },
-					 { 8, 2, 1 } },
-			       } },
-	{ PixelFormat::YVU422, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 2, 1 },
-					 { 8, 2, 1 } },
-			       } },
-	{ PixelFormat::YUV444, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 1, 1 },
-					 { 8, 1, 1 } },
-			       } },
-	{ PixelFormat::YVU444, {
-				       PixelColorType::YUV,
-				       3,
-				       { {
-						 8,
-						 1,
-						 1,
-					 },
-					 { 8, 1, 1 },
-					 { 8, 1, 1 } },
-			       } },
-	/* RGB8 */
-	{ PixelFormat::RGB332, {
-				       PixelColorType::RGB,
-				       1,
-				       { { 8, 1, 1 } },
-			       } },
+	{ PixelFormat::NV12, { PixelColorType::YUV, 2, { { 8, 1, 1, }, { 8, 2, 2 } }, } },
+	{ PixelFormat::NV21, { PixelColorType::YUV, 2, { { 8, 1, 1, }, { 8, 2, 2 } }, } },
 	/* RGB16 */
-	{ PixelFormat::RGB565, {
-				       PixelColorType::RGB,
-				       1,
-				       { { 16, 1, 1 } },
-			       } },
-	{ PixelFormat::BGR565, {
-				       PixelColorType::RGB,
-				       1,
-				       { { 16, 1, 1 } },
-			       } },
-	{ PixelFormat::XRGB4444, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 16, 1, 1 } },
-				 } },
-	{ PixelFormat::XRGB1555, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 16, 1, 1 } },
-				 } },
-	{ PixelFormat::ARGB4444, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 16, 1, 1 } },
-				 } },
-	{ PixelFormat::ARGB1555, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 16, 1, 1 } },
-				 } },
+	{ PixelFormat::RGB565, { PixelColorType::RGB, 1, { { 16, 1, 1 } }, } },
+	{ PixelFormat::BGR565, { PixelColorType::RGB, 1, { { 16, 1, 1 } }, } },
 	/* RGB24 */
-	{ PixelFormat::RGB888, {
-				       PixelColorType::RGB,
-				       1,
-				       { { 24, 1, 1 } },
-			       } },
-	{ PixelFormat::BGR888, {
-				       PixelColorType::RGB,
-				       1,
-				       { { 24, 1, 1 } },
-			       } },
+	{ PixelFormat::RGB888, { PixelColorType::RGB, 1, { { 24, 1, 1 } }, } },
+	{ PixelFormat::BGR888, { PixelColorType::RGB, 1, { { 24, 1, 1 } }, } },
 	/* RGB32 */
-	{ PixelFormat::XRGB8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::XBGR8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::RGBX8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::BGRX8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
+	{ PixelFormat::XRGB8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::XBGR8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::RGBX8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::BGRX8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
 
-	{ PixelFormat::ARGB8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::ABGR8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::RGBA8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
-	{ PixelFormat::BGRA8888, {
-					 PixelColorType::RGB,
-					 1,
-					 { { 32, 1, 1 } },
-				 } },
+	{ PixelFormat::ARGB8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::ABGR8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::RGBA8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::BGRA8888, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
 
-	{ PixelFormat::XRGB2101010, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::XBGR2101010, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::RGBX1010102, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::BGRX1010102, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
+	{ PixelFormat::XRGB2101010, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::XBGR2101010, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::RGBX1010102, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::BGRX1010102, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
 
-	{ PixelFormat::ARGB2101010, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::ABGR2101010, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::RGBA1010102, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
-	{ PixelFormat::BGRA1010102, {
-					    PixelColorType::RGB,
-					    1,
-					    { { 32, 1, 1 } },
-				    } },
+	{ PixelFormat::ARGB2101010, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::ABGR2101010, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::RGBA1010102, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+	{ PixelFormat::BGRA1010102, { PixelColorType::RGB, 1, { { 32, 1, 1 } }, } },
+
+	{ PixelFormat::ARGB4444, { PixelColorType::RGB, 1, { { 16, 1, 1 } }, } },
+	{ PixelFormat::ARGB1555, { PixelColorType::RGB, 1, { { 16, 1, 1 } }, } },
 };
 
 const struct PixelFormatInfo& get_pixel_format_info(PixelFormat format)
@@ -278,4 +54,4 @@
 	return format_info_array.at(format);
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/plane.cpp b/kms++/src/plane.cpp
index bd426dd..f68c8d0 100644
--- a/kms++/src/plane.cpp
+++ b/kms++/src/plane.cpp
@@ -1,4 +1,4 @@
-#include <cstdio>
+#include <stdio.h>
 #include <iostream>
 #include <unistd.h>
 #include <fcntl.h>
@@ -13,12 +13,14 @@
 
 namespace kms
 {
-struct PlanePriv {
+
+struct PlanePriv
+{
 	drmModePlanePtr drm_plane;
 };
 
-Plane::Plane(Card& card, uint32_t id, uint32_t idx)
-	: DrmPropObject(card, id, DRM_MODE_OBJECT_PLANE, idx)
+Plane::Plane(Card &card, uint32_t id, uint32_t idx)
+	:DrmPropObject(card, id, DRM_MODE_OBJECT_PLANE, idx)
 {
 	m_priv = new PlanePriv();
 	m_priv->drm_plane = drmModeGetPlane(this->card().fd(), this->id());
@@ -49,7 +51,7 @@
 
 PlaneType Plane::plane_type() const
 {
-	if (card().has_universal_planes()) {
+	if (card().has_has_universal_planes()) {
 		switch (get_prop_value("type")) {
 		case DRM_PLANE_TYPE_OVERLAY:
 			return PlaneType::Overlay;
@@ -74,13 +76,14 @@
 	for (uint32_t crtc_mask = m_priv->drm_plane->possible_crtcs;
 	     crtc_mask;
 	     idx++, crtc_mask >>= 1) {
+
 		if ((crtc_mask & 1) == 0)
 			continue;
 
 		auto iter = find_if(crtcs.begin(), crtcs.end(), [idx](Crtc* crtc) { return crtc->idx() == idx; });
 
 		if (iter == crtcs.end())
-			continue;
+			throw runtime_error("get_possible_crtcs: crtc missing");
 
 		v.push_back(*iter);
 	}
@@ -94,7 +97,7 @@
 	vector<PixelFormat> r;
 
 	for (unsigned i = 0; i < p->count_formats; ++i)
-		r.push_back((PixelFormat)p->formats[i]);
+		r.push_back((PixelFormat) p->formats[i]);
 
 	return r;
 }
@@ -134,4 +137,4 @@
 	return m_priv->drm_plane->gamma_size;
 }
 
-} // namespace kms
+}
diff --git a/kms++/src/property.cpp b/kms++/src/property.cpp
index 0484f0e..ee79922 100644
--- a/kms++/src/property.cpp
+++ b/kms++/src/property.cpp
@@ -7,7 +7,9 @@
 
 namespace kms
 {
-struct PropertyPriv {
+
+struct PropertyPriv
+{
 	drmModePropertyPtr drm_prop;
 };
 
@@ -82,4 +84,4 @@
 	drmModePropertyPtr p = m_priv->drm_prop;
 	return vector<uint32_t>(p->blob_ids, p->blob_ids + p->count_blobs);
 }
-} // namespace kms
+}
diff --git a/kms++/src/videomode.cpp b/kms++/src/videomode.cpp
index b039059..b8bd797 100644
--- a/kms++/src/videomode.cpp
+++ b/kms++/src/videomode.cpp
@@ -1,8 +1,7 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
-#include <cmath>
+#include <math.h>
 #include <sstream>
-#include <fmt/format.h>
 
 #include <kms++/kms++.h>
 #include "helpers.h"
@@ -11,10 +10,6 @@
 
 namespace kms
 {
-bool Videomode::valid() const
-{
-	return !!clock;
-}
 
 unique_ptr<Blob> Videomode::to_blob(Card& card) const
 {
@@ -93,60 +88,21 @@
 	}
 }
 
-string Videomode::to_string_short() const
+string Videomode::to_string() const
 {
-	return fmt::format("{}x{}{}@{:.2f}", hdisplay, vdisplay, interlace() ? "i" : "", calculated_vrefresh());
-}
-
-static char sync_to_char(SyncPolarity pol)
-{
-	switch (pol) {
-	case SyncPolarity::Positive:
-		return '+';
-	case SyncPolarity::Negative:
-		return '-';
-	default:
-		return '?';
-	}
-}
-
-string Videomode::to_string_long() const
-{
-	string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync()));
-	string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync()));
-
-	string str = fmt::format("{} {:.3f} {} {} {} ({:.2f}) {:#x} {:#x}",
-				 to_string_short(),
-				 clock / 1000.0,
-				 h, v,
-				 vrefresh, calculated_vrefresh(),
-				 flags,
-				 type);
-
-	return str;
-}
-
-string Videomode::to_string_long_padded() const
-{
-	string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync()));
-	string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync()));
-
-	string str = fmt::format("{:<16} {:7.3f} {:<18} {:<18} {:2} ({:.2f}) {:#10x} {:#6x}",
-				 to_string_short(),
-				 clock / 1000.0,
-				 h, v,
-				 vrefresh, calculated_vrefresh(),
-				 flags,
-				 type);
-
-	return str;
+	std::stringstream ss;
+	ss << hdisplay << "x" << vdisplay;
+	if (interlace())
+		ss << "i";
+	ss << "@" << calculated_vrefresh();
+	return ss.str();
 }
 
 Videomode videomode_from_timings(uint32_t clock_khz,
 				 uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp,
 				 uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp)
 {
-	Videomode m{};
+	Videomode m { };
 	m.clock = clock_khz;
 
 	m.hdisplay = hact;
@@ -162,4 +118,4 @@
 	return m;
 }
 
-} // namespace kms
+}
diff --git a/kms++util/CMakeLists.txt b/kms++util/CMakeLists.txt
new file mode 100644
index 0000000..70f3b17
--- /dev/null
+++ b/kms++util/CMakeLists.txt
@@ -0,0 +1,23 @@
+file(GLOB SRCS "src/*.cpp" "src/*.h")
+file(GLOB PUB_HDRS "inc/kms++util/*.h")
+add_library(kms++util ${SRCS} ${PUB_HDRS})
+
+target_include_directories(kms++util PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
+    $<INSTALL_INTERFACE:include>
+    PRIVATE src)
+
+target_link_libraries(kms++util kms++)
+
+if (KMSXX_ENABLE_THREADING)
+    target_link_libraries(kms++util pthread)
+    add_definitions(-DHAS_PTHREAD)
+endif()
+
+set_target_properties(kms++util PROPERTIES
+    PUBLIC_HEADER "${PUB_HDRS}")
+
+install(TARGETS kms++util
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib
+    PUBLIC_HEADER DESTINATION include/kms++util)
diff --git a/kms++util/inc/kms++util/color.h b/kms++util/inc/kms++util/color.h
index 5232b37..2bf6e66 100644
--- a/kms++util/inc/kms++util/color.h
+++ b/kms++util/inc/kms++util/color.h
@@ -14,7 +14,8 @@
 	MAX,
 };
 
-struct RGB {
+struct RGB
+{
 	RGB();
 	RGB(uint8_t r, uint8_t g, uint8_t b);
 	RGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b);
@@ -33,7 +34,6 @@
 	uint32_t rgba1010102() const;
 	uint32_t bgra1010102() const;
 
-	uint8_t rgb332() const;
 	uint16_t rgb565() const;
 	uint16_t bgr565() const;
 	uint16_t argb4444() const;
@@ -46,7 +46,8 @@
 	uint8_t a;
 };
 
-struct YUV {
+struct YUV
+{
 	YUV();
 	YUV(uint8_t y, uint8_t u, uint8_t v);
 	YUV(const RGB& rgb, YUVType type = YUVType::BT601_Lim);
@@ -56,4 +57,4 @@
 	uint8_t y;
 	uint8_t a;
 };
-} // namespace kms
+}
diff --git a/kms++util/inc/kms++util/cpuframebuffer.h b/kms++util/inc/kms++util/cpuframebuffer.h
index e4de150..4273e0d 100644
--- a/kms++util/inc/kms++util/cpuframebuffer.h
+++ b/kms++util/inc/kms++util/cpuframebuffer.h
@@ -4,8 +4,8 @@
 
 namespace kms
 {
-class CPUFramebuffer : public IFramebuffer
-{
+
+class CPUFramebuffer : public IFramebuffer {
 public:
 	CPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format);
 
@@ -30,7 +30,7 @@
 		uint32_t size;
 		uint32_t stride;
 		uint32_t offset;
-		uint8_t* map;
+		uint8_t *map;
 	};
 
 	uint32_t m_width;
@@ -41,4 +41,4 @@
 	struct FramebufferPlane m_planes[4];
 };
 
-} // namespace kms
+}
diff --git a/kms++util/inc/kms++util/extcpuframebuffer.h b/kms++util/inc/kms++util/extcpuframebuffer.h
index 29a06c0..92ca43a 100644
--- a/kms++util/inc/kms++util/extcpuframebuffer.h
+++ b/kms++util/inc/kms++util/extcpuframebuffer.h
@@ -4,6 +4,7 @@
 
 namespace kms
 {
+
 class ExtCPUFramebuffer : public IFramebuffer
 {
 public:
@@ -29,7 +30,7 @@
 		uint32_t size;
 		uint32_t stride;
 		uint32_t offset;
-		uint8_t* map;
+		uint8_t *map;
 	};
 
 	uint32_t m_width;
@@ -39,4 +40,4 @@
 	unsigned m_num_planes;
 	struct FramebufferPlane m_planes[4];
 };
-} // namespace kms
+}
diff --git a/kms++util/inc/kms++util/kms++util.h b/kms++util/inc/kms++util/kms++util.h
index 52b6ce9..62ec663 100644
--- a/kms++util/inc/kms++util/kms++util.h
+++ b/kms++util/inc/kms++util/kms++util.h
@@ -18,18 +18,17 @@
 class IFramebuffer;
 
 void draw_rgb_pixel(IFramebuffer& buf, unsigned x, unsigned y, RGB color);
-void draw_yuv444_pixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv);
 void draw_yuv422_macropixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv1, YUV yuv2);
 void draw_yuv420_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-			    YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4);
-void draw_rect(IFramebuffer& fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color);
+				   YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4);
+void draw_rect(IFramebuffer &fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color);
 void draw_circle(IFramebuffer& fb, int32_t xCenter, int32_t yCenter, int32_t radius, RGB color);
 void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y, const std::string& str, RGB color);
 
 void draw_color_bar(IFramebuffer& buf, int old_xpos, int xpos, int width);
 
-void draw_test_pattern(IFramebuffer& fb, YUVType yuvt = YUVType::BT601_Lim);
-} // namespace kms
+void draw_test_pattern(IFramebuffer &fb, YUVType yuvt = YUVType::BT601_Lim);
+}
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 
@@ -42,32 +41,32 @@
 #define __STRING(x) #x
 #endif
 
-#define ASSERT(x)                                                                                                        \
-	if (unlikely(!(x))) {                                                                                            \
+#define ASSERT(x) \
+	if (unlikely(!(x))) { \
 		fprintf(stderr, "%s:%d: %s: ASSERT(%s) failed\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, __STRING(x)); \
-		abort();                                                                                                 \
+		abort(); \
 	}
 
-#define FAIL(fmt, ...)                                                                                            \
-	do {                                                                                                      \
+#define FAIL(fmt, ...) \
+	do { \
 		fprintf(stderr, "%s:%d: %s:\n" fmt "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__); \
-		abort();                                                                                          \
-	} while (0)
+		abort(); \
+	} while(0)
 
-#define FAIL_IF(x, fmt, ...)                                                                                      \
-	if (unlikely(x)) {                                                                                        \
+#define FAIL_IF(x, fmt, ...) \
+	if (unlikely(x)) { \
 		fprintf(stderr, "%s:%d: %s:\n" fmt "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__); \
-		abort();                                                                                          \
+		abort(); \
 	}
 
-#define EXIT(fmt, ...)                                    \
-	do {                                              \
+#define EXIT(fmt, ...) \
+	do { \
 		fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
-		exit(-1);                                 \
-	} while (0)
+		exit(-1); \
+	} while(0)
 
-#define EXIT_IF(x, fmt, ...)                              \
-	if (unlikely(x)) {                                \
+#define EXIT_IF(x, fmt, ...) \
+	if (unlikely(x)) { \
 		fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
-		exit(-1);                                 \
+		exit(-1); \
 	}
diff --git a/kms++util/inc/kms++util/opts.h b/kms++util/inc/kms++util/opts.h
index 6058b27..1b0fd22 100644
--- a/kms++util/inc/kms++util/opts.h
+++ b/kms++util/inc/kms++util/opts.h
@@ -7,7 +7,6 @@
 class Option
 {
 	friend class OptionSet;
-
 public:
 	Option(const std::string& str, std::function<void()> func);
 	Option(const std::string& str, std::function<void(const std::string)> func);
diff --git a/kms++util/inc/kms++util/resourcemanager.h b/kms++util/inc/kms++util/resourcemanager.h
index 11c11b3..1b5cf21 100644
--- a/kms++util/inc/kms++util/resourcemanager.h
+++ b/kms++util/inc/kms++util/resourcemanager.h
@@ -2,8 +2,8 @@
 #include <set>
 #include <string>
 
-namespace kms
-{
+namespace kms {
+
 class ResourceManager
 {
 public:
@@ -14,16 +14,13 @@
 	Card& card() const { return m_card; }
 	Connector* reserve_connector(const std::string& name = "");
 	Connector* reserve_connector(Connector* conn);
-	void release_connector(Connector* conn);
 	Crtc* reserve_crtc(Connector* conn);
 	Crtc* reserve_crtc(Crtc* crtc);
-	void release_crtc(Crtc* crtc);
 	Plane* reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format = PixelFormat::Undefined);
 	Plane* reserve_plane(Plane* plane);
 	Plane* reserve_generic_plane(Crtc* crtc, PixelFormat format = PixelFormat::Undefined);
 	Plane* reserve_primary_plane(Crtc* crtc, PixelFormat format = PixelFormat::Undefined);
 	Plane* reserve_overlay_plane(Crtc* crtc, PixelFormat format = PixelFormat::Undefined);
-	void release_plane(Plane* plane);
 
 private:
 	Card& m_card;
@@ -32,4 +29,4 @@
 	std::set<Plane*> m_reserved_planes;
 };
 
-} // namespace kms
+}
diff --git a/kms++util/inc/kms++util/strhelpers.h b/kms++util/inc/kms++util/strhelpers.h
index c4032d7..2c540f3 100644
--- a/kms++util/inc/kms++util/strhelpers.h
+++ b/kms++util/inc/kms++util/strhelpers.h
@@ -5,7 +5,7 @@
 
 std::string to_lower(const std::string& str);
 
-template<typename T>
+template <typename T>
 std::string join(const T& values, const std::string& delim)
 {
 	std::ostringstream ss;
@@ -17,7 +17,7 @@
 	return ss.str();
 }
 
-template<typename T>
+template <typename T>
 std::string join(const std::vector<T>& values, const std::string& delim, std::function<std::string(T)> func)
 {
 	std::ostringstream ss;
@@ -28,3 +28,6 @@
 	}
 	return ss.str();
 }
+
+std::string sformat(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
diff --git a/kms++util/inc/kms++util/videodevice.h b/kms++util/inc/kms++util/videodevice.h
index 3bce4a9..e089bcd 100644
--- a/kms++util/inc/kms++util/videodevice.h
+++ b/kms++util/inc/kms++util/videodevice.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include <string>
-#include <memory>
 #include <kms++/kms++.h>
 
 class VideoStreamer;
@@ -9,7 +8,8 @@
 class VideoDevice
 {
 public:
-	struct VideoFrameSize {
+	struct VideoFrameSize
+	{
 		uint32_t min_w, max_w, step_w;
 		uint32_t min_h, max_h, step_h;
 	};
@@ -50,8 +50,8 @@
 	std::vector<kms::DumbFramebuffer*> m_capture_fbs;
 	std::vector<kms::DumbFramebuffer*> m_output_fbs;
 
-	std::unique_ptr<VideoStreamer> m_capture_streamer;
-	std::unique_ptr<VideoStreamer> m_output_streamer;
+	VideoStreamer* m_capture_streamer;
+	VideoStreamer* m_output_streamer;
 };
 
 class VideoStreamer
diff --git a/kms++util/meson.build b/kms++util/meson.build
deleted file mode 100644
index 4105db6..0000000
--- a/kms++util/meson.build
+++ /dev/null
@@ -1,52 +0,0 @@
-libkmsxxutil_sources = files([
-    'src/colorbar.cpp',
-    'src/color.cpp',
-    'src/cpuframebuffer.cpp',
-    'src/drawing.cpp',
-    'src/extcpuframebuffer.cpp',
-    'src/opts.cpp',
-    'src/resourcemanager.cpp',
-    'src/strhelpers.cpp',
-    'src/testpat.cpp',
-    'src/videodevice.cpp',
-])
-
-public_headers = [
-    'inc/kms++util/color.h',
-    'inc/kms++util/kms++util.h',
-    'inc/kms++util/stopwatch.h',
-    'inc/kms++util/cpuframebuffer.h',
-    'inc/kms++util/strhelpers.h',
-    'inc/kms++util/opts.h',
-    'inc/kms++util/extcpuframebuffer.h',
-    'inc/kms++util/resourcemanager.h',
-    'inc/kms++util/videodevice.h',
-]
-
-private_includes = include_directories('src', 'inc')
-public_includes = include_directories('inc')
-
-thread_dep = dependency('threads', required : false)
-
-libkmsxxutil_args = [ ]
-
-if thread_dep.found()
-    libkmsxxutil_args += [ '-DHAS_PTHREAD' ]
-endif
-
-libkmsxxutil_deps = [ libkmsxx_dep, libfmt_dep, thread_dep ]
-
-libkmsxxutil = library('kms++util',
-                       libkmsxxutil_sources,
-                       install : true,
-                       include_directories : private_includes,
-                       dependencies : libkmsxxutil_deps,
-                       cpp_args : libkmsxxutil_args)
-
-libkmsxxutil_dep = declare_dependency(include_directories : public_includes,
-                                      link_with : libkmsxxutil)
-
-install_headers(public_headers, subdir : 'kms++util')
-
-pkg = import('pkgconfig')
-pkg.generate(libkmsxxutil)
diff --git a/kms++util/src/color.cpp b/kms++util/src/color.cpp
index 74ff8c9..80e4866 100644
--- a/kms++util/src/color.cpp
+++ b/kms++util/src/color.cpp
@@ -9,7 +9,7 @@
 }
 
 RGB::RGB(uint8_t r, uint8_t g, uint8_t b)
-	: RGB(255, r, g, b)
+	:RGB(255, r, g, b)
 {
 }
 
@@ -79,11 +79,6 @@
 	return (b << 24) | (g << 14) | (r << 4) | (a >> 6);
 }
 
-uint8_t RGB::rgb332() const
-{
-	return ((r >> 5) << 5) | ((g >> 5) << 2) | ((b >> 6) << 0);
-}
-
 uint16_t RGB::rgb565() const
 {
 	return ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
@@ -110,27 +105,33 @@
 }
 
 #define CF_ONE (256)
-#define CF(a, b, c)                                                           \
-	{                                                                     \
-		((int)((a)*CF_ONE)), ((int)((b)*CF_ONE)), ((int)((c)*CF_ONE)) \
-	}
-#define CLAMP(a) ((a) > (CF_ONE - 1) ? (CF_ONE - 1) : (a) < 0 ? 0 : (a))
+#define CF(a, b, c) { ((int) ((a) * CF_ONE)), ((int) ((b) * CF_ONE)), ((int) ((c) * CF_ONE)) }
+#define CLAMP(a) ((a) > (CF_ONE-1) ? (CF_ONE-1) : (a) < 0 ? 0 : (a))
 
 const int YUVcoef[static_cast<unsigned>(YUVType::MAX)][3][3] = {
 	[static_cast<unsigned>(YUVType::BT601_Lim)] = {
-		CF(0.257, 0.504, 0.098),
-		CF(-0.148, -0.291, 0.439),
-		CF(0.439, -0.368, -0.071) },
-	[static_cast<unsigned>(YUVType::BT601_Full)] = { CF(0.299, 0.587, 0.114), CF(-0.169, -0.331, 0.500), CF(0.500, -0.419, -0.081) },
-	[static_cast<unsigned>(YUVType::BT709_Lim)] = { CF(0.1826, 0.6142, 0.0620), CF(-0.1006, -0.3386, 0.4392), CF(0.4392, -0.3989, -0.0403) },
-	[static_cast<unsigned>(YUVType::BT709_Full)] = { CF(0.2126, 0.7152, 0.0722), CF(-0.1146, -0.3854, 0.5000), CF(0.5000, -0.4542, -0.0468) },
+		CF( 0.257,  0.504,  0.098),
+		CF(-0.148, -0.291,  0.439),
+		CF( 0.439, -0.368, -0.071) },
+	[static_cast<unsigned>(YUVType::BT601_Full)] = {
+		CF( 0.299,  0.587,  0.114),
+		CF(-0.169, -0.331,  0.500),
+		CF( 0.500, -0.419, -0.081) },
+	[static_cast<unsigned>(YUVType::BT709_Lim)] = {
+		CF( 0.1826,  0.6142,  0.0620),
+		CF(-0.1006, -0.3386,  0.4392),
+		CF( 0.4392, -0.3989, -0.0403) },
+	[static_cast<unsigned>(YUVType::BT709_Full)] = {
+		CF( 0.2126,  0.7152,  0.0722),
+		CF(-0.1146, -0.3854,  0.5000),
+		CF( 0.5000, -0.4542, -0.0468) },
 };
 
 const int YUVoffset[static_cast<unsigned>(YUVType::MAX)][3] = {
-	[static_cast<unsigned>(YUVType::BT601_Lim)] = CF(0.0625, 0.5, 0.5),
-	[static_cast<unsigned>(YUVType::BT601_Full)] = CF(0, 0.5, 0.5),
-	[static_cast<unsigned>(YUVType::BT709_Lim)] = CF(0.0625, 0.5, 0.5),
-	[static_cast<unsigned>(YUVType::BT709_Full)] = CF(0, 0.5, 0.5),
+	[static_cast<unsigned>(YUVType::BT601_Lim)]  = CF(0.0625,  0.5,  0.5),
+	[static_cast<unsigned>(YUVType::BT601_Full)] = CF(     0,  0.5,  0.5),
+	[static_cast<unsigned>(YUVType::BT709_Lim)]  = CF(0.0625,  0.5,  0.5),
+	[static_cast<unsigned>(YUVType::BT709_Full)] = CF(     0,  0.5,  0.5),
 };
 
 YUV::YUV()
@@ -146,33 +147,33 @@
 	this->a = 0;
 }
 
-static inline uint8_t MAKE_YUV_Y(uint8_t r, uint8_t g, uint8_t b, YUVType type)
+static inline
+uint8_t MAKE_YUV_Y(uint8_t r, uint8_t g, uint8_t b, YUVType type)
 {
 	unsigned tidx = static_cast<unsigned>(type);
 
 	return CLAMP(((YUVcoef[tidx][0][0] * r + YUVcoef[tidx][0][1] * g +
-		       YUVcoef[tidx][0][2] * b + CF_ONE / 2) /
-		      CF_ONE) +
+		      YUVcoef[tidx][0][2] * b + CF_ONE/2) / CF_ONE) +
 		     YUVoffset[tidx][0]);
 }
 
-static inline uint8_t MAKE_YUV_U(uint8_t r, uint8_t g, uint8_t b, YUVType type)
+static inline
+uint8_t MAKE_YUV_U(uint8_t r, uint8_t g, uint8_t b, YUVType type)
 {
 	unsigned tidx = static_cast<unsigned>(type);
 
 	return CLAMP(((YUVcoef[tidx][1][0] * r + YUVcoef[tidx][1][1] * g +
-		       YUVcoef[tidx][1][2] * b + CF_ONE / 2) /
-		      CF_ONE) +
+		       YUVcoef[tidx][1][2] * b + CF_ONE/2) / CF_ONE) +
 		     YUVoffset[tidx][1]);
 }
 
-static inline uint8_t MAKE_YUV_V(uint8_t r, uint8_t g, uint8_t b, YUVType type)
+static inline
+uint8_t MAKE_YUV_V(uint8_t r, uint8_t g, uint8_t b, YUVType type)
 {
 	unsigned tidx = static_cast<unsigned>(type);
 
 	return CLAMP(((YUVcoef[tidx][2][0] * r + YUVcoef[tidx][2][1] * g +
-		       YUVcoef[tidx][2][2] * b + CF_ONE / 2) /
-		      CF_ONE) +
+		       YUVcoef[tidx][2][2] * b + CF_ONE/2) / CF_ONE) +
 		     YUVoffset[tidx][2]);
 }
 
@@ -183,4 +184,4 @@
 	this->v = MAKE_YUV_V(rgb.r, rgb.g, rgb.b, type);
 	this->a = rgb.a;
 }
-} // namespace kms
+}
diff --git a/kms++util/src/colorbar.cpp b/kms++util/src/colorbar.cpp
index cd0b978..c08ed9d 100644
--- a/kms++util/src/colorbar.cpp
+++ b/kms++util/src/colorbar.cpp
@@ -39,7 +39,7 @@
 {
 	for (unsigned y = 0; y < buf.height(); ++y) {
 		RGB bcol = colors32[y * ARRAY_SIZE(colors32) / buf.height()];
-		uint32_t* line = (uint32_t*)(buf.map(0) + buf.stride(0) * y);
+		uint32_t *line = (uint32_t*)(buf.map(0) + buf.stride(0) * y);
 
 		if (old_xpos >= 0) {
 			for (int x = old_xpos; x < old_xpos + width; ++x)
@@ -57,7 +57,7 @@
 
 	for (unsigned y = 0; y < buf.height(); ++y) {
 		uint16_t bcol = colors16[y * ARRAY_SIZE(colors16) / buf.height()];
-		uint16_t* line = (uint16_t*)(buf.map(0) + buf.stride(0) * y);
+		uint16_t *line = (uint16_t*)(buf.map(0) + buf.stride(0) * y);
 
 		if (old_xpos >= 0) {
 			for (int x = old_xpos; x < old_xpos + width; ++x)
@@ -85,7 +85,7 @@
 
 	for (unsigned y = 0; y < buf.height(); ++y) {
 		unsigned int bcol = colors[y * ARRAY_SIZE(colors) / buf.height()];
-		uint8_t* line = (uint8_t*)(buf.map(0) + buf.stride(0) * y);
+		uint8_t *line = (uint8_t*)(buf.map(0) + buf.stride(0) * y);
 
 		if (old_xpos >= 0) {
 			for (int x = old_xpos; x < old_xpos + width; ++x)
@@ -129,4 +129,4 @@
 		ASSERT(false);
 	}
 }
-} // namespace kms
+}
diff --git a/kms++util/src/cpuframebuffer.cpp b/kms++util/src/cpuframebuffer.cpp
index c3bc248..d356596 100644
--- a/kms++util/src/cpuframebuffer.cpp
+++ b/kms++util/src/cpuframebuffer.cpp
@@ -4,8 +4,8 @@
 
 using namespace std;
 
-namespace kms
-{
+namespace kms {
+
 CPUFramebuffer::CPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format)
 	: m_width(width), m_height(height), m_format(format)
 {
@@ -18,7 +18,7 @@
 		FramebufferPlane& plane = m_planes[i];
 
 		plane.stride = width * pi.bitspp / 8;
-		plane.size = plane.stride * height / pi.ysub;
+		plane.size = plane.stride * height/ pi.ysub;
 		plane.offset = 0;
 		plane.map = new uint8_t[plane.size];
 	}
@@ -29,8 +29,8 @@
 	for (unsigned i = 0; i < m_num_planes; ++i) {
 		FramebufferPlane& plane = m_planes[i];
 
-		delete[] plane.map;
+		delete plane.map;
 	}
 }
 
-} // namespace kms
+}
diff --git a/kms++util/src/drawing.cpp b/kms++util/src/drawing.cpp
index 79e0d90..194daf8 100644
--- a/kms++util/src/drawing.cpp
+++ b/kms++util/src/drawing.cpp
@@ -15,91 +15,98 @@
 
 	switch (buf.format()) {
 	case PixelFormat::XRGB8888:
-	case PixelFormat::ARGB8888: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::ARGB8888:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.argb8888();
 		break;
 	}
 	case PixelFormat::XBGR8888:
-	case PixelFormat::ABGR8888: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::ABGR8888:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.abgr8888();
 		break;
 	}
 	case PixelFormat::RGBX8888:
-	case PixelFormat::RGBA8888: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::RGBA8888:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.rgba8888();
 		break;
 	}
 	case PixelFormat::BGRX8888:
-	case PixelFormat::BGRA8888: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::BGRA8888:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.bgra8888();
 		break;
 	}
 	case PixelFormat::XRGB2101010:
-	case PixelFormat::ARGB2101010: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::ARGB2101010:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.argb2101010();
 		break;
 	}
 	case PixelFormat::XBGR2101010:
-	case PixelFormat::ABGR2101010: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::ABGR2101010:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.abgr2101010();
 		break;
 	}
 	case PixelFormat::RGBX1010102:
-	case PixelFormat::RGBA1010102: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::RGBA1010102:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.rgba1010102();
 		break;
 	}
 	case PixelFormat::BGRX1010102:
-	case PixelFormat::BGRA1010102: {
-		uint32_t* p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
+	case PixelFormat::BGRA1010102:
+	{
+		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
 		*p = color.bgra1010102();
 		break;
 	}
-	case PixelFormat::RGB888: {
-		uint8_t* p = buf.map(0) + buf.stride(0) * y + x * 3;
+	case PixelFormat::RGB888:
+	{
+		uint8_t *p = buf.map(0) + buf.stride(0) * y + x * 3;
 		p[0] = color.b;
 		p[1] = color.g;
 		p[2] = color.r;
 		break;
 	}
-	case PixelFormat::BGR888: {
-		uint8_t* p = buf.map(0) + buf.stride(0) * y + x * 3;
+	case PixelFormat::BGR888:
+	{
+		uint8_t *p = buf.map(0) + buf.stride(0) * y + x * 3;
 		p[0] = color.r;
 		p[1] = color.g;
 		p[2] = color.b;
 		break;
 	}
-	case PixelFormat::RGB332: {
-		uint8_t* p = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x);
-		*p = color.rgb332();
-		break;
-	}
-	case PixelFormat::RGB565: {
-		uint16_t* p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
+	case PixelFormat::RGB565:
+	{
+		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
 		*p = color.rgb565();
 		break;
 	}
-	case PixelFormat::BGR565: {
-		uint16_t* p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
+	case PixelFormat::BGR565:
+	{
+		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
 		*p = color.bgr565();
 		break;
 	}
-	case PixelFormat::XRGB4444:
-	case PixelFormat::ARGB4444: {
-		uint16_t* p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
+	case PixelFormat::ARGB4444:
+	{
+		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
 		*p = color.argb4444();
 		break;
 	}
-	case PixelFormat::XRGB1555:
-	case PixelFormat::ARGB1555: {
-		uint16_t* p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
+	case PixelFormat::ARGB1555:
+	{
+		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
 		*p = color.argb1555();
 		break;
 	}
@@ -108,37 +115,14 @@
 	}
 }
 
-void draw_yuv444_pixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv)
+void draw_yuv422_macropixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv1, YUV yuv2)
 {
-	if (x >= buf.width() || y >= buf.height())
+	if ((x + 1) >= buf.width() || y >= buf.height())
 		throw runtime_error("attempt to draw outside the buffer");
 
-	uint8_t* py = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x);
-	uint8_t* pu = (uint8_t*)(buf.map(1) + buf.stride(1) * y + x);
-	uint8_t* pv = (uint8_t*)(buf.map(2) + buf.stride(2) * y + x);
+	ASSERT((x & 1) == 0);
 
-	switch (buf.format()) {
-	case PixelFormat::YUV444:
-		py[0] = yuv.y;
-		pu[0] = yuv.u;
-		pv[0] = yuv.v;
-		break;
-
-	case PixelFormat::YVU444:
-		py[0] = yuv.y;
-		pu[0] = yuv.v;
-		pv[0] = yuv.u;
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
-static void draw_yuv422_packed_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-					  YUV yuv1, YUV yuv2)
-{
-	uint8_t* p = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
+	uint8_t *p = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
 
 	uint8_t y0 = yuv1.y;
 	uint8_t y1 = yuv2.y;
@@ -179,178 +163,6 @@
 	}
 }
 
-static void draw_yuv422_semiplanar_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-					      YUV yuv1, YUV yuv2)
-{
-	uint8_t* py = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x);
-	uint8_t* puv = (uint8_t*)(buf.map(1) + buf.stride(1) * y + x);
-
-	uint8_t y0 = yuv1.y;
-	uint8_t y1 = yuv2.y;
-	uint8_t u = (yuv1.u + yuv2.u) / 2;
-	uint8_t v = (yuv1.v + yuv2.v) / 2;
-
-	switch (buf.format()) {
-	case PixelFormat::NV16:
-		py[0] = y0;
-		py[1] = y1;
-		puv[0] = u;
-		puv[1] = v;
-		break;
-
-	case PixelFormat::NV61:
-		py[0] = y0;
-		py[1] = y1;
-		puv[0] = v;
-		puv[1] = u;
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
-static void draw_yuv422_planar_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-					  YUV yuv1, YUV yuv2)
-{
-	uint8_t* py = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x);
-	uint8_t* pu = (uint8_t*)(buf.map(1) + buf.stride(1) * y + x / 2);
-	uint8_t* pv = (uint8_t*)(buf.map(2) + buf.stride(2) * y + x / 2);
-
-	uint8_t y0 = yuv1.y;
-	uint8_t y1 = yuv2.y;
-	uint8_t u = (yuv1.u + yuv2.u) / 2;
-	uint8_t v = (yuv1.v + yuv2.v) / 2;
-
-	switch (buf.format()) {
-	case PixelFormat::YUV422:
-		py[0] = y0;
-		py[1] = y1;
-		pu[0] = u;
-		pv[0] = v;
-		break;
-
-	case PixelFormat::YVU422:
-		py[0] = y0;
-		py[1] = y1;
-		pu[0] = v;
-		pv[0] = u;
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
-void draw_yuv422_macropixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv1, YUV yuv2)
-{
-	if ((x + 1) >= buf.width() || y >= buf.height())
-		throw runtime_error("attempt to draw outside the buffer");
-
-	ASSERT((x & 1) == 0);
-
-	switch (buf.format()) {
-	case PixelFormat::UYVY:
-	case PixelFormat::YUYV:
-	case PixelFormat::YVYU:
-	case PixelFormat::VYUY:
-		draw_yuv422_packed_macropixel(buf, x, y, yuv1, yuv2);
-		break;
-
-	case PixelFormat::NV16:
-	case PixelFormat::NV61:
-		draw_yuv422_semiplanar_macropixel(buf, x, y, yuv1, yuv2);
-		break;
-
-	case PixelFormat::YUV422:
-	case PixelFormat::YVU422:
-		draw_yuv422_planar_macropixel(buf, x, y, yuv1, yuv2);
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
-static void draw_yuv420_semiplanar_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-					      YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4)
-{
-	uint8_t* py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x);
-	uint8_t* py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x);
-
-	uint8_t* puv = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x);
-
-	uint8_t y0 = yuv1.y;
-	uint8_t y1 = yuv2.y;
-	uint8_t y2 = yuv3.y;
-	uint8_t y3 = yuv4.y;
-	uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4;
-	uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4;
-
-	switch (buf.format()) {
-	case PixelFormat::NV12:
-		py1[0] = y0;
-		py1[1] = y1;
-		py2[0] = y2;
-		py2[1] = y3;
-		puv[0] = u;
-		puv[1] = v;
-		break;
-
-	case PixelFormat::NV21:
-		py1[0] = y0;
-		py1[1] = y1;
-		py2[0] = y2;
-		py2[1] = y3;
-		puv[0] = v;
-		puv[1] = u;
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
-static void draw_yuv420_planar_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
-					  YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4)
-{
-	uint8_t* py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x);
-	uint8_t* py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x);
-
-	uint8_t* pu = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x / 2);
-	uint8_t* pv = (uint8_t*)(buf.map(2) + buf.stride(2) * (y / 2) + x / 2);
-
-	uint8_t y0 = yuv1.y;
-	uint8_t y1 = yuv2.y;
-	uint8_t y2 = yuv3.y;
-	uint8_t y3 = yuv4.y;
-	uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4;
-	uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4;
-
-	switch (buf.format()) {
-	case PixelFormat::YUV420:
-		py1[0] = y0;
-		py1[1] = y1;
-		py2[0] = y2;
-		py2[1] = y3;
-		pu[0] = u;
-		pv[0] = v;
-		break;
-
-	case PixelFormat::YVU420:
-		py1[0] = y0;
-		py1[1] = y1;
-		py2[0] = y2;
-		py2[1] = y3;
-		pu[0] = v;
-		pv[0] = u;
-		break;
-
-	default:
-		throw std::invalid_argument("invalid pixelformat");
-	}
-}
-
 void draw_yuv420_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
 			    YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4)
 {
@@ -360,15 +172,35 @@
 	ASSERT((x & 1) == 0);
 	ASSERT((y & 1) == 0);
 
+	uint8_t *py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x);
+	uint8_t *py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x);
+
+	uint8_t *puv = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x);
+
+	uint8_t y0 = yuv1.y;
+	uint8_t y1 = yuv2.y;
+	uint8_t y2 = yuv3.y;
+	uint8_t y3 = yuv4.y;
+	uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4;
+	uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4;
+
 	switch (buf.format()) {
 	case PixelFormat::NV12:
-	case PixelFormat::NV21:
-		draw_yuv420_semiplanar_macropixel(buf, x, y, yuv1, yuv2, yuv3, yuv4);
+		py1[0] = y0;
+		py1[1] = y1;
+		py2[0] = y2;
+		py2[1] = y3;
+		puv[0] = u;
+		puv[1] = v;
 		break;
 
-	case PixelFormat::YUV420:
-	case PixelFormat::YVU420:
-		draw_yuv420_planar_macropixel(buf, x, y, yuv1, yuv2, yuv3, yuv4);
+	case PixelFormat::NV21:
+		py1[0] = y0;
+		py1[1] = y1;
+		py2[0] = y2;
+		py2[1] = y3;
+		puv[0] = v;
+		puv[1] = u;
 		break;
 
 	default:
@@ -376,7 +208,7 @@
 	}
 }
 
-void draw_rect(IFramebuffer& fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color)
+void draw_rect(IFramebuffer &fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color)
 {
 	unsigned i, j;
 	YUV yuvcolor = color.yuv();
@@ -390,11 +222,8 @@
 	case PixelFormat::BGR888:
 	case PixelFormat::RGB565:
 	case PixelFormat::BGR565:
-	case PixelFormat::XRGB4444:
-	case PixelFormat::XRGB1555:
 	case PixelFormat::ARGB4444:
 	case PixelFormat::ARGB1555:
-	case PixelFormat::RGB332:
 		for (j = 0; j < h; j++) {
 			for (i = 0; i < w; i++) {
 				draw_rgb_pixel(fb, x + i, y + j, color);
@@ -402,23 +231,10 @@
 		}
 		break;
 
-	case PixelFormat::YUV444:
-	case PixelFormat::YVU444:
-		for (j = 0; j < h; j++) {
-			for (i = 0; i < w; i++) {
-				draw_yuv444_pixel(fb, x + i, y + j, yuvcolor);
-			}
-		}
-		break;
-
 	case PixelFormat::UYVY:
 	case PixelFormat::YUYV:
 	case PixelFormat::YVYU:
 	case PixelFormat::VYUY:
-	case PixelFormat::NV16:
-	case PixelFormat::NV61:
-	case PixelFormat::YUV422:
-	case PixelFormat::YVU422:
 		for (j = 0; j < h; j++) {
 			for (i = 0; i < w; i += 2) {
 				draw_yuv422_macropixel(fb, x + i, y + j, yuvcolor, yuvcolor);
@@ -428,8 +244,6 @@
 
 	case PixelFormat::NV12:
 	case PixelFormat::NV21:
-	case PixelFormat::YUV420:
-	case PixelFormat::YVU420:
 		for (j = 0; j < h; j += 2) {
 			for (i = 0; i < w; i += 2) {
 				draw_yuv420_macropixel(fb, x + i, y + j,
@@ -482,11 +296,8 @@
 	case PixelFormat::BGR888:
 	case PixelFormat::RGB565:
 	case PixelFormat::BGR565:
-	case PixelFormat::XRGB4444:
-	case PixelFormat::XRGB1555:
 	case PixelFormat::ARGB4444:
 	case PixelFormat::ARGB1555:
-	case PixelFormat::RGB332:
 		for (y = 0; y < 8; y++) {
 			for (x = 0; x < 8; x++) {
 				bool b = get_char_pixel(c, x, y);
@@ -496,25 +307,10 @@
 		}
 		break;
 
-	case PixelFormat::YUV444:
-	case PixelFormat::YVU444:
-		for (y = 0; y < 8; y++) {
-			for (x = 0; x < 8; x++) {
-				bool b = get_char_pixel(c, x, y);
-
-				draw_yuv444_pixel(buf, xpos + x, ypos + y, b ? yuvcolor : YUV(RGB()));
-			}
-		}
-		break;
-
 	case PixelFormat::UYVY:
 	case PixelFormat::YUYV:
 	case PixelFormat::YVYU:
 	case PixelFormat::VYUY:
-	case PixelFormat::NV16:
-	case PixelFormat::NV61:
-	case PixelFormat::YUV422:
-	case PixelFormat::YVU422:
 		for (y = 0; y < 8; y++) {
 			for (x = 0; x < 8; x += 2) {
 				bool b0 = get_char_pixel(c, x, y);
@@ -528,8 +324,6 @@
 
 	case PixelFormat::NV12:
 	case PixelFormat::NV21:
-	case PixelFormat::YUV420:
-	case PixelFormat::YVU420:
 		for (y = 0; y < 8; y += 2) {
 			for (x = 0; x < 8; x += 2) {
 				bool b00 = get_char_pixel(c, x, y);
@@ -550,8 +344,8 @@
 
 void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y, const string& str, RGB color)
 {
-	for (unsigned i = 0; i < str.size(); i++)
+	for(unsigned i = 0; i < str.size(); i++)
 		draw_char(buf, (x + 8 * i), y, str[i], color);
 }
 
-} // namespace kms
+}
diff --git a/kms++util/src/extcpuframebuffer.cpp b/kms++util/src/extcpuframebuffer.cpp
index 0ee79ee..feb3add 100644
--- a/kms++util/src/extcpuframebuffer.cpp
+++ b/kms++util/src/extcpuframebuffer.cpp
@@ -5,6 +5,7 @@
 
 namespace kms
 {
+
 ExtCPUFramebuffer::ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format,
 				     uint8_t* buffer, uint32_t size, uint32_t pitch, uint32_t offset)
 	: m_width(width), m_height(height), m_format(format)
@@ -45,4 +46,4 @@
 {
 }
 
-} // namespace kms
+}
diff --git a/kms++util/src/font_8x8.h b/kms++util/src/font_8x8.h
index ed9bf3f..2a2a1ea 100644
--- a/kms++util/src/font_8x8.h
+++ b/kms++util/src/font_8x8.h
@@ -2567,3 +2567,4 @@
 	0x00, /* 00000000 */
 
 };
+
diff --git a/kms++util/src/opts.cpp b/kms++util/src/opts.cpp
index ba49995..afef452 100644
--- a/kms++util/src/opts.cpp
+++ b/kms++util/src/opts.cpp
@@ -1,5 +1,4 @@
 #include <algorithm>
-#include <stdexcept>
 
 #include <unistd.h>
 #include <getopt.h>
@@ -75,7 +74,7 @@
 		}
 	}
 
-	longopts.push_back(option{});
+	longopts.push_back(option {});
 
 	while (1) {
 		int long_idx = 0;
diff --git a/kms++util/src/resourcemanager.cpp b/kms++util/src/resourcemanager.cpp
index 5a9f016..9a8a66b 100644
--- a/kms++util/src/resourcemanager.cpp
+++ b/kms++util/src/resourcemanager.cpp
@@ -104,11 +104,6 @@
 	return conn;
 }
 
-void ResourceManager::release_connector(Connector* conn)
-{
-	m_reserved_connectors.erase(conn);
-}
-
 Crtc* ResourceManager::reserve_crtc(Connector* conn)
 {
 	if (!conn)
@@ -143,11 +138,6 @@
 	return crtc;
 }
 
-void ResourceManager::release_crtc(Crtc* crtc)
-{
-	m_reserved_crtcs.erase(crtc);
-}
-
 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
 {
 	if (!crtc)
@@ -214,8 +204,3 @@
 {
 	return reserve_plane(crtc, PlaneType::Overlay, format);
 }
-
-void ResourceManager::release_plane(Plane* plane)
-{
-	m_reserved_planes.erase(plane);
-}
diff --git a/kms++util/src/strhelpers.cpp b/kms++util/src/strhelpers.cpp
index 5eba2a9..f59bb6d 100644
--- a/kms++util/src/strhelpers.cpp
+++ b/kms++util/src/strhelpers.cpp
@@ -11,3 +11,17 @@
 	transform(data.begin(), data.end(), data.begin(), ::tolower);
 	return data;
 }
+
+string sformat(const char *fmt, ...)
+{
+	static char s_format_buf[1024];
+
+	va_list args;
+	va_start(args, fmt);
+
+	vsnprintf(s_format_buf, sizeof(s_format_buf), fmt, args);
+
+	va_end(args);
+
+	return string(s_format_buf);
+}
diff --git a/kms++util/src/testpat.cpp b/kms++util/src/testpat.cpp
index 78c9d19..f9a3c8a 100644
--- a/kms++util/src/testpat.cpp
+++ b/kms++util/src/testpat.cpp
@@ -15,6 +15,7 @@
 
 namespace kms
 {
+
 static RGB get_test_pattern_pixel(IFramebuffer& fb, unsigned x, unsigned y)
 {
 	const unsigned w = fb.width();
@@ -105,7 +106,6 @@
 	unsigned w = fb.width();
 
 	const PixelFormatInfo& format_info = get_pixel_format_info(fb.format());
-	const PixelFormatPlaneInfo& plane_info = format_info.planes[format_info.num_planes - 1];
 
 	switch (format_info.type) {
 	case PixelColorType::RGB:
@@ -118,17 +118,8 @@
 		break;
 
 	case PixelColorType::YUV:
-		switch (plane_info.xsub + plane_info.ysub) {
-		case 2:
-			for (y = start_y; y < end_y; y++) {
-				for (x = 0; x < w; x++) {
-					RGB pixel = get_test_pattern_pixel(fb, x, y);
-					draw_yuv444_pixel(fb, x, y, pixel.yuv(yuvt));
-				}
-			}
-			break;
-
-		case 3:
+		switch (format_info.num_planes) {
+		case 1:
 			for (y = start_y; y < end_y; y++) {
 				for (x = 0; x < w; x += 2) {
 					RGB pixel1 = get_test_pattern_pixel(fb, x, y);
@@ -138,7 +129,7 @@
 			}
 			break;
 
-		case 4:
+		case 2:
 			for (y = start_y; y < end_y; y += 2) {
 				for (x = 0; x < w; x += 2) {
 					RGB pixel00 = get_test_pattern_pixel(fb, x, y);
@@ -197,7 +188,7 @@
 #endif
 }
 
-void draw_test_pattern(IFramebuffer& fb, YUVType yuvt)
+void draw_test_pattern(IFramebuffer &fb, YUVType yuvt)
 {
 #ifdef DRAW_PERF_PRINT
 	Stopwatch sw;
@@ -212,4 +203,4 @@
 #endif
 }
 
-} // namespace kms
+}
diff --git a/kms++util/src/videodevice.cpp b/kms++util/src/videodevice.cpp
index 9530d60..cc11357 100644
--- a/kms++util/src/videodevice.cpp
+++ b/kms++util/src/videodevice.cpp
@@ -15,32 +15,16 @@
 using namespace std;
 using namespace kms;
 
-/*
- * V4L2 and DRM differ in their interpretation of YUV420::NV12
- *
- * V4L2 NV12 is a Y and UV co-located planes in a single plane buffer.
- * DRM NV12 is a Y and UV planes presented as dual plane buffer,
- * which is known as NM12 in V4L2.
- *
- * Since here we have hybrid DRM/V4L2 user space helper functions
- * we need to translate DRM::NV12 to V4L2:NM12 pixel format back
- * and forth to keep the data view consistent.
- */
-
 /* V4L2 helper funcs */
 static vector<PixelFormat> v4l2_get_formats(int fd, uint32_t buf_type)
 {
 	vector<PixelFormat> v;
 
-	v4l2_fmtdesc desc{};
+	v4l2_fmtdesc desc { };
 	desc.type = buf_type;
 
 	while (ioctl(fd, VIDIOC_ENUM_FMT, &desc) == 0) {
-		if (desc.pixelformat == V4L2_PIX_FMT_NV12M)
-			v.push_back(PixelFormat::NV12);
-		else if (desc.pixelformat != V4L2_PIX_FMT_NV12)
-			v.push_back((PixelFormat)desc.pixelformat);
-
+		v.push_back((PixelFormat)desc.pixelformat);
 		desc.index++;
 	}
 
@@ -51,7 +35,7 @@
 {
 	int r;
 
-	v4l2_format v4lfmt{};
+	v4l2_format v4lfmt { };
 
 	v4lfmt.type = buf_type;
 	r = ioctl(fd, VIDIOC_G_FMT, &v4lfmt);
@@ -63,14 +47,8 @@
 
 	if (mplane) {
 		v4l2_pix_format_mplane& mp = v4lfmt.fmt.pix_mp;
-		uint32_t used_fmt;
 
-		if (fmt == PixelFormat::NV12)
-			used_fmt = V4L2_PIX_FMT_NV12M;
-		else
-			used_fmt = (uint32_t)fmt;
-
-		mp.pixelformat = used_fmt;
+		mp.pixelformat = (uint32_t)fmt;
 		mp.width = width;
 		mp.height = height;
 
@@ -87,7 +65,7 @@
 		r = ioctl(fd, VIDIOC_S_FMT, &v4lfmt);
 		ASSERT(r == 0);
 
-		ASSERT(mp.pixelformat == used_fmt);
+		ASSERT(mp.pixelformat == (uint32_t)fmt);
 		ASSERT(mp.width == width);
 		ASSERT(mp.height == height);
 
@@ -177,7 +155,7 @@
 
 static void v4l2_request_bufs(int fd, uint32_t queue_size, uint32_t buf_type)
 {
-	v4l2_requestbuffers v4lreqbuf{};
+	v4l2_requestbuffers v4lreqbuf { };
 	v4lreqbuf.type = buf_type;
 	v4lreqbuf.memory = V4L2_MEMORY_DMABUF;
 	v4lreqbuf.count = queue_size;
@@ -188,7 +166,7 @@
 
 static void v4l2_queue_dmabuf(int fd, uint32_t index, DumbFramebuffer* fb, uint32_t buf_type)
 {
-	v4l2_buffer buf{};
+	v4l2_buffer buf { };
 	buf.type = buf_type;
 	buf.memory = V4L2_MEMORY_DMABUF;
 	buf.index = index;
@@ -200,7 +178,7 @@
 	if (mplane) {
 		buf.length = pfi.num_planes;
 
-		v4l2_plane planes[4]{};
+		v4l2_plane planes[4] { };
 		buf.m.planes = planes;
 
 		for (unsigned i = 0; i < pfi.num_planes; ++i) {
@@ -221,12 +199,12 @@
 
 static uint32_t v4l2_dequeue(int fd, uint32_t buf_type)
 {
-	v4l2_buffer buf{};
+	v4l2_buffer buf { };
 	buf.type = buf_type;
 	buf.memory = V4L2_MEMORY_DMABUF;
 
 	// V4L2 crashes if planes are not set
-	v4l2_plane planes[4]{};
+	v4l2_plane planes[4] { };
 	buf.m.planes = planes;
 	buf.length = 4;
 
@@ -237,18 +215,20 @@
 	return buf.index;
 }
 
+
+
+
 VideoDevice::VideoDevice(const string& dev)
-	: VideoDevice(::open(dev.c_str(), O_RDWR | O_NONBLOCK))
+	:VideoDevice(::open(dev.c_str(), O_RDWR | O_NONBLOCK))
 {
 }
 
 VideoDevice::VideoDevice(int fd)
-	: m_fd(fd), m_has_capture(false), m_has_output(false), m_has_m2m(false)
+	: m_fd(fd), m_has_capture(false), m_has_output(false), m_has_m2m(false), m_capture_streamer(0), m_output_streamer(0)
 {
-	if (fd < 0)
-		throw runtime_error("bad fd");
+	FAIL_IF(fd < 0, "Bad fd");
 
-	struct v4l2_capability cap = {};
+	struct v4l2_capability cap = { };
 	int r = ioctl(fd, VIDIOC_QUERYCAP, &cap);
 	ASSERT(r == 0);
 
@@ -296,10 +276,10 @@
 
 	if (!m_capture_streamer) {
 		auto type = m_has_mplane_capture ? VideoStreamer::StreamerType::CaptureMulti : VideoStreamer::StreamerType::CaptureSingle;
-		m_capture_streamer = std::unique_ptr<VideoStreamer>(new VideoStreamer(m_fd, type));
+		m_capture_streamer = new VideoStreamer(m_fd, type);
 	}
 
-	return m_capture_streamer.get();
+	return m_capture_streamer;
 }
 
 VideoStreamer* VideoDevice::get_output_streamer()
@@ -308,17 +288,17 @@
 
 	if (!m_output_streamer) {
 		auto type = m_has_mplane_output ? VideoStreamer::StreamerType::OutputMulti : VideoStreamer::StreamerType::OutputSingle;
-		m_output_streamer = std::unique_ptr<VideoStreamer>(new VideoStreamer(m_fd, type));
+		m_output_streamer = new VideoStreamer(m_fd, type);
 	}
 
-	return m_output_streamer.get();
+	return m_output_streamer;
 }
 
 vector<tuple<uint32_t, uint32_t>> VideoDevice::get_discrete_frame_sizes(PixelFormat fmt)
 {
 	vector<tuple<uint32_t, uint32_t>> v;
 
-	v4l2_frmsizeenum v4lfrms{};
+	v4l2_frmsizeenum v4lfrms { };
 	v4lfrms.pixel_format = (uint32_t)fmt;
 
 	int r = ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms);
@@ -336,7 +316,7 @@
 
 VideoDevice::VideoFrameSize VideoDevice::get_frame_sizes(PixelFormat fmt)
 {
-	v4l2_frmsizeenum v4lfrms{};
+	v4l2_frmsizeenum v4lfrms { };
 	v4lfrms.pixel_format = (uint32_t)fmt;
 
 	int r = ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms);
@@ -368,13 +348,10 @@
 		if (stat(name.c_str(), &buffer) != 0)
 			continue;
 
-		try {
-			VideoDevice vid(name);
+		VideoDevice vid(name);
 
-			if (vid.has_capture() && !vid.has_m2m())
-				v.push_back(name);
-		} catch (...) {
-		}
+		if (vid.has_capture() && !vid.has_m2m())
+			v.push_back(name);
 	}
 
 	return v;
@@ -391,21 +368,20 @@
 		if (stat(name.c_str(), &buffer) != 0)
 			continue;
 
-		try {
-			VideoDevice vid(name);
+		VideoDevice vid(name);
 
-			if (vid.has_m2m())
-				v.push_back(name);
-		} catch (...) {
-		}
+		if (vid.has_m2m())
+			v.push_back(name);
 	}
 
 	return v;
 }
 
+
 VideoStreamer::VideoStreamer(int fd, StreamerType type)
 	: m_fd(fd), m_type(type)
 {
+
 }
 
 std::vector<string> VideoStreamer::get_ports()
@@ -414,9 +390,9 @@
 
 	switch (m_type) {
 	case StreamerType::CaptureSingle:
-	case StreamerType::CaptureMulti: {
-		struct v4l2_input input {
-		};
+	case StreamerType::CaptureMulti:
+	{
+		struct v4l2_input input { };
 
 		while (ioctl(m_fd, VIDIOC_ENUMINPUT, &input) == 0) {
 			v.push_back(string((char*)&input.name));
@@ -427,9 +403,9 @@
 	}
 
 	case StreamerType::OutputSingle:
-	case StreamerType::OutputMulti: {
-		struct v4l2_output output {
-		};
+	case StreamerType::OutputMulti:
+	{
+		struct v4l2_output output { };
 
 		while (ioctl(m_fd, VIDIOC_ENUMOUTPUT, &output) == 0) {
 			v.push_back(string((char*)&output.name));
diff --git a/kmscube/CMakeLists.txt b/kmscube/CMakeLists.txt
new file mode 100644
index 0000000..b6bac29
--- /dev/null
+++ b/kmscube/CMakeLists.txt
@@ -0,0 +1,45 @@
+
+pkg_check_modules(GLESv2 glesv2 REQUIRED)
+pkg_check_modules(EGL egl REQUIRED)
+pkg_check_modules(GBM gbm REQUIRED)
+pkg_check_modules(X11 x11 REQUIRED)
+pkg_check_modules(XCB xcb REQUIRED)
+pkg_check_modules(X11XCB x11-xcb REQUIRED)
+pkg_check_modules(WL wayland-client REQUIRED)
+pkg_check_modules(WL_EGL wayland-egl REQUIRED)
+
+
+include_directories(
+    ${LIBDRM_INCLUDE_DIRS}
+    ${GLESv2_INCLUDE_DIRS}
+    ${EGL_INCLUDE_DIRS}
+    ${GBM_INCLUDE_DIRS}
+    ${X11_INCLUDE_DIRS}
+    ${XCB_INCLUDE_DIRS}
+    ${X11XCB_INCLUDE_DIRS}
+)
+
+link_directories(
+    ${LIBDRM_LIBRARY_DIRS}
+    ${GLESv2_LIBRARY_DIRS}
+    ${EGL_LIBRARY_DIRS}
+    ${GBM_LIBRARY_DIRS}
+    ${X11_LIBRARY_DIRS}
+    ${XCB_LIBRARY_DIRS}
+    ${X11XCB_LIBRARY_DIRS}
+)
+
+add_executable (kmscube cube.cpp cube.h cube-egl.cpp cube-egl.h cube-gles2.cpp cube-gles2.h
+    cube-null.cpp cube-gbm.cpp cube-x11.cpp cube-wl.cpp
+    esTransform.c esTransform.h)
+target_link_libraries(kmscube kms++ kms++util
+    ${LIBDRM_LIBRARIES}
+    ${GLESv2_LIBRARIES}
+    ${EGL_LIBRARIES}
+    ${GBM_LIBRARIES}
+    ${X11_LIBRARIES}
+    ${XCB_LIBRARIES}
+    ${X11XCB_LIBRARIES}
+    ${WL_LIBRARIES}
+    ${WL_EGL_LIBRARIES}
+)
diff --git a/kmscube/cube-egl.cpp b/kmscube/cube-egl.cpp
index 5f23c4e..81b3107 100644
--- a/kmscube/cube-egl.cpp
+++ b/kmscube/cube-egl.cpp
@@ -22,7 +22,7 @@
 	       getconf(EGL_NATIVE_VISUAL_TYPE));
 }
 
-EglState::EglState(void* native_display)
+EglState::EglState(void *native_display)
 {
 	EGLBoolean b;
 	EGLint major, minor, n;
@@ -60,6 +60,7 @@
 	b = eglBindAPI(EGL_OPENGL_ES_API);
 	FAIL_IF(!b, "failed to bind api EGL_OPENGL_ES_API");
 
+
 	if (s_verbose) {
 		EGLint numConfigs;
 		b = eglGetConfigs(m_display, nullptr, 0, &numConfigs);
@@ -95,7 +96,7 @@
 	eglTerminate(m_display);
 }
 
-EglSurface::EglSurface(const EglState& egl, void* native_window)
+EglSurface::EglSurface(const EglState &egl, void *native_window)
 	: egl(egl)
 {
 	esurface = eglCreateWindowSurface(egl.display(), egl.config(), (EGLNativeWindowType)native_window, NULL);
diff --git a/kmscube/cube-egl.h b/kmscube/cube-egl.h
index f492d07..a7de103 100644
--- a/kmscube/cube-egl.h
+++ b/kmscube/cube-egl.h
@@ -5,7 +5,7 @@
 class EglState
 {
 public:
-	EglState(void* native_display);
+	EglState(void *native_display);
 	~EglState();
 
 	EGLDisplay display() const { return m_display; }
@@ -21,7 +21,7 @@
 class EglSurface
 {
 public:
-	EglSurface(const EglState& egl, void* native_window);
+	EglSurface(const EglState& egl, void *native_window);
 	~EglSurface();
 
 	void make_current();
diff --git a/kmscube/cube-gbm.cpp b/kmscube/cube-gbm.cpp
index d998f0b..e239a0c 100644
--- a/kmscube/cube-gbm.cpp
+++ b/kmscube/cube-gbm.cpp
@@ -74,7 +74,7 @@
 		return gbm_surface_lock_front_buffer(m_surface);
 	}
 
-	void release_buffer(gbm_bo* bo)
+	void release_buffer(gbm_bo *bo)
 	{
 		gbm_surface_release_buffer(m_surface, bo);
 	}
@@ -116,13 +116,13 @@
 		eglSwapBuffers(egl.display(), esurface);
 	}
 
-	static void drm_fb_destroy_callback(struct gbm_bo* bo, void* data)
+	static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
 	{
 		auto fb = reinterpret_cast<Framebuffer*>(data);
 		delete fb;
 	}
 
-	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo* bo, Card& card)
+	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo *bo, Card& card)
 	{
 		auto fb = reinterpret_cast<Framebuffer*>(gbm_bo_get_user_data(bo));
 		if (fb)
@@ -134,9 +134,9 @@
 		uint32_t handle = gbm_bo_get_handle(bo).u32;
 		PixelFormat format = (PixelFormat)gbm_bo_get_format(bo);
 
-		vector<uint32_t> handles{ handle };
-		vector<uint32_t> strides{ stride };
-		vector<uint32_t> offsets{ 0 };
+		vector<uint32_t> handles { handle };
+		vector<uint32_t> strides { stride };
+		vector<uint32_t> offsets { 0 };
 
 		fb = new ExtFramebuffer(card, width, height, format, handles, strides, offsets);
 
@@ -237,7 +237,7 @@
 	{
 		++m_frame_num;
 
-		if (m_frame_num % 100 == 0) {
+		if (m_frame_num  % 100 == 0) {
 			auto t2 = chrono::steady_clock::now();
 			chrono::duration<float> fsec = t2 - m_t1;
 			printf("fps: %f\n", 100.0 / fsec.count());
@@ -351,11 +351,11 @@
 	for (auto& out : outputs)
 		out->start_flipping();
 
-	struct pollfd fds[2] = {};
+	struct pollfd fds[2] = { };
 	fds[0].fd = 0;
-	fds[0].events = POLLIN;
+	fds[0].events =  POLLIN;
 	fds[1].fd = card.fd();
-	fds[1].events = POLLIN;
+	fds[1].events =  POLLIN;
 
 	while (!s_need_exit || s_flip_pending) {
 		int r = poll(fds, ARRAY_SIZE(fds), -1);
diff --git a/kmscube/cube-gles2.cpp b/kmscube/cube-gles2.cpp
index 854c90e..05567ea 100644
--- a/kmscube/cube-gles2.cpp
+++ b/kmscube/cube-gles2.cpp
@@ -41,40 +41,40 @@
 		-1.0f, -1.0f, -1.0f, // point black
 		+1.0f, -1.0f, -1.0f, // point red
 		-1.0f, -1.0f, +1.0f, // point blue
-		+1.0f, -1.0f, +1.0f // point magenta
+		+1.0f, -1.0f, +1.0f  // point magenta
 	};
 
 	static const GLfloat vColors[] = {
 		// front
-		0.0f, 0.0f, 1.0f, // blue
-		1.0f, 0.0f, 1.0f, // magenta
-		0.0f, 1.0f, 1.0f, // cyan
-		1.0f, 1.0f, 1.0f, // white
+		0.0f,  0.0f,  1.0f, // blue
+		1.0f,  0.0f,  1.0f, // magenta
+		0.0f,  1.0f,  1.0f, // cyan
+		1.0f,  1.0f,  1.0f, // white
 		// back
-		1.0f, 0.0f, 0.0f, // red
-		0.0f, 0.0f, 0.0f, // black
-		1.0f, 1.0f, 0.0f, // yellow
-		0.0f, 1.0f, 0.0f, // green
+		1.0f,  0.0f,  0.0f, // red
+		0.0f,  0.0f,  0.0f, // black
+		1.0f,  1.0f,  0.0f, // yellow
+		0.0f,  1.0f,  0.0f, // green
 		// right
-		1.0f, 0.0f, 1.0f, // magenta
-		1.0f, 0.0f, 0.0f, // red
-		1.0f, 1.0f, 1.0f, // white
-		1.0f, 1.0f, 0.0f, // yellow
+		1.0f,  0.0f,  1.0f, // magenta
+		1.0f,  0.0f,  0.0f, // red
+		1.0f,  1.0f,  1.0f, // white
+		1.0f,  1.0f,  0.0f, // yellow
 		// left
-		0.0f, 0.0f, 0.0f, // black
-		0.0f, 0.0f, 1.0f, // blue
-		0.0f, 1.0f, 0.0f, // green
-		0.0f, 1.0f, 1.0f, // cyan
+		0.0f,  0.0f,  0.0f, // black
+		0.0f,  0.0f,  1.0f, // blue
+		0.0f,  1.0f,  0.0f, // green
+		0.0f,  1.0f,  1.0f, // cyan
 		// top
-		0.0f, 1.0f, 1.0f, // cyan
-		1.0f, 1.0f, 1.0f, // white
-		0.0f, 1.0f, 0.0f, // green
-		1.0f, 1.0f, 0.0f, // yellow
+		0.0f,  1.0f,  1.0f, // cyan
+		1.0f,  1.0f,  1.0f, // white
+		0.0f,  1.0f,  0.0f, // green
+		1.0f,  1.0f,  0.0f, // yellow
 		// bottom
-		0.0f, 0.0f, 0.0f, // black
-		1.0f, 0.0f, 0.0f, // red
-		0.0f, 0.0f, 1.0f, // blue
-		1.0f, 0.0f, 1.0f // magenta
+		0.0f,  0.0f,  0.0f, // black
+		1.0f,  0.0f,  0.0f, // red
+		0.0f,  0.0f,  1.0f, // blue
+		1.0f,  0.0f,  1.0f  // magenta
 	};
 
 	static const GLfloat vNormals[] = {
@@ -107,42 +107,43 @@
 		+0.0f, -1.0f, +0.0f, // down
 		+0.0f, -1.0f, +0.0f, // down
 		+0.0f, -1.0f, +0.0f, // down
-		+0.0f, -1.0f, +0.0f // down
+		+0.0f, -1.0f, +0.0f  // down
 	};
 
-	static const char* vertex_shader_source =
-		"uniform mat4 modelviewMatrix;      \n"
-		"uniform mat4 modelviewprojectionMatrix;\n"
-		"uniform mat3 normalMatrix;         \n"
-		"                                   \n"
-		"attribute vec4 in_position;        \n"
-		"attribute vec3 in_normal;          \n"
-		"attribute vec4 in_color;           \n"
-		"\n"
-		"vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
-		"                                   \n"
-		"varying vec4 vVaryingColor;        \n"
-		"                                   \n"
-		"void main()                        \n"
-		"{                                  \n"
-		"    gl_Position = modelviewprojectionMatrix * in_position;\n"
-		"    vec3 vEyeNormal = normalMatrix * in_normal;\n"
-		"    vec4 vPosition4 = modelviewMatrix * in_position;\n"
-		"    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
-		"    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
-		"    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
-		"    vVaryingColor = vec4(diff * in_color.rgb, 1.0);\n"
-		"}                                  \n";
+	static const char *vertex_shader_source =
+			"uniform mat4 modelviewMatrix;      \n"
+			"uniform mat4 modelviewprojectionMatrix;\n"
+			"uniform mat3 normalMatrix;         \n"
+			"                                   \n"
+			"attribute vec4 in_position;        \n"
+			"attribute vec3 in_normal;          \n"
+			"attribute vec4 in_color;           \n"
+			"\n"
+			"vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0);\n"
+			"                                   \n"
+			"varying vec4 vVaryingColor;        \n"
+			"                                   \n"
+			"void main()                        \n"
+			"{                                  \n"
+			"    gl_Position = modelviewprojectionMatrix * in_position;\n"
+			"    vec3 vEyeNormal = normalMatrix * in_normal;\n"
+			"    vec4 vPosition4 = modelviewMatrix * in_position;\n"
+			"    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;\n"
+			"    vec3 vLightDir = normalize(lightSource.xyz - vPosition3);\n"
+			"    float diff = max(0.0, dot(vEyeNormal, vLightDir));\n"
+			"    vVaryingColor = vec4(diff * in_color.rgb, 1.0);\n"
+			"}                                  \n";
 
-	static const char* fragment_shader_source =
-		"precision mediump float;           \n"
-		"                                   \n"
-		"varying vec4 vVaryingColor;        \n"
-		"                                   \n"
-		"void main()                        \n"
-		"{                                  \n"
-		"    gl_FragColor = vVaryingColor;  \n"
-		"}                                  \n";
+	static const char *fragment_shader_source =
+			"precision mediump float;           \n"
+			"                                   \n"
+			"varying vec4 vVaryingColor;        \n"
+			"                                   \n"
+			"void main()                        \n"
+			"{                                  \n"
+			"    gl_FragColor = vVaryingColor;  \n"
+			"}                                  \n";
+
 
 	if (s_verbose) {
 		printf("GL_VENDOR:       %s\n", glGetString(GL_VENDOR));
diff --git a/kmscube/cube-null.cpp b/kmscube/cube-null.cpp
index 1fba1db..f8f2091 100644
--- a/kmscube/cube-null.cpp
+++ b/kmscube/cube-null.cpp
@@ -18,9 +18,9 @@
 
 	int framenum = 0;
 
-	struct pollfd fds[1] = {};
+	struct pollfd fds[1] = { };
 	fds[0].fd = 0;
-	fds[0].events = POLLIN;
+	fds[0].events =  POLLIN;
 
 	while (true) {
 		int r = poll(fds, ARRAY_SIZE(fds), 0);
diff --git a/kmscube/cube-wl.cpp b/kmscube/cube-wl.cpp
index 136a4ed..de75f88 100644
--- a/kmscube/cube-wl.cpp
+++ b/kmscube/cube-wl.cpp
@@ -9,18 +9,18 @@
 #include "cube-egl.h"
 #include "cube-gles2.h"
 
-static struct wl_compositor* s_compositor = NULL;
-static struct wl_shell* s_shell = NULL;
+static struct wl_compositor *s_compositor = NULL;
+static struct wl_shell *s_shell = NULL;
 static char s_running = 1;
 
 struct window {
-	struct wl_surface* surface;
-	struct wl_shell_surface* shell_surface;
-	struct wl_egl_window* egl_window;
+	struct wl_surface *surface;
+	struct wl_shell_surface *shell_surface;
+	struct wl_egl_window *egl_window;
 };
 
 // listeners
-static void registry_add_object(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
+static void registry_add_object(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
 {
 	if (!strcmp(interface, "wl_compositor"))
 		s_compositor = (struct wl_compositor*)wl_registry_bind(registry, name, &wl_compositor_interface, 0);
@@ -28,33 +28,35 @@
 		s_shell = (struct wl_shell*)wl_registry_bind(registry, name, &wl_shell_interface, 0);
 }
 
-static void registry_remove_object(void* data, struct wl_registry* registry, uint32_t name)
+static void registry_remove_object(void *data, struct wl_registry *registry, uint32_t name)
 {
+
 }
 
 static struct wl_registry_listener registry_listener = { &registry_add_object, &registry_remove_object };
 
-static void shell_surface_ping(void* data, struct wl_shell_surface* shell_surface, uint32_t serial)
+static void shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial)
 {
 	wl_shell_surface_pong(shell_surface, serial);
 }
 
-static void shell_surface_configure(void* data, struct wl_shell_surface* shell_surface, uint32_t edges, int32_t width, int32_t height)
+static void shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height)
 {
-	struct window* window = (struct window*)data;
+	struct window *window = (struct window*)data;
 
 	wl_egl_window_resize(window->egl_window, width, height, 0, 0);
 }
 
-static void shell_surface_popup_done(void* data, struct wl_shell_surface* shell_surface)
+static void shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface)
 {
+
 }
 
 static struct wl_shell_surface_listener shell_surface_listener = {
 	&shell_surface_ping, &shell_surface_configure, &shell_surface_popup_done
 };
 
-static void create_window(struct window* window, int32_t width, int32_t height)
+static void create_window(struct window *window, int32_t width, int32_t height)
 {
 	window->surface = wl_compositor_create_surface(s_compositor);
 	window->shell_surface = wl_shell_get_shell_surface(s_shell, window->surface);
@@ -63,7 +65,7 @@
 	window->egl_window = wl_egl_window_create(window->surface, width, height);
 }
 
-static void delete_window(struct window* window)
+static void delete_window(struct window *window)
 {
 	wl_egl_window_destroy(window->egl_window);
 	wl_shell_surface_destroy(window->shell_surface);
@@ -72,8 +74,8 @@
 
 void main_wl()
 {
-	struct wl_display* display = wl_display_connect(NULL);
-	struct wl_registry* registry = wl_display_get_registry(display);
+	struct wl_display *display = wl_display_connect(NULL);
+	struct wl_registry *registry = wl_display_get_registry(display);
 	wl_registry_add_listener(registry, &registry_listener, NULL);
 	wl_display_roundtrip(display);
 
diff --git a/kmscube/cube-x11.cpp b/kmscube/cube-x11.cpp
index ae018ea..47a1d2b 100644
--- a/kmscube/cube-x11.cpp
+++ b/kmscube/cube-x11.cpp
@@ -10,7 +10,7 @@
 
 using namespace std;
 
-static void main_loop(Display* dpy, xcb_connection_t* c, xcb_window_t window, uint32_t width, uint32_t height)
+static void main_loop(Display* dpy, xcb_connection_t *c, xcb_window_t window, uint32_t width, uint32_t height)
 {
 	EglState egl(dpy);
 	EglSurface surface(egl, (void*)(uintptr_t)window);
@@ -25,9 +25,10 @@
 
 	bool need_exit = false;
 
-	xcb_generic_event_t* event;
+	xcb_generic_event_t *event;
 	while (true) {
-		while ((event = xcb_poll_for_event(c))) {
+
+		while ((event = xcb_poll_for_event (c))) {
 			bool handled = false;
 			uint8_t response_type = event->response_type & ~0x80;
 
@@ -39,7 +40,7 @@
 			case XCB_KEY_PRESS: {
 				handled = true;
 
-				xcb_key_press_event_t* kp = (xcb_key_press_event_t*)event;
+				xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
 				if (kp->detail == 24 || kp->detail == 9) {
 					printf("Exit due to keypress\n");
 					need_exit = true;
@@ -84,14 +85,14 @@
 	Display* dpy = XOpenDisplay(NULL);
 	FAIL_IF(!dpy, "Failed to connect to the X server");
 
-	xcb_connection_t* c = XGetXCBConnection(dpy);
+	xcb_connection_t *c = XGetXCBConnection(dpy);
 
 	/* Acquire event queue ownership */
 	XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
 
 	/* Get the first screen */
-	const xcb_setup_t* setup = xcb_get_setup(c);
-	xcb_screen_t* screen = xcb_setup_roots_iterator(setup).data;
+	const xcb_setup_t      *setup  = xcb_get_setup (c);
+	xcb_screen_t           *screen = xcb_setup_roots_iterator (setup).data;
 
 	/* Create the window */
 
@@ -114,22 +115,23 @@
 		XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS,
 	};
 
-	xcb_window_t window = xcb_generate_id(c);
-	xcb_create_window(c, /* Connection          */
-			  XCB_COPY_FROM_PARENT, /* depth (same as root)*/
-			  window, /* window Id           */
-			  screen->root, /* parent window       */
-			  0, 0, /* x, y                */
-			  width, height, /* width, height       */
-			  0, /* border_width        */
-			  XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
-			  screen->root_visual, /* visual              */
-			  xcb_window_attrib_mask,
-			  xcb_window_attrib_list);
+	xcb_window_t window = xcb_generate_id (c);
+	xcb_create_window (c,                    /* Connection          */
+			   XCB_COPY_FROM_PARENT,          /* depth (same as root)*/
+			   window,                        /* window Id           */
+			   screen->root,                  /* parent window       */
+			   0, 0,                          /* x, y                */
+			   width, height,                 /* width, height       */
+			   0,                             /* border_width        */
+			   XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
+			   screen->root_visual,           /* visual              */
+			   xcb_window_attrib_mask,
+			   xcb_window_attrib_list);
 
-	if (s_fullscreen) {
-		const char* net_wm_state = "_NET_WM_STATE";
-		const char* net_wm_state_fullscreen = "_NET_WM_STATE_FULLSCREEN";
+	if (s_fullscreen)
+	{
+		const char *net_wm_state = "_NET_WM_STATE";
+		const char *net_wm_state_fullscreen = "_NET_WM_STATE_FULLSCREEN";
 
 		xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, 0, strlen(net_wm_state), net_wm_state);
 		xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(c, cookie, 0);
@@ -137,11 +139,11 @@
 		xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(c, 0, strlen(net_wm_state_fullscreen), net_wm_state_fullscreen);
 		xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, 0);
 
-		xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, reply->atom, XCB_ATOM_ATOM, 32, 1, (void*)&reply2->atom);
+		xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, reply->atom, XCB_ATOM_ATOM , 32, 1, (void*)&reply2->atom);
 	}
 
-	xcb_map_window(c, window);
-	xcb_flush(c);
+	xcb_map_window (c, window);
+	xcb_flush (c);
 
 	main_loop(dpy, c, window, width, height);
 
diff --git a/kmscube/cube.cpp b/kmscube/cube.cpp
index 406bb8d..4129554 100644
--- a/kmscube/cube.cpp
+++ b/kmscube/cube.cpp
@@ -34,21 +34,24 @@
 bool s_fullscreen;
 unsigned s_num_frames;
 
-int main(int argc, char* argv[])
+int main(int argc, char *argv[])
 {
 	OptionSet optionset = {
 		Option("v|verbose",
-		       [&]() {
-			       s_verbose = true;
-		       }),
+		[&]()
+		{
+			s_verbose = true;
+		}),
 		Option("f|fullscreen",
-		       [&]() {
-			       s_fullscreen = true;
-		       }),
+		[&]()
+		{
+			s_fullscreen = true;
+		}),
 		Option("n|numframes=",
-		       [&](string s) {
-			       s_num_frames = stoi(s);
-		       }),
+		[&](string s)
+		{
+			s_num_frames = stoi(s);
+		}),
 	};
 
 	optionset.parse(argc, argv);
diff --git a/kmscube/cube.h b/kmscube/cube.h
index 18ab0e0..6368162 100644
--- a/kmscube/cube.h
+++ b/kmscube/cube.h
@@ -8,3 +8,4 @@
 void main_gbm();
 void main_x11();
 void main_wl();
+
diff --git a/kmscube/esTransform.cpp b/kmscube/esTransform.c
similarity index 68%
rename from kmscube/esTransform.cpp
rename to kmscube/esTransform.c
index daa28ac..899c038 100644
--- a/kmscube/esTransform.cpp
+++ b/kmscube/esTransform.c
@@ -46,7 +46,8 @@
 
 #define PI 3.1415926535897932384626433832795f
 
-void esScale(ESMatrix* result, GLfloat sx, GLfloat sy, GLfloat sz)
+void
+esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz)
 {
 	result->m[0][0] *= sx;
 	result->m[0][1] *= sx;
@@ -64,7 +65,8 @@
 	result->m[2][3] *= sz;
 }
 
-void esTranslate(ESMatrix* result, GLfloat tx, GLfloat ty, GLfloat tz)
+void
+esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz)
 {
 	result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
 	result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
@@ -72,14 +74,16 @@
 	result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
 }
 
-void esRotate(ESMatrix* result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+void
+esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 {
 	GLfloat sinAngle, cosAngle;
 	GLfloat mag = sqrtf(x * x + y * y + z * z);
 
-	sinAngle = sinf(angle * PI / 180.0f);
-	cosAngle = cosf(angle * PI / 180.0f);
-	if (mag > 0.0f) {
+	sinAngle = sinf ( angle * PI / 180.0f );
+	cosAngle = cosf ( angle * PI / 180.0f );
+	if ( mag > 0.0f )
+	{
 		GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
 		GLfloat oneMinusCos;
 		ESMatrix rotMat;
@@ -119,19 +123,20 @@
 		rotMat.m[3][2] = 0.0F;
 		rotMat.m[3][3] = 1.0F;
 
-		esMatrixMultiply(result, &rotMat, result);
+		esMatrixMultiply( result, &rotMat, result );
 	}
 }
 
-void esFrustum(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
+void
+esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
 {
-	float deltaX = right - left;
-	float deltaY = top - bottom;
-	float deltaZ = farZ - nearZ;
-	ESMatrix frust;
+	float       deltaX = right - left;
+	float       deltaY = top - bottom;
+	float       deltaZ = farZ - nearZ;
+	ESMatrix    frust;
 
-	if ((nearZ <= 0.0f) || (farZ <= 0.0f) ||
-	    (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f))
+	if ( (nearZ <= 0.0f) || (farZ <= 0.0f) ||
+			(deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) )
 		return;
 
 	frust.m[0][0] = 2.0f * nearZ / deltaX;
@@ -151,24 +156,27 @@
 	esMatrixMultiply(result, &frust, result);
 }
 
-void esPerspective(ESMatrix* result, float fovy, float aspect, float nearZ, float farZ)
+
+void
+esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ)
 {
 	GLfloat frustumW, frustumH;
 
-	frustumH = tanf(fovy / 360.0f * PI) * nearZ;
+	frustumH = tanf( fovy / 360.0f * PI ) * nearZ;
 	frustumW = frustumH * aspect;
 
-	esFrustum(result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
+	esFrustum( result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ );
 }
 
-void esOrtho(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
+void
+esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
 {
-	float deltaX = right - left;
-	float deltaY = top - bottom;
-	float deltaZ = farZ - nearZ;
-	ESMatrix ortho;
+	float       deltaX = right - left;
+	float       deltaY = top - bottom;
+	float       deltaZ = farZ - nearZ;
+	ESMatrix    ortho;
 
-	if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f))
+	if ( (deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f) )
 		return;
 
 	esMatrixLoadIdentity(&ortho);
@@ -182,36 +190,41 @@
 	esMatrixMultiply(result, &ortho, result);
 }
 
-void esMatrixMultiply(ESMatrix* result, ESMatrix* srcA, ESMatrix* srcB)
+
+void
+esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB)
 {
-	ESMatrix tmp;
-	int i;
+	ESMatrix    tmp;
+	int         i;
 
-	for (i = 0; i < 4; i++) {
-		tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
-			      (srcA->m[i][1] * srcB->m[1][0]) +
-			      (srcA->m[i][2] * srcB->m[2][0]) +
-			      (srcA->m[i][3] * srcB->m[3][0]);
+	for (i=0; i<4; i++)
+	{
+		tmp.m[i][0] =	(srcA->m[i][0] * srcB->m[0][0]) +
+				(srcA->m[i][1] * srcB->m[1][0]) +
+				(srcA->m[i][2] * srcB->m[2][0]) +
+				(srcA->m[i][3] * srcB->m[3][0]) ;
 
-		tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
-			      (srcA->m[i][1] * srcB->m[1][1]) +
-			      (srcA->m[i][2] * srcB->m[2][1]) +
-			      (srcA->m[i][3] * srcB->m[3][1]);
+		tmp.m[i][1] =	(srcA->m[i][0] * srcB->m[0][1]) +
+				(srcA->m[i][1] * srcB->m[1][1]) +
+				(srcA->m[i][2] * srcB->m[2][1]) +
+				(srcA->m[i][3] * srcB->m[3][1]) ;
 
-		tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
-			      (srcA->m[i][1] * srcB->m[1][2]) +
-			      (srcA->m[i][2] * srcB->m[2][2]) +
-			      (srcA->m[i][3] * srcB->m[3][2]);
+		tmp.m[i][2] =	(srcA->m[i][0] * srcB->m[0][2]) +
+				(srcA->m[i][1] * srcB->m[1][2]) +
+				(srcA->m[i][2] * srcB->m[2][2]) +
+				(srcA->m[i][3] * srcB->m[3][2]) ;
 
-		tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
-			      (srcA->m[i][1] * srcB->m[1][3]) +
-			      (srcA->m[i][2] * srcB->m[2][3]) +
-			      (srcA->m[i][3] * srcB->m[3][3]);
+		tmp.m[i][3] =	(srcA->m[i][0] * srcB->m[0][3]) +
+				(srcA->m[i][1] * srcB->m[1][3]) +
+				(srcA->m[i][2] * srcB->m[2][3]) +
+				(srcA->m[i][3] * srcB->m[3][3]) ;
 	}
 	memcpy(result, &tmp, sizeof(ESMatrix));
 }
 
-void esMatrixLoadIdentity(ESMatrix* result)
+
+void
+esMatrixLoadIdentity(ESMatrix *result)
 {
 	memset(result, 0x0, sizeof(ESMatrix));
 	result->m[0][0] = 1.0f;
@@ -219,3 +232,4 @@
 	result->m[2][2] = 1.0f;
 	result->m[3][3] = 1.0f;
 }
+
diff --git a/kmscube/esTransform.h b/kmscube/esTransform.h
index f89e7b4..c0383ab 100644
--- a/kmscube/esTransform.h
+++ b/kmscube/esTransform.h
@@ -52,7 +52,7 @@
 
 typedef struct
 {
-	GLfloat m[4][4];
+	GLfloat   m[4][4];
 } ESMatrix;
 
 //
@@ -60,14 +60,14 @@
 /// \param result Specifies the input matrix.  Scaled matrix is returned in result.
 /// \param sx, sy, sz Scale factors along the x, y and z axes respectively
 //
-void esScale(ESMatrix* result, GLfloat sx, GLfloat sy, GLfloat sz);
+void esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz);
 
 //
 /// \brief multiply matrix specified by result with a translation matrix and return new matrix in result
 /// \param result Specifies the input matrix.  Translated matrix is returned in result.
 /// \param tx, ty, tz Scale factors along the x, y and z axes respectively
 //
-void esTranslate(ESMatrix* result, GLfloat tx, GLfloat ty, GLfloat tz);
+void esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz);
 
 //
 /// \brief multiply matrix specified by result with a rotation matrix and return new matrix in result
@@ -75,7 +75,7 @@
 /// \param angle Specifies the angle of rotation, in degrees.
 /// \param x, y, z Specify the x, y and z coordinates of a vector, respectively
 //
-void esRotate(ESMatrix* result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
 
 //
 // \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
@@ -84,7 +84,7 @@
 /// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
 /// \param nearZ, farZ Distances to the near and far depth clipping planes.  Both distances must be positive.
 //
-void esFrustum(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ);
+void esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
 
 //
 /// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
@@ -94,7 +94,7 @@
 /// \param nearZ Near plane distance
 /// \param farZ Far plane distance
 //
-void esPerspective(ESMatrix* result, float fovy, float aspect, float nearZ, float farZ);
+void esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ);
 
 //
 /// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
@@ -103,20 +103,20 @@
 /// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
 /// \param nearZ, farZ Distances to the near and far depth clipping planes.  These values are negative if plane is behind the viewer
 //
-void esOrtho(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ);
+void esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
 
 //
 /// \brief perform the following operation - result matrix = srcA matrix * srcB matrix
 /// \param result Returns multiplied matrix
 /// \param srcA, srcB Input matrices to be multiplied
 //
-void esMatrixMultiply(ESMatrix* result, ESMatrix* srcA, ESMatrix* srcB);
+void esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB);
 
 //
 //// \brief return an indentity matrix
 //// \param result returns identity matrix
 //
-void esMatrixLoadIdentity(ESMatrix* result);
+void esMatrixLoadIdentity(ESMatrix *result);
 
 #ifdef __cplusplus
 }
diff --git a/kmscube/meson.build b/kmscube/meson.build
deleted file mode 100644
index 68765f2..0000000
--- a/kmscube/meson.build
+++ /dev/null
@@ -1,24 +0,0 @@
-kmscube_sources = files([
-    'cube.cpp',
-    'cube-egl.cpp',
-    'cube-gbm.cpp',
-    'cube-gles2.cpp',
-    'cube-null.cpp',
-    'cube-wl.cpp',
-    'cube-x11.cpp',
-    'esTransform.cpp',
-])
-
-kmscube_deps = [
-    libdrm_dep, libkmsxx_dep, libkmsxxutil_dep, libfmt_dep,
-    dependency('x11'),
-    dependency('xcb'),
-    dependency('x11-xcb'),
-    dependency('gbm'),
-    dependency('wayland-client'),
-    dependency('wayland-egl'),
-    dependency('glesv2'),
-    dependency('egl'),
-]
-
-executable('kmscube', kmscube_sources, dependencies : kmscube_deps)
diff --git a/meson.build b/meson.build
deleted file mode 100644
index cdc8cab..0000000
--- a/meson.build
+++ /dev/null
@@ -1,52 +0,0 @@
-project('kms++', 'cpp',
-    default_options : [
-        'cpp_std=c++17',
-    ],
-)
-
-cpp = meson.get_compiler('cpp')
-cpp_arguments = []
-
-if (cpp.get_id() == 'gcc' and
-    host_machine.cpu_family() == 'arm' and
-    cpp.has_argument('-Wno-psabi'))
-    cpp_arguments += [
-        '-Wno-psabi',
-    ]
-endif
-
-if cpp.has_argument('-Wno-c99-designator')
-    cpp_arguments += [
-        '-Wno-c99-designator',
-    ]
-endif
-
-add_project_arguments(cpp_arguments, language : 'cpp')
-
-link_arguments = []
-
-if get_option('static-libc')
-    link_arguments += ['-static-libgcc', '-static-libstdc++']
-endif
-
-add_global_link_arguments(link_arguments, language : 'cpp')
-
-libfmt_dep = dependency('fmt')
-
-libdrmomap_dep = dependency('libdrm_omap', required : get_option('omap'))
-
-subdir('kms++')
-
-if get_option('libutils')
-    subdir('kms++util')
-endif
-
-if get_option('utils')
-    subdir('utils')
-endif
-
-subdir('py')
-
-if get_option('kmscube')
-    subdir('kmscube')
-endif
diff --git a/meson_options.txt b/meson_options.txt
deleted file mode 100644
index d18988b..0000000
--- a/meson_options.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-option('omap', type : 'feature', value : 'auto',
-       description : 'Build omapdrm extensions')
-
-option('static-libc', type : 'boolean', value : false,
-       description : 'Build with -static-libgcc -static-libstdc++')
-
-option('libutils', type : 'boolean', value : true,
-       description : 'Build kms++utils library')
-
-option('utils', type : 'boolean', value : true,
-       description : 'Build an assortment of kms++ utils and tests')
-
-option('pykms', type : 'feature', value : 'auto',
-       description : 'Build python bindings')
-
-option('system-pybind11', type : 'feature', value : 'auto',
-       description : 'Use pybind11 from the system or from meson subproject')
-
-option('kmscube', type : 'boolean', value : false,
-       description : 'Build kmscube test application')
diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt
new file mode 100644
index 0000000..77f19b4
--- /dev/null
+++ b/py/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(pykms)
+add_subdirectory(tests)
diff --git a/py/meson.build b/py/meson.build
deleted file mode 100644
index 3130bf2..0000000
--- a/py/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-subdir('pykms')
diff --git a/py/pykms/CMakeLists.txt b/py/pykms/CMakeLists.txt
new file mode 100644
index 0000000..505c0c3
--- /dev/null
+++ b/py/pykms/CMakeLists.txt
@@ -0,0 +1,30 @@
+include_directories(${LIBDRM_INCLUDE_DIRS})
+link_directories(${LIBDRM_LIBRARY_DIRS})
+
+pkg_search_module(PYTHON REQUIRED ${KMSXX_PYTHON_VERSION})
+include_directories(${PYTHON_INCLUDE_DIRS})
+
+if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
+endif()
+
+include_directories(${PROJECT_SOURCE_DIR}/ext/pybind11/include)
+
+set(SRCS pykms.cpp pykmsbase.cpp pykmsutil.cpp pyvid.cpp)
+
+if(LIBDRM_OMAP_FOUND)
+    set(SRCS ${SRCS} pykmsomap.cpp)
+endif()
+
+add_library(pykms SHARED ${SRCS})
+target_link_libraries(pykms kms++ kms++util ${LIBDRM_LIBRARIES})
+
+# Don't add a 'lib' prefix to the shared library
+set_target_properties(pykms PROPERTIES PREFIX "")
+set_target_properties(pykms PROPERTIES LIBRARY_OUTPUT_DIRECTORY "")
+
+configure_file(__init__.py __init__.py COPYONLY)
+
+set(PY_DESTDIR lib/python${PYTHON_VERSION}/site-packages/pykms)
+install(FILES __init__.py DESTINATION ${PY_DESTDIR})
+install(TARGETS pykms DESTINATION ${PY_DESTDIR})
diff --git a/py/pykms/meson.build b/py/pykms/meson.build
deleted file mode 100644
index b29cd9f..0000000
--- a/py/pykms/meson.build
+++ /dev/null
@@ -1,58 +0,0 @@
-py3_dep = dependency('python3', required : get_option('pykms'))
-
-if py3_dep.found() == false
-    subdir_done()
-endif
-
-if get_option('system-pybind11').enabled()
-    pybind11_dep = dependency('pybind11')
-elif get_option('system-pybind11').disabled()
-    pybind11_proj = subproject('pybind11')
-    pybind11_dep = pybind11_proj.get_variable('pybind11_dep')
-else
-    pybind11_dep = dependency('pybind11', fallback : ['pybind11', 'pybind11_dep'])
-endif
-
-pykms_sources = files([
-    'pykmsbase.cpp',
-    'pykms.cpp',
-])
-
-if get_option('utils')
-    pykms_sources += files([
-        'pykmsutil.cpp',
-        'pyvid.cpp',
-    ])
-endif
-
-if libdrmomap_dep.found()
-    pykms_sources += files([
-        'pykmsomap.cpp',
-    ])
-endif
-
-pykms_deps = [
-    libkmsxx_dep,
-    py3_dep,
-    pybind11_dep,
-]
-
-if get_option('utils')
-    pykms_deps += [ libkmsxxutil_dep ]
-endif
-
-pykms_args = [ '-fvisibility=hidden' ]
-
-destdir = get_option('libdir') / 'python' + py3_dep.version() / 'site-packages/pykms'
-
-pykms = shared_module('pykms',
-                      pykms_sources,
-                      install : true,
-                      install_dir : destdir,
-                      name_prefix : '',
-                      dependencies : pykms_deps,
-                      cpp_args : pykms_args)
-
-# Copy __init__.py to build dir so that we can run without installing
-configure_file(input: '__init__.py', output: '__init__.py', copy: true,
-               install : true, install_dir : destdir)
diff --git a/py/pykms/pykms.cpp b/py/pykms/pykms.cpp
index b91a1a9..fec8417 100644
--- a/py/pykms/pykms.cpp
+++ b/py/pykms/pykms.cpp
@@ -7,16 +7,15 @@
 using namespace kms;
 using namespace std;
 
-void init_pykmstest(py::module& m);
-void init_pykmsbase(py::module& m);
-void init_pyvid(py::module& m);
+void init_pykmstest(py::module &m);
+void init_pykmsbase(py::module &m);
+void init_pyvid(py::module &m);
 
 #if HAS_LIBDRM_OMAP
-void init_pykmsomap(py::module& m);
+void init_pykmsomap(py::module &m);
 #endif
 
-PYBIND11_MODULE(pykms, m)
-{
+PYBIND11_MODULE(pykms, m) {
 	init_pykmsbase(m);
 
 	init_pykmstest(m);
diff --git a/py/pykms/pykmsbase.cpp b/py/pykms/pykmsbase.cpp
index a963843..668e6e3 100644
--- a/py/pykms/pykmsbase.cpp
+++ b/py/pykms/pykmsbase.cpp
@@ -17,264 +17,234 @@
 	return v;
 }
 
-void init_pykmsbase(py::module& m)
+void init_pykmsbase(py::module &m)
 {
 	py::class_<Card>(m, "Card")
-		.def(py::init<>())
-		.def(py::init<const string&>())
-		.def(py::init<const string&, uint32_t>())
-		.def_property_readonly("fd", &Card::fd)
-		.def_property_readonly("minor", &Card::dev_minor)
-		.def_property_readonly("get_first_connected_connector", &Card::get_first_connected_connector)
+			.def(py::init<>())
+			.def(py::init<const string&>())
+			.def(py::init<const string&, uint32_t>())
+			.def_property_readonly("fd", &Card::fd)
+			.def_property_readonly("get_first_connected_connector", &Card::get_first_connected_connector)
 
-		// XXX pybind11 can't handle vector<T*> where T is non-copyable, and complains:
-		// RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
-		// So we do this manually.
-		.def_property_readonly("connectors", [](Card* self) {
-			return convert_vector(self->get_connectors());
-		})
+			// XXX pybind11 can't handle vector<T*> where T is non-copyable, and complains:
+			// RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
+			// So we do this manually.
+			.def_property_readonly("connectors", [](Card* self) {
+				return convert_vector(self->get_connectors());
+			})
 
-		.def_property_readonly("crtcs", [](Card* self) {
-			return convert_vector(self->get_crtcs());
-		})
+			.def_property_readonly("crtcs", [](Card* self) {
+				return convert_vector(self->get_crtcs());
+			})
 
-		.def_property_readonly("encoders", [](Card* self) {
-			return convert_vector(self->get_encoders());
-		})
+			.def_property_readonly("encoders", [](Card* self) {
+				return convert_vector(self->get_encoders());
+			})
 
-		.def_property_readonly("planes", [](Card* self) {
-			return convert_vector(self->get_planes());
-		})
+			.def_property_readonly("planes", [](Card* self) {
+				return convert_vector(self->get_planes());
+			})
 
-		.def_property_readonly("has_atomic", &Card::has_atomic)
-		.def("get_prop", (Property * (Card::*)(uint32_t) const) & Card::get_prop)
+			.def_property_readonly("has_atomic", &Card::has_atomic)
+			.def("get_prop", (Property* (Card::*)(uint32_t) const)&Card::get_prop)
 
-		.def_property_readonly("version_name", &Card::version_name);
-	;
+			.def_property_readonly("version_name", &Card::version_name);
+			;
 
 	py::class_<DrmObject, unique_ptr<DrmObject, py::nodelete>>(m, "DrmObject")
-		.def_property_readonly("id", &DrmObject::id)
-		.def_property_readonly("idx", &DrmObject::idx)
-		.def_property_readonly("card", &DrmObject::card);
+			.def_property_readonly("id", &DrmObject::id)
+			.def_property_readonly("idx", &DrmObject::idx)
+			.def_property_readonly("card", &DrmObject::card)
+			;
 
 	py::class_<DrmPropObject, DrmObject, unique_ptr<DrmPropObject, py::nodelete>>(m, "DrmPropObject")
-		.def("refresh_props", &DrmPropObject::refresh_props)
-		.def_property_readonly("prop_map", &DrmPropObject::get_prop_map)
-		.def("get_prop_value", (uint64_t(DrmPropObject::*)(const string&) const) & DrmPropObject::get_prop_value)
-		.def("set_prop_value", (int (DrmPropObject::*)(const string&, uint64_t)) & DrmPropObject::set_prop_value)
-		.def("get_prop_value_as_blob", &DrmPropObject::get_prop_value_as_blob)
-		.def("get_prop", &DrmPropObject::get_prop)
-		.def("has_prop", &DrmPropObject::has_prop);
+			.def("refresh_props", &DrmPropObject::refresh_props)
+			.def_property_readonly("prop_map", &DrmPropObject::get_prop_map)
+			.def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value)
+			.def("set_prop_value",(int (DrmPropObject::*)(const string&, uint64_t)) &DrmPropObject::set_prop_value)
+			.def("get_prop_value_as_blob", &DrmPropObject::get_prop_value_as_blob)
+			.def("get_prop", &DrmPropObject::get_prop)
+			;
 
 	py::class_<Connector, DrmPropObject, unique_ptr<Connector, py::nodelete>>(m, "Connector")
-		.def_property_readonly("fullname", &Connector::fullname)
-		.def("get_default_mode", &Connector::get_default_mode)
-		.def("get_current_crtc", &Connector::get_current_crtc)
-		.def("get_possible_crtcs", [](Connector* self) {
-			return convert_vector(self->get_possible_crtcs());
-		})
-		.def("get_modes", &Connector::get_modes)
-		.def("get_mode", (Videomode(Connector::*)(const string& mode) const) & Connector::get_mode)
-		.def("get_mode", (Videomode(Connector::*)(unsigned xres, unsigned yres, float refresh, bool ilace) const) & Connector::get_mode)
-		.def("connected", &Connector::connected)
-		.def("__repr__", [](const Connector& o) { return "<pykms.Connector " + to_string(o.id()) + ">"; })
-		.def("refresh", &Connector::refresh);
+			.def_property_readonly("fullname", &Connector::fullname)
+			.def("get_default_mode", &Connector::get_default_mode)
+			.def("get_current_crtc", &Connector::get_current_crtc)
+			.def("get_possible_crtcs", [](Connector* self) {
+				return convert_vector(self->get_possible_crtcs());
+			})
+			.def("get_modes", &Connector::get_modes)
+			.def("get_mode", (Videomode (Connector::*)(const string& mode) const)&Connector::get_mode)
+			.def("get_mode", (Videomode (Connector::*)(unsigned xres, unsigned yres, float refresh, bool ilace) const)&Connector::get_mode)
+			.def("connected", &Connector::connected)
+			.def("__repr__", [](const Connector& o) { return "<pykms.Connector " + to_string(o.id()) + ">"; })
+			.def("refresh", &Connector::refresh)
+			;
 
 	py::class_<Crtc, DrmPropObject, unique_ptr<Crtc, py::nodelete>>(m, "Crtc")
-		.def("set_mode", (int (Crtc::*)(Connector*, const Videomode&)) & Crtc::set_mode)
-		.def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&)) & Crtc::set_mode)
-		.def("disable_mode", &Crtc::disable_mode)
-		.def(
-			"page_flip",
-			[](Crtc* self, Framebuffer& fb, uint32_t data) {
-				self->page_flip(fb, (void*)(intptr_t)data);
-			},
-			py::arg("fb"), py::arg("data") = 0)
-		.def("set_plane", &Crtc::set_plane)
-		.def_property_readonly("possible_planes", &Crtc::get_possible_planes)
-		.def_property_readonly("primary_plane", &Crtc::get_primary_plane)
-		.def_property_readonly("mode", &Crtc::mode)
-		.def_property_readonly("mode_valid", &Crtc::mode_valid)
-		.def("__repr__", [](const Crtc& o) { return "<pykms.Crtc " + to_string(o.id()) + ">"; })
-		.def("refresh", &Crtc::refresh)
-		.def("legacy_gamma_size", &Crtc::legacy_gamma_size)
-		.def("legacy_gamma_set", &Crtc::legacy_gamma_set);
+			.def("set_mode", (int (Crtc::*)(Connector*, const Videomode&))&Crtc::set_mode)
+			.def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&))&Crtc::set_mode)
+			.def("disable_mode", &Crtc::disable_mode)
+			.def("page_flip",
+			     [](Crtc* self, Framebuffer& fb, uint32_t data)
+				{
+					self->page_flip(fb, (void*)(intptr_t)data);
+				}, py::arg("fb"), py::arg("data") = 0)
+			.def("set_plane", &Crtc::set_plane)
+			.def_property_readonly("possible_planes", &Crtc::get_possible_planes)
+			.def_property_readonly("primary_plane", &Crtc::get_primary_plane)
+			.def_property_readonly("mode", &Crtc::mode)
+			.def_property_readonly("mode_valid", &Crtc::mode_valid)
+			.def("__repr__", [](const Crtc& o) { return "<pykms.Crtc " + to_string(o.id()) + ">"; })
+			.def("refresh", &Crtc::refresh)
+			;
 
 	py::class_<Encoder, DrmPropObject, unique_ptr<Encoder, py::nodelete>>(m, "Encoder")
-		.def("refresh", &Encoder::refresh);
+			.def("refresh", &Encoder::refresh)
+			;
 
 	py::class_<Plane, DrmPropObject, unique_ptr<Plane, py::nodelete>>(m, "Plane")
-		.def("supports_crtc", &Plane::supports_crtc)
-		.def_property_readonly("formats", &Plane::get_formats)
-		.def_property_readonly("plane_type", &Plane::plane_type)
-		.def("__repr__", [](const Plane& o) { return "<pykms.Plane " + to_string(o.id()) + ">"; });
+			.def("supports_crtc", &Plane::supports_crtc)
+			.def_property_readonly("formats", &Plane::get_formats)
+			.def_property_readonly("plane_type", &Plane::plane_type)
+			.def("__repr__", [](const Plane& o) { return "<pykms.Plane " + to_string(o.id()) + ">"; })
+			;
 
 	py::enum_<PlaneType>(m, "PlaneType")
-		.value("Overlay", PlaneType::Overlay)
-		.value("Primary", PlaneType::Primary)
-		.value("Cursor", PlaneType::Cursor);
+			.value("Overlay", PlaneType::Overlay)
+			.value("Primary", PlaneType::Primary)
+			.value("Cursor", PlaneType::Cursor)
+			;
 
 	py::class_<Property, DrmObject, unique_ptr<Property, py::nodelete>>(m, "Property")
-		.def_property_readonly("name", &Property::name)
-		.def_property_readonly("enums", &Property::get_enums);
+			.def_property_readonly("name", &Property::name)
+			.def_property_readonly("enums", &Property::get_enums)
+			;
 
 	py::class_<Blob>(m, "Blob")
-		.def(py::init([](Card& card, py::buffer buf) {
-			     py::buffer_info info = buf.request();
-			     if (info.ndim != 1)
-				     throw std::runtime_error("Incompatible buffer dimension!");
+			.def("__init__", [](Blob& instance, Card& card, py::buffer buf) {
+					py::buffer_info info = buf.request();
+					if (info.ndim != 1)
+						throw std::runtime_error("Incompatible buffer dimension!");
 
-			     return new Blob(card, info.ptr, info.size * info.itemsize);
-		     }),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
+					new (&instance) Blob(card, info.ptr, info.size * info.itemsize);
+				},
+				py::keep_alive<1, 3>())	// Keep Card alive until this is destructed
 
-		.def_property_readonly("data", &Blob::data)
+			.def_property_readonly("data", &Blob::data)
 
-		// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
-		// and a subclass with standard holder-type.
-		// So we just copy the DrmObject members here.
-		// Note that this means that python thinks we don't derive from DrmObject
-		.def_property_readonly("id", &DrmObject::id)
-		.def_property_readonly("idx", &DrmObject::idx)
-		.def_property_readonly("card", &DrmObject::card);
+			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
+			// and a subclass with standard holder-type.
+			// So we just copy the DrmObject members here.
+			// Note that this means that python thinks we don't derive from DrmObject
+			.def_property_readonly("id", &DrmObject::id)
+			.def_property_readonly("idx", &DrmObject::idx)
+			.def_property_readonly("card", &DrmObject::card)
+			;
 
 	py::class_<Framebuffer>(m, "Framebuffer")
-		.def_property_readonly("width", &Framebuffer::width)
-		.def_property_readonly("height", &Framebuffer::height)
-		.def_property_readonly("format", &Framebuffer::format)
-		.def_property_readonly("num_planes", &Framebuffer::num_planes)
-		.def("stride", &Framebuffer::stride)
-		.def("size", &Framebuffer::size)
-		.def("offset", &Framebuffer::offset)
-		.def("fd", &Framebuffer::prime_fd)
+			.def_property_readonly("width", &Framebuffer::width)
+			.def_property_readonly("height", &Framebuffer::height)
 
-		// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
-		// and a subclass with standard holder-type.
-		// So we just copy the DrmObject members here.
-		// Note that this means that python thinks we don't derive from DrmObject
-		.def_property_readonly("id", &DrmObject::id)
-		.def_property_readonly("idx", &DrmObject::idx)
-		.def_property_readonly("card", &DrmObject::card);
+			// XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
+			// and a subclass with standard holder-type.
+			// So we just copy the DrmObject members here.
+			// Note that this means that python thinks we don't derive from DrmObject
+			.def_property_readonly("id", &DrmObject::id)
+			.def_property_readonly("idx", &DrmObject::idx)
+			.def_property_readonly("card", &DrmObject::card)
+			;
 
 	py::class_<DumbFramebuffer, Framebuffer>(m, "DumbFramebuffer")
-		.def(py::init<Card&, uint32_t, uint32_t, const string&>(),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
-		.def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
-		;
+			.def(py::init<Card&, uint32_t, uint32_t, const string&>(),
+			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
+			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(),
+			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
+			.def_property_readonly("format", &DumbFramebuffer::format)
+			.def_property_readonly("num_planes", &DumbFramebuffer::num_planes)
+			.def("fd", &DumbFramebuffer::prime_fd)
+			.def("stride", &DumbFramebuffer::stride)
+			.def("offset", &DumbFramebuffer::offset)
+			;
 
-	py::class_<DmabufFramebuffer, Framebuffer>(m, "DmabufFramebuffer")
-		.def(py::init<Card&, uint32_t, uint32_t, const string&, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
-		.def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
-		;
+	py::class_<ExtFramebuffer, Framebuffer>(m, "ExtFramebuffer")
+			.def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
+			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
+			;
 
 	py::enum_<PixelFormat>(m, "PixelFormat")
-		.value("Undefined", PixelFormat::Undefined)
+			.value("Undefined", PixelFormat::Undefined)
 
-		.value("NV12", PixelFormat::NV12)
-		.value("NV21", PixelFormat::NV21)
-		.value("NV16", PixelFormat::NV16)
-		.value("NV61", PixelFormat::NV61)
+			.value("NV12", PixelFormat::NV12)
+			.value("NV21", PixelFormat::NV21)
 
-		.value("YUV420", PixelFormat::YUV420)
-		.value("YVU420", PixelFormat::YVU420)
-		.value("YUV422", PixelFormat::YUV422)
-		.value("YVU422", PixelFormat::YVU422)
-		.value("YUV444", PixelFormat::YUV444)
-		.value("YVU444", PixelFormat::YVU444)
+			.value("UYVY", PixelFormat::UYVY)
+			.value("YUYV", PixelFormat::YUYV)
+			.value("YVYU", PixelFormat::YVYU)
+			.value("VYUY", PixelFormat::VYUY)
 
-		.value("UYVY", PixelFormat::UYVY)
-		.value("YUYV", PixelFormat::YUYV)
-		.value("YVYU", PixelFormat::YVYU)
-		.value("VYUY", PixelFormat::VYUY)
+			.value("XRGB8888", PixelFormat::XRGB8888)
+			.value("XBGR8888", PixelFormat::XBGR8888)
+			.value("ARGB8888", PixelFormat::ARGB8888)
+			.value("ABGR8888", PixelFormat::ABGR8888)
 
-		.value("XRGB8888", PixelFormat::XRGB8888)
-		.value("XBGR8888", PixelFormat::XBGR8888)
-		.value("RGBX8888", PixelFormat::RGBX8888)
-		.value("BGRX8888", PixelFormat::BGRX8888)
+			.value("RGB888", PixelFormat::RGB888)
+			.value("BGR888", PixelFormat::BGR888)
 
-		.value("ARGB8888", PixelFormat::ARGB8888)
-		.value("ABGR8888", PixelFormat::ABGR8888)
-		.value("RGBA8888", PixelFormat::RGBA8888)
-		.value("BGRA8888", PixelFormat::BGRA8888)
-
-		.value("RGB888", PixelFormat::RGB888)
-		.value("BGR888", PixelFormat::BGR888)
-
-		.value("RGB332", PixelFormat::RGB332)
-
-		.value("RGB565", PixelFormat::RGB565)
-		.value("BGR565", PixelFormat::BGR565)
-
-		.value("XRGB4444", PixelFormat::XRGB4444)
-		.value("XRGB1555", PixelFormat::XRGB1555)
-
-		.value("ARGB4444", PixelFormat::ARGB4444)
-		.value("ARGB1555", PixelFormat::ARGB1555)
-
-		.value("XRGB2101010", PixelFormat::XRGB2101010)
-		.value("XBGR2101010", PixelFormat::XBGR2101010)
-		.value("RGBX1010102", PixelFormat::RGBX1010102)
-		.value("BGRX1010102", PixelFormat::BGRX1010102)
-
-		.value("ARGB2101010", PixelFormat::ARGB2101010)
-		.value("ABGR2101010", PixelFormat::ABGR2101010)
-		.value("RGBA1010102", PixelFormat::RGBA1010102)
-		.value("BGRA1010102", PixelFormat::BGRA1010102);
+			.value("RGB565", PixelFormat::RGB565)
+			.value("BGR565", PixelFormat::BGR565)
+			;
 
 	py::enum_<SyncPolarity>(m, "SyncPolarity")
-		.value("Undefined", SyncPolarity::Undefined)
-		.value("Positive", SyncPolarity::Positive)
-		.value("Negative", SyncPolarity::Negative);
+			.value("Undefined", SyncPolarity::Undefined)
+			.value("Positive", SyncPolarity::Positive)
+			.value("Negative", SyncPolarity::Negative)
+			;
 
 	py::class_<Videomode>(m, "Videomode")
-		.def(py::init<>())
+			.def(py::init<>())
 
-		.def_readwrite("name", &Videomode::name)
+			.def_readwrite("name", &Videomode::name)
 
-		.def_readwrite("clock", &Videomode::clock)
+			.def_readwrite("clock", &Videomode::clock)
 
-		.def_readwrite("hdisplay", &Videomode::hdisplay)
-		.def_readwrite("hsync_start", &Videomode::hsync_start)
-		.def_readwrite("hsync_end", &Videomode::hsync_end)
-		.def_readwrite("htotal", &Videomode::htotal)
+			.def_readwrite("hdisplay", &Videomode::hdisplay)
+			.def_readwrite("hsync_start", &Videomode::hsync_start)
+			.def_readwrite("hsync_end", &Videomode::hsync_end)
+			.def_readwrite("htotal", &Videomode::htotal)
 
-		.def_readwrite("vdisplay", &Videomode::vdisplay)
-		.def_readwrite("vsync_start", &Videomode::vsync_start)
-		.def_readwrite("vsync_end", &Videomode::vsync_end)
-		.def_readwrite("vtotal", &Videomode::vtotal)
+			.def_readwrite("vdisplay", &Videomode::vdisplay)
+			.def_readwrite("vsync_start", &Videomode::vsync_start)
+			.def_readwrite("vsync_end", &Videomode::vsync_end)
+			.def_readwrite("vtotal", &Videomode::vtotal)
 
-		.def_readwrite("vrefresh", &Videomode::vrefresh)
+			.def_readwrite("vrefresh", &Videomode::vrefresh)
 
-		.def_readwrite("flags", &Videomode::flags)
-		.def_readwrite("type", &Videomode::type)
+			.def_readwrite("flags", &Videomode::flags)
+			.def_readwrite("type", &Videomode::type)
 
-		.def("__repr__", [](const Videomode& vm) { return "<pykms.Videomode " + to_string(vm.hdisplay) + "x" + to_string(vm.vdisplay) + ">"; })
+			.def("__repr__", [](const Videomode& vm) { return "<pykms.Videomode " + to_string(vm.hdisplay) + "x" + to_string(vm.vdisplay) + ">"; })
 
-		.def("to_blob", &Videomode::to_blob)
+			.def("to_blob", &Videomode::to_blob)
 
-		.def_property("hsync", &Videomode::hsync, &Videomode::set_hsync)
-		.def_property("vsync", &Videomode::vsync, &Videomode::set_vsync)
+			.def_property("hsync", &Videomode::hsync, &Videomode::set_hsync)
+			.def_property("vsync", &Videomode::vsync, &Videomode::set_vsync)
+			;
 
-		.def("to_string_short", &Videomode::to_string_short)
-		.def("to_string_long", &Videomode::to_string_long);
 
 	m.def("videomode_from_timings", &videomode_from_timings);
 
 	py::class_<AtomicReq>(m, "AtomicReq")
-		.def(py::init<Card&>(),
-		     py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
-		.def("add", (void (AtomicReq::*)(DrmPropObject*, const string&, uint64_t)) & AtomicReq::add)
-		.def("add", (void (AtomicReq::*)(DrmPropObject*, Property*, uint64_t)) & AtomicReq::add)
-		.def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) & AtomicReq::add)
-		.def("test", &AtomicReq::test, py::arg("allow_modeset") = false)
-		.def(
-			"commit",
-			[](AtomicReq* self, uint32_t data, bool allow) {
-				return self->commit((void*)(intptr_t)data, allow);
-			},
-			py::arg("data") = 0, py::arg("allow_modeset") = false)
-		.def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false);
+			.def(py::init<Card&>(),
+			     py::keep_alive<1, 2>())	// Keep Card alive until this is destructed
+			.def("add", (void (AtomicReq::*)(DrmPropObject*, const string&, uint64_t)) &AtomicReq::add)
+			.def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) &AtomicReq::add)
+			.def("test", &AtomicReq::test, py::arg("allow_modeset") = false)
+			.def("commit",
+			     [](AtomicReq* self, uint32_t data, bool allow)
+				{
+					return self->commit((void*)(intptr_t)data, allow);
+				}, py::arg("data") = 0, py::arg("allow_modeset") = false)
+			.def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false)
+			;
 }
diff --git a/py/pykms/pykmsomap.cpp b/py/pykms/pykmsomap.cpp
index eb01f47..4fc7084 100644
--- a/py/pykms/pykmsomap.cpp
+++ b/py/pykms/pykmsomap.cpp
@@ -8,32 +8,35 @@
 using namespace kms;
 using namespace std;
 
-void init_pykmsomap(py::module& m)
+void init_pykmsomap(py::module &m)
 {
 	py::class_<OmapCard, Card>(m, "OmapCard")
-		.def(py::init<>());
+			.def(py::init<>())
+			;
 
 	py::class_<OmapFramebuffer, Framebuffer> omapfb(m, "OmapFramebuffer");
 
 	// XXX we should use py::arithmetic() here to support or and and operators, but it's not supported in the pybind11 we use
 	py::enum_<OmapFramebuffer::Flags>(omapfb, "Flags")
-		.value("None", OmapFramebuffer::Flags::None)
-		.value("Tiled", OmapFramebuffer::Flags::Tiled)
-		.value("MemContig", OmapFramebuffer::Flags::MemContig)
-		.value("MemTiler", OmapFramebuffer::Flags::MemTiler)
-		.value("MemPin", OmapFramebuffer::Flags::MemPin)
-		.export_values();
+			.value("None", OmapFramebuffer::Flags::None)
+			.value("Tiled", OmapFramebuffer::Flags::Tiled)
+			.value("MemContig", OmapFramebuffer::Flags::MemContig)
+			.value("MemTiler", OmapFramebuffer::Flags::MemTiler)
+			.value("MemPin", OmapFramebuffer::Flags::MemPin)
+			.export_values()
+			;
 
 	omapfb
-		.def(py::init<OmapCard&, uint32_t, uint32_t, const string&, OmapFramebuffer::Flags>(),
-		     py::keep_alive<1, 2>(), // Keep Card alive until this is destructed
-		     py::arg("card"), py::arg("width"), py::arg("height"), py::arg("fourcc"), py::arg("flags") = OmapFramebuffer::None)
-		.def(py::init<OmapCard&, uint32_t, uint32_t, PixelFormat, OmapFramebuffer::Flags>(),
-		     py::keep_alive<1, 2>(), // Keep OmapCard alive until this is destructed
-		     py::arg("card"), py::arg("width"), py::arg("height"), py::arg("pixfmt"), py::arg("flags") = OmapFramebuffer::None)
-		.def_property_readonly("format", &OmapFramebuffer::format)
-		.def_property_readonly("num_planes", &OmapFramebuffer::num_planes)
-		.def("fd", &OmapFramebuffer::prime_fd)
-		.def("stride", &OmapFramebuffer::stride)
-		.def("offset", &OmapFramebuffer::offset);
+			.def(py::init<OmapCard&, uint32_t, uint32_t, const string&, OmapFramebuffer::Flags>(),
+			     py::keep_alive<1, 2>(),	// Keep Card alive until this is destructed
+			     py::arg("card"), py::arg("width"), py::arg("height"), py::arg("fourcc"), py::arg("flags") = OmapFramebuffer::None)
+			.def(py::init<OmapCard&, uint32_t, uint32_t, PixelFormat, OmapFramebuffer::Flags>(),
+			     py::keep_alive<1, 2>(),	// Keep OmapCard alive until this is destructed
+			     py::arg("card"), py::arg("width"), py::arg("height"), py::arg("pixfmt"), py::arg("flags") = OmapFramebuffer::None)
+			.def_property_readonly("format", &OmapFramebuffer::format)
+			.def_property_readonly("num_planes", &OmapFramebuffer::num_planes)
+			.def("fd", &OmapFramebuffer::prime_fd)
+			.def("stride", &OmapFramebuffer::stride)
+			.def("offset", &OmapFramebuffer::offset)
+			;
 }
diff --git a/py/pykms/pykmsutil.cpp b/py/pykms/pykmsutil.cpp
index 666cbdc..d5d7fde 100644
--- a/py/pykms/pykmsutil.cpp
+++ b/py/pykms/pykmsutil.cpp
@@ -8,55 +8,58 @@
 using namespace kms;
 using namespace std;
 
-void init_pykmstest(py::module& m)
+void init_pykmstest(py::module &m)
 {
 	py::class_<RGB>(m, "RGB")
-		.def(py::init<>())
-		.def(py::init<uint8_t, uint8_t, uint8_t&>())
-		.def(py::init<uint8_t, uint8_t, uint8_t, uint8_t&>())
-		.def_property_readonly("rgb888", &RGB::rgb888)
-		.def_property_readonly("argb8888", &RGB::argb8888)
-		.def_property_readonly("abgr8888", &RGB::abgr8888)
-		.def_property_readonly("rgb565", &RGB::rgb565);
+			.def(py::init<>())
+			.def(py::init<uint8_t, uint8_t, uint8_t&>())
+			.def(py::init<uint8_t, uint8_t, uint8_t, uint8_t&>())
+			.def_property_readonly("rgb888", &RGB::rgb888)
+			.def_property_readonly("argb8888", &RGB::argb8888)
+			.def_property_readonly("abgr8888", &RGB::abgr8888)
+			.def_property_readonly("rgb565", &RGB::rgb565)
+			;
 
 	py::class_<ResourceManager>(m, "ResourceManager")
-		.def(py::init<Card&>())
-		.def("reset", &ResourceManager::reset)
-		.def("reserve_connector", (Connector * (ResourceManager::*)(const string& name)) & ResourceManager::reserve_connector,
-		     py::arg("name") = string())
-		.def("reserve_crtc", (Crtc * (ResourceManager::*)(Connector*)) & ResourceManager::reserve_crtc)
-		.def("reserve_plane", (Plane * (ResourceManager::*)(Crtc*, PlaneType, PixelFormat)) & ResourceManager::reserve_plane,
-		     py::arg("crtc"),
-		     py::arg("type"),
-		     py::arg("format") = PixelFormat::Undefined)
-		.def("reserve_generic_plane", &ResourceManager::reserve_generic_plane,
-		     py::arg("crtc"),
-		     py::arg("format") = PixelFormat::Undefined)
-		.def("reserve_primary_plane", &ResourceManager::reserve_primary_plane,
-		     py::arg("crtc"),
-		     py::arg("format") = PixelFormat::Undefined)
-		.def("reserve_overlay_plane", &ResourceManager::reserve_overlay_plane,
-		     py::arg("crtc"),
-		     py::arg("format") = PixelFormat::Undefined);
+			.def(py::init<Card&>())
+			.def("reset", &ResourceManager::reset)
+			.def("reserve_connector", (Connector* (ResourceManager::*)(const string& name))&ResourceManager::reserve_connector,
+			     py::arg("name") = string())
+			.def("reserve_crtc", (Crtc* (ResourceManager::*)(Connector*))&ResourceManager::reserve_crtc)
+			.def("reserve_plane", (Plane* (ResourceManager::*)(Crtc*, PlaneType, PixelFormat))&ResourceManager::reserve_plane,
+			     py::arg("crtc"),
+			     py::arg("type"),
+			     py::arg("format") = PixelFormat::Undefined)
+			.def("reserve_generic_plane", &ResourceManager::reserve_generic_plane,
+			     py::arg("crtc"),
+			     py::arg("format") = PixelFormat::Undefined)
+			.def("reserve_primary_plane", &ResourceManager::reserve_primary_plane,
+			     py::arg("crtc"),
+			     py::arg("format") = PixelFormat::Undefined)
+			.def("reserve_overlay_plane", &ResourceManager::reserve_overlay_plane,
+			     py::arg("crtc"),
+			     py::arg("format") = PixelFormat::Undefined)
+			;
 	py::enum_<YUVType>(m, "YUVType")
-		.value("BT601_Lim", YUVType::BT601_Lim)
-		.value("BT601_Full", YUVType::BT601_Full)
-		.value("BT709_Lim", YUVType::BT709_Lim)
-		.value("BT709_Full", YUVType::BT709_Full);
+			.value("BT601_Lim", YUVType::BT601_Lim)
+			.value("BT601_Full", YUVType::BT601_Full)
+			.value("BT709_Lim", YUVType::BT709_Lim)
+			.value("BT709_Full", YUVType::BT709_Full)
+			;
 
 	// Use lambdas to handle IFramebuffer
-	m.def(
-		"draw_test_pattern", [](Framebuffer& fb, YUVType yuvt) { draw_test_pattern(fb, yuvt); },
-		py::arg("fb"),
-		py::arg("yuvt") = YUVType::BT601_Lim);
+	m.def("draw_test_pattern", [](Framebuffer& fb, YUVType yuvt) { draw_test_pattern(fb, yuvt); },
+	      py::arg("fb"),
+	      py::arg("yuvt") = YUVType::BT601_Lim);
 	m.def("draw_color_bar", [](Framebuffer& fb, int old_xpos, int xpos, int width) {
 		draw_color_bar(fb, old_xpos, xpos, width);
-	});
+	} );
 	m.def("draw_rect", [](Framebuffer& fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color) {
 		draw_rect(fb, x, y, w, h, color);
-	});
+	} );
 	m.def("draw_circle", [](Framebuffer& fb, int32_t xCenter, int32_t yCenter, int32_t radius, RGB color) {
 		draw_circle(fb, xCenter, yCenter, radius, color);
-	});
-	m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y, const string& str, RGB color) { draw_text(fb, x, y, str, color); });
+	} );
+	m.def("draw_text", [](Framebuffer& fb, uint32_t x, uint32_t y, const string& str, RGB color) {
+		draw_text(fb, x, y, str, color); } );
 }
diff --git a/py/pykms/pyvid.cpp b/py/pykms/pyvid.cpp
index 54ad480..8b0450a 100644
--- a/py/pykms/pyvid.cpp
+++ b/py/pykms/pyvid.cpp
@@ -9,38 +9,40 @@
 using namespace kms;
 using namespace std;
 
-void init_pyvid(py::module& m)
+void init_pyvid(py::module &m)
 {
 	py::class_<VideoDevice>(m, "VideoDevice")
-		.def(py::init<const string&>())
-		.def_property_readonly("fd", &VideoDevice::fd)
-		.def_property_readonly("has_capture", &VideoDevice::has_capture)
-		.def_property_readonly("has_output", &VideoDevice::has_output)
-		.def_property_readonly("has_m2m", &VideoDevice::has_m2m)
-		.def_property_readonly("capture_streamer", &VideoDevice::get_capture_streamer)
-		.def_property_readonly("output_streamer", &VideoDevice::get_output_streamer)
-		.def_property_readonly("discrete_frame_sizes", &VideoDevice::get_discrete_frame_sizes)
-		.def_property_readonly("frame_sizes", &VideoDevice::get_frame_sizes)
-		.def("get_capture_devices", &VideoDevice::get_capture_devices);
+			.def(py::init<const string&>())
+			.def_property_readonly("fd", &VideoDevice::fd)
+			.def_property_readonly("has_capture", &VideoDevice::has_capture)
+			.def_property_readonly("has_output", &VideoDevice::has_output)
+			.def_property_readonly("has_m2m", &VideoDevice::has_m2m)
+			.def_property_readonly("capture_streamer", &VideoDevice::get_capture_streamer)
+			.def_property_readonly("output_streamer", &VideoDevice::get_output_streamer)
+			.def_property_readonly("discrete_frame_sizes", &VideoDevice::get_discrete_frame_sizes)
+			.def_property_readonly("frame_sizes", &VideoDevice::get_frame_sizes)
+			.def("get_capture_devices", &VideoDevice::get_capture_devices)
+			;
 
 	py::class_<VideoStreamer>(m, "VideoStreamer")
-		.def_property_readonly("fd", &VideoStreamer::fd)
-		.def_property_readonly("ports", &VideoStreamer::get_ports)
-		.def("set_port", &VideoStreamer::set_port)
-		.def_property_readonly("formats", &VideoStreamer::get_formats)
-		.def("set_format", &VideoStreamer::set_format)
-		.def("get_selection", [](VideoStreamer* self) {
-			uint32_t left, top, width, height;
-			self->get_selection(left, top, width, height);
-			return make_tuple(left, top, width, height);
-		})
-		.def("set_selection", [](VideoStreamer* self, uint32_t left, uint32_t top, uint32_t width, uint32_t height) {
-			self->set_selection(left, top, width, height);
-			return make_tuple(left, top, width, height);
-		})
-		.def("set_queue_size", &VideoStreamer::set_queue_size)
-		.def("queue", &VideoStreamer::queue)
-		.def("dequeue", &VideoStreamer::dequeue)
-		.def("stream_on", &VideoStreamer::stream_on)
-		.def("stream_off", &VideoStreamer::stream_off);
+			.def_property_readonly("fd", &VideoStreamer::fd)
+			.def_property_readonly("ports", &VideoStreamer::get_ports)
+			.def("set_port", &VideoStreamer::set_port)
+			.def_property_readonly("formats", &VideoStreamer::get_formats)
+			.def("set_format", &VideoStreamer::set_format)
+			.def("get_selection", [](VideoStreamer *self) {
+				uint32_t left, top, width, height;
+				self->get_selection(left, top, width, height);
+				return make_tuple(left, top, width, height);
+			} )
+			.def("set_selection", [](VideoStreamer *self, uint32_t left, uint32_t top, uint32_t width, uint32_t height) {
+				self->set_selection(left, top, width, height);
+				return make_tuple(left, top, width, height);
+			} )
+			.def("set_queue_size", &VideoStreamer::set_queue_size)
+			.def("queue", &VideoStreamer::queue)
+			.def("dequeue", &VideoStreamer::dequeue)
+			.def("stream_on", &VideoStreamer::stream_on)
+			.def("stream_off", &VideoStreamer::stream_off)
+			;
 }
diff --git a/py/tests/CMakeLists.txt b/py/tests/CMakeLists.txt
new file mode 100644
index 0000000..a670ed9
--- /dev/null
+++ b/py/tests/CMakeLists.txt
@@ -0,0 +1,7 @@
+file(GLOB PY_SRCS "*.py")
+add_custom_target(pyextras SOURCES ${PY_SRCS})
+
+add_test(NAME pytest COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/functest.py")
+set_property(TEST pytest PROPERTY
+        ENVIRONMENT "PYTHONPATH=." "LD_LIBRARY_PATH=."
+)
diff --git a/py/tests/alpha-test.py b/py/tests/alpha-test.py
index 94d3836..e329ce4 100755
--- a/py/tests/alpha-test.py
+++ b/py/tests/alpha-test.py
@@ -2,37 +2,23 @@
 
 import pykms
 import time
-import argparse
-
-parser = argparse.ArgumentParser(description='Simple alpha blending test.')
-parser.add_argument('--resetcrtc', action="store_true",
-		    help='Reset legacy CRTC color properties')
-parser.add_argument('--connector', '-c', dest='connector', default="",
-		    required=False, help='connector to output')
-parser.add_argument('--mode', '-m', dest='modename',
-		    required=False, help='Video mode name to use')
-args = parser.parse_args()
-
-max_planes = 4
 
 card = pykms.Card()
 res = pykms.ResourceManager(card)
-conn = res.reserve_connector(args.connector)
+conn = res.reserve_connector()
 crtc = res.reserve_crtc(conn)
-if args.modename == None:
-    mode = conn.get_default_mode()
-else:
-    mode = conn.get_mode(args.modename)
+mode = conn.get_default_mode()
 
 planes = []
 
-for i in range(max_planes):
+for i in range(3):
     p = res.reserve_generic_plane(crtc)
-    if p == None:
-        break
-    planes.append(p)
 
-print("Got {} planes. Test supports up to 4 planes.".format(len(planes)))
+    if p == None:
+        print("Need 3 planes!")
+        exit(1)
+
+    planes.append(p)
 
 card.disable_planes()
 
@@ -41,29 +27,25 @@
 
 fbs=[]
 
-for i in range(max_planes):
+for i in range(len(planes)):
     fbs.append(pykms.DumbFramebuffer(card, w, h, "AR24"))
 
 pykms.draw_rect(fbs[0], 50, 50, 200, 200, pykms.RGB(128, 255, 0, 0))
 pykms.draw_rect(fbs[1], 150, 50, 200, 200, pykms.RGB(128, 0, 255, 0))
 pykms.draw_rect(fbs[2], 50, 150, 200, 200, pykms.RGB(128, 0, 0, 255))
-pykms.draw_rect(fbs[3], 150, 150, 200, 200, pykms.RGB(128, 128, 128, 128))
 
-card.disable_planes()
-
-if args.resetcrtc:
-    crtc.set_props({
-        "trans-key-mode": 0,
-        "trans-key": 0,
-        "background": 0,
-        "alpha_blender": 1,
-    })
+crtc.set_props({
+    "trans-key-mode": 0,
+    "trans-key": 0,
+    "background": 0,
+    "alpha_blender": 1,
+})
 
 for i in range(len(planes)):
     plane = planes[i]
     fb = fbs[i]
 
-    print("set crtc {}, plane {}, z {}, fb {}".format(crtc.id, plane.id, i, fb.id))
+    print("set crtc {}, plane {}, fb {}".format(crtc.id, p.id, fbs[i].id))
 
     plane.set_props({
         "FB_ID": fb.id,
diff --git a/py/tests/cam.py b/py/tests/cam.py
index b7294ed..c813b2f 100755
--- a/py/tests/cam.py
+++ b/py/tests/cam.py
@@ -3,20 +3,11 @@
 import sys
 import selectors
 import pykms
-import argparse
-import time
 
-parser = argparse.ArgumentParser()
-parser.add_argument("width", type=int)
-parser.add_argument("height", type=int)
-args = parser.parse_args()
-
-w = args.width
-h = args.height
+w = 640
+h = 480
 fmt = pykms.PixelFormat.YUYV
 
-print("Capturing in {}x{}".format(w, h))
-
 card = pykms.Card()
 res = pykms.ResourceManager(card)
 conn = res.reserve_connector()
diff --git a/py/tests/ctm_test.py b/py/tests/ctm_test.py
index 2273221..7ceed6f 100755
--- a/py/tests/ctm_test.py
+++ b/py/tests/ctm_test.py
@@ -2,7 +2,6 @@
 
 import sys
 import pykms
-import argparse
 
 def ctm_to_blob(ctm, card):
     len=9
@@ -23,55 +22,21 @@
     return pykms.Blob(card, arr);
 
 
-parser = argparse.ArgumentParser(description='Simple CRTC CTM-property test.')
-parser.add_argument('--connector', '-c', dest='connector',
-		    required=False, help='connector to output')
-parser.add_argument('--mode', '-m', dest='modename',
-		    required=False, help='Video mode name to use')
-parser.add_argument('--plane', '-p', dest='plane', type=int,
-		    required=False, help='plane number to use')
-args = parser.parse_args()
+if len(sys.argv) > 1:
+    conn_name = sys.argv[1]
+else:
+    conn_name = ""
 
 card = pykms.Card()
 res = pykms.ResourceManager(card)
-conn = res.reserve_connector(args.connector)
+conn = res.reserve_connector(conn_name)
 crtc = res.reserve_crtc(conn)
-format = pykms.PixelFormat.ARGB8888
-if args.modename == None:
-    mode = conn.get_default_mode()
-else:
-    mode = conn.get_mode(args.modename)
-modeb = mode.to_blob(card)
+mode = conn.get_default_mode()
 
 fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
 pykms.draw_test_pattern(fb);
 
-if args.plane == None:
-	plane = res.reserve_generic_plane(crtc, fb.format)
-else:
-	plane = card.planes[args.plane]
-
-card.disable_planes()
-crtc.disable_mode()
-
-input("press enter to set ctm at the same time with crtc mode\n")
-
-ctm = [ 0.0,	1.0,	0.0,
-        0.0,	0.0,	1.0,
-        1.0,	0.0,	0.0 ]
-
-ctmb = ctm_to_blob(ctm, card)
-
-req = pykms.AtomicReq(card)
-req.add(conn, "CRTC_ID", crtc.id)
-req.add(crtc, {"ACTIVE": 1,
-               "MODE_ID": modeb.id,
-               "CTM": ctmb.id})
-req.add_plane(plane, fb, crtc)
-r = req.commit_sync(allow_modeset = True)
-assert r == 0, "Initial commit failed: %d" % r
-
-print("r->b g->r b->g ctm active\n")
+crtc.set_mode(conn, fb, mode)
 
 input("press enter to set normal ctm\n")
 
@@ -85,6 +50,18 @@
 
 input("press enter to set new ctm\n")
 
+ctm = [ 0.0,	1.0,	0.0,
+        0.0,	0.0,	1.0,
+        1.0,	0.0,	0.0 ]
+
+ctmb = ctm_to_blob(ctm, card)
+
+crtc.set_prop("CTM", ctmb.id)
+
+print("r->b g->r b->g ctm active\n")
+
+input("press enter to set new ctm\n")
+
 ctm = [ 0.0,	0.0,	1.0,
         1.0,	0.0,	0.0,
         0.0,	1.0,	0.0 ]
diff --git a/py/tests/gamma.py b/py/tests/gamma.py
index 03499bc..5969b82 100755
--- a/py/tests/gamma.py
+++ b/py/tests/gamma.py
@@ -1,16 +1,14 @@
 #!/usr/bin/python3
 
 import pykms
-import argparse
 
-parser = argparse.ArgumentParser()
-parser.add_argument("-c", "--connector", default="")
-parser.add_argument("-l", "--legacy", action="store_true", default=False)
-args = parser.parse_args()
+# This hack makes drm initialize the fbcon, setting up the default connector
+card = pykms.Card()
+card = 0
 
 card = pykms.Card()
 res = pykms.ResourceManager(card)
-conn = res.reserve_connector(args.connector)
+conn = res.reserve_connector()
 crtc = res.reserve_crtc(conn)
 mode = conn.get_default_mode()
 
@@ -19,76 +17,24 @@
 
 crtc.set_mode(conn, fb, mode)
 
-use_legacy = args.legacy
+len=256
+arr = bytearray(len*2*4)
+view = memoryview(arr).cast("H")
 
-if not use_legacy:
-	prop = crtc.get_prop("GAMMA_LUT")
+for i in range(len):
+    g = round(65535 * pow(i / float(len), 1 / 2.2))
 
-	if not prop:
-		prop = crtc.get_prop("DEGAMMA_LUT")
+    view[i * 4 + 0] = g
+    view[i * 4 + 1] = g
+    view[i * 4 + 2] = g
+    view[i * 4 + 3] = 0
 
-		if not prop:
-			print("No gamma property found")
-			exit(-1)
-		else:
-			print("Using DEGAMMA_LUT for gamma")
+gamma = pykms.Blob(card, arr);
 
-
-def legacy_gamma_set():
-	len = crtc.legacy_gamma_size()
-
-	table = []
-
-	for i in range(len):
-	    g = round(65535 * pow(i / float(len), 1 / 2.2))
-	    table.append((g, g, g))
-
-	crtc.legacy_gamma_set(table)
-
-def legacy_gamma_clear():
-	len = crtc.legacy_gamma_size()
-
-	table = []
-
-	for i in range(len):
-	    g = round(65535 * (i / float(len)))
-	    table.append((g, g, g))
-
-	crtc.legacy_gamma_set(table)
-
-def gamma_set():
-	len=256
-	arr = bytearray(len*2*4)
-	view = memoryview(arr).cast("H")
-
-	for i in range(len):
-	    g = round(65535 * pow(i / float(len), 1 / 2.2))
-
-	    view[i * 4 + 0] = g
-	    view[i * 4 + 1] = g
-	    view[i * 4 + 2] = g
-	    view[i * 4 + 3] = 0
-
-	gamma = pykms.Blob(card, arr);
-
-	crtc.set_prop(prop, gamma.id)
-
-
-def gamma_clear():
-	crtc.set_prop(prop, 0)
-
-input("press enter to apply gamma\n")
-
-if use_legacy:
-	legacy_gamma_set()
-else:
-	gamma_set()
+crtc.set_prop("GAMMA_LUT", gamma.id)
 
 input("press enter to remove gamma\n")
 
-if use_legacy:
-	legacy_gamma_clear()
-else:
-	gamma_clear()
+crtc.set_prop("GAMMA_LUT", 0)
 
 input("press enter to exit\n")
diff --git a/py/tests/global_alpha_test.py b/py/tests/global_alpha_test.py
index 33fd12e..6981b72 100755
--- a/py/tests/global_alpha_test.py
+++ b/py/tests/global_alpha_test.py
@@ -2,22 +2,12 @@
 
 import pykms
 import time
-import argparse
 
-parser = argparse.ArgumentParser(description='Plane "alpha"-property test.')
-parser.add_argument('--connector', '-c', dest='connector', default="",
-		    required=False, help='connector to output')
-parser.add_argument('--mode', '-m', dest='modename',
-		    required=False, help='Video mode name to use')
-args = parser.parse_args()
 card = pykms.Card()
 res = pykms.ResourceManager(card)
-conn = res.reserve_connector(args.connector)
+conn = res.reserve_connector("")
 crtc = res.reserve_crtc(conn)
-if args.modename == None:
-    mode = conn.get_default_mode()
-else:
-    mode = conn.get_mode(args.modename)
+mode = conn.get_default_mode()
 modeb = mode.to_blob(card)
 format = pykms.PixelFormat.ARGB8888
 plane1 = res.reserve_generic_plane(crtc, format)
@@ -34,8 +24,6 @@
 
 alpha = 0
 
-card.disable_planes()
-
 req = pykms.AtomicReq(card)
 req.add(conn, "CRTC_ID", crtc.id)
 req.add(crtc, {"ACTIVE": 1,
@@ -46,16 +34,13 @@
 r = req.commit_sync(allow_modeset = True)
 assert r == 0, "Initial commit failed: %d" % r
 
-input("press enter start\n")
-
 while alpha <= 0xFFFF:
 	print("alpha %d" % (alpha >>  8))
 	req = pykms.AtomicReq(card)
 	req.add(plane2, {"alpha": alpha })
 	r = req.commit_sync()
 	assert r == 0, "alpha change commit failed: %d" % r
-	alpha = alpha + 0x101
-	time.sleep(0.03)
+	alpha = alpha + 0xFF
+	time.sleep(0.1)
 
 input("press enter exit\n")
-card.disable_planes()
diff --git a/py/tests/hpd.py b/py/tests/hpd.py
index 185d784..d26f260 100755
--- a/py/tests/hpd.py
+++ b/py/tests/hpd.py
@@ -4,7 +4,8 @@
 import pykms
 
 card = pykms.Card()
-conns = card.connectors
+res = pykms.ResourceManager(card)
+conn = res.reserve_connector("hdmi")
 
 context = pyudev.Context()
 
@@ -15,8 +16,7 @@
 
 for device in iter(monitor.poll, None):
 	if 'HOTPLUG' in device:
+		conn.refresh()
+		mode = conn.get_modes()
 		print("HPD")
-		for conn in conns:
-			conn.refresh()
-			modes = conn.get_modes()
-			print("  ", conn.fullname, ["{}x{}".format(m.hdisplay, m.vdisplay) for m in modes])
+		print(mode)
diff --git a/py/tests/kmsmodeview.py b/py/tests/kmsmodeview.py
index 0372d0a..355db02 100755
--- a/py/tests/kmsmodeview.py
+++ b/py/tests/kmsmodeview.py
@@ -293,11 +293,8 @@
 mode_buttons = []
 
 card = pykms.Card()
-
-res = pykms.ResourceManager(card)
-conn = res.reserve_connector()
-crtc = res.reserve_crtc(conn)
-plane = res.reserve_generic_plane(crtc)
+conn = card.get_first_connected_connector()
+crtc = conn.get_current_crtc()
 modes = conn.get_modes()
 i = 0
 for m in modes:
diff --git a/py/tests/test.py b/py/tests/test.py
index 3f9e205..83cf16a 100755
--- a/py/tests/test.py
+++ b/py/tests/test.py
@@ -28,7 +28,7 @@
 	origfb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
 
 if args.dmabuf:
-        fb = pykms.DmabufFramebuffer(card, origfb.width, origfb.height, origfb.format,
+	fb = pykms.ExtFramebuffer(card, origfb.width, origfb.height, origfb.format,
 		[origfb.fd(0)], [origfb.stride(0)], [origfb.offset(0)])
 else:
 	fb = origfb
diff --git a/py/tests/testmodes.py b/py/tests/testmodes.py
deleted file mode 100755
index 0508f31..0000000
--- a/py/tests/testmodes.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/python3
-
-import sys
-import pykms
-import argparse
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-c", "--connector", default="")
-args = parser.parse_args()
-
-card = pykms.Card()
-
-res = pykms.ResourceManager(card)
-conn = res.reserve_connector(args.connector)
-crtc = res.reserve_crtc(conn)
-plane = res.reserve_generic_plane(crtc)
-
-card.disable_planes()
-
-modes = conn.get_modes()
-
-def even(i):
-	return i & ~1
-
-for mode in modes:
-	long_str = mode.to_string_long()
-	short_str = mode.to_string_short()
-
-	print(long_str)
-
-	modeb = mode.to_blob(card)
-
-	fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
-	pykms.draw_test_pattern(fb);
-	pykms.draw_text(fb, even((fb.width // 2) - (8 * len(short_str)) // 2), 4, short_str, pykms.white)
-
-	req = pykms.AtomicReq(card)
-
-	req.add_connector(conn, crtc)
-	req.add_crtc(crtc, modeb)
-	req.add_plane(plane, fb, crtc, dst=(0, 0, mode.hdisplay, mode.vdisplay))
-
-	req.commit_sync(allow_modeset = True)
-
-	input("press enter to show next videomode\n")
-
-print("done")
diff --git a/scripts/clang-format-all.sh b/scripts/clang-format-all.sh
deleted file mode 100755
index 38091fb..0000000
--- a/scripts/clang-format-all.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-dirs="kms++ kmscube kms++util py utils"
-find $dirs \( -name "*.cpp" -o -name "*.h" \) -exec clang-format -i {} \;
diff --git a/subprojects/pybind11.wrap b/subprojects/pybind11.wrap
deleted file mode 100644
index 38bc5f3..0000000
--- a/subprojects/pybind11.wrap
+++ /dev/null
@@ -1,12 +0,0 @@
-[wrap-file]
-directory = pybind11-2.6.0
-source_url = https://github.com/pybind/pybind11/archive/v2.6.0.zip
-source_filename = pybind11-2.6.0.zip
-source_hash = c2ed3fc84db08f40a36ce1d03331624ed6977497b35dfed36a1423396928559a
-patch_url = https://wrapdb.mesonbuild.com/v1/projects/pybind11/2.6.0/1/get_zip
-patch_filename = pybind11-2.6.0-1-wrap.zip
-patch_hash = dd52c46ccfdbca06b6967e89c9981408c6a3f4ed3d50c32b809f392b4ac5b0d2
-
-[provide]
-pybind11 = pybind11_dep
-
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
new file mode 100644
index 0000000..f79b207
--- /dev/null
+++ b/utils/CMakeLists.txt
@@ -0,0 +1,29 @@
+include_directories(${LIBDRM_INCLUDE_DIRS})
+link_directories(${LIBDRM_LIBRARY_DIRS})
+
+add_executable (kmstest kmstest.cpp)
+target_link_libraries(kmstest kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (kmsview kmsview.cpp)
+target_link_libraries(kmsview kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (kmsprint kmsprint.cpp)
+target_link_libraries(kmsprint kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (fbtest fbtest.cpp)
+target_link_libraries(fbtest kms++util)
+
+add_executable (kmscapture kmscapture.cpp)
+target_link_libraries(kmscapture kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (kmsblank kmsblank.cpp)
+target_link_libraries(kmsblank kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (wbcap wbcap.cpp)
+target_link_libraries(wbcap kms++ kms++util ${LIBDRM_LIBRARIES})
+
+add_executable (wbm2m wbm2m.cpp)
+target_link_libraries(wbm2m kms++ kms++util ${LIBDRM_LIBRARIES})
+
+install(TARGETS kmstest kmsprint fbtest
+    DESTINATION bin)
diff --git a/utils/fbtest.cpp b/utils/fbtest.cpp
index fba7ba7..1c9a5f1 100644
--- a/utils/fbtest.cpp
+++ b/utils/fbtest.cpp
@@ -34,9 +34,9 @@
 	FAIL_IF(r, "FBIOGET_FSCREENINFO failed");
 
 	uint8_t* ptr = (uint8_t*)mmap(NULL,
-				      var.yres_virtual * fix.line_length,
-				      PROT_WRITE | PROT_READ,
-				      MAP_SHARED, fd, 0);
+			 var.yres_virtual * fix.line_length,
+			 PROT_WRITE | PROT_READ,
+			 MAP_SHARED, fd, 0);
 
 	FAIL_IF(ptr == MAP_FAILED, "mmap failed");
 
diff --git a/utils/kmsblank.cpp b/utils/kmsblank.cpp
index d9a3460..286c7f7 100644
--- a/utils/kmsblank.cpp
+++ b/utils/kmsblank.cpp
@@ -9,22 +9,23 @@
 using namespace kms;
 
 static const char* usage_str =
-	"Usage: kmsblank [OPTION]...\n\n"
-	"Blank screen(s)\n\n"
-	"Options:\n"
-	"      --device=DEVICE       DEVICE is the path to DRM card to open\n"
-	"  -c, --connector=CONN      CONN is <connector>\n"
-	"  -t, --time=TIME           blank/unblank in TIME intervals\n"
-	"\n"
-	"<connector> can be given by index (<idx>) or id (@<id>).\n"
-	"<connector> can also be given by name.\n";
+		"Usage: kmsblank [OPTION]...\n\n"
+		"Blank screen(s)\n\n"
+		"Options:\n"
+		"      --device=DEVICE       DEVICE is the path to DRM card to open\n"
+		"  -c, --connector=CONN      CONN is <connector>\n"
+		"  -t, --time=TIME           blank/unblank in TIME intervals\n"
+		"\n"
+		"<connector> can be given by index (<idx>) or id (@<id>).\n"
+		"<connector> can also be given by name.\n"
+		;
 
 static void usage()
 {
 	puts(usage_str);
 }
 
-int main(int argc, char** argv)
+int main(int argc, char **argv)
 {
 	string dev_path;
 
@@ -32,16 +33,20 @@
 	uint32_t time = 0;
 
 	OptionSet optionset = {
-		Option("|device=", [&dev_path](string s) {
+		Option("|device=", [&dev_path](string s)
+		{
 			dev_path = s;
 		}),
-		Option("c|connector=", [&conn_strs](string str) {
+		Option("c|connector=", [&conn_strs](string str)
+		{
 			conn_strs.push_back(str);
 		}),
-		Option("t|time=", [&time](string str) {
+		Option("t|time=", [&time](string str)
+		{
 			time = stoul(str);
 		}),
-		Option("h|help", []() {
+		Option("h|help", []()
+		{
 			usage();
 			exit(-1);
 		}),
diff --git a/utils/kmscapture.cpp b/utils/kmscapture.cpp
index 099d40f..01eac61 100644
--- a/utils/kmscapture.cpp
+++ b/utils/kmscapture.cpp
@@ -6,13 +6,14 @@
 #include <unistd.h>
 #include <fstream>
 #include <sys/ioctl.h>
+#include <xf86drm.h>
 #include <glob.h>
 
 #include <kms++/kms++.h>
 #include <kms++util/kms++util.h>
 
-#define CAMERA_BUF_QUEUE_SIZE 3
-#define MAX_CAMERA 9
+#define CAMERA_BUF_QUEUE_SIZE	3
+#define MAX_CAMERA		9
 
 using namespace std;
 using namespace kms;
@@ -33,13 +34,12 @@
 	CameraPipeline(const CameraPipeline& other) = delete;
 	CameraPipeline& operator=(const CameraPipeline& other) = delete;
 
-	void show_next_frame(AtomicReq& req);
+	void show_next_frame(AtomicReq &req);
 	int fd() const { return m_fd; }
 	void start_streaming();
-
 private:
-	DmabufFramebuffer* GetDmabufFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt);
-	int m_fd; /* camera file descriptor */
+	ExtFramebuffer* GetExtFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt);
+	int m_fd;	/* camera file descriptor */
 	Crtc* m_crtc;
 	Plane* m_plane;
 	BufferProvider m_buffer_provider;
@@ -51,7 +51,7 @@
 	uint32_t m_out_x, m_out_y;
 };
 
-static int buffer_export(int v4lfd, enum v4l2_buf_type bt, uint32_t index, int* dmafd)
+static int buffer_export(int v4lfd, enum v4l2_buf_type bt, uint32_t index, int *dmafd)
 {
 	struct v4l2_exportbuffer expbuf;
 
@@ -68,7 +68,7 @@
 	return 0;
 }
 
-DmabufFramebuffer* CameraPipeline::GetDmabufFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt)
+ExtFramebuffer* CameraPipeline::GetExtFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt)
 {
 	int r, dmafd;
 
@@ -78,12 +78,12 @@
 	const PixelFormatInfo& format_info = get_pixel_format_info(pixfmt);
 	ASSERT(format_info.num_planes == 1);
 
-	vector<int> fds{ dmafd };
-	vector<uint32_t> pitches{ m_in_width * (format_info.planes[0].bitspp / 8) };
-	vector<uint32_t> offsets{ 0 };
+	vector<int> fds { dmafd };
+	vector<uint32_t> pitches { m_in_width * (format_info.planes[0].bitspp / 8) };
+	vector<uint32_t> offsets { 0 };
 
-	return new DmabufFramebuffer(card, m_in_width, m_in_height, pixfmt,
-				     fds, pitches, offsets);
+	return new ExtFramebuffer(card, m_in_width, m_in_height, pixfmt,
+				  fds, pitches, offsets);
 }
 
 bool inline better_size(struct v4l2_frmsize_discrete* v4ldisc,
@@ -97,16 +97,17 @@
 	return false;
 }
 
-CameraPipeline::CameraPipeline(int cam_fd, Card& card, Crtc* crtc, Plane* plane, uint32_t x, uint32_t y,
+CameraPipeline::CameraPipeline(int cam_fd, Card& card, Crtc *crtc, Plane* plane, uint32_t x, uint32_t y,
 			       uint32_t iw, uint32_t ih, PixelFormat pixfmt,
 			       BufferProvider buffer_provider)
 	: m_fd(cam_fd), m_crtc(crtc), m_buffer_provider(buffer_provider), m_prev_fb_index(-1)
 {
+
 	int r;
 	uint32_t best_w = 320;
 	uint32_t best_h = 240;
 
-	struct v4l2_frmsizeenum v4lfrms = {};
+	struct v4l2_frmsizeenum v4lfrms = { };
 	v4lfrms.pixel_format = (uint32_t)pixfmt;
 	while (ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms) == 0) {
 		if (v4lfrms.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
@@ -137,7 +138,7 @@
 
 	printf("Capture: %ux%u\n", best_w, best_h);
 
-	struct v4l2_format v4lfmt = {};
+	struct v4l2_format v4lfmt = { };
 	v4lfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	r = ioctl(m_fd, VIDIOC_G_FMT, &v4lfmt);
 	ASSERT(r == 0);
@@ -156,7 +157,7 @@
 	else
 		v4l_mem = V4L2_MEMORY_DMABUF;
 
-	struct v4l2_requestbuffers v4lreqbuf = {};
+	struct v4l2_requestbuffers v4lreqbuf = { };
 	v4lreqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	v4lreqbuf.memory = v4l_mem;
 	v4lreqbuf.count = CAMERA_BUF_QUEUE_SIZE;
@@ -164,15 +165,15 @@
 	ASSERT(r == 0);
 	ASSERT(v4lreqbuf.count == CAMERA_BUF_QUEUE_SIZE);
 
-	struct v4l2_buffer v4lbuf = {};
+	struct v4l2_buffer v4lbuf = { };
 	v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	v4lbuf.memory = v4l_mem;
 
 	for (unsigned i = 0; i < CAMERA_BUF_QUEUE_SIZE; i++) {
-		Framebuffer* fb;
+		Framebuffer *fb;
 
 		if (m_buffer_provider == BufferProvider::V4L2)
-			fb = GetDmabufFrameBuffer(card, i, pixfmt);
+			fb = GetExtFrameBuffer(card, i, pixfmt);
 		else
 			fb = new DumbFramebuffer(card, m_in_width,
 						 m_in_height, pixfmt);
@@ -192,7 +193,7 @@
 	// set the FB when page flipping
 	AtomicReq req(card);
 
-	Framebuffer* fb = m_fb[0];
+	Framebuffer *fb = m_fb[0];
 
 	req.add(m_plane, "CRTC_ID", m_crtc->id());
 	req.add(m_plane, "FB_ID", fb->id());
@@ -237,7 +238,7 @@
 	else
 		v4l_mem = V4L2_MEMORY_DMABUF;
 
-	struct v4l2_buffer v4l2buf = {};
+	struct v4l2_buffer v4l2buf = { };
 	v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	v4l2buf.memory = v4l_mem;
 	r = ioctl(m_fd, VIDIOC_DQBUF, &v4l2buf);
@@ -248,7 +249,7 @@
 
 	unsigned fb_index = v4l2buf.index;
 
-	Framebuffer* fb = m_fb[fb_index];
+	Framebuffer *fb = m_fb[fb_index];
 
 	req.add(m_plane, "FB_ID", fb->id());
 
@@ -261,6 +262,7 @@
 			v4l2buf.m.fd = m_fb[m_prev_fb_index]->prime_fd(0);
 		r = ioctl(m_fd, VIDIOC_QBUF, &v4l2buf);
 		ASSERT(r == 0);
+
 	}
 
 	m_prev_fb_index = fb_index;
@@ -268,7 +270,7 @@
 
 static bool is_capture_dev(int fd)
 {
-	struct v4l2_capability cap = {};
+	struct v4l2_capability cap = { };
 	int r = ioctl(fd, VIDIOC_QUERYCAP, &cap);
 	ASSERT(r == 0);
 	return cap.capabilities & V4L2_CAP_VIDEO_CAPTURE;
@@ -279,18 +281,19 @@
 	glob_t glob_result;
 	glob(pat.c_str(), 0, NULL, &glob_result);
 	vector<string> ret;
-	for (unsigned i = 0; i < glob_result.gl_pathc; ++i)
+	for(unsigned i = 0; i < glob_result.gl_pathc; ++i)
 		ret.push_back(string(glob_result.gl_pathv[i]));
 	globfree(&glob_result);
 	return ret;
 }
 
 static const char* usage_str =
-	"Usage: kmscapture [OPTIONS]\n\n"
-	"Options:\n"
-	"  -s, --single                Single camera mode. Open only /dev/video0\n"
-	"      --buffer-type=<drm|v4l> Use DRM or V4L provided buffers. Default: DRM\n"
-	"  -h, --help                  Print this help\n";
+		"Usage: kmscapture [OPTIONS]\n\n"
+		"Options:\n"
+		"  -s, --single                Single camera mode. Open only /dev/video0\n"
+		"      --buffer-type=<drm|v4l> Use DRM or V4L provided buffers. Default: DRM\n"
+		"  -h, --help                  Print this help\n"
+		;
 
 int main(int argc, char** argv)
 {
@@ -298,10 +301,12 @@
 	bool single_cam = false;
 
 	OptionSet optionset = {
-		Option("s|single", [&]() {
+		Option("s|single", [&]()
+		{
 			single_cam = true;
 		}),
-		Option("|buffer-type=", [&](string s) {
+		Option("|buffer-type=", [&](string s)
+		{
 			if (s == "v4l")
 				buffer_provider = BufferProvider::V4L2;
 			else if (s == "drm")
@@ -309,7 +314,8 @@
 			else
 				FAIL("Invalid buffer provider: %s", s.c_str());
 		}),
-		Option("h|help", [&]() {
+		Option("h|help", [&]()
+		{
 			puts(usage_str);
 			exit(-1);
 		}),
@@ -329,7 +335,7 @@
 	auto conn = card.get_first_connected_connector();
 	auto crtc = conn->get_current_crtc();
 	printf("Display: %dx%d\n", crtc->width(), crtc->height());
-	printf("Buffer provider: %s\n", buffer_provider == BufferProvider::V4L2 ? "V4L" : "DRM");
+	printf("Buffer provider: %s\n", buffer_provider == BufferProvider::V4L2? "V4L" : "DRM");
 
 	vector<int> camera_fds;
 
@@ -384,10 +390,10 @@
 
 	for (unsigned i = 0; i < nr_cameras; i++) {
 		fds[i].fd = cameras[i]->fd();
-		fds[i].events = POLLIN;
+		fds[i].events =  POLLIN;
 	}
 	fds[nr_cameras].fd = 0;
-	fds[nr_cameras].events = POLLIN;
+	fds[nr_cameras].events =  POLLIN;
 
 	for (auto cam : cameras)
 		cam->start_streaming();
diff --git a/utils/kmsprint.cpp b/utils/kmsprint.cpp
index 7469b47..116fead 100644
--- a/utils/kmsprint.cpp
+++ b/utils/kmsprint.cpp
@@ -4,7 +4,6 @@
 #include <iostream>
 #include <string>
 #include <unistd.h>
-#include <fmt/format.h>
 
 #include <kms++/kms++.h>
 #include <kms++util/kms++util.h>
@@ -23,19 +22,28 @@
 {
 	string str;
 
-	str = fmt::format("  {:2} ", idx);
+	str = sformat("  %2u ", idx);
 
 	if (s_opts.x_modeline) {
-		str += fmt::format("{:12} {:6} {:4} {:4} {:4} {:4} {:4} {:4} {:4} {:4} {:3} {:#x} {:#x}",
-				   m.name,
-				   m.clock,
-				   m.hdisplay, m.hsync_start, m.hsync_end, m.htotal,
-				   m.vdisplay, m.vsync_start, m.vsync_end, m.vtotal,
-				   m.vrefresh,
-				   m.flags,
-				   m.type);
+		str += sformat("%12s %6u %4u %4u %4u %4u %4u %4u %4u %4u  %2u %#x %#x",
+			       m.name.c_str(),
+			       m.clock,
+			       m.hdisplay, m.hsync_start, m.hsync_end, m.htotal,
+			       m.vdisplay, m.vsync_start, m.vsync_end, m.vtotal,
+			       m.vrefresh,
+			       m.flags,
+			       m.type);
 	} else {
-		str += m.to_string_long_padded();
+		string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp());
+		string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp());
+
+		str += sformat("%-12s %7.3f %-16s %-16s %2u (%.2f) %#10x %#6x",
+			       m.name.c_str(),
+			       m.clock / 1000.0,
+			       h.c_str(), v.c_str(),
+			       m.vrefresh, m.calculated_vrefresh(),
+			       m.flags,
+			       m.type);
 	}
 
 	return str;
@@ -43,15 +51,22 @@
 
 static string format_mode_short(const Videomode& m)
 {
-	return m.to_string_long();
+	string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp());
+	string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp());
+
+	return sformat("%s %.3f %s %s %u (%.2f)",
+		       m.name.c_str(),
+		       m.clock / 1000.0,
+		       h.c_str(), v.c_str(),
+		       m.vrefresh, m.calculated_vrefresh());
 }
 
 static string format_connector(Connector& c)
 {
 	string str;
 
-	str = fmt::format("Connector {} ({}) {}",
-			  c.idx(), c.id(), c.fullname());
+	str = sformat("Connector %u (%u) %s",
+		      c.idx(), c.id(), c.fullname().c_str());
 
 	switch (c.connector_status()) {
 	case ConnectorStatus::Connected:
@@ -70,15 +85,15 @@
 
 static string format_encoder(Encoder& e)
 {
-	return fmt::format("Encoder {} ({}) {}",
-			   e.idx(), e.id(), e.get_encoder_type());
+	return sformat("Encoder %u (%u) %s",
+		       e.idx(), e.id(), e.get_encoder_type().c_str());
 }
 
 static string format_crtc(Crtc& c)
 {
 	string str;
 
-	str = fmt::format("Crtc {} ({})", c.idx(), c.id());
+	str = sformat("Crtc %u (%u)", c.idx(), c.id());
 
 	if (c.mode_valid())
 		str += " " + format_mode_short(c.mode());
@@ -90,112 +105,118 @@
 {
 	string str;
 
-	str = fmt::format("Plane {} ({})", p.idx(), p.id());
+	str = sformat("Plane %u (%u)", p.idx(), p.id());
 
 	if (p.fb_id())
-		str += fmt::format(" fb-id: {}", p.fb_id());
+		str += sformat(" fb-id: %u", p.fb_id());
 
 	string crtcs = join<Crtc*>(p.get_possible_crtcs(), " ", [](Crtc* crtc) { return to_string(crtc->idx()); });
 
-	str += fmt::format(" (crtcs: {})", crtcs);
+	str += sformat(" (crtcs: %s)", crtcs.c_str());
 
 	if (p.card().has_atomic()) {
-		str += fmt::format(" {},{} {}x{} -> {},{} {}x{}",
-				   (uint32_t)p.get_prop_value("SRC_X") >> 16,
-				   (uint32_t)p.get_prop_value("SRC_Y") >> 16,
-				   (uint32_t)p.get_prop_value("SRC_W") >> 16,
-				   (uint32_t)p.get_prop_value("SRC_H") >> 16,
-				   (uint32_t)p.get_prop_value("CRTC_X"),
-				   (uint32_t)p.get_prop_value("CRTC_Y"),
-				   (uint32_t)p.get_prop_value("CRTC_W"),
-				   (uint32_t)p.get_prop_value("CRTC_H"));
+		str += sformat(" %u,%u %ux%u -> %u,%u %ux%u",
+			       (uint32_t)p.get_prop_value("SRC_X") >> 16,
+			       (uint32_t)p.get_prop_value("SRC_Y") >> 16,
+			       (uint32_t)p.get_prop_value("SRC_W") >> 16,
+			       (uint32_t)p.get_prop_value("SRC_H") >> 16,
+			       (uint32_t)p.get_prop_value("CRTC_X"),
+			       (uint32_t)p.get_prop_value("CRTC_Y"),
+			       (uint32_t)p.get_prop_value("CRTC_W"),
+			       (uint32_t)p.get_prop_value("CRTC_H"));
 	}
 
 	string fmts = join<PixelFormat>(p.get_formats(), " ", [](PixelFormat fmt) { return PixelFormatToFourCC(fmt); });
 
-	str += fmt::format(" ({})", fmts);
+	str += sformat(" (%s)", fmts.c_str());
 
 	return str;
 }
 
 static string format_fb(Framebuffer& fb)
 {
-	return fmt::format("FB {} {}x{}",
-			   fb.id(), fb.width(), fb.height());
+	return sformat("FB %u %ux%u",
+		       fb.id(), fb.width(), fb.height());
 }
 
 static string format_property(const Property* prop, uint64_t val)
 {
-	string ret = fmt::format("{} ({}) = ", prop->name(), prop->id());
+	string ret = sformat("%s (%u) = ", prop->name().c_str(), prop->id());
 
 	switch (prop->type()) {
-	case PropertyType::Bitmask: {
+	case PropertyType::Bitmask:
+	{
 		vector<string> v, vall;
 
 		for (auto kvp : prop->get_enums()) {
 			if (val & (1 << kvp.first))
 				v.push_back(kvp.second);
-			vall.push_back(fmt::format("{}={:#x}", kvp.second, 1 << kvp.first));
+			vall.push_back(sformat("%s=0x%x", kvp.second.c_str(), 1 << kvp.first));
 		}
 
-		// XXX
-		ret += fmt::format("{:#x} ({}) [{}]", val, join(v, "|"), join(vall, "|"));
+		ret += sformat("0x%" PRIx64 " (%s) [%s]", val, join(v, "|").c_str(), join(vall, "|").c_str());
 
 		break;
 	}
 
-	case PropertyType::Blob: {
+	case PropertyType::Blob:
+	{
 		uint32_t blob_id = (uint32_t)val;
 
 		if (blob_id) {
 			Blob blob(prop->card(), blob_id);
 			auto data = blob.data();
 
-			ret += fmt::format("blob-id {} len {}", blob_id, data.size());
+			ret += sformat("blob-id %u len %zu", blob_id, data.size());
 		} else {
-			ret += fmt::format("blob-id {}", blob_id);
+			ret += sformat("blob-id %u", blob_id);
 		}
 
 		break;
 	}
 
-	case PropertyType::Enum: {
+	case PropertyType::Enum:
+	{
 		string cur;
 		vector<string> vall;
 
 		for (auto kvp : prop->get_enums()) {
 			if (val == kvp.first)
 				cur = kvp.second;
-			vall.push_back(fmt::format("{}={}", kvp.second, kvp.first));
+			vall.push_back(sformat("%s=%" PRIu64, kvp.second.c_str(), kvp.first));
 		}
 
-		ret += fmt::format("{} ({}) [{}]", val, cur, join(vall, "|"));
+		ret += sformat("%" PRIu64 " (%s) [%s]", val, cur.c_str(), join(vall, "|").c_str());
 
 		break;
 	}
 
-	case PropertyType::Object: {
-		ret += fmt::format("object id {}", val);
+	case PropertyType::Object:
+	{
+		ret += sformat("object id %u", (uint32_t)val);
 		break;
 	}
 
-	case PropertyType::Range: {
+	case PropertyType::Range:
+	{
 		auto values = prop->get_values();
 
-		ret += fmt::format("{} [{} - {}]",
-				   val, values[0], values[1]);
+		ret += sformat("%" PRIu64 " [%" PRIu64 " - %" PRIu64 "]",
+			       val, values[0], values[1]);
 
 		break;
 	}
 
-	case PropertyType::SignedRange: {
+	case PropertyType::SignedRange:
+	{
 		auto values = prop->get_values();
 
-		ret += fmt::format("{} [{} - {}]",
-				   (int64_t)val, (int64_t)values[0], (int64_t)values[1]);
+		ret += sformat("%" PRIi64 " [%" PRIi64 " - %" PRIi64 "]",
+			       (int64_t)val, (int64_t)values[0], (int64_t)values[1]);
 
 		break;
 	}
+
 	}
 
 	if (prop->is_pending())
@@ -240,14 +261,15 @@
 {
 	vector<T> result;
 
-	for (auto it = sequence.begin(); it != sequence.end(); ++it)
-		if (predicate(*it))
+	for(auto it = sequence.begin(); it != sequence.end(); ++it)
+		if(predicate(*it))
 			result.push_back(*it);
 
 	return result;
 }
 
-struct Entry {
+struct Entry
+{
 	string title;
 	vector<string> lines;
 	vector<Entry> children;
@@ -295,16 +317,14 @@
 
 };
 
-const string& get_glyph(TreeGlyph glyph)
+const char* get_glyph(TreeGlyph glyph)
 {
-	static const string s_empty = "  ";
-
 	if (s_glyph_mode == TreeGlyphMode::None)
-		return s_empty;
+		return "  ";
 
 	const map<TreeGlyph, string>& glyphs = s_glyph_mode == TreeGlyphMode::UTF8 ? glyphs_utf8 : glyphs_ascii;
 
-	return glyphs.at(glyph);
+	return glyphs.at(glyph).c_str();
 }
 
 static void print_entry(const Entry& e, const string& prefix, bool is_child, bool is_last)
@@ -317,7 +337,7 @@
 		prefix2 = prefix + (is_last ? get_glyph(TreeGlyph::Space) : get_glyph(TreeGlyph::Vertical));
 	}
 
-	fmt::print("{}{}\n", prefix1, e.title);
+	printf("%s%s\n", prefix1.c_str(), e.title.c_str());
 
 	bool has_children = e.children.size() > 0;
 
@@ -325,7 +345,7 @@
 
 	for (const string& str : e.lines) {
 		string p = data_prefix + get_glyph(TreeGlyph::Space);
-		fmt::print("{}{}\n", p, str);
+		printf("%s%s\n", p.c_str(), str.c_str());
 	}
 
 	for (const Entry& child : e.children) {
@@ -337,7 +357,7 @@
 
 static void print_entries(const vector<Entry>& entries, const string& prefix)
 {
-	for (const Entry& e : entries) {
+	for (const Entry& e: entries) {
 		print_entry(e, "", false, false);
 	}
 }
@@ -348,6 +368,7 @@
 	dst.insert(dst.end(), src.begin(), src.end());
 }
 
+
 static void print_as_list(Card& card)
 {
 	vector<DrmPropObject*> obs;
@@ -363,7 +384,7 @@
 
 	for (Crtc* crtc : card.get_crtcs()) {
 		obs.push_back(crtc);
-		if (crtc->buffer_id() && !card.has_universal_planes()) {
+		if (crtc->buffer_id() && !card.has_has_universal_planes()) {
 			Framebuffer* fb = new Framebuffer(card, crtc->buffer_id());
 			fbs.push_back(fb);
 		}
@@ -377,17 +398,17 @@
 		}
 	}
 
-	for (DrmPropObject* ob : obs) {
-		fmt::print("{}\n", format_ob(ob));
+	for (DrmPropObject* ob: obs) {
+		printf("%s\n", format_ob(ob).c_str());
 
 		if (s_opts.print_props) {
 			for (string str : format_props(ob))
-				fmt::print("    {}\n", str);
+				printf("    %s\n", str.c_str());
 		}
 	}
 
-	for (Framebuffer* fb : fbs) {
-		fmt::print("{}\n", format_ob(fb));
+	for (Framebuffer* fb: fbs) {
+		printf("%s\n", format_ob(fb).c_str());
 	}
 }
 
@@ -402,6 +423,7 @@
 			e1.lines = format_props(conn);
 
 		for (Encoder* enc : conn->get_encoders()) {
+
 			Entry& e2 = add_entry(e1.children);
 			e2.title = format_ob(enc);
 			if (s_opts.print_props)
@@ -413,7 +435,7 @@
 				if (s_opts.print_props)
 					e3.lines = format_props(crtc);
 
-				if (crtc->buffer_id() && !card.has_universal_planes()) {
+				if (crtc->buffer_id() && !card.has_has_universal_planes()) {
 					Framebuffer fb(card, crtc->buffer_id());
 					Entry& e5 = add_entry(e3.children);
 
@@ -451,49 +473,55 @@
 		if (!conn->connected())
 			continue;
 
-		fmt::print("{}\n", format_ob(conn));
+		printf("%s\n", format_ob(conn).c_str());
 
 		auto modes = conn->get_modes();
 		for (unsigned i = 0; i < modes.size(); ++i)
-			fmt::print("{}\n", format_mode(modes[i], i));
+			printf("%s\n", format_mode(modes[i], i).c_str());
 	}
 }
 
 static const char* usage_str =
-	"Usage: kmsprint [OPTIONS]\n\n"
-	"Options:\n"
-	"      --device=DEVICE     DEVICE is the path to DRM card to open\n"
-	"  -l, --list              Print list instead of tree\n"
-	"  -m, --modes             Print modes\n"
-	"      --xmode             Print modes using X modeline\n"
-	"  -p, --props             Print properties\n";
+		"Usage: kmsprint [OPTIONS]\n\n"
+		"Options:\n"
+		"      --device=DEVICE     DEVICE is the path to DRM card to open\n"
+		"  -l, --list              Print list instead of tree\n"
+		"  -m, --modes             Print modes\n"
+		"      --xmode             Print modes using X modeline\n"
+		"  -p, --props             Print properties\n"
+		;
 
 static void usage()
 {
 	puts(usage_str);
 }
 
-int main(int argc, char** argv)
+int main(int argc, char **argv)
 {
 	string dev_path;
 
 	OptionSet optionset = {
-		Option("|device=", [&dev_path](string s) {
+		Option("|device=", [&dev_path](string s)
+		{
 			dev_path = s;
 		}),
-		Option("l|list", []() {
+		Option("l|list", []()
+		{
 			s_opts.print_list = true;
 		}),
-		Option("m|modes", []() {
+		Option("m|modes", []()
+		{
 			s_opts.print_modes = true;
 		}),
-		Option("p|props", []() {
+		Option("p|props", []()
+		{
 			s_opts.print_props = true;
 		}),
 		Option("|xmode", []() {
 			s_opts.x_modeline = true;
 		}),
-		Option("h|help", []() {
+		Option("h|help", []()
+		{
 			usage();
 			exit(-1);
 		}),
diff --git a/utils/kmstest.cpp b/utils/kmstest.cpp
index 3f1716f..8144117 100644
--- a/utils/kmstest.cpp
+++ b/utils/kmstest.cpp
@@ -9,8 +9,6 @@
 
 #include <sys/select.h>
 
-#include <fmt/format.h>
-
 #include <kms++/kms++.h>
 #include <kms++/modedb.h>
 #include <kms++/mode_cvt.h>
@@ -21,15 +19,15 @@
 using namespace kms;
 
 struct PropInfo {
-	PropInfo(string n, uint64_t v)
-		: prop(NULL), name(n), val(v) {}
+	PropInfo(string n, uint64_t v) : prop(NULL), name(n), val(v) {}
 
-	Property* prop;
+	Property *prop;
 	string name;
 	uint64_t val;
 };
 
-struct PlaneInfo {
+struct PlaneInfo
+{
 	Plane* plane;
 
 	unsigned x;
@@ -47,7 +45,8 @@
 	vector<PropInfo> props;
 };
 
-struct OutputInfo {
+struct OutputInfo
+{
 	Connector* connector;
 
 	Crtc* crtc;
@@ -69,13 +68,13 @@
 static bool s_cvt_v2;
 static bool s_cvt_vid_opt;
 static unsigned s_max_flips;
-static bool s_print_crc;
 
-__attribute__((unused)) static void print_regex_match(smatch sm)
+__attribute__ ((unused))
+static void print_regex_match(smatch sm)
 {
 	for (unsigned i = 0; i < sm.size(); ++i) {
 		string str = sm[i].str();
-		fmt::print("{}: {}\n", i, str);
+		printf("%u: %s\n", i, str.c_str());
 	}
 }
 
@@ -86,6 +85,9 @@
 	if (!conn)
 		EXIT("No connector '%s'", str.c_str());
 
+	if (!conn->connected())
+		EXIT("Connector '%s' not connected", conn->fullname().c_str());
+
 	output.connector = conn;
 	output.mode = output.connector->get_default_mode();
 }
@@ -98,10 +100,11 @@
 		EXIT("Could not find available crtc");
 }
 
-static PlaneInfo* add_default_planeinfo(OutputInfo* output)
+
+static PlaneInfo *add_default_planeinfo(OutputInfo* output)
 {
-	output->planes.push_back(PlaneInfo{});
-	PlaneInfo* ret = &output->planes.back();
+	output->planes.push_back(PlaneInfo { });
+	PlaneInfo *ret = &output->planes.back();
 	ret->w = output->mode.hdisplay;
 	ret->h = output->mode.vdisplay;
 	return ret;
@@ -112,16 +115,16 @@
 	// @12:1920x1200i@60
 	// @12:33000000,800/210/30/16/-,480/22/13/10/-,i
 
-	const regex modename_re("(?:(@?)(\\d+):)?" // @12:
-				"(?:(\\d+)x(\\d+)(i)?)" // 1920x1200i
-				"(?:@([\\d\\.]+))?"); // @60
+	const regex modename_re("(?:(@?)(\\d+):)?"	// @12:
+				"(?:(\\d+)x(\\d+)(i)?)"	// 1920x1200i
+				"(?:@([\\d\\.]+))?");	// @60
 
-	const regex modeline_re("(?:(@?)(\\d+):)?" // @12:
-				"(\\d+)," // 33000000,
-				"(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])," // 800/210/30/16/-,
-				"(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])" // 480/22/13/10/-
-				"(?:,([i]+))?" // ,i
-	);
+	const regex modeline_re("(?:(@?)(\\d+):)?"			// @12:
+				"(\\d+),"				// 33000000,
+				"(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-]),"	// 800/210/30/16/-,
+				"(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])"	// 480/22/13/10/-
+				"(?:,([i]+))?"				// ,i
+				);
 
 	smatch sm;
 	if (regex_match(crtc_str, sm, modename_re)) {
@@ -243,9 +246,9 @@
 static void parse_plane(ResourceManager& resman, Card& card, const string& plane_str, const OutputInfo& output, PlaneInfo& pinfo)
 {
 	// 3:400,400-400x400
-	const regex plane_re("(?:(@?)(\\d+):)?" // 3:
-			     "(?:(\\d+),(\\d+)-)?" // 400,400-
-			     "(\\d+)x(\\d+)"); // 400x400
+	const regex plane_re("(?:(@?)(\\d+):)?"		// 3:
+			     "(?:(\\d+),(\\d+)-)?"	// 400,400-
+			     "(\\d+)x(\\d+)");		// 400x400
 
 	smatch sm;
 	if (!regex_match(plane_str, sm, plane_re))
@@ -289,7 +292,7 @@
 		pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2;
 }
 
-static void parse_prop(const string& prop_str, vector<PropInfo>& props)
+static void parse_prop(const string& prop_str, vector<PropInfo> &props)
 {
 	string name, val;
 
@@ -299,12 +302,12 @@
 		EXIT("Equal sign ('=') not found in %s", prop_str.c_str());
 
 	name = prop_str.substr(0, split);
-	val = prop_str.substr(split + 1);
+	val = prop_str.substr(split+1);
 
 	props.push_back(PropInfo(name, stoull(val, 0, 0)));
 }
 
-static void get_props(Card& card, vector<PropInfo>& props, const DrmPropObject* propobj)
+static void get_props(Card& card, vector<PropInfo> &props, const DrmPropObject* propobj)
 {
 	for (auto& pi : props)
 		pi.prop = propobj->get_prop(pi.name);
@@ -336,9 +339,9 @@
 	if (!fb_str.empty()) {
 		// XXX the regexp is not quite correct
 		// 400x400-NV12
-		const regex fb_re("(?:(\\d+)x(\\d+))?" // 400x400
-				  "(?:-)?" // -
-				  "(\\w\\w\\w\\w)?"); // NV12
+		const regex fb_re("(?:(\\d+)x(\\d+))?"		// 400x400
+				  "(?:-)?"			// -
+				  "(\\w\\w\\w\\w)?");		// NV12
 
 		smatch sm;
 		if (!regex_match(fb_str, sm, fb_re))
@@ -365,7 +368,7 @@
 
 static void parse_view(const string& view_str, PlaneInfo& pinfo)
 {
-	const regex view_re("(\\d+),(\\d+)-(\\d+)x(\\d+)"); // 400,400-400x400
+	const regex view_re("(\\d+),(\\d+)-(\\d+)x(\\d+)");		// 400,400-400x400
 
 	smatch sm;
 	if (!regex_match(view_str, sm, view_re))
@@ -378,54 +381,55 @@
 }
 
 static const char* usage_str =
-	"Usage: kmstest [OPTION]...\n\n"
-	"Show a test pattern on a display or plane\n\n"
-	"Options:\n"
-	"      --device=DEVICE       DEVICE is the path to DRM card to open\n"
-	"  -c, --connector=CONN      CONN is <connector>\n"
-	"  -r, --crtc=CRTC           CRTC is [<crtc>:]<w>x<h>[@<Hz>]\n"
-	"                            or\n"
-	"                            [<crtc>:]<pclk>,<hact>/<hfp>/<hsw>/<hbp>/<hsp>,<vact>/<vfp>/<vsw>/<vbp>/<vsp>[,i]\n"
-	"  -p, --plane=PLANE         PLANE is [<plane>:][<x>,<y>-]<w>x<h>\n"
-	"  -f, --fb=FB               FB is [<w>x<h>][-][<4cc>]\n"
-	"  -v, --view=VIEW           VIEW is <x>,<y>-<w>x<h>\n"
-	"  -P, --property=PROP=VAL   Set PROP to VAL in the previous DRM object\n"
-	"      --dmt                 Search for the given mode from DMT tables\n"
-	"      --cea                 Search for the given mode from CEA tables\n"
-	"      --cvt=CVT             Create videomode with CVT. CVT is 'v1', 'v2' or 'v2o'\n"
-	"      --flip[=max]          Do page flipping for each output with an optional maximum flips count\n"
-	"      --sync                Synchronize page flipping\n"
-	"      --crc                 Print CRC16 for framebuffer contents\n"
-	"\n"
-	"<connector>, <crtc> and <plane> can be given by index (<idx>) or id (@<id>).\n"
-	"<connector> can also be given by name.\n"
-	"\n"
-	"Options can be given multiple times to set up multiple displays or planes.\n"
-	"Options may apply to previous options, e.g. a plane will be set on a crtc set in\n"
-	"an earlier option.\n"
-	"If you omit parameters, kmstest tries to guess what you mean\n"
-	"\n"
-	"Examples:\n"
-	"\n"
-	"Set eDP-1 mode to 1920x1080@60, show XR24 framebuffer on the crtc, and a 400x400 XB24 plane:\n"
-	"    kmstest -c eDP-1 -r 1920x1080@60 -f XR24 -p 400x400 -f XB24\n\n"
-	"XR24 framebuffer on first connected connector in the default mode:\n"
-	"    kmstest -f XR24\n\n"
-	"XR24 framebuffer on a 400x400 plane on the first connected connector in the default mode:\n"
-	"    kmstest -p 400x400 -f XR24\n\n"
-	"Test pattern on the second connector with default mode:\n"
-	"    kmstest -c 1\n"
-	"\n"
-	"Environmental variables:\n"
-	"    KMSXX_DISABLE_UNIVERSAL_PLANES    Don't enable universal planes even if available\n"
-	"    KMSXX_DISABLE_ATOMIC              Don't enable atomic modesetting even if available\n";
+		"Usage: kmstest [OPTION]...\n\n"
+		"Show a test pattern on a display or plane\n\n"
+		"Options:\n"
+		"      --device=DEVICE       DEVICE is the path to DRM card to open\n"
+		"  -c, --connector=CONN      CONN is <connector>\n"
+		"  -r, --crtc=CRTC           CRTC is [<crtc>:]<w>x<h>[@<Hz>]\n"
+		"                            or\n"
+		"                            [<crtc>:]<pclk>,<hact>/<hfp>/<hsw>/<hbp>/<hsp>,<vact>/<vfp>/<vsw>/<vbp>/<vsp>[,i]\n"
+		"  -p, --plane=PLANE         PLANE is [<plane>:][<x>,<y>-]<w>x<h>\n"
+		"  -f, --fb=FB               FB is [<w>x<h>][-][<4cc>]\n"
+		"  -v, --view=VIEW           VIEW is <x>,<y>-<w>x<h>\n"
+		"  -P, --property=PROP=VAL   Set PROP to VAL in the previous DRM object\n"
+		"      --dmt                 Search for the given mode from DMT tables\n"
+		"      --cea                 Search for the given mode from CEA tables\n"
+		"      --cvt=CVT             Create videomode with CVT. CVT is 'v1', 'v2' or 'v2o'\n"
+		"      --flip[=max]          Do page flipping for each output with an optional maximum flips count\n"
+		"      --sync                Synchronize page flipping\n"
+		"\n"
+		"<connector>, <crtc> and <plane> can be given by index (<idx>) or id (@<id>).\n"
+		"<connector> can also be given by name.\n"
+		"\n"
+		"Options can be given multiple times to set up multiple displays or planes.\n"
+		"Options may apply to previous options, e.g. a plane will be set on a crtc set in\n"
+		"an earlier option.\n"
+		"If you omit parameters, kmstest tries to guess what you mean\n"
+		"\n"
+		"Examples:\n"
+		"\n"
+		"Set eDP-1 mode to 1920x1080@60, show XR24 framebuffer on the crtc, and a 400x400 XB24 plane:\n"
+		"    kmstest -c eDP-1 -r 1920x1080@60 -f XR24 -p 400x400 -f XB24\n\n"
+		"XR24 framebuffer on first connected connector in the default mode:\n"
+		"    kmstest -f XR24\n\n"
+		"XR24 framebuffer on a 400x400 plane on the first connected connector in the default mode:\n"
+		"    kmstest -p 400x400 -f XR24\n\n"
+		"Test pattern on the second connector with default mode:\n"
+		"    kmstest -c 1\n"
+		"\n"
+		"Environmental variables:\n"
+		"    KMSXX_DISABLE_UNIVERSAL_PLANES    Don't enable universal planes even if available\n"
+		"    KMSXX_DISABLE_ATOMIC              Don't enable atomic modesetting even if available\n"
+		;
 
 static void usage()
 {
 	puts(usage_str);
 }
 
-enum class ArgType {
+enum class ArgType
+{
 	Connector,
 	Crtc,
 	Plane,
@@ -434,57 +438,70 @@
 	Property,
 };
 
-struct Arg {
+struct Arg
+{
 	ArgType type;
 	string arg;
 };
 
 static string s_device_path;
 
-static vector<Arg> parse_cmdline(int argc, char** argv)
+static vector<Arg> parse_cmdline(int argc, char **argv)
 {
 	vector<Arg> args;
 
 	OptionSet optionset = {
 		Option("|device=",
-		       [&](string s) {
-			       s_device_path = s;
-		       }),
+		[&](string s)
+		{
+			s_device_path = s;
+		}),
 		Option("c|connector=",
-		       [&](string s) {
-			       args.push_back(Arg{ ArgType::Connector, s });
-		       }),
-		Option("r|crtc=", [&](string s) {
-			args.push_back(Arg{ ArgType::Crtc, s });
+		[&](string s)
+		{
+			args.push_back(Arg { ArgType::Connector, s });
 		}),
-		Option("p|plane=", [&](string s) {
-			args.push_back(Arg{ ArgType::Plane, s });
+		Option("r|crtc=", [&](string s)
+		{
+			args.push_back(Arg { ArgType::Crtc, s });
 		}),
-		Option("f|fb=", [&](string s) {
-			args.push_back(Arg{ ArgType::Framebuffer, s });
+		Option("p|plane=", [&](string s)
+		{
+			args.push_back(Arg { ArgType::Plane, s });
 		}),
-		Option("v|view=", [&](string s) {
-			args.push_back(Arg{ ArgType::View, s });
+		Option("f|fb=", [&](string s)
+		{
+			args.push_back(Arg { ArgType::Framebuffer, s });
 		}),
-		Option("P|property=", [&](string s) {
-			args.push_back(Arg{ ArgType::Property, s });
+		Option("v|view=", [&](string s)
+		{
+			args.push_back(Arg { ArgType::View, s });
 		}),
-		Option("|dmt", []() {
+		Option("P|property=", [&](string s)
+		{
+			args.push_back(Arg { ArgType::Property, s });
+		}),
+		Option("|dmt", []()
+		{
 			s_use_dmt = true;
 		}),
-		Option("|cea", []() {
+		Option("|cea", []()
+		{
 			s_use_cea = true;
 		}),
-		Option("|flip?", [&](string s) {
+		Option("|flip?", [&](string s)
+		{
 			s_flip_mode = true;
 			s_num_buffers = 2;
 			if (!s.empty())
 				s_max_flips = stoi(s);
 		}),
-		Option("|sync", []() {
+		Option("|sync", []()
+		{
 			s_flip_sync = true;
 		}),
-		Option("|cvt=", [&](string s) {
+		Option("|cvt=", [&](string s)
+		{
 			if (s == "v1")
 				s_cvt = true;
 			else if (s == "v2")
@@ -496,10 +513,8 @@
 				exit(-1);
 			}
 		}),
-		Option("|crc", []() {
-			s_print_crc = true;
-		}),
-		Option("h|help", [&]() {
+		Option("h|help", [&]()
+		{
 			usage();
 			exit(-1);
 		}),
@@ -524,8 +539,9 @@
 
 	for (auto& arg : output_args) {
 		switch (arg.type) {
-		case ArgType::Connector: {
-			outputs.push_back(OutputInfo{});
+		case ArgType::Connector:
+		{
+			outputs.push_back(OutputInfo { });
 			current_output = &outputs.back();
 
 			get_connector(resman, *current_output, arg.arg);
@@ -534,9 +550,10 @@
 			break;
 		}
 
-		case ArgType::Crtc: {
+		case ArgType::Crtc:
+		{
 			if (!current_output) {
-				outputs.push_back(OutputInfo{});
+				outputs.push_back(OutputInfo { });
 				current_output = &outputs.back();
 			}
 
@@ -550,9 +567,10 @@
 			break;
 		}
 
-		case ArgType::Plane: {
+		case ArgType::Plane:
+		{
 			if (!current_output) {
-				outputs.push_back(OutputInfo{});
+				outputs.push_back(OutputInfo { });
 				current_output = &outputs.back();
 			}
 
@@ -569,9 +587,10 @@
 			break;
 		}
 
-		case ArgType::Framebuffer: {
+		case ArgType::Framebuffer:
+		{
 			if (!current_output) {
-				outputs.push_back(OutputInfo{});
+				outputs.push_back(OutputInfo { });
 				current_output = &outputs.back();
 			}
 
@@ -589,7 +608,8 @@
 			break;
 		}
 
-		case ArgType::View: {
+		case ArgType::View:
+		{
 			if (!current_plane || current_plane->fbs.empty())
 				EXIT("'view' parameter requires a plane and a fb");
 
@@ -597,7 +617,8 @@
 			break;
 		}
 
-		case ArgType::Property: {
+		case ArgType::Property:
+		{
 			if (!current_output)
 				EXIT("No object to which set the property");
 
@@ -618,10 +639,10 @@
 	if (outputs.empty()) {
 		// no outputs defined, show a pattern on all connected screens
 		for (Connector* conn : card.get_connectors()) {
-			if (!conn->connected())
+			if (conn->connector_status() != ConnectorStatus::Connected)
 				continue;
 
-			OutputInfo output = {};
+			OutputInfo output = { };
 			output.connector = resman.reserve_connector(conn);
 			EXIT_IF(!output.connector, "Failed to reserve connector %s", conn->fullname().c_str());
 			output.crtc = resman.reserve_crtc(conn);
@@ -640,9 +661,6 @@
 
 		get_props(card, o.crtc_props, o.crtc);
 
-		if (!o.mode.valid())
-			EXIT("Mode not valid for %s", o.connector->fullname().c_str());
-
 		if (card.has_atomic()) {
 			if (o.planes.empty())
 				add_default_planeinfo(&o);
@@ -651,7 +669,7 @@
 				o.legacy_fbs = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay);
 		}
 
-		for (PlaneInfo& p : o.planes) {
+		for (PlaneInfo &p : o.planes) {
 			if (p.fbs.empty())
 				p.fbs = get_default_fb(card, p.w, p.h);
 		}
@@ -673,46 +691,30 @@
 	return outputs;
 }
 
-static uint16_t crc16(uint16_t crc, uint8_t data)
+static char sync_to_char(SyncPolarity pol)
 {
-	const uint16_t CRC16_IBM = 0x8005;
-
-	for (uint8_t i = 0; i < 8; i++) {
-		if (((crc & 0x8000) >> 8) ^ (data & 0x80))
-			crc = (crc << 1) ^ CRC16_IBM;
-		else
-			crc = (crc << 1);
-
-		data <<= 1;
+	switch (pol) {
+	case SyncPolarity::Positive:
+		return '+';
+	case SyncPolarity::Negative:
+		return '-';
+	default:
+		return '?';
 	}
-
-	return crc;
 }
 
-static string fb_crc(IFramebuffer* fb)
+static std::string videomode_to_string(const Videomode& m)
 {
-	uint8_t* p = fb->map(0);
-	uint16_t r, g, b;
+	string h = sformat("%u/%u/%u/%u/%c", m.hdisplay, m.hfp(), m.hsw(), m.hbp(), sync_to_char(m.hsync()));
+	string v = sformat("%u/%u/%u/%u/%c", m.vdisplay, m.vfp(), m.vsw(), m.vbp(), sync_to_char(m.vsync()));
 
-	r = g = b = 0;
-
-	for (unsigned y = 0; y < fb->height(); ++y) {
-		for (unsigned x = 0; x < fb->width(); ++x) {
-			uint32_t* p32 = (uint32_t*)(p + fb->stride(0) * y + x * 4);
-			RGB rgb(*p32);
-
-			r = crc16(r, rgb.r);
-			r = crc16(r, 0);
-
-			g = crc16(g, rgb.g);
-			g = crc16(g, 0);
-
-			b = crc16(b, rgb.b);
-			b = crc16(b, 0);
-		}
-	}
-
-	return fmt::format("{:#06x} {:#06x} {:#06x}", r, g, b);
+	return sformat("%s %.3f %s %s %u (%.2f) %#x %#x",
+		       m.name.c_str(),
+		       m.clock / 1000.0,
+		       h.c_str(), v.c_str(),
+		       m.vrefresh, m.calculated_vrefresh(),
+		       m.flags,
+		       m.type);
 }
 
 static void print_outputs(const vector<OutputInfo>& outputs)
@@ -720,37 +722,38 @@
 	for (unsigned i = 0; i < outputs.size(); ++i) {
 		const OutputInfo& o = outputs[i];
 
-		fmt::print("Connector {}/@{}: {}", o.connector->idx(), o.connector->id(),
-			   o.connector->fullname());
+		printf("Connector %u/@%u: %s", o.connector->idx(), o.connector->id(),
+		       o.connector->fullname().c_str());
 
-		for (const PropInfo& prop : o.conn_props)
-			fmt::print(" {}={}", prop.prop->name(), prop.val);
+		for (const PropInfo &prop: o.conn_props)
+			printf(" %s=%" PRIu64, prop.prop->name().c_str(),
+			       prop.val);
 
-		fmt::print("\n  Crtc {}/@{}", o.crtc->idx(), o.crtc->id());
+		printf("\n  Crtc %u/@%u", o.crtc->idx(), o.crtc->id());
 
-		for (const PropInfo& prop : o.crtc_props)
-			fmt::print(" {}={}", prop.prop->name(), prop.val);
+		for (const PropInfo &prop: o.crtc_props)
+			printf(" %s=%" PRIu64, prop.prop->name().c_str(),
+			       prop.val);
 
-		fmt::print(": {}\n", o.mode.to_string_long());
+		printf(": %s\n", videomode_to_string(o.mode).c_str());
 
 		if (!o.legacy_fbs.empty()) {
 			auto fb = o.legacy_fbs[0];
-			fmt::print("    Fb {} {}x{}-{}\n", fb->id(), fb->width(), fb->height(), PixelFormatToFourCC(fb->format()));
+			printf("    Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(), PixelFormatToFourCC(fb->format()).c_str());
 		}
 
 		for (unsigned j = 0; j < o.planes.size(); ++j) {
 			const PlaneInfo& p = o.planes[j];
 			auto fb = p.fbs[0];
-			fmt::print("  Plane {}/@{}: {},{}-{}x{}", p.plane->idx(), p.plane->id(),
-				   p.x, p.y, p.w, p.h);
-			for (const PropInfo& prop : p.props)
-				fmt::print(" {}={}", prop.prop->name(), prop.val);
-			fmt::print("\n");
+			printf("  Plane %u/@%u: %u,%u-%ux%u", p.plane->idx(), p.plane->id(),
+			       p.x, p.y, p.w, p.h);
+			for (const PropInfo &prop: p.props)
+				printf(" %s=%" PRIu64, prop.prop->name().c_str(),
+				       prop.val);
+			printf("\n");
 
-			fmt::print("    Fb {} {}x{}-{}\n", fb->id(), fb->width(), fb->height(),
-				   PixelFormatToFourCC(fb->format()));
-			if (s_print_crc)
-				fmt::print("      CRC16 {}\n", fb_crc(fb).c_str());
+			printf("    Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(),
+			       PixelFormatToFourCC(fb->format()).c_str());
 		}
 	}
 }
@@ -796,8 +799,8 @@
 			auto fb = o.legacy_fbs[0];
 			r = crtc->set_mode(conn, *fb, o.mode);
 			if (r)
-				fmt::print(stderr, "crtc->set_mode() failed for crtc {}: {}\n",
-					   crtc->id(), strerror(-r));
+				printf("crtc->set_mode() failed for crtc %u: %s\n",
+				       crtc->id(), strerror(-r));
 		}
 
 		for (const PlaneInfo& p : o.planes) {
@@ -808,11 +811,11 @@
 
 			auto fb = p.fbs[0];
 			r = crtc->set_plane(p.plane, *fb,
-					    p.x, p.y, p.w, p.h,
-					    0, 0, fb->width(), fb->height());
+						p.x, p.y, p.w, p.h,
+						0, 0, fb->width(), fb->height());
 			if (r)
-				fmt::print(stderr, "crtc->set_plane() failed for plane {}: {}\n",
-					   p.plane->id(), strerror(-r));
+				printf("crtc->set_plane() failed for plane %u: %s\n",
+				       p.plane->id(), strerror(-r));
 		}
 	}
 }
@@ -833,21 +836,22 @@
 		//	continue;
 
 		disable_req.add(crtc, {
-					      { "ACTIVE", 0 },
-				      });
+				{ "ACTIVE", 0 },
+			});
 	}
 
 	// Disable unused planes
 	for (Plane* plane : card.get_planes())
 		disable_req.add(plane, {
-					       { "FB_ID", 0 },
-					       { "CRTC_ID", 0 },
-				       });
+				{ "FB_ID", 0 },
+				{ "CRTC_ID", 0 },
+			});
 
 	r = disable_req.commit_sync(true);
 	if (r)
 		EXIT("Atomic commit failed when disabling: %d\n", r);
 
+
 	// Keep blobs here so that we keep ref to them until we have committed the req
 	vector<unique_ptr<Blob>> blobs;
 
@@ -861,37 +865,37 @@
 		Blob* mode_blob = blobs.back().get();
 
 		req.add(conn, {
-				      { "CRTC_ID", crtc->id() },
-			      });
+				{ "CRTC_ID", crtc->id() },
+			});
 
-		for (const PropInfo& prop : o.conn_props)
+		for (const PropInfo &prop: o.conn_props)
 			req.add(conn, prop.prop, prop.val);
 
 		req.add(crtc, {
-				      { "ACTIVE", 1 },
-				      { "MODE_ID", mode_blob->id() },
-			      });
+				{ "ACTIVE", 1 },
+				{ "MODE_ID", mode_blob->id() },
+			});
 
-		for (const PropInfo& prop : o.crtc_props)
+		for (const PropInfo &prop: o.crtc_props)
 			req.add(crtc, prop.prop, prop.val);
 
 		for (const PlaneInfo& p : o.planes) {
 			auto fb = p.fbs[0];
 
 			req.add(p.plane, {
-						 { "FB_ID", fb->id() },
-						 { "CRTC_ID", crtc->id() },
-						 { "SRC_X", (p.view_x ?: 0) << 16 },
-						 { "SRC_Y", (p.view_y ?: 0) << 16 },
-						 { "SRC_W", (p.view_w ?: fb->width()) << 16 },
-						 { "SRC_H", (p.view_h ?: fb->height()) << 16 },
-						 { "CRTC_X", p.x },
-						 { "CRTC_Y", p.y },
-						 { "CRTC_W", p.w },
-						 { "CRTC_H", p.h },
-					 });
+					{ "FB_ID", fb->id() },
+					{ "CRTC_ID", crtc->id() },
+					{ "SRC_X", (p.view_x ?: 0) << 16 },
+					{ "SRC_Y", (p.view_y ?: 0) << 16 },
+					{ "SRC_W", (p.view_w ?: fb->width()) << 16 },
+					{ "SRC_H", (p.view_h ?: fb->height()) << 16 },
+					{ "CRTC_X", p.x },
+					{ "CRTC_Y", p.y },
+					{ "CRTC_W", p.w },
+					{ "CRTC_H", p.h },
+				});
 
-			for (const PropInfo& prop : p.props)
+			for (const PropInfo &prop: p.props)
 				req.add(p.plane, prop.prop, prop.val);
 		}
 	}
@@ -951,12 +955,12 @@
 		if (diff > m_slowest_frame)
 			m_slowest_frame = diff;
 
-		if (m_frame_num % 100 == 0) {
+		if (m_frame_num  % 100 == 0) {
 			std::chrono::duration<float> fsec = now - m_prev_print;
-			fmt::print("Connector {}: fps {:.2f}, slowest {:.2f} ms\n",
-				   m_name.c_str(),
-				   100.0 / fsec.count(),
-				   m_slowest_frame.count() * 1000);
+			printf("Connector %s: fps %f, slowest %.2f ms\n",
+			       m_name.c_str(),
+			       100.0 / fsec.count(),
+			       m_slowest_frame.count() * 1000);
 			m_prev_print = now;
 			m_slowest_frame = std::chrono::duration<float>::min();
 		}
@@ -990,8 +994,8 @@
 			draw_bar(fb, frame_num);
 
 			req.add(p.plane, {
-						 { "FB_ID", fb->id() },
-					 });
+					{ "FB_ID", fb->id() },
+				});
 		}
 	}
 
@@ -1055,8 +1059,6 @@
 
 static void main_flip(Card& card, const vector<OutputInfo>& outputs)
 {
-// clang-tidy does not seem to handle FD_xxx macros
-#ifndef __clang_analyzer__
 	fd_set fds;
 
 	FD_ZERO(&fds);
@@ -1094,19 +1096,18 @@
 
 		r = select(fd + 1, &fds, NULL, NULL, NULL);
 		if (r < 0) {
-			fmt::print(stderr, "select() failed with {}: {}\n", errno, strerror(errno));
+			fprintf(stderr, "select() failed with %d: %m\n", errno);
 			break;
 		} else if (FD_ISSET(0, &fds)) {
-			fmt::print(stderr, "Exit due to user-input\n");
+			fprintf(stderr, "Exit due to user-input\n");
 			break;
 		} else if (FD_ISSET(fd, &fds)) {
 			card.call_page_flip_handlers();
 		}
 	}
-#endif
 }
 
-int main(int argc, char** argv)
+int main(int argc, char **argv)
 {
 	vector<Arg> output_args = parse_cmdline(argc, argv);
 
@@ -1129,7 +1130,7 @@
 
 	set_crtcs_n_planes(card, outputs);
 
-	fmt::print("press enter to exit\n");
+	printf("press enter to exit\n");
 
 	if (s_flip_mode)
 		main_flip(card, outputs);
diff --git a/utils/kmstouch.cpp b/utils/kmstouch.cpp
deleted file mode 100644
index 8afcee5..0000000
--- a/utils/kmstouch.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-#include <cstdio>
-#include <unistd.h>
-#include <algorithm>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <cstring>
-
-#include <libevdev/libevdev.h>
-#include <libevdev/libevdev-uinput.h>
-
-#include <kms++/kms++.h>
-#include <kms++util/kms++util.h>
-
-using namespace std;
-using namespace kms;
-
-static const char* usage_str =
-	"Usage: kmstouch [OPTION]...\n\n"
-	"Simple touchscreen tester\n\n"
-	"Options:\n"
-	"      --input=DEVICE        DEVICE is the path to input device to open\n"
-	"      --device=DEVICE       DEVICE is the path to DRM card to open\n"
-	"  -c, --connector=CONN      CONN is <connector>\n"
-	"\n";
-
-static void usage()
-{
-	puts(usage_str);
-}
-
-static bool s_print_ev = false;
-
-static vector<pair<int32_t, int32_t>> s_coords;
-
-// axis -> min,max
-static map<int, pair<int32_t, int32_t>> s_abs_map;
-// axis -> value
-static map<int, int32_t> s_abs_vals;
-
-static void print_abs_bits(struct libevdev* dev, int axis)
-{
-	const struct input_absinfo* abs;
-
-	if (!libevdev_has_event_code(dev, EV_ABS, axis))
-		return;
-
-	abs = libevdev_get_abs_info(dev, axis);
-
-	printf("	Value	%6d\n", abs->value);
-	printf("	Min	%6d\n", abs->minimum);
-	printf("	Max	%6d\n", abs->maximum);
-	if (abs->fuzz)
-		printf("	Fuzz	%6d\n", abs->fuzz);
-	if (abs->flat)
-		printf("	Flat	%6d\n", abs->flat);
-	if (abs->resolution)
-		printf("	Resolution	%6d\n", abs->resolution);
-}
-
-static void print_code_bits(struct libevdev* dev, unsigned int type, unsigned int max)
-{
-	for (uint32_t i = 0; i <= max; i++) {
-		if (!libevdev_has_event_code(dev, type, i))
-			continue;
-
-		printf("    Event code %i (%s)\n", i, libevdev_event_code_get_name(type, i));
-		if (type == EV_ABS)
-			print_abs_bits(dev, i);
-	}
-}
-
-static void print_bits(struct libevdev* dev)
-{
-	printf("Supported events:\n");
-
-	for (uint32_t i = 0; i <= EV_MAX; i++) {
-		if (!libevdev_has_event_type(dev, i))
-			continue;
-
-		printf("  Event type %d (%s)\n", i, libevdev_event_type_get_name(i));
-
-		switch (i) {
-		case EV_KEY:
-			print_code_bits(dev, EV_KEY, KEY_MAX);
-			break;
-		case EV_REL:
-			print_code_bits(dev, EV_REL, REL_MAX);
-			break;
-		case EV_ABS:
-			print_code_bits(dev, EV_ABS, ABS_MAX);
-			break;
-		case EV_LED:
-			print_code_bits(dev, EV_LED, LED_MAX);
-			break;
-		}
-	}
-}
-
-static void collect_current(struct libevdev* dev)
-{
-	for (uint32_t i = 0; i <= ABS_MAX; i++) {
-		if (!libevdev_has_event_code(dev, EV_ABS, i))
-			continue;
-
-		const struct input_absinfo* abs;
-
-		abs = libevdev_get_abs_info(dev, i);
-
-		s_abs_vals[i] = abs->value;
-		s_abs_map[i] = make_pair(abs->minimum, abs->maximum);
-	}
-}
-
-static void print_props(struct libevdev* dev)
-{
-	printf("Properties:\n");
-
-	for (uint32_t i = 0; i <= INPUT_PROP_MAX; i++) {
-		if (!libevdev_has_property(dev, i))
-			continue;
-
-		printf("  Property type %d (%s)\n", i, libevdev_property_get_name(i));
-	}
-}
-
-static void handle_event(struct input_event& ev, DumbFramebuffer* fb)
-{
-	static vector<pair<uint16_t, int32_t>> s_event_vec;
-
-	if (s_print_ev)
-		printf("%-6s %20s %6d\n",
-		       libevdev_event_type_get_name(ev.type),
-		       libevdev_event_code_get_name(ev.type, ev.code),
-		       ev.value);
-
-	switch (ev.type) {
-	case EV_ABS:
-		s_event_vec.emplace_back(ev.code, ev.value);
-		break;
-
-	case EV_KEY:
-		s_event_vec.emplace_back(ev.code, ev.value);
-		break;
-
-	case EV_SYN:
-		switch (ev.code) {
-		case SYN_REPORT: {
-			int32_t min_x = s_abs_map[ABS_X].first;
-			int32_t max_x = s_abs_map[ABS_X].second;
-
-			int32_t min_y = s_abs_map[ABS_Y].first;
-			int32_t max_y = s_abs_map[ABS_Y].second;
-
-			for (const auto& p : s_event_vec) {
-				switch (p.first) {
-				case ABS_X:
-				case ABS_Y:
-					s_abs_vals[p.first] = p.second;
-					break;
-				default:
-					break;
-				}
-			}
-
-			int32_t abs_x = s_abs_vals[ABS_X];
-			int32_t abs_y = s_abs_vals[ABS_Y];
-
-			int32_t x = (abs_x - min_x) * (fb->width() - 1) / (max_x - min_x);
-			int32_t y = (abs_y - min_y) * (fb->height() - 1) / (max_y - min_y);
-
-			printf("%d, %d -> %d, %d\n", abs_x, abs_y, x, y);
-
-			draw_rgb_pixel(*fb, x, y, RGB(255, 255, 255));
-
-			s_event_vec.clear();
-
-			if (s_print_ev)
-				printf("----\n");
-			break;
-		}
-
-		default:
-			EXIT("Unhandled syn event code %u\n", ev.code);
-			break;
-		}
-
-		break;
-
-	default:
-		EXIT("Unhandled event type %u\n", ev.type);
-		break;
-	}
-}
-
-int main(int argc, char** argv)
-{
-	string drm_dev_path = "/dev/dri/card0";
-	string input_dev_path = "/dev/input/event0";
-	string conn_name;
-
-	OptionSet optionset = {
-		Option("i|input=", [&input_dev_path](string s) {
-			input_dev_path = s;
-		}),
-		Option("|device=", [&drm_dev_path](string s) {
-			drm_dev_path = s;
-		}),
-		Option("c|connector=", [&conn_name](string s) {
-			conn_name = s;
-		}),
-		Option("h|help", []() {
-			usage();
-			exit(-1);
-		}),
-	};
-
-	optionset.parse(argc, argv);
-
-	if (optionset.params().size() > 0) {
-		usage();
-		exit(-1);
-	}
-
-	struct libevdev* dev = nullptr;
-
-	int fd = open(input_dev_path.c_str(), O_RDONLY | O_NONBLOCK);
-	FAIL_IF(fd < 0, "Failed to open input device %s: %s\n", input_dev_path.c_str(), strerror(errno));
-	int rc = libevdev_new_from_fd(fd, &dev);
-	FAIL_IF(rc < 0, "Failed to init libevdev (%s)\n", strerror(-rc));
-
-	printf("Input device name: \"%s\"\n", libevdev_get_name(dev));
-	printf("Input device ID: bus %#x vendor %#x product %#x\n",
-	       libevdev_get_id_bustype(dev),
-	       libevdev_get_id_vendor(dev),
-	       libevdev_get_id_product(dev));
-
-	if (!libevdev_has_event_type(dev, EV_ABS) ||
-	    !libevdev_has_event_code(dev, EV_KEY, BTN_TOUCH)) {
-		printf("This device does not look like a mouse\n");
-		exit(1);
-	}
-
-	print_bits(dev);
-	print_props(dev);
-
-	collect_current(dev);
-
-	Card card(drm_dev_path);
-	ResourceManager resman(card);
-
-	auto pixfmt = PixelFormat::XRGB8888;
-
-	Connector* conn = resman.reserve_connector(conn_name);
-	Crtc* crtc = resman.reserve_crtc(conn);
-	Plane* plane = resman.reserve_overlay_plane(crtc, pixfmt);
-
-	Videomode mode = conn->get_default_mode();
-
-	uint32_t w = mode.hdisplay;
-	uint32_t h = mode.vdisplay;
-
-	auto fb = new DumbFramebuffer(card, w, h, pixfmt);
-
-	AtomicReq req(card);
-
-	req.add(plane, "CRTC_ID", crtc->id());
-	req.add(plane, "FB_ID", fb->id());
-
-	req.add(plane, "CRTC_X", 0);
-	req.add(plane, "CRTC_Y", 0);
-	req.add(plane, "CRTC_W", w);
-	req.add(plane, "CRTC_H", h);
-
-	req.add(plane, "SRC_X", 0);
-	req.add(plane, "SRC_Y", 0);
-	req.add(plane, "SRC_W", w << 16);
-	req.add(plane, "SRC_H", h << 16);
-
-	int r = req.commit_sync();
-	FAIL_IF(r, "initial plane setup failed");
-
-	do {
-		struct input_event ev {
-		};
-		rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
-		if (rc == 0)
-			handle_event(ev, fb);
-
-	} while (rc == 1 || rc == 0 || rc == -EAGAIN);
-
-	delete fb;
-}
diff --git a/utils/kmsview.cpp b/utils/kmsview.cpp
index c2654b0..eea9dde 100644
--- a/utils/kmsview.cpp
+++ b/utils/kmsview.cpp
@@ -1,7 +1,6 @@
 #include <cstdio>
 #include <fstream>
 #include <unistd.h>
-#include <cassert>
 
 #include <kms++/kms++.h>
 #include <kms++util/kms++util.h>
@@ -25,10 +24,11 @@
 }
 
 static const char* usage_str =
-	"Usage: kmsview [options] <file> <width> <height> <fourcc>\n\n"
-	"Options:\n"
-	"  -c, --connector <name>	Output connector\n"
-	"  -t, --time <ms>		Milliseconds to sleep between frames\n";
+		"Usage: kmsview [options] <file> <width> <height> <fourcc>\n\n"
+		"Options:\n"
+		"  -c, --connector <name>	Output connector\n"
+		"  -t, --time <ms>		Milliseconds to sleep between frames\n"
+		;
 
 static void usage()
 {
@@ -42,16 +42,20 @@
 	string conn_name;
 
 	OptionSet optionset = {
-		Option("c|connector=", [&conn_name](string s) {
+		Option("c|connector=", [&conn_name](string s)
+		{
 			conn_name = s;
 		}),
-		Option("|device=", [&dev_path](string s) {
+		Option("|device=", [&dev_path](string s)
+		{
 			dev_path = s;
 		}),
-		Option("t|time=", [&time](const string& str) {
+		Option("t|time=", [&time](const string& str)
+		{
 			time = stoul(str);
 		}),
-		Option("h|help", []() {
+		Option("h|help", []()
+		{
 			usage();
 			exit(-1);
 		}),
@@ -79,6 +83,7 @@
 	unsigned fsize = is.tellg();
 	is.seekg(0);
 
+
 	Card card(dev_path);
 	ResourceManager res(card);
 
@@ -93,14 +98,11 @@
 	for (unsigned i = 0; i < fb->num_planes(); ++i)
 		frame_size += fb->size(i);
 
-	assert(frame_size);
-
 	unsigned num_frames = fsize / frame_size;
 	printf("file size %u, frame size %u, frames %u\n", fsize, frame_size, num_frames);
 
 	for (unsigned i = 0; i < num_frames; ++i) {
-		printf("frame %d", i);
-		fflush(stdout);
+		printf("frame %d", i); fflush(stdout);
 		read_frame(is, fb, crtc, plane);
 		if (!time) {
 			getchar();
diff --git a/utils/meson.build b/utils/meson.build
deleted file mode 100644
index b1e7918..0000000
--- a/utils/meson.build
+++ /dev/null
@@ -1,17 +0,0 @@
-common_deps = [ libkmsxx_dep, libkmsxxutil_dep, libfmt_dep ]
-
-libevdev_dep = dependency('libevdev', required : false)
-
-executable('kmstest', 'kmstest.cpp', dependencies : [ common_deps ], install : true)
-executable('kmsview', 'kmsview.cpp', dependencies : [ common_deps ], install : false)
-executable('kmsprint', 'kmsprint.cpp', dependencies : [ common_deps ], install : true)
-executable('fbtest', 'fbtest.cpp', dependencies : [ common_deps ], install : true)
-executable('kmscapture', 'kmscapture.cpp', dependencies : [ common_deps ], install : false)
-executable('kmsblank', 'kmsblank.cpp', dependencies : [ common_deps ], install : true)
-
-if libevdev_dep.found()
-    executable('kmstouch', 'kmstouch.cpp', dependencies : [ common_deps, libevdev_dep ], install : false)
-endif
-
-executable('omap-wbcap', 'omap-wbcap.cpp', dependencies : [ common_deps ], install : false)
-executable('omap-wbm2m', 'omap-wbm2m.cpp', dependencies : [ common_deps ], install : false)
diff --git a/utils/omap-wbcap.cpp b/utils/wbcap.cpp
similarity index 87%
rename from utils/omap-wbcap.cpp
rename to utils/wbcap.cpp
index 8033869..5a94a70 100644
--- a/utils/omap-wbcap.cpp
+++ b/utils/wbcap.cpp
@@ -213,19 +213,19 @@
 		draw_bar(fb, m_frame_num);
 
 		req.add(m_plane, {
-					 { "CRTC_ID", m_crtc->id() },
-					 { "FB_ID", fb->id() },
+				{ "CRTC_ID", m_crtc->id() },
+				{ "FB_ID", fb->id() },
 
-					 { "CRTC_X", 0 },
-					 { "CRTC_Y", 0 },
-					 { "CRTC_W", min((uint32_t)m_crtc->mode().hdisplay, fb->width()) },
-					 { "CRTC_H", min((uint32_t)m_crtc->mode().vdisplay, fb->height()) },
+				{ "CRTC_X", 0 },
+				{ "CRTC_Y", 0 },
+				{ "CRTC_W", min((uint32_t)m_crtc->mode().hdisplay, fb->width()) },
+				{ "CRTC_H", min((uint32_t)m_crtc->mode().vdisplay, fb->height()) },
 
-					 { "SRC_X", 0 },
-					 { "SRC_Y", 0 },
-					 { "SRC_W", fb->width() << 16 },
-					 { "SRC_H", fb->height() << 16 },
-				 });
+				{ "SRC_X", 0 },
+				{ "SRC_Y", 0 },
+				{ "SRC_W", fb->width() << 16 },
+				{ "SRC_H", fb->height() << 16 },
+			});
 
 		int r = req.commit(this);
 		if (r)
@@ -247,15 +247,16 @@
 };
 
 static const char* usage_str =
-	"Usage: wbcap [OPTIONS]\n\n"
-	"Options:\n"
-	"  -s, --src=CONN            Source connector\n"
-	"  -d, --dst=CONN            Destination connector\n"
-	"  -m, --smode=MODE          Source connector videomode\n"
-	"  -M, --dmode=MODE          Destination connector videomode\n"
-	"  -f, --format=4CC          Format\n"
-	"  -w, --write               Write captured frames to wbcap.raw file\n"
-	"  -h, --help                Print this help\n";
+		"Usage: wbcap [OPTIONS]\n\n"
+		"Options:\n"
+		"  -s, --src=CONN            Source connector\n"
+		"  -d, --dst=CONN            Destination connector\n"
+		"  -m, --smode=MODE          Source connector videomode\n"
+		"  -M, --dmode=MODE          Destination connector videomode\n"
+		"  -f, --format=4CC          Format\n"
+		"  -w, --write               Write captured frames to wbcap.raw file\n"
+		"  -h, --help                Print this help\n"
+		;
 
 int main(int argc, char** argv)
 {
@@ -267,25 +268,32 @@
 	bool write_file = false;
 
 	OptionSet optionset = {
-		Option("s|src=", [&](string s) {
+		Option("s|src=", [&](string s)
+		{
 			src_conn_name = s;
 		}),
-		Option("m|smode=", [&](string s) {
+		Option("m|smode=", [&](string s)
+		{
 			src_mode_name = s;
 		}),
-		Option("d|dst=", [&](string s) {
+		Option("d|dst=", [&](string s)
+		{
 			dst_conn_name = s;
 		}),
-		Option("M|dmode=", [&](string s) {
+		Option("M|dmode=", [&](string s)
+		{
 			dst_mode_name = s;
 		}),
-		Option("f|format=", [&](string s) {
+		Option("f|format=", [&](string s)
+		{
 			pixfmt = FourCCToPixelFormat(s);
 		}),
-		Option("w|write", [&]() {
+		Option("w|write", [&]()
+		{
 			write_file = true;
 		}),
-		Option("h|help", [&]() {
+		Option("h|help", [&]()
+		{
 			puts(usage_str);
 			exit(-1);
 		}),
@@ -318,6 +326,7 @@
 	Videomode src_mode = src_mode_name.empty() ? src_conn->get_default_mode() : src_conn->get_mode(src_mode_name);
 	src_crtc->set_mode(src_conn, src_mode);
 
+
 	auto dst_conn = resman.reserve_connector(dst_conn_name);
 	auto dst_crtc = resman.reserve_crtc(dst_conn);
 	auto dst_plane = resman.reserve_overlay_plane(dst_crtc, pixfmt);
@@ -333,9 +342,9 @@
 	if (src_mode.interlace())
 		dst_height /= 2;
 
-	printf("src %s, crtc %s\n", src_conn->fullname().c_str(), src_mode.to_string_short().c_str());
+	printf("src %s, crtc %s\n", src_conn->fullname().c_str(), src_mode.to_string().c_str());
 
-	printf("dst %s, crtc %s\n", dst_conn->fullname().c_str(), dst_mode.to_string_short().c_str());
+	printf("dst %s, crtc %s\n", dst_conn->fullname().c_str(), dst_mode.to_string().c_str());
 
 	printf("src_fb %ux%u, dst_fb %ux%u\n", src_width, src_height, dst_width, dst_height);
 
@@ -362,11 +371,11 @@
 	vector<pollfd> fds(3);
 
 	fds[0].fd = 0;
-	fds[0].events = POLLIN;
+	fds[0].events =  POLLIN;
 	fds[1].fd = wb.fd();
-	fds[1].events = POLLIN;
+	fds[1].events =  POLLIN;
 	fds[2].fd = card.fd();
-	fds[2].events = POLLIN;
+	fds[2].events =  POLLIN;
 
 	uint32_t dst_frame_num = 0;
 
diff --git a/utils/omap-wbm2m.cpp b/utils/wbm2m.cpp
similarity index 79%
rename from utils/omap-wbm2m.cpp
rename to utils/wbm2m.cpp
index a00fab2..b69bb28 100644
--- a/utils/omap-wbm2m.cpp
+++ b/utils/wbm2m.cpp
@@ -6,24 +6,24 @@
 #include <fstream>
 #include <map>
 #include <system_error>
-#include <fmt/format.h>
 
 #include <kms++/kms++.h>
 #include <kms++util/kms++util.h>
 #include <kms++util/videodevice.h>
 
-const uint32_t NUM_SRC_BUFS = 2;
-const uint32_t NUM_DST_BUFS = 2;
+const uint32_t NUM_SRC_BUFS=2;
+const uint32_t NUM_DST_BUFS=2;
 
 using namespace std;
 using namespace kms;
 
 static const char* usage_str =
-	"Usage: wbm2m [OPTIONS]\n\n"
-	"Options:\n"
-	"  -f, --format=4CC          Output format\n"
-	"  -c, --crop=CROP           CROP is <x>,<y>-<w>x<h>\n"
-	"  -h, --help                Print this help\n";
+		"Usage: wbm2m [OPTIONS]\n\n"
+		"Options:\n"
+		"  -f, --format=4CC          Output format\n"
+		"  -c, --crop=CROP           CROP is <x>,<y>-<w>x<h>\n"
+		"  -h, --help                Print this help\n"
+		;
 
 const int bar_speed = 4;
 const int bar_width = 10;
@@ -50,7 +50,7 @@
 static void parse_crop(const string& crop_str, uint32_t& c_left, uint32_t& c_top,
 		       uint32_t& c_width, uint32_t& c_height)
 {
-	const regex crop_re("(\\d+),(\\d+)-(\\d+)x(\\d+)"); // 400,400-400x400
+	const regex crop_re("(\\d+),(\\d+)-(\\d+)x(\\d+)");		// 400,400-400x400
 
 	smatch sm;
 	if (!regex_match(crop_str, sm, crop_re))
@@ -78,14 +78,17 @@
 	bool use_selection = false;
 
 	OptionSet optionset = {
-		Option("f|format=", [&](string s) {
+		Option("f|format=", [&](string s)
+		{
 			dst_fmt = FourCCToPixelFormat(s);
 		}),
-		Option("c|crop=", [&](string s) {
+		Option("c|crop=", [&](string s)
+		{
 			parse_crop(s, c_left, c_top, c_width, c_height);
 			use_selection = true;
 		}),
-		Option("h|help", [&]() {
+		Option("h|help", [&]()
+		{
 			puts(usage_str);
 			exit(-1);
 		}),
@@ -98,13 +101,8 @@
 		exit(-1);
 	}
 
-	printf("%ux%u-%s -> %ux%u-%s\n", src_width, src_height, PixelFormatToFourCC(src_fmt).c_str(),
-	       dst_width, dst_height, PixelFormatToFourCC(dst_fmt).c_str());
-
-	const string filename = fmt::format("wb-out-{}x{}-{}.raw", dst_width, dst_height,
-					    PixelFormatToFourCC(dst_fmt));
-
-	printf("writing to %s\n", filename.c_str());
+	const string filename = sformat("wb-out-%ux%u_%4.4s.raw", dst_width, dst_height,
+					PixelFormatToFourCC(dst_fmt).c_str());
 
 	VideoDevice vid("/dev/video10");
 
@@ -127,6 +125,7 @@
 	out->set_queue_size(NUM_SRC_BUFS);
 	in->set_queue_size(NUM_DST_BUFS);
 
+
 	for (unsigned i = 0; i < min(NUM_SRC_BUFS, num_src_frames); ++i) {
 		auto fb = new DumbFramebuffer(card, src_width, src_height, src_fmt);
 
@@ -143,11 +142,11 @@
 	vector<pollfd> fds(3);
 
 	fds[0].fd = 0;
-	fds[0].events = POLLIN;
+	fds[0].events =  POLLIN;
 	fds[1].fd = vid.fd();
-	fds[1].events = POLLIN;
+	fds[1].events =  POLLIN;
 	fds[2].fd = card.fd();
-	fds[2].events = POLLIN;
+	fds[2].events =  POLLIN;
 
 	ofstream os(filename, ofstream::binary);
 
@@ -164,8 +163,9 @@
 		if (fds[1].revents) {
 			fds[1].revents = 0;
 
+
 			try {
-				DumbFramebuffer* dst_fb = in->dequeue();
+				DumbFramebuffer *dst_fb = in->dequeue();
 				printf("Writing frame %u\n", dst_frame_num);
 				for (unsigned i = 0; i < dst_fb->num_planes(); ++i)
 					os.write((char*)dst_fb->map(i), dst_fb->size(i));
@@ -183,7 +183,7 @@
 				break;
 			}
 
-			DumbFramebuffer* src_fb = out->dequeue();
+			DumbFramebuffer *src_fb = out->dequeue();
 
 			if (src_frame_num < num_src_frames) {
 				read_frame(src_fb, src_frame_num++);