diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..076dc769 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +# The way this works is a little weird. But basically, the create-release job +# runs purely to initialize the GitHub release itself. Once done, the upload +# URL of the release is saved as an artifact. +# +# The build-release job runs only once create-release is finished. It gets +# the release upload URL by downloading the corresponding artifact (which was +# uploaded by create-release). It then builds the release executables for each +# supported platform and attaches them as release assets to the previously +# created release. +# +# The key here is that we create the release only once. +# +# Adapted from: https://github.com/BurntSushi/ripgrep/blob/master/.github/workflows/release.yml + +name: release +on: + push: + # Enable when testing release infrastructure on a branch. + branches: + - build + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' +jobs: + create-release: + name: create-release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Install meson + run: pip install meson ninja + - name: Meson setup + run: meson setup builddir/ + - name: Create source distribution + # no unit tests yet + run: meson dist -C builddir/ --no-tests + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: builddir/meson-dist/* + diff --git a/.gitignore b/.gitignore index eb38bd2d..ef986db5 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ src/*.xkb.bin src/*.vert.bin.c src/*.frag.bin.c src/*.xkb.bin.c +.cache/ diff --git a/COPYING b/COPYING index 93889ebe..3ad47b73 100644 --- a/COPYING +++ b/COPYING @@ -14,6 +14,7 @@ This software was written by: ysangkok Hoàng Đức Hiếu Swift Geek + Aetf = Copyright Notice = diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 01c60520..00000000 --- a/Makefile.am +++ /dev/null @@ -1,638 +0,0 @@ -# -# Kmscon - Global Makefile -# Copyright (c) 2012-2013 David Herrmann -# - -# -# Global Configurations and Initializations -# - -ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} -AM_MAKEFLAGS = --no-print-directory -AUTOMAKE_OPTIONS = color-tests -AM_DISTCHECK_CONFIGURE_FLAGS = --enable-all - -SUBDIRS = . - -.DELETE_ON_ERROR: - -include_HEADERS = -EXTRA_DIST = \ - README \ - COPYING \ - NEWS \ - docs/kmscon.service \ - docs/kmsconvt@.service -CLEANFILES = -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = -MANPAGES = -MANPAGES_ALIASES = -TPHONY = - -check_PROGRAMS = -noinst_PROGRAMS = -lib_LTLIBRARIES = -noinst_LTLIBRARIES = -bin_SCRIPTS = - -moduledir = $(libdir)/kmscon -module_LTLIBRARIES = - -helperdir = $(libexecdir)/kmscon -helper_PROGRAMS = - -# -# Default CFlags -# Make all files include "config.h" by default. This shouldn't cause any -# problems and we cannot forget to include it anymore. -# -# Also make the linker discard all unused symbols. -# -# When compiling in debug mode, we enable debug symbols so debugging with gdb -# is easier. If optimizations are disabled, we pass -O0 to the compiler. -# Otherwise, we use standard optimizations -O2. -# - -AM_CFLAGS = \ - -Wall \ - -pipe \ - -fno-common \ - -ffast-math \ - -fdiagnostics-show-option \ - -fno-strict-aliasing \ - -fvisibility=hidden \ - -ffunction-sections \ - -fdata-sections \ - -fstack-protector -AM_CPPFLAGS = \ - -DBUILD_MODULE_DIR='"$(moduledir)"' \ - -include $(top_builddir)/config.h \ - -I $(srcdir)/src -AM_LDFLAGS = \ - -Wl,--as-needed \ - -Wl,--gc-sections \ - -Wl,-z,relro \ - -Wl,-z,now - -if BUILD_ENABLE_DEBUG -AM_CFLAGS += -g -endif - -if BUILD_ENABLE_OPTIMIZATIONS -AM_CFLAGS += -O2 -else -AM_CFLAGS += -O0 -endif - -# -# GIT-HEAD helper -# The file ./src/shl_githead.c contains a constant "shl_git_head" which is -# defined to the string returned by "git describe". We need to adjust this -# string for every build and correctly rebuild any sources that depend on it. -# Therefore, you should use this file rarely as it causes rebuilds on every -# git-commit. -# -# We have a helper-script ./src/genversion.sh that takes as argument the source -# file and creates it if necessary. It updates it only if the new git-describe -# string is different to the old one. So the file is only modified on changes. -# Hence, we can use it as normal dependency in this Makefile. -# However, we need to run this script on _every_ "make" invocation before any -# recipy is executed. To achieve this, we use $(shell ...) and assign it to a -# "simply expanded" variable (:=) so the shell command is executed on -# variable-declaration and not during expansion. -# -# Note that we must not clean ./src/shl_githead.c ever! If we would, a -# distribution tarball might delete that file and have no way to recreate it. -# We could delete it on something like "make maintainerclean", but then again, -# it seems unnecessary so lets simply not clean it at all. -# -# If the helper-script is executed in a directory that is not a git-repository -# (like a distribution tarball) and shl_githead.c exists, then it does nothing -# as it expects shl_githead.c to be correctly written by "make dist". -# However, if shl_githead.c does not exist, it will print a warning and write -# an unknown random git-revision. -# This guarantees, that shl_githead.c is always present and has the most correct -# value that we can get under any conditions. -# -# The $(emptyvariable) expansion below is used for broken $(shell ...) -# syntax-highlighting algorithms in many existing editors. -# - -EXTRA_DIST += src/genversion.sh -GITHEAD:=$(shell $(emptyvariable)"$(srcdir)/src/genversion.sh" "$(srcdir)/src/shl_githead.c") - -# -# Binary File Compiler -# This target gets as input a binary file *.bin and produces an ELF/etc. output -# object file *.bin.o and the corresponding libtool file *.bin.lo. -# Note that we fake the libtool object files as there is no way to make libtool -# create it. The comments in the .lo file are mandatory so don't remove them! -# - -CLEANFILES += src/*.bin.c - -src/%.bin.c: src/%.bin - $(AM_V_at)echo '#include ' >"$@" - $(AM_V_at)echo 'static const unsigned char data[] = {' >>"$@" - $(AM_V_GEN)od -An -vtu1 <"$<" | sed 's/^[[:space:]]*//;s/[[:space:]]*$$/,/;s/[[:space:]]\{1,\}/,/g' >>"$@" - $(AM_V_at)echo '};' >>"$@" - $(AM_V_at)PREFIX=_binary_`echo "$<" | sed 's/\W/_/g'`; \ - echo "const char *const $${PREFIX}_start = (const char*)data;" >>"$@"; \ - echo "const char *const $${PREFIX}_end = (const char*)data + sizeof(data);" >>"$@"; \ - echo "const size_t $${PREFIX}_size = sizeof(data);" >>"$@" - -# -# Shader Converter -# We use a few built-in shader files. To reduce memory-consumption, this helper -# removes useless lines from the shaders before they are compiled into an object -# file. -# -# Following regexp are used to remove characters/lines: -# ^/*.*$ Start of multi-line comment -# ^ *.*$ Multi-line comment body -# ^[ \t]* Indentation whitespace -# [\r\n] Newlines -# - -CLEANFILES += src/*.vert.bin src/*.frag.bin -SHADER_SED = -e 's/^\/\*.*$$//' -e 's/^ \*.*$$//' -e 's/^[ \t]*//' -SHADER_TR = -d "\r\n" - -src/%.vert.bin: $(top_srcdir)/src/%.vert - $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" - -src/%.frag.bin: $(top_srcdir)/src/%.frag - $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" - -# -# XKB Fallback Converter -# We use a static built-in XKB fallback keymap. To avoid huge memory consumption -# we remove useless lines/characters first. -# We also append an ASCII 0 character so it can be used as regular C-string. -# -# Following regexp are used to remove characters/lines: -# *= * Whitespace around assignments -# *, * Whitespace around commatas -# *[][{}()] * Whitespace around braces -# ^[ \t]* Indentation whitespace -# [\r\n] Newlines -# - -CLEANFILES += src/*.xkb.bin -XKB_SED = -e 's/^[ \t]*//' -e 's/ *\([,=]\) */\1/g' -e 's/ *\([][{}()]\) */\1/g' -XKB_TR = -d "\r\n" - -src/%.xkb.bin: $(top_srcdir)/src/%.xkb - $(AM_V_at)$(SED) $(XKB_SED) "$<" | tr $(XKB_TR) >"$@" - $(AM_V_at)echo -ne "\x00" >>"$@" - -# -# SHL - Static Helper Library -# The SHL subsystem contains several small code pieces used all over kmscon and -# other applications. -# - -noinst_LTLIBRARIES += libshl.la - -libshl_la_SOURCES = \ - src/shl_githead.h \ - src/shl_githead.c \ - src/shl_dlist.h \ - src/shl_array.h \ - src/shl_hashtable.h \ - external/htable.h \ - external/htable.c \ - src/shl_ring.h \ - src/shl_timer.h \ - src/shl_llog.h \ - src/shl_log.h \ - src/shl_log.c \ - src/shl_hook.h \ - src/shl_misc.h \ - src/shl_register.h \ - src/shl_flagset.h -libshl_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(XKBCOMMON_CFLAGS) \ - -pthread -libshl_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -pthread -libshl_la_LIBADD = \ - $(AM_LIBADD) \ - $(XKBCOMMON_LIBS) - -if BUILD_HAVE_GLES2 -libshl_la_SOURCES += src/shl_gl.h src/shl_gl_shader.c src/shl_gl_math.c -libshl_la_CPPFLAGS += $(GLES2_CFLAGS) -libshl_la_LIBADD += $(GLES2_LIBS) -endif - -# -# libeloop -# This library contains the whole event-loop implementation of kmscon. It is -# compiled into a separate object to allow using it in several other programs. -# - -noinst_LTLIBRARIES += libeloop.la - -libeloop_la_SOURCES = \ - src/eloop.h \ - src/eloop.c - -libeloop_la_LIBADD = libshl.la -libeloop_la_CPPFLAGS = $(AM_CPPFLAGS) -libeloop_la_LDFLAGS = $(AM_LDFLAGS) - -# -# libuterm -# The uterm library provides helpers to create terminals in user-space. They -# are not limited to text-based terminals but rather provide graphics contexts -# so arbitrary output can be displayed. Additionally, they provide VT -# abstractions and an input layer -# - -noinst_LTLIBRARIES += libuterm.la - -libuterm_la_SOURCES = \ - src/uterm_input.h \ - src/uterm_monitor.h \ - src/uterm_video.h \ - src/uterm_vt.h \ - src/uterm_input_internal.h \ - src/uterm_video_internal.h \ - src/uterm_systemd_internal.h \ - src/uterm_video.c \ - src/uterm_monitor.c \ - src/uterm_vt.c \ - src/uterm_input.c \ - src/uterm_input_uxkb.c - -nodist_libuterm_la_SOURCES = - -libuterm_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(UDEV_CFLAGS) \ - $(XKBCOMMON_CFLAGS) -libuterm_la_LIBADD = \ - $(UDEV_LIBS) \ - $(XKBCOMMON_LIBS) \ - libeloop.la \ - libshl.la \ - src/uterm_input_fallback.xkb.bin.lo -libuterm_la_LDFLAGS = \ - $(AM_LDFLAGS) - -if BUILD_ENABLE_MULTI_SEAT -libuterm_la_SOURCES += src/uterm_systemd.c -libuterm_la_CPPFLAGS += $(SYSTEMD_CFLAGS) -libuterm_la_LIBADD += $(SYSTEMD_LIBS) -endif - -if BUILD_ENABLE_VIDEO_FBDEV -libuterm_la_SOURCES += \ - src/uterm_fbdev_internal.h \ - src/uterm_fbdev_video.c \ - src/uterm_fbdev_render.c -endif - -if BUILD_ENABLE_VIDEO_DRM2D -libuterm_la_SOURCES += \ - src/uterm_drm2d_internal.h \ - src/uterm_drm2d_video.c \ - src/uterm_drm2d_render.c -libuterm_la_CPPFLAGS += $(DRM_CFLAGS) -libuterm_la_LIBADD += $(DRM_LIBS) -endif - -if BUILD_ENABLE_VIDEO_DRM3D -libuterm_la_SOURCES += \ - src/uterm_drm3d_internal.h \ - src/uterm_drm3d_video.c \ - src/uterm_drm3d_render.c \ - src/uterm_drm3d_blend.vert.bin.c \ - src/uterm_drm3d_blend.frag.bin.c \ - src/uterm_drm3d_blit.vert.bin.c \ - src/uterm_drm3d_blit.frag.bin.c \ - src/uterm_drm3d_fill.vert.bin.c \ - src/uterm_drm3d_fill.frag.bin.c -libuterm_la_CPPFLAGS += \ - $(DRM_CFLAGS) \ - $(EGL_CFLAGS) \ - $(GBM_CFLAGS) \ - $(GLES2_CFLAGS) -libuterm_la_LIBADD += \ - $(DRM_LIBS) \ - $(EGL_LIBS) \ - $(GBM_LIBS) \ - $(GLES2_LIBS) -endif - -# add shared sources only once -UTERM_DRM_SHARED_SRC = \ - src/uterm_drm_shared_internal.h \ - src/uterm_drm_shared.c -if BUILD_ENABLE_VIDEO_DRM2D -libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC) -else -if BUILD_ENABLE_VIDEO_DRM3D -libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC) -endif -endif - -# -# Unifont Generator -# This generates the unifont sources from raw hex-encoded font data. -# - -UNIFONT = $(top_srcdir)/src/font_unifont_data.hex -UNIFONT_BIN = src/font_unifont_data.bin - -EXTRA_DIST += $(UNIFONT) -CLEANFILES += $(UNIFONT_BIN) -genunifont_SOURCES = src/genunifont.c - -genunifont$(BUILD_EXEEXT) $(genunifont_OBJECTS): CC = $(CC_FOR_BUILD) -genunifont$(BUILD_EXEEXT) $(genunifont_OBJECTS): CFLAGS = $(CFLAGS_FOR_BUILD) -genunifont$(BUILD_EXEEXT): LDFLAGS = $(LDFLAGS_FOR_BUILD) - -$(UNIFONT_BIN): $(UNIFONT) genunifont$(BUILD_EXEEXT) - $(AM_V_GEN)./genunifont$(BUILD_EXEEXT) $(UNIFONT_BIN) $(UNIFONT) - -# -# Kmscon Modules -# - -if BUILD_ENABLE_FONT_UNIFONT -module_LTLIBRARIES += mod-unifont.la -noinst_PROGRAMS += genunifont -endif - -mod_unifont_la_SOURCES = \ - src/kmscon_module_interface.h \ - src/font_unifont.c \ - src/kmscon_mod_unifont.c \ - src/font_unifont_data.bin.c -mod_unifont_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(TSM_CFLAGS) -mod_unifont_la_LIBADD = \ - $(TSM_LIBS) \ - libshl.la -mod_unifont_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -module \ - -avoid-version - -if BUILD_ENABLE_FONT_PANGO -module_LTLIBRARIES += mod-pango.la -endif - -mod_pango_la_SOURCES = \ - src/kmscon_module_interface.h \ - src/font_pango.c \ - src/kmscon_mod_pango.c -mod_pango_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(PANGO_CFLAGS) \ - $(TSM_CFLAGS) -mod_pango_la_LIBADD = \ - $(PANGO_LIBS) \ - $(TSM_LIBS) \ - -lpthread \ - libshl.la -mod_pango_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -module \ - -avoid-version - -if BUILD_ENABLE_RENDERER_BBULK -module_LTLIBRARIES += mod-bbulk.la -endif - -mod_bbulk_la_SOURCES = \ - src/kmscon_module_interface.h \ - src/text_bbulk.c \ - src/kmscon_mod_bbulk.c -mod_bbulk_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(TSM_CFLAGS) -mod_bbulk_la_LIBADD = \ - $(TSM_LIBS) \ - libshl.la -mod_bbulk_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -module \ - -avoid-version - -if BUILD_ENABLE_RENDERER_GLTEX -module_LTLIBRARIES += mod-gltex.la -endif - -mod_gltex_la_SOURCES = \ - src/kmscon_module_interface.h \ - src/text_gltex.c \ - src/kmscon_mod_gltex.c -mod_gltex_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(TSM_CFLAGS) \ - $(GLES2_CFLAGS) -mod_gltex_la_LIBADD = \ - $(GLES2_LIBS) \ - $(TSM_LIBS) \ - libshl.la \ - src/text_gltex_atlas.vert.bin.lo \ - src/text_gltex_atlas.frag.bin.lo -mod_gltex_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -module \ - -avoid-version - -if BUILD_ENABLE_RENDERER_PIXMAN -module_LTLIBRARIES += mod-pixman.la -endif - -mod_pixman_la_SOURCES = \ - src/kmscon_module_interface.h \ - src/text_pixman.c \ - src/kmscon_mod_pixman.c -mod_pixman_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(PIXMAN_CFLAGS) -mod_pixman_la_LIBADD = \ - $(PIXMAN_LIBS) \ - libshl.la -mod_pixman_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - -module \ - -avoid-version - -# -# Binaries -# These are the sources for the main binaries and test programs. They mostly -# consists of a single source file only and include all the libraries that are -# built as part of kmscon. -# - -bin_SCRIPTS += scripts/kmscon -helper_PROGRAMS += kmscon -check_PROGRAMS += \ - test_output \ - test_vt \ - test_input \ - test_key -MANPAGES += docs/man/kmscon.1 - -kmscon_SOURCES = \ - src/conf.h \ - src/conf.c \ - src/pty.h \ - src/pty.c \ - src/font.h \ - src/font.c \ - src/font_8x16.c \ - src/text.h \ - src/text.c \ - src/text_bblit.c \ - src/kmscon_module_interface.h \ - src/kmscon_module.h \ - src/kmscon_module.c \ - src/kmscon_terminal.h \ - src/kmscon_dummy.h \ - src/kmscon_seat.h \ - src/kmscon_seat.c \ - src/kmscon_conf.h \ - src/kmscon_conf.c \ - src/kmscon_main.c -nodist_kmscon_SOURCES = - -kmscon_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(XKBCOMMON_CFLAGS) \ - $(TSM_CFLAGS) -kmscon_LDADD = \ - $(XKBCOMMON_LIBS) \ - $(TSM_LIBS) \ - libeloop.la \ - libuterm.la \ - libshl.la \ - -lpthread \ - -ldl -kmscon_LDFLAGS = \ - $(AM_LDFLAGS) \ - -rdynamic - -if BUILD_ENABLE_SESSION_DUMMY -kmscon_SOURCES += src/kmscon_dummy.c -endif - -if BUILD_ENABLE_SESSION_TERMINAL -kmscon_SOURCES += src/kmscon_terminal.c -endif - -# -# Tests -# - -test_sources = \ - src/conf.h \ - src/conf.c \ - tests/test_include.h -test_cflags = \ - $(AM_CPPFLAGS) \ - $(XKBCOMMON_CFLAGS) -test_libs = \ - $(XKBCOMMON_LIBS) \ - libeloop.la \ - libshl.la - -test_output_SOURCES = \ - $(test_sources) \ - tests/test_output.c -test_output_CPPFLAGS = $(test_cflags) -test_output_LDADD = \ - $(test_libs) \ - libuterm.la - -test_vt_SOURCES = \ - $(test_sources) \ - tests/test_vt.c -test_vt_CPPFLAGS = $(test_cflags) -test_vt_LDADD = \ - $(test_libs) \ - libuterm.la - -test_input_SOURCES = \ - $(test_sources) \ - tests/test_input.c -test_input_CPPFLAGS = $(test_cflags) -test_input_LDADD = \ - $(test_libs) \ - libuterm.la - -test_key_SOURCES = \ - $(test_sources) \ - tests/test_key.c -test_key_CPPFLAGS = $(test_cflags) -test_key_LDADD = $(test_libs) - -# -# Manpages -# - -man_MANS = -EXTRA_DIST += ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,$(MANPAGES)}}}} -CLEANFILES += $(MANPAGES) $(MANPAGES_ALIASES) .man_fixup - -if BUILD_HAVE_XSLTPROC -if BUILD_HAVE_MANPAGES_STYLESHEET - -man_MANS += $(MANPAGES) $(MANPAGES_ALIASES) - -XSLTPROC_FLAGS = \ - --stringparam man.authors.section.enabled 0 \ - --stringparam man.copyright.section.enabled 0 \ - --stringparam funcsynopsis.style ansi \ - --stringparam man.output.quietly 1 \ - --nonet - -XSLTPROC_PROCESS_MAN = \ - $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ - $(XSLTPROC) -o "$@" $(XSLTPROC_FLAGS) $(BUILD_MANPAGES_STYLESHEET) "$<" && \ - touch .man_fixup - -# Force .man_fixup if $(MANPAGES) are not built -.man_fixup: | $(MANPAGES) - @touch .man_fixup - -$(MANPAGES_ALIASES): $(MANPAGES) .man_fixup - $(AM_V_GEN)if test -n "$@" ; then $(SED) -i -e 's/^\.so \([a-z_]\+\)\.\([0-9]\)$$/\.so man\2\/\1\.\2/' "$@" ; fi - -docs/man/%.1: docs/man/%.xml - $(XSLTPROC_PROCESS_MAN) - -docs/man/%.3: docs/man/%.xml - $(XSLTPROC_PROCESS_MAN) - -docs/man/%.5: docs/man/%.xml - $(XSLTPROC_PROCESS_MAN) - -docs/man/%.7: docs/man/%.xml - $(XSLTPROC_PROCESS_MAN) - -endif # BUILD_HAVE_MANPAGES_STYLESHEET -endif # BUILD_HAVE_XSLTPROC - -# -# Phony targets -# - -.PHONY: $(TPHONY) - -# -# Empty .SECONDARY target causes alle intermediate files to be treated as -# secondary files. That is, they don't get deleted after make finished. -# - -.SECONDARY: diff --git a/README b/README deleted file mode 100644 index da1290f7..00000000 --- a/README +++ /dev/null @@ -1,116 +0,0 @@ -= KMSCON = - -Kmscon is a simple terminal emulator based on linux kernel mode setting (KMS). -It is an attempt to replace the in-kernel VT implementation with a userspace -console. See kmscon(1) man-page for usage information. - -Website: - http://www.freedesktop.org/wiki/Software/kmscon - -== Requirements == - - Kmscon requires the following software: - - libtsm: terminal emulator state machine - http://www.freedesktop.org/wiki/Software/kmscon/libtsm/ - - libudev: providing input, video, etc. device hotplug support (>=v172) - http://www.freedesktop.org/wiki/Software/systemd/ - - libxkbcommon: providing internationalized keyboard handling - http://xkbcommon.org/ - - libdrm: graphics access to DRM/KMS subsystem - - linux-headers: linux kernel headers for ABI definitions - - Everything else is optional: - - For video output at least one of the following is required: - - fbdev: For framebuffer video output the kernel headers must be installed - and located in the default include path. - - DRM: For unaccelerated drm output the "libdrm" library must be installed - and accessible via pkg-config. - - OpenGLES2: For accelerated video output via OpenGLESv2 the following must - be installed: libdrm, libgbm, egl, glesv2 (i.e., mesa) - - For font handling the following is required: - - 8x16: The 8x16 font is a static built-in font which does not require - external dependencies. - - unifont: Static font without external dependencies. - - pango: drawing text with pango - Pango requires: glib, pango, fontconfig, freetype2 and more - - For multi-seat support you need the following packages: - - systemd: Actually only the systemd-logind daemon and library is required. - -== Download == - -Released tarballs can be found at: - http://www.freedesktop.org/software/kmscon/releases - -== Install == - - To compile the kmscon binary, run the standard autotools commands: - $ test -f ./configure || NOCONFIGURE=1 ./autogen.sh - $ ./configure - $ make - $ make install - To compile the test applications, run: - $ make check - - If you want only a very basic kmscon program without any major dependencies, - use: - $ ./configure --with-video=fbdev,drm2d --with-renderers= --with-fonts=unifont --disable-multi-seat --with-sessions=dummy,terminal - However, you will loose a lot of functionality by dropping all dependencies. - - The following configure options are available. If build-time dependencies - cannot be satisfied, an option is automatically turned off, except if you - explicitly enable it via command line: - --enable-multi-seat: This requires the systemd-logind library to provide - multi-seat support for kmscon. [default: on] - --enable-debug: Enable debug mode/messages [default: on] - --enable-optimizations: Enable code optimizations [default: on] - - Backends for several subsystems in kmscon can be selected with the following - options (all of them take a comma-separated list of backend names): - --with-video: Video backens. Available backends are: - - fbdev: Linux fbdev video backend - - drm2d: Linux DRM software-rendering backend - - drm3d: Linux DRM hardware-rendering backend - Default is: fbdev,drm2d,drm3d - --with-fonts: Font renderers. Available backends are: - - unifont: Static built-in non-scalable font (Unicode Unifont) - - pango: Pango based scalable font renderer - Default is: unifont,pango - The 8x16 backend is always built-in. - --with-renderers: Console rendering backends. Available are: - - bbulk: Simple 2D software-renderer (bulk-mode) - - gltex: OpenGLESv2 accelerated renderer - - pixman: pixman based renderer - Default is: bbulk,gltex - The bblit backend is always built-in. - --with-sessions: Built in sessions. Available sessions are: - - dummy: Dummy fallback session - - terminal: Terminal-emulator sessions - -== Running == - - To get usage information, run: - $ ./kmscon --help - You can then run kmscon with: - $ ./kmscon [options] - - For debug output use "--debug". For verbose output use "--verbose". - With "--xkb-layout=" you can switch the keyboard layout. - See "man kmscon" / kmscon(1) for more information. - -== License == - - This software is licensed under the terms of an MIT-like license. Please see - ./COPYING for further information. - -== FAQ == - - Please see: http://www.freedesktop.org/wiki/Software/kmscon - -== Contact == - - This software is maintained by: - David Herrmann - If you have any questions, do not hesitate to contact one of the maintainers. diff --git a/README.md b/README.md new file mode 100644 index 00000000..b9c931fb --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +# KMSCON + +Kmscon is a simple terminal emulator based on linux kernel mode setting (KMS). +It is an attempt to replace the in-kernel VT implementation with a userspace +console. See kmscon(1) man-page for usage information. + +## Requirements + +Kmscon requires the following software: + - [libtsm](https://github.com/Aetf/libtsm): terminal emulator state machine + - [libudev](https://www.freedesktop.org/software/systemd/man/libudev.html): providing input, video, etc. device hotplug support (>=v172) + - [libxkbcommon](https://xkbcommon.org/): providing internationalized keyboard handling + - [libdrm](https://gitlab.freedesktop.org/mesa/drm): graphics access to DRM/KMS subsystem + - linux-headers: linux kernel headers for ABI definitions + +Everything else is optional: + +For video output at least one of the following is required: +- fbdev: For framebuffer video output the kernel headers must be installed and located in the default include path. +- DRM: For unaccelerated drm output the "libdrm" library must be installed and accessible via pkg-config. +- OpenGLES2: For accelerated video output via OpenGLESv2 the following must be installed: libdrm, libgbm, egl, glesv2 (i.e., mesa) + +For font handling the following is required: +- 8x16: The 8x16 font is a static built-in font which does not require external dependencies. +- unifont: Static font without external dependencies. +- pango: drawing text with pango Pango requires: glib, pango, fontconfig, freetype2 and more + +For multi-seat support you need the following packages: +- systemd: Actually only the systemd-logind daemon and library is required. + +## Download + +Released tarballs can be found at: https://github.com/Aetf/kmscon/releases + +## Install + +To compile the kmscon binary, run the standard meson commands: +```bash +meson builddir/ +```` + +By default this will install into `/usr/local`, you can change your prefix with `--prefix=/usr` +(or `meson configure builddir/ -Dprefix=/usr` after the initial meson setup). + +Then build and install. Note that this requires ninja. +```bash +meson -C builddir/ install +``` + +The following meson options are available. +They can be used to select backends for several subsystems in kmscon. +If build-time dependencies cannot be satisfied, an option is automatically turned off, except if you +explicitly enable it via command line: + +| option | default | description | +|:------|:-------:|:-----------| +|`extra_debug`| `false` | Additional debug outputs | +|`multi_seat`| `auto` | This requires the systemd-logind library to provide multi-seat support for kmscon | +|`video_fbdev`| `auto` | Linux fbdev video backend | +|`video_drm2d`| `auto` | Linux DRM software-rendering backend | +|`video_drm3d`| `auto` | Linux DRM hardware-rendering backend | +|`font_unifont`| `auto` | Static built-in non-scalable font (Unicode Unifont) | +|`font_pango`| `auto` | Pango based scalable font renderer | +|`renderer_bbulk`| `auto` | Simple 2D software-renderer (bulk-mode) | +|`renderer_gltex`| `auto` | OpenGLESv2 accelerated renderer | +|`renderer_pixman`| `auto` | pixman based renderer | +|`session_dummy`| `auto` | Dummy fallback session | +|`session_terminal`| `auto` | Terminal-emulator sessions | + +## Running + +To get usage information, run: +```bash +kmscon --help +``` +You can then run kmscon with: +```bash +kmscon [options] +``` + +### Locale + +Kmscon queries and setups system locale settings before starting if systemd-localed is available. +Otherwise, you can change locale settings via `--xkb-{model,layout,variant,options}` command line options. +See `man kmscon` for more information. + +### Config file + +The default configuration file is `/etc/kmscon/kmscon.conf`. Any command line option can be put in the config file in +its long form without the leading `--` (double dash). See `man kmscon` for more information. + +## License + +This software is licensed under the terms of an MIT-like license. Please see +[`COPYING`](./COPYING) for further information. + +## History + +This is a personal fork from https://www.freedesktop.org/wiki/Software/kmscon, which hasn't been updated since 2014. + diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 65a6fe10..00000000 --- a/autogen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -e - -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. - -origdir=`pwd` -cd $srcdir - -mkdir -p m4 -autoreconf -is --force - -cd $origdir - -if test -z "$NOCONFIGURE" ; then - exec $srcdir/configure "$@" -fi diff --git a/configure.ac b/configure.ac deleted file mode 100644 index f472c92f..00000000 --- a/configure.ac +++ /dev/null @@ -1,825 +0,0 @@ -# -# Kmscon - build configuration script -# Copyright (c) 2012 David Herrmann -# - -AC_PREREQ(2.68) - -AC_INIT([kmscon], - [8], - [http://bugs.freedesktop.org/enter_bug.cgi?product=kmscon], - [kmscon], - [http://www.freedesktop.org/wiki/Software/kmscon]) -AC_CONFIG_SRCDIR([src/kmscon_main.c]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_HEADER(config.h) -AC_USE_SYSTEM_EXTENSIONS -AC_SYS_LARGEFILE -AC_CANONICAL_SYSTEM - -AM_INIT_AUTOMAKE([foreign 1.11 subdir-objects dist-xz no-dist-gzip tar-pax -Wall -Werror -Wno-portability]) -AM_SILENT_RULES([yes]) - -# -# Don't add a default "-g -O2" if CFLAGS wasn't specified. For debugging it is -# often more convenient to have "-g -O0". You can still override it by -# explicitly setting it on the command line. -# - -: ${CFLAGS=""} - -AC_PROG_CC -AX_PROG_CC_FOR_BUILD -AC_PROG_CC_C99 -AM_PROG_CC_C_O -m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) -AC_PROG_SED -AC_PROG_MKDIR_P -AC_PROG_LN_S -AC_PROG_GREP -AC_PROG_AWK - -LT_PREREQ(2.2) -LT_INIT - -# -# Required pkg-config dependencies -# - -PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon >= 0.5.0]) -AC_SUBST(XKBCOMMON_CFLAGS) -AC_SUBST(XKBCOMMON_LIBS) - -PKG_CHECK_MODULES([TSM], [libtsm >= 4.0.0]) -AC_SUBST(TSM_CFLAGS) -AC_SUBST(TSM_LIBS) - -PKG_CHECK_MODULES([UDEV], [libudev >= 172]) -AC_SUBST(UDEV_CFLAGS) -AC_SUBST(UDEV_LIBS) - -PKG_CHECK_MODULES([DRM], [libdrm]) -AC_SUBST(DRM_CFLAGS) -AC_SUBST(DRM_LIBS) - -# -# pkg-config dependencies -# This unconditionally checks for all dependencies even if they are disabled. We -# later look whether all required depedencies are met and finish the -# configuration. We group similar packages into one logical group here to avoid -# having variables for each single library. -# This, however, makes ./configure output very unintuitive error messages if a -# package is not found so we must make sure we print more verbose messages -# ourself. -# - -PKG_CHECK_MODULES([SYSTEMD], [libsystemd], - [have_systemd=yes], [have_systemd=no]) -AC_SUBST(SYSTEMD_CFLAGS) -AC_SUBST(SYSTEMD_LIBS) - -PKG_CHECK_MODULES([GBM], [gbm], - [have_gbm=yes], [have_gbm=no]) -AC_SUBST(GBM_CFLAGS) -AC_SUBST(GBM_LIBS) - -PKG_CHECK_MODULES([EGL], [egl], - [have_egl=yes], [have_egl=no]) -AC_SUBST(EGL_CFLAGS) -AC_SUBST(EGL_LIBS) - -PKG_CHECK_MODULES([GLES2], [glesv2], - [have_gles2=yes], [have_gles2=no]) -AC_SUBST(GLES2_CFLAGS) -AC_SUBST(GLES2_LIBS) - -PKG_CHECK_MODULES([PANGO], [pango pangoft2], - [have_pango=yes], [have_pango=no]) -AC_SUBST(PANGO_CFLAGS) -AC_SUBST(PANGO_LIBS) - -PKG_CHECK_MODULES([PIXMAN], [pixman-1], - [have_pixman=yes], [have_pixman=no]) -AC_SUBST(PIXMAN_CFLAGS) -AC_SUBST(PIXMAN_LIBS) - -# -# Parse arguments -# This parses all arguments that are given via "--enable-XY" or "--with-XY" and -# saves the results in local variables. This does not check dependencies or -# similar but does only parse the arguments. -# - -# all -AC_MSG_CHECKING([whether user wants all]) -AC_ARG_ENABLE([all], - [AS_HELP_STRING([--enable-all], - [enable all options (used for debugging)])]) -if test "x$enable_all" = "x" ; then - enable_all="no" -fi -AC_MSG_RESULT([$enable_all]) - -# debug -AC_MSG_CHECKING([whether to build with debugging on]) -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug], - [whether to build with debugging on])]) -if test "x$enable_all" = "xyes" ; then - enable_debug="yes" -elif test "x$enable_debug" = "x" ; then - enable_debug="yes (default)" -fi -AC_MSG_RESULT([$enable_debug]) - -# optimizations -AC_MSG_CHECKING([whether to disable code optimizations]) -AC_ARG_ENABLE([optimizations], - [AS_HELP_STRING([--disable-optimizations], - [whether to disable code optimizations])]) -if test "x$enable_all" = "xyes" ; then - enable_optimizations="yes" -elif test "x$enable_optimizations" = "x" ; then - enable_optimizations="yes (default)" -fi -AC_MSG_RESULT([$enable_optimizations]) - -# multi-seat -AC_MSG_CHECKING([whether user wants systemd for multi-seat support]) -AC_ARG_ENABLE([multi-seat], - [AS_HELP_STRING([--enable-multi-seat], - [enable multi-seat support with systemd])]) -if test "x$enable_all" = "xyes" ; then - enable_multi_seat="yes" -elif test "x$enable_multi_seat" = "x" ; then - enable_multi_seat="yes (default)" -fi -AC_MSG_RESULT([$enable_multi_seat]) - -# video backends -AC_MSG_CHECKING([which video backends the user wants]) -AC_ARG_WITH([video], - [AS_HELP_STRING([--with-video], - [specify list of optional video backends])], - [], - [with_video="default"]) -enable_video_fbdev="no" -enable_video_drm2d="no" -enable_video_drm3d="no" -if test "x$enable_all" = "xyes" ; then - enable_video_fbdev="yes" - enable_video_drm2d="yes" - enable_video_drm3d="yes" - with_video="fbdev,drm2d,drm3d (all)" -elif test "x$with_video" = "xdefault" ; then - enable_video_fbdev="yes (default)" - enable_video_drm2d="yes (default)" - enable_video_drm3d="yes (default)" - with_video="fbdev,drm2d,drm3d (default)" -elif test ! "x$with_video" = "x" ; then - SAVEIFS="$IFS" - IFS="," - for i in $with_video ; do - if test "x$i" = "xfbdev" ; then - enable_video_fbdev="yes" - elif test "x$i" = "xdrm2d" ; then - enable_video_drm2d="yes" - elif test "x$i" = "xdrm3d" ; then - enable_video_drm3d="yes" - else - IFS="$SAVEIFS" - AC_ERROR([Invalid video backend $i]) - fi - done - IFS="$SAVEIFS" -fi -AC_MSG_RESULT([$with_video]) - -# renderers -AC_MSG_CHECKING([which render backends the user wants]) -AC_ARG_WITH([renderers], - [AS_HELP_STRING([--with-renderers], - [specify list of optional render backends])], - [], - [with_renderers="default"]) -enable_renderer_bbulk="no" -enable_renderer_gltex="no" -enable_renderer_pixman="no" -if test "x$enable_all" = "xyes" ; then - enable_renderer_bbulk="yes" - enable_renderer_gltex="yes" - enable_renderer_pixman="yes" - with_renderers="bbulk,gltex,pixman (all)" -elif test "x$with_renderers" = "xdefault" ; then - enable_renderer_bbulk="yes (default)" - enable_renderer_gltex="yes (default)" - enable_renderer_pixman="no (default)" - with_renderers="bbulk,gltex (default)" -elif test ! "x$with_renderers" = "x" ; then - SAVEIFS="$IFS" - IFS="," - for i in $with_renderers ; do - if test "x$i" = "xbbulk" ; then - enable_renderer_bbulk="yes" - elif test "x$i" = "xgltex" ; then - enable_renderer_gltex="yes" - elif test "x$i" = "xpixman" ; then - enable_renderer_pixman="yes" - else - IFS="$SAVEIFS" - AC_ERROR([Unknown renderer $i]) - fi - done - IFS="$SAVEIFS" -fi -AC_MSG_RESULT([$with_renderers]) - -# font backends -AC_MSG_CHECKING([which font backends the user wants]) -AC_ARG_WITH([fonts], - [AS_HELP_STRING([--with-fonts], - [specify list of optional font backends])], - [], - [with_fonts="default"]) -enable_font_unifont="no" -enable_font_pango="no" -if test "x$enable_all" = "xyes" ; then - enable_font_unifont="yes" - enable_font_pango="yes" - with_fonts="unifont,pango (all)" -elif test "x$with_fonts" = "xdefault" ; then - enable_font_unifont="yes (default)" - enable_font_pango="yes (default)" - with_fonts="unifont,pango (default)" -elif test ! "x$with_fonts" = "x" ; then - SAVEIFS="$IFS" - IFS="," - for i in $with_fonts ; do - if test "x$i" = "xunifont" ; then - enable_font_unifont="yes" - elif test "x$i" = "xpango" ; then - enable_font_pango="yes" - else - IFS="$SAVEIFS" - AC_ERROR([Unknown font backend $i]) - fi - done - IFS="$SAVEIFS" -fi -AC_MSG_RESULT([$with_fonts]) - -# kmscon sessions -AC_MSG_CHECKING([which sessions the user wants]) -AC_ARG_WITH([sessions], - [AS_HELP_STRING([--with-sessions], - [specify list of optional sessions])], - [], - [with_sessions="default"]) -enable_session_dummy="no" -enable_session_terminal="no" -if test "x$enable_all" = "xyes" ; then - enable_session_dummy="yes" - enable_session_terminal="yes" - with_sessions="dummy,terminal (all)" -elif test "x$with_sessions" = "xdefault" ; then - enable_session_dummy="yes (default)" - enable_session_terminal="yes (default)" - with_sessions="dummy,terminal (default)" -elif test ! "x$with_sessions" = "x" ; then - SAVEIFS="$IFS" - IFS="," - for i in $with_sessions ; do - if test "x$i" = "xdummy" ; then - enable_session_dummy="yes" - elif test "x$i" = "xterminal" ; then - enable_session_terminal="yes" - else - IFS="$SAVEIFS" - AC_ERROR([Unknown session type $i]) - fi - done - IFS="$SAVEIFS" -fi -AC_MSG_RESULT([$with_sessions]) - -# -# Check what can be built -# This checks each configuration option and tests whether all dependencies are -# met. This is done from bottom up to ensure the right order. -# - -# debug -debug_avail=no -debug_missing="" -if test ! "x$enable_debug" = "xno" ; then - debug_avail=yes -else - debug_missing="enable-debug" -fi - -# optimizations -optimizations_avail=no -optimizations_missing="" -if test ! "x$enable_optimizations" = "xno" ; then - optimizations_avail=yes -else - optimizations_missing="enable-optimizations" -fi - -# video fbdev -video_fbdev_avail=no -video_fbdev_missing="" -if test ! "x$enable_video_fbdev" = "xno" ; then - # TODO: check for kernel headers - video_fbdev_avail=yes -else - video_fbdev_missing="enable-video-fbdev" -fi - -# video drm2d -video_drm2d_avail=no -video_drm2d_missing="" -if test ! "x$enable_video_drm2d" = "xno" ; then - video_drm2d_avail=yes -else - video_drm2d_missing="enable-video-drm2d" -fi - -# video drm3d -video_drm3d_avail=no -video_drm3d_missing="" -if test ! "x$enable_video_drm3d" = "xno" ; then - video_drm3d_avail=yes - if test "x$have_gbm" = "xno" ; then - video_drm3d_avail=no - video_drm3d_missing="libgbm,$video_drm3d_missing" - fi - if test "x$have_egl" = "xno" ; then - video_drm3d_avail=no - video_drm3d_missing="libegl,$video_drm3d_missing" - fi - if test "x$have_gles2" = "xno" ; then - video_drm3d_avail=no - video_drm3d_missing="libgles2,$video_drm3d_missing" - fi - - if test "x$video_drm3d_avail" = "xno" ; then - if test "x$enable_video_drm3d" = "xyes" ; then - AC_ERROR([missing for drm3d video backend: $video_drm3d_missing]) - fi - fi -else - video_drm3d_missing="enable-video-drm3d" -fi - -# multi-seat -multi_seat_avail=no -multi_seat_missing="" -if test ! "x$enable_multi_seat" = "xno" ; then - multi_seat_avail=yes - if test "x$have_systemd" = "xno" ; then - multi_seat_avail=no - multi_seat_missing="libsystemd" - fi - - if test "x$multi_seat_avail" = "xno" ; then - if test "x$enable_multi_seat" = "xyes" ; then - AC_ERROR([missing for multi-seat support: $multi_seat_missing]) - fi - fi -else - multi_seat_missing="enable-multi-seat" -fi - -# renderer bbulk -renderer_bbulk_avail=no -renderer_bbulk_missing="" -if test ! "x$enable_renderer_bbulk" = "xno" ; then - renderer_bbulk_avail=yes -else - renderer_bbulk_missing="enable-renderer-bbulk" -fi - -# renderer gltex -renderer_gltex_avail=no -renderer_gltex_missing="" -if test ! "x$enable_renderer_gltex" = "xno" ; then - renderer_gltex_avail=yes - if test "x$have_gles2" = "xno" ; then - renderer_gltex_avail=no - renderer_gltex_missing="libgles2" - fi - - if test "x$renderer_gltex_avail" = "xno" ; then - if test "x$enable_renderer_gltex" = "xyes" ; then - AC_ERROR([missing for renderer-gltex: $renderer_gltex_missing]) - fi - fi -else - renderer_gltex_missing="enable-renderer-gltex" -fi - -# renderer pixman -renderer_pixman_avail=no -renderer_pixman_missing="" -if test ! "x$enable_renderer_pixman" = "xno" ; then - renderer_pixman_avail=yes - if test "x$have_pixman" = "xno" ; then - renderer_pixman_avail=no - renderer_pixman_missing="pixman" - fi - - if test "x$renderer_pixman_avail" = "xno" ; then - if test "x$enable_renderer_pixman" = "xyes" ; then - AC_ERROR([missing for renderer-pixman: $renderer_pixman_missing]) - fi - fi -else - renderer_pixman_missing="enable-renderer-pixman" -fi - -# font unifont -font_unifont_avail=no -font_unifont_missing="" -if test ! "x$enable_font_unifont" = "xno" ; then - font_unifont_avail=yes -else - font_unifont_missing="enable-font-unifont" -fi - -# font pango -font_pango_avail=no -font_pango_missing="" -if test ! "x$enable_font_pango" = "xno" ; then - font_pango_avail=yes - if test "x$have_pango" = "xno" ; then - font_pango_avail=no - font_pango_missing="libpango" - fi - - if test "x$font_pango_avail" = "xno" ; then - if test "x$enable_font_pango" = "xyes" ; then - AC_ERROR([missing for font-pango: $font_pango_missing]) - fi - fi -else - font_pango_missing="enable-font-pango" -fi - -# session dummy -session_dummy_avail=no -session_dummy_missing="" -if test ! "x$enable_session_dummy" = "xno" ; then - session_dummy_avail=yes -else - session_dummy_missing="enable-session-dummy" -fi - -# session terminal -session_terminal_avail=no -session_terminal_missing="" -if test ! "x$enable_session_terminal" = "xno" ; then - session_terminal_avail=yes -else - session_terminal_missing="enable-session-terminal" -fi - -# -# Enable all required modules -# We now know which modules can be built by checking the *_avail variables set -# above. We now only have to disable all modules that are disabled by default -# and the user didn't force-enable them and no other module that is enabled -# needs them. This is done top-down of course. -# - -# session terminal -session_terminal_enabled=no -if test "x$session_terminal_avail" = "xyes" ; then - if test "x${enable_session_terminal% *}" = "xyes" ; then - session_terminal_enabled=yes - fi -fi - -# session dummy -session_dummy_enabled=no -if test "x$session_dummy_avail" = "xyes" ; then - if test "x${enable_session_dummy% *}" = "xyes" ; then - session_dummy_enabled=yes - fi -fi - -# font pango -font_pango_enabled=no -if test "x$font_pango_avail" = "xyes" ; then - if test "x${enable_font_pango% *}" = "xyes" ; then - font_pango_enabled=yes - fi -fi - -# font unifont -font_unifont_enabled=no -if test "x$font_unifont_avail" = "xyes" ; then - if test "x${enable_font_unifont% *}" = "xyes" ; then - font_unifont_enabled=yes - fi -fi - -# renderer gltex -renderer_gltex_enabled=no -if test "x$renderer_gltex_avail" = "xyes" ; then - if test "x${enable_renderer_gltex% *}" = "xyes" ; then - renderer_gltex_enabled=yes - fi -fi - -# renderer pixman -renderer_pixman_enabled=no -if test "x$renderer_pixman_avail" = "xyes" ; then - if test "x${enable_renderer_pixman% *}" = "xyes" ; then - renderer_pixman_enabled=yes - fi -fi - -# renderer bbulk -renderer_bbulk_enabled=no -if test "x$renderer_bbulk_avail" = "xyes" ; then - if test "x${enable_renderer_bbulk% *}" = "xyes" ; then - renderer_bbulk_enabled=yes - fi -fi - -# multi-seat -multi_seat_enabled=no -if test "x$multi_seat_avail" = "xyes" ; then - if test "x${enable_multi_seat% *}" = "xyes" ; then - multi_seat_enabled=yes - fi -fi - -# video drm3d -video_drm3d_enabled=no -if test "x$video_drm3d_avail" = "xyes" ; then - if test "x${enable_video_drm3d% *}" = "xyes" ; then - video_drm3d_enabled=yes - fi -fi - -# video drm2d -video_drm2d_enabled=no -if test "x$video_drm2d_avail" = "xyes" ; then - if test "x${enable_video_drm2d% *}" = "xyes" ; then - video_drm2d_enabled=yes - fi -fi - -# video fbdev -video_fbdev_enabled=no -if test "x$video_fbdev_avail" = "xyes" ; then - if test "x${enable_video_fbdev% *}" = "xyes" ; then - video_fbdev_enabled=yes - fi -fi - -# optimizations -optimizations_enabled=no -if test "x$optimizations_avail" = "xyes" ; then - if test "x${enable_optimizations% *}" = "xyes" ; then - optimizations_enabled=yes - fi -fi - -# debug -debug_enabled=no -if test "x$debug_avail" = "xyes" ; then - if test "x${enable_debug% *}" = "xyes" ; then - debug_enabled=yes - fi -fi - -# -# Module Configuration -# We have now done all dependency checking and default-value validation and we -# now know which modules are enabled via the *_enabled variables. -# Everything below is related to the configuration of each module and setting -# the correct flags for the build process. -# - -# debug -if test "x$debug_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_DEBUG], [1], [Enable debug mode]) -else - AC_DEFINE([NDEBUG], [1], [No Debug]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_DEBUG], - [test "x$debug_enabled" = "xyes"]) - -# optimizations -AM_CONDITIONAL([BUILD_ENABLE_OPTIMIZATIONS], - [test "x$optimizations_enabled" = "xyes"]) - -# video fbdev -if test "x$video_fbdev_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_VIDEO_FBDEV], [1], - [Build uterm fbdev video backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_VIDEO_FBDEV], - [test "x$video_fbdev_enabled" = "xyes"]) - -# video drm2d -if test "x$video_drm2d_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_VIDEO_DRM2D], [1], - [Build uterm drm2d drm3d video backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_VIDEO_DRM2D], - [test "x$video_drm2d_enabled" = "xyes"]) - -# video drm3d -if test "x$video_drm3d_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_VIDEO_DRM3D], [1], - [Build uterm drm3d video backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_VIDEO_DRM3D], - [test "x$video_drm3d_enabled" = "xyes"]) - -# multi-seat -if test "x$multi_seat_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_MULTI_SEAT], [1], - [Use systemd for multi-seat support]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_MULTI_SEAT], - [test "x$multi_seat_enabled" = "xyes"]) - -# renderer bbulk -if test "x$renderer_bbulk_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_RENDERER_BBULK], [1], - [Build bbulk rendering backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_RENDERER_BBULK], - [test "x$renderer_bbulk_enabled" = "xyes"]) - -# renderer gltex -if test "x$renderer_gltex_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_RENDERER_GLTEX], [1], - [Build gltex rendering backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_RENDERER_GLTEX], - [test "x$renderer_gltex_enabled" = "xyes"]) - -# renderer pixman -if test "x$renderer_pixman_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_RENDERER_PIXMAN], [1], - [Build pixman rendering backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_RENDERER_PIXMAN], - [test "x$renderer_pixman_enabled" = "xyes"]) - -# font unifont -if test "x$font_unifont_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_FONT_UNIFONT], [1], - [Build static unifont backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_FONT_UNIFONT], - [test "x$font_unifont_enabled" = "xyes"]) - -# font pango -if test "x$font_pango_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_FONT_PANGO], [1], - [Build pango font backend]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_FONT_PANGO], - [test "x$font_pango_enabled" = "xyes"]) - -# session dummy -if test "x$session_dummy_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_SESSION_DUMMY], [1], - [Build dummy session]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_SESSION_DUMMY], - [test "x$session_dummy_enabled" = "xyes"]) - -# session terminal -if test "x$session_terminal_enabled" = "xyes" ; then - AC_DEFINE([BUILD_ENABLE_SESSION_TERMINAL], [1], - [Build terminal session]) -fi - -AM_CONDITIONAL([BUILD_ENABLE_SESSION_TERMINAL], - [test "x$session_terminal_enabled" = "xyes"]) - -# -# Miscellaneous Checks -# All checks below are independent of module checking or depend on the results -# of it. They do not have any dependencies themselves so they are not part of the -# module infrastructure. -# - -# check for _Static_assert -AC_MSG_CHECKING([whether _Static_assert() is supported]) -AC_LANG([C]) -have_static_assert=yes -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[_Static_assert(1, "What?");]])], - [AC_DEFINE([BUILD_HAVE_STATIC_ASSERT], - [1], - [Define to 1 if _Static_assert() is supported])], - [have_static_assert=no]) -AC_MSG_RESULT([$have_static_assert]) - -# check for gbm_bo_get_pitch() function, otherwise gbm_bo_get_stride() is used -if test x$have_gbm = xyes ; then - save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" - save_LDFLAGS="$LDFLAGS" - CFLAGS="$DRM_CFLAGS $GBM_CFLAGS" - LIBS="$DRM_LIBS $GBM_LIBS" - LDFLAGS="" - AC_CHECK_LIB([gbm], - [gbm_bo_get_pitch], - [AC_DEFINE([BUILD_HAVE_GBM_BO_GET_PITCH], - [1], - [Define to 1 if your libgbm provides gbm_bo_get_pitch])]) - CFLAGS="$save_CFLAGS" - LIBS="$save_LIBS" - LDFLAGS="$save_LDFLAGS" -fi - -# check for xsltproc -AC_ARG_VAR([XSLTPROC], [xsltproc program]) -AC_PATH_PROG(XSLTPROC, xsltproc) -AM_CONDITIONAL([BUILD_HAVE_XSLTPROC], [test "x$XSLTPROC" != "x"]) - -# check for offline man-pages stylesheet -AC_MSG_CHECKING([for docbook manpages stylesheet]) -BUILD_MANPAGES_STYLESHEET="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" -AC_PATH_PROGS_FEATURE_CHECK([XSLTPROC_TMP], [xsltproc], - AS_IF([`"$ac_path_XSLTPROC_TMP" --nonet "$BUILD_MANPAGES_STYLESHEET" > /dev/null 2>&1`], - [BUILD_HAVE_MANPAGES_STYLESHEET=yes])) -if test "x$BUILD_HAVE_MANPAGES_STYLESHEET" = "xyes"; then - AM_CONDITIONAL([BUILD_HAVE_MANPAGES_STYLESHEET], true) - AC_SUBST(BUILD_MANPAGES_STYLESHEET) - AC_MSG_RESULT([yes]) -else - AM_CONDITIONAL([BUILD_HAVE_MANPAGES_STYLESHEET], false) - AC_MSG_RESULT([no]) -fi - -# gles2 helpers -AM_CONDITIONAL([BUILD_HAVE_GLES2], [test "x$have_gles2" = "xyes"]) - -# -# Makefile vars -# After everything is configured, we correctly substitute the values for the -# makefiles. -# - -AC_CONFIG_FILES([Makefile scripts/kmscon]) -AC_OUTPUT - -# -# Configuration output -# Show configuration to the user so they can check whether everything was -# configured as expected. -# - -AC_MSG_NOTICE([Build configuration: - - prefix: $prefix - exec-prefix: $exec_prefix - libdir: $libdir - includedir: $includedir - - Miscellaneous Options: - debug: $debug_enabled ($debug_avail: $debug_missing) - optimizations: $optimizations_enabled ($optimizations_avail: $optimizations_missing) - multi-seat: $multi_seat_enabled ($multi_seat_avail: $multi_seat_missing) - - Video Backends: - fbdev: $video_fbdev_enabled ($video_fbdev_avail: $video_fbdev_missing) - drm2d: $video_drm2d_enabled ($video_drm2d_avail: $video_drm2d_missing) - drm3d: $video_drm3d_enabled ($video_drm3d_avail: $video_drm3d_missing) - - Font Backends: - unifont: $font_unifont_enabled ($font_unifont_avail: $font_unifont_missing) - pango: $font_pango_enabled ($font_pango_avail: $font_pango_missing) - - Renderers: - bbulk: $renderer_bbulk_enabled ($renderer_bbulk_avail: $renderer_bbulk_missing) - gltex: $renderer_gltex_enabled ($renderer_gltex_avail: $renderer_gltex_missing) - pixman: $renderer_pixman_enabled ($renderer_pixman_avail: $renderer_pixman_missing) - - Session Types: - dummy: $session_dummy_enabled ($session_dummy_avail: $session_dummy_missing) - terminal: $session_terminal_enabled ($session_terminal_avail: $session_terminal_missing) - - Run "${MAKE-make}" to start compilation process]) diff --git a/docs/kmscon.service b/docs/kmscon.service.in similarity index 74% rename from docs/kmscon.service rename to docs/kmscon.service.in index a3cc4ed3..c29fe924 100644 --- a/docs/kmscon.service +++ b/docs/kmscon.service.in @@ -3,7 +3,7 @@ Description=KMS System Console Documentation=man:kmscon(1) [Service] -ExecStart=/usr/bin/kmscon -l /bin/login +ExecStart=@bindir@/kmscon -l /bin/login [Install] WantedBy=multi-user.target diff --git a/docs/kmsconvt@.service b/docs/kmsconvt@.service.in similarity index 96% rename from docs/kmsconvt@.service rename to docs/kmsconvt@.service.in index 7b648239..84b66bf4 100644 --- a/docs/kmsconvt@.service +++ b/docs/kmsconvt@.service.in @@ -37,7 +37,7 @@ IgnoreOnIsolate=yes ConditionPathExists=/dev/tty0 [Service] -ExecStart=/usr/bin/kmscon "--vt=%I" --seats=seat0 --no-switchvt +ExecStart=@bindir@/kmscon "--vt=%I" --seats=seat0 --no-switchvt UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes diff --git a/docs/man/kmscon.xml b/docs/man/kmscon.1.xml.in similarity index 98% rename from docs/man/kmscon.xml rename to docs/man/kmscon.1.xml.in index 5d992cdc..594de2aa 100644 --- a/docs/man/kmscon.xml +++ b/docs/man/kmscon.1.xml.in @@ -104,7 +104,7 @@ - Specify path to config directory. (default: /etc/kmscon/) + Specify path to config directory. (default: @CONFIG_DIR@) @@ -129,7 +129,7 @@ use this option if kmscon runs on multiple seats (see ). To avoid this, specify this option in a seat configuration - /etc/kmscon/{seat}.kmscon.conf. + @CONFIG_DIR@/{seat}.kmscon.conf. You must not run multiple applications on a single VT, otherwise, you might get an unresponsive system. Also note, by default, kmscon tries to use it's controlling terminal as VT and @@ -694,11 +694,11 @@ Configuration - Default configuration directory is /etc/kmscon/ + Default configuration directory is @CONFIG_DIR@ and the main configuration file is called - /etc/kmscon/kmscon.conf. You can provide an + @CONFIG_DIR@/kmscon.conf. You can provide an additional configuration file for each seat via - /etc/kmscon/{seatname}.kmscon.conf. + @CONFIG_DIR@/{seatname}.kmscon.conf. Any command-line option that can be passed to kmscon can also be put into those configuration files. For example: diff --git a/docs/meson.build b/docs/meson.build new file mode 100644 index 00000000..a26e520f --- /dev/null +++ b/docs/meson.build @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT + +manpages = [ + 'kmscon.1.xml.in', +] + +data = configuration_data() +data.set('CONFIG_DIR', prefix / sysconfdir) + +foreach man : manpages + xml = configure_file(input: f'man/@man@', output: '@BASENAME@', configuration: data) + name = fs.replace_suffix(fs.replace_suffix(man, ''), '') + custom_target( + name, + command: [ + xsltproc, + '--stringparam', 'man.authors.section.enabled', '0', + '--stringparam', 'man.copyright.section.enabled', '0', + '--stringparam', 'funcsynopsis.style', 'ansi', + '--stringparam', 'man.output.quietly', '1', + '--nonet', + '-o', '@OUTPUT@', + manpages_stylesheet, + '@INPUT@' + ], + input: [ + xml + ], + output: name, + build_by_default: true, + install: true, + install_dir: mandir / 'man1', + ) +endforeach + diff --git a/external/meson.build b/external/meson.build new file mode 100644 index 00000000..094ad49a --- /dev/null +++ b/external/meson.build @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT + +# +# htable - hash table +# +htable = static_library('ext-htable', ['htable.c']) + +htable_deps = declare_dependency( + link_with: [htable], + include_directories: [ + include_directories('.'), + ] +) + diff --git a/external/wcwidth.c b/external/wcwidth.c deleted file mode 100644 index 61e822ad..00000000 --- a/external/wcwidth.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * This is an implementation of wcwidth() and wcswidth() (defined in - * IEEE Std 1002.1-2001) for Unicode. - * - * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html - * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html - * - * In fixed-width output devices, Latin characters all occupy a single - * "cell" position of equal width, whereas ideographic CJK characters - * occupy two such cells. Interoperability between terminal-line - * applications and (teletype-style) character terminals using the - * UTF-8 encoding requires agreement on which character should advance - * the cursor by how many cell positions. No established formal - * standards exist at present on which Unicode character shall occupy - * how many cell positions on character terminals. These routines are - * a first attempt of defining such behavior based on simple rules - * applied to data provided by the Unicode Consortium. - * - * For some graphical characters, the Unicode standard explicitly - * defines a character-cell width via the definition of the East Asian - * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. - * In all these cases, there is no ambiguity about which width a - * terminal shall use. For characters in the East Asian Ambiguous (A) - * class, the width choice depends purely on a preference of backward - * compatibility with either historic CJK or Western practice. - * Choosing single-width for these characters is easy to justify as - * the appropriate long-term solution, as the CJK practice of - * displaying these characters as double-width comes from historic - * implementation simplicity (8-bit encoded characters were displayed - * single-width and 16-bit ones double-width, even for Greek, - * Cyrillic, etc.) and not any typographic considerations. - * - * Much less clear is the choice of width for the Not East Asian - * (Neutral) class. Existing practice does not dictate a width for any - * of these characters. It would nevertheless make sense - * typographically to allocate two character cells to characters such - * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be - * represented adequately with a single-width glyph. The following - * routines at present merely assign a single-cell width to all - * neutral characters, in the interest of simplicity. This is not - * entirely satisfactory and should be reconsidered before - * establishing a formal standard in this area. At the moment, the - * decision which Not East Asian (Neutral) characters should be - * represented by double-width glyphs cannot yet be answered by - * applying a simple rule from the Unicode database content. Setting - * up a proper standard for the behavior of UTF-8 character terminals - * will require a careful analysis not only of each Unicode character, - * but also of each presentation form, something the author of these - * routines has avoided to do so far. - * - * http://www.unicode.org/unicode/reports/tr11/ - * - * Markus Kuhn -- 2007-05-26 (Unicode 5.0) - * - * Permission to use, copy, modify, and distribute this software - * for any purpose and without fee is hereby granted. The author - * disclaims all warranties with regard to this software. - * - * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - */ - -#include - -struct interval { - int first; - int last; -}; - -/* auxiliary function for binary search in interval table */ -static int bisearch(wchar_t ucs, const struct interval *table, int max) { - int min = 0; - int mid; - - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return 1; - } - - return 0; -} - - -/* The following two functions define the column width of an ISO 10646 - * character as follows: - * - * - The null character (U+0000) has a column width of 0. - * - * - Other C0/C1 control characters and DEL will lead to a return - * value of -1. - * - * - Non-spacing and enclosing combining characters (general - * category code Mn or Me in the Unicode database) have a - * column width of 0. - * - * - SOFT HYPHEN (U+00AD) has a column width of 1. - * - * - Other format characters (general category code Cf in the Unicode - * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. - * - * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) - * have a column width of 0. - * - * - Spacing characters in the East Asian Wide (W) or East Asian - * Full-width (F) category as defined in Unicode Technical - * Report #11 have a column width of 2. - * - * - All remaining characters (including all printable - * ISO 8859-1 and WGL4 characters, Unicode control characters, - * etc.) have a column width of 1. - * - * This implementation assumes that wchar_t characters are encoded - * in ISO 10646. - */ - -int mk_wcwidth(wchar_t ucs) -{ - /* sorted list of non-overlapping intervals of non-spacing characters */ - /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ - static const struct interval combining[] = { - { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, - { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, - { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, - { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, - { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, - { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, - { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, - { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, - { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, - { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, - { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, - { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, - { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, - { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, - { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, - { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, - { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, - { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, - { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, - { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, - { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, - { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, - { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, - { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, - { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, - { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, - { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, - { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, - { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, - { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, - { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, - { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, - { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, - { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, - { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, - { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, - { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, - { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, - { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, - { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, - { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, - { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, - { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, - { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, - { 0xE0100, 0xE01EF } - }; - - /* test for 8-bit control characters */ - if (ucs == 0) - return 0; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return -1; - - /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, - sizeof(combining) / sizeof(struct interval) - 1)) - return 0; - - /* if we arrive here, ucs is not a combining or C0/C1 control character */ - - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); -} - - -int mk_wcswidth(const wchar_t *pwcs, size_t n) -{ - int w, width = 0; - - for (;*pwcs && n-- > 0; pwcs++) - if ((w = mk_wcwidth(*pwcs)) < 0) - return -1; - else - width += w; - - return width; -} - - -/* - * The following functions are the same as mk_wcwidth() and - * mk_wcswidth(), except that spacing characters in the East Asian - * Ambiguous (A) category as defined in Unicode Technical Report #11 - * have a column width of 2. This variant might be useful for users of - * CJK legacy encodings who want to migrate to UCS without changing - * the traditional terminal character-width behaviour. It is not - * otherwise recommended for general use. - */ -int mk_wcwidth_cjk(wchar_t ucs) -{ - /* sorted list of non-overlapping intervals of East Asian Ambiguous - * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ - static const struct interval ambiguous[] = { - { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, - { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, - { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, - { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, - { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, - { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, - { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, - { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, - { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, - { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, - { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, - { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, - { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, - { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, - { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, - { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, - { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, - { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, - { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, - { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, - { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, - { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, - { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, - { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, - { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, - { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, - { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, - { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, - { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, - { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, - { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, - { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, - { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, - { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, - { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, - { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, - { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, - { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, - { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, - { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, - { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, - { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, - { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, - { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, - { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, - { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, - { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 }, - { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, - { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, - { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, - { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF }, - { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } - }; - - /* binary search in table of non-spacing characters */ - if (bisearch(ucs, ambiguous, - sizeof(ambiguous) / sizeof(struct interval) - 1)) - return 2; - - return mk_wcwidth(ucs); -} - - -int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) -{ - int w, width = 0; - - for (;*pwcs && n-- > 0; pwcs++) - if ((w = mk_wcwidth_cjk(*pwcs)) < 0) - return -1; - else - width += w; - - return width; -} diff --git a/external/wcwidth.h b/external/wcwidth.h deleted file mode 100644 index 3b7337b0..00000000 --- a/external/wcwidth.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This is an implementation of wcwidth() and wcswidth() (defined in - * IEEE Std 1002.1-2001) for Unicode. - * - * Markus Kuhn -- 2007-05-26 (Unicode 5.0) - * - * Permission to use, copy, modify, and distribute this software - * for any purpose and without fee is hereby granted. The author - * disclaims all warranties with regard to this software. - */ - -#include -#include - -int mk_wcwidth(wchar_t ucs); -int mk_wcswidth(const wchar_t *pwcs, size_t n); -int mk_wcwidth_cjk(wchar_t ucs); -int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n); diff --git a/fblog/0001-fblog-new-framebuffer-kernel-log-dummy-driver.patch b/fblog/0001-fblog-new-framebuffer-kernel-log-dummy-driver.patch deleted file mode 100644 index d68a1bb9..00000000 --- a/fblog/0001-fblog-new-framebuffer-kernel-log-dummy-driver.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 19c80ae416f42991c764501ff2283b0294fd6b5b Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 22:44:09 +0200 -Subject: [PATCH 01/10] fblog: new framebuffer kernel log dummy driver - -Fblog displays all kernel log messages on all connected framebuffers. It -replaces fbcon when CONFIG_VT=n is selected. Its main purpose is to debug -boot problems by displaying the whole boot log on the screen. This patch -provides the first dummy module-init/deinit functions. - -As is uses all the font and fb functions I placed it in -drivers/video/console. However, this means that we need to move the check -for CONFIG_VT in Makefile/Kconfig from drivers/video into -drivers/video/console as fblog does not depend on CONFIG_VT. - -Signed-off-by: David Herrmann ---- - drivers/video/Kconfig | 5 +--- - drivers/video/Makefile | 2 +- - drivers/video/console/Kconfig | 37 +++++++++++++++++++++------ - drivers/video/console/Makefile | 1 + - drivers/video/console/fblog.c | 55 ++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 87 insertions(+), 13 deletions(-) - create mode 100644 drivers/video/console/fblog.c - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 0217f74..e8fd53d 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -2448,10 +2448,7 @@ source "drivers/video/omap/Kconfig" - source "drivers/video/omap2/Kconfig" - source "drivers/video/exynos/Kconfig" - source "drivers/video/backlight/Kconfig" -- --if VT -- source "drivers/video/console/Kconfig" --endif -+source "drivers/video/console/Kconfig" - - if FB || SGI_NEWPORT_CONSOLE - source "drivers/video/logo/Kconfig" -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index ee8dafb..9f8a7f0 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -11,7 +11,7 @@ fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ - modedb.o fbcvt.o - fb-objs := $(fb-y) - --obj-$(CONFIG_VT) += console/ -+obj-y += console/ - obj-$(CONFIG_LOGO) += logo/ - obj-y += backlight/ - -diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig -index c2d11fe..cfee482 100644 ---- a/drivers/video/console/Kconfig -+++ b/drivers/video/console/Kconfig -@@ -6,7 +6,7 @@ menu "Console display driver support" - - config VGA_CONSOLE - bool "VGA text console" if EXPERT || !X86 -- depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) -+ depends on VT && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) - default y - help - Saying Y here will allow you to use Linux in text mode through a -@@ -45,7 +45,7 @@ config VGACON_SOFT_SCROLLBACK_SIZE - screenfuls of scrollback buffer - - config MDA_CONSOLE -- depends on !M68K && !PARISC && ISA -+ depends on VT && !M68K && !PARISC && ISA - tristate "MDA text console (dual-headed) (EXPERIMENTAL)" - ---help--- - Say Y here if you have an old MDA or monochrome Hercules graphics -@@ -61,14 +61,14 @@ config MDA_CONSOLE - - config SGI_NEWPORT_CONSOLE - tristate "SGI Newport Console support" -- depends on SGI_IP22 -+ depends on VT && SGI_IP22 - help - Say Y here if you want the console on the Newport aka XL graphics - card of your Indy. Most people say Y here. - - config DUMMY_CONSOLE - bool -- depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y -+ depends on VT && (VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y) - default y - - config DUMMY_CONSOLE_COLUMNS -@@ -89,7 +89,7 @@ config DUMMY_CONSOLE_ROWS - - config FRAMEBUFFER_CONSOLE - tristate "Framebuffer Console support" -- depends on FB -+ depends on VT && FB - select CRC32 - help - Low-level framebuffer-based console driver. -@@ -122,16 +122,37 @@ config FRAMEBUFFER_CONSOLE_ROTATION - - config STI_CONSOLE - bool "STI text console" -- depends on PARISC -+ depends on VT && PARISC - default y - help - The STI console is the builtin display/keyboard on HP-PARISC - machines. Say Y here to build support for it into your kernel. - The alternative is to use your primary serial port as a console. - -+config FBLOG -+ tristate "Framebuffer Kernel Log Driver" -+ depends on !VT && FB -+ default n -+ help -+ This driver displays all kernel log messages on all connected -+ framebuffers. It is mutually exclusive with CONFIG_FRAMEBUFFER_CONSOLE -+ and CONFIG_VT. It was mainly created for debugging purposes when -+ CONFIG_VT is not selected but you still want kernel boot messages on -+ the screen. -+ -+ This driver overwrites all other graphics output on the framebuffer as -+ long as it is active so the kernel log will always be visible. You -+ need to disable this driver via sysfs to be able to start another -+ graphics application. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the module will -+ be called fblog. -+ - config FONTS - bool "Select compiled-in fonts" -- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE -+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE || FBLOG - help - Say Y here if you would like to use fonts other than the default - your frame buffer console usually use. -@@ -158,7 +179,7 @@ config FONT_8x8 - - config FONT_8x16 - bool "VGA 8x16 font" if FONTS -- depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON -+ depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON || FBLOG - default y if !SPARC && !FONTS - help - This is the "high resolution" font for the VGA frame buffer (the one -diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile -index a862e91..f608c97 100644 ---- a/drivers/video/console/Makefile -+++ b/drivers/video/console/Makefile -@@ -20,6 +20,7 @@ font-objs += $(font-objs-y) - - # Each configuration option enables a list of files. - -+obj-$(CONFIG_FBLOG) += fblog.o font.o - obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o - obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o - obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -new file mode 100644 -index 0000000..ea83643 ---- /dev/null -+++ b/drivers/video/console/fblog.c -@@ -0,0 +1,55 @@ -+/* -+ * Framebuffer Kernel Log Driver -+ * Copyright (c) 2012 David Herrmann -+ */ -+ -+/* -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ */ -+ -+/* -+ * Framebuffer Kernel Log -+ * This driver prints the kernel log to all connected display devices. It -+ * replaces CONFIG_VT and cannot run simultaneously with it. It does not provide -+ * any virtual-terminal, though. It should only be used to get kernel boot -+ * messages to debug kernel errors. -+ * Hence, this driver is neither optimized for speed, nor does it provide any -+ * fancy features like colored text output. After booting is done, the init -+ * process should set /sys/class/graphics/fblog/active to 0 which disables this -+ * driver and you can start using the graphics devices. During shutdown, you can -+ * set this to 1 to get log messages again. -+ * This driver forcibly writes to the framebuffer while active, therefore, you -+ * cannot run other graphics applications simultaneously. -+ * -+ * fblog_redraw_line() is heavily based on the fbcon driver. See bitblit.c for -+ * the original implementation copyrighted by: -+ * Copyright (C) 2004 Antonino Daplas -+ * -+ * Please note that nearly all functions here must be called with console_lock -+ * held. This way, we have no locking problems and do not need special -+ * synchronization. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int __init fblog_init(void) -+{ -+ return 0; -+} -+ -+static void __exit fblog_exit(void) -+{ -+} -+ -+module_init(fblog_init); -+module_exit(fblog_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("David Herrmann "); -+MODULE_DESCRIPTION("Framebuffer Kernel Log Driver"); --- -1.7.10.4 - diff --git a/fblog/0002-fblog-implement-buffer-management.patch b/fblog/0002-fblog-implement-buffer-management.patch deleted file mode 100644 index a79a49b8..00000000 --- a/fblog/0002-fblog-implement-buffer-management.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 71d0022376609edba28571ee1ecab3c4ccfcc009 Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 22:49:35 +0200 -Subject: [PATCH 02/10] fblog: implement buffer management - -Each available framebuffer can have a different font and buffer size -inside of fblog. Therefore, we need to remember all the log messages that -are currently printed on screen. We save them as an array of lines which -can be rotated and traversed very fast. - -This also implements a very trivial way of resizing the buffer but still -keeping the content. As there is no need to improve this for speed, we can -keep it this way. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 126 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index ea83643..1504ba9 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -39,6 +39,132 @@ - #include - #include - -+/** -+ * struct fblog_buf: Console text buffer -+ * -+ * Each framebuffer has its own text buffer which contains all characters that -+ * are currently printed on screen. The buffers might have different sizes and -+ * can be resized during runtime. When the buffer content changes, we redraw the -+ * screen. -+ * -+ * width: Width of buffer in characters -+ * height: Height of buffer in characters -+ * lines: Array of lines -+ * pos_x: Cursor x-position -+ * pos_y: Cursor y-position -+ */ -+struct fblog_buf { -+ size_t width; -+ size_t height; -+ char **lines; -+ size_t pos_x; -+ size_t pos_y; -+}; -+ -+static void fblog_buf_resize(struct fblog_buf *buf, size_t width, -+ size_t height) -+{ -+ char **lines = NULL; -+ size_t i, j, minw, minh; -+ -+ if (buf->height == height && buf->width == width) -+ return; -+ -+ if (width && height) { -+ lines = kzalloc(height * sizeof(char*), GFP_KERNEL); -+ if (!lines) -+ return; -+ -+ for (i = 0; i < height; ++i) { -+ lines[i] = kzalloc(width * sizeof(char), GFP_KERNEL); -+ if (!lines[i]) { -+ while (i--) -+ kfree(lines[i]); -+ return; -+ } -+ } -+ -+ /* copy old lines */ -+ minw = min(width, buf->width); -+ minh = min(height, buf->height); -+ if (height >= buf->height) -+ i = 0; -+ else -+ i = buf->height - height; -+ -+ for (j = 0; j < minh; ++i, ++j) -+ memcpy(lines[j], buf->lines[i], minw * sizeof(char)); -+ } else { -+ width = 0; -+ height = 0; -+ } -+ -+ for (i = 0; i < buf->height; ++i) -+ kfree(buf->lines[i]); -+ kfree(buf->lines); -+ -+ buf->lines = lines; -+ buf->width = width; -+ buf->height = height; -+} -+ -+static void fblog_buf_init(struct fblog_buf *buf) -+{ -+ fblog_buf_resize(buf, 80, 24); -+} -+ -+static void fblog_buf_deinit(struct fblog_buf *buf) -+{ -+ fblog_buf_resize(buf, 0, 0); -+} -+ -+static void fblog_buf_rotate(struct fblog_buf *buf) -+{ -+ char *line; -+ -+ if (!buf->height) -+ return; -+ -+ line = buf->lines[0]; -+ memset(line, 0, sizeof(char) * buf->width); -+ -+ memmove(buf->lines, &buf->lines[1], sizeof(char*) * (buf->height - 1)); -+ buf->lines[buf->height - 1] = line; -+} -+ -+static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) -+{ -+ char c; -+ -+ if (!buf->height) -+ return; -+ -+ while (len--) { -+ c = *str++; -+ -+ if (c == '\n') { -+ buf->pos_x = 0; -+ if (++buf->pos_y >= buf->height) { -+ buf->pos_y = buf->height - 1; -+ fblog_buf_rotate(buf); -+ } -+ } else if (c == 0) { -+ /* ignore */ -+ } else { -+ if (buf->pos_x >= buf->width) { -+ buf->pos_x = 0; -+ ++buf->pos_y; -+ } -+ if (buf->pos_y >= buf->height) { -+ buf->pos_y = buf->height - 1; -+ fblog_buf_rotate(buf); -+ } -+ -+ buf->lines[buf->pos_y][buf->pos_x++] = c; -+ } -+ } -+} -+ - static int __init fblog_init(void) - { - return 0; --- -1.7.10.4 - diff --git a/fblog/0003-fblog-register-framebuffer-objects.patch b/fblog/0003-fblog-register-framebuffer-objects.patch deleted file mode 100644 index fab782ad..00000000 --- a/fblog/0003-fblog-register-framebuffer-objects.patch +++ /dev/null @@ -1,152 +0,0 @@ -From cbb97ae4af35277a5478383045a86438f2e97c71 Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 22:56:55 +0200 -Subject: [PATCH 03/10] fblog: register framebuffer objects - -We register each available framebuffer in the system with the fblog driver -so we always know all active devices. We directly open the fb-driver, -initialize the buffer and load a font so we are ready for drawing -operations. If a device cannot be opened, we mark it as dead and ignore it -in all other functions. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 108 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 108 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 1504ba9..8038dcc 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -39,6 +39,14 @@ - #include - #include - -+#define FBLOG_STR(x) x, sizeof(x) - 1 -+ -+enum fblog_flags { -+ FBLOG_KILLED, -+ FBLOG_SUSPENDED, -+ FBLOG_BLANKED, -+}; -+ - /** - * struct fblog_buf: Console text buffer - * -@@ -61,6 +69,30 @@ struct fblog_buf { - size_t pos_y; - }; - -+/** -+ * struct fblog_fb: Framebuffer object -+ * -+ * For each framebuffer we register this object. It contains all data we need to -+ * display the console log on it. The index of a framebuffer in registered_fb[] -+ * is the same as in fblog_fbs[]. So the following must always be true if the -+ * pointers are non-NULL: -+ * registered_fb[idx] == fblog_fbs[idx]->info -+ * fblog_fbs[idx]->info->node == idx -+ * -+ * flags: Framebuffer flags (see fblog_flags) -+ * info: Pointer to the associated framebuffer device -+ * font: Currently used font -+ * buf: Console text buffer -+ */ -+struct fblog_fb { -+ unsigned long flags; -+ struct fb_info *info; -+ const struct font_desc *font; -+ struct fblog_buf buf; -+}; -+ -+static struct fblog_fb *fblog_fbs[FB_MAX]; -+ - static void fblog_buf_resize(struct fblog_buf *buf, size_t width, - size_t height) - { -@@ -165,6 +197,82 @@ static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) - } - } - -+static struct fblog_fb *fblog_info2fb(struct fb_info *info) -+{ -+ if (!info || info->node < 0 || info->node >= FB_MAX || -+ !registered_fb[info->node]) -+ return NULL; -+ -+ return fblog_fbs[info->node]; -+} -+ -+static void fblog_register(struct fb_info *info) -+{ -+ struct fblog_fb *fb; -+ struct fb_var_screeninfo var; -+ const struct fb_videomode *mode; -+ unsigned int width, height; -+ -+ if (!info || info->node < 0 || info->node >= FB_MAX) -+ return; -+ if (!registered_fb[info->node] || fblog_fbs[info->node]) -+ return; -+ -+ fb = kzalloc(sizeof(*fb), GFP_KERNEL); -+ if (!fb) -+ return; -+ -+ fblog_fbs[info->node] = fb; -+ fb->info = info; -+ fblog_buf_init(&fb->buf); -+ fblog_buf_write(&fb->buf, FBLOG_STR("Framebuffer log initialized\n")); -+ -+ if (!try_module_get(info->fbops->owner)) -+ goto out_killed; -+ if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) -+ goto out_unref; -+ -+ var = info->var; -+ mode = fb_find_best_mode(&var, &info->modelist); -+ var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; -+ fb_set_var(info, &var); -+ -+ fb->font = get_default_font(info->var.xres, info->var.yres, -+ info->pixmap.blit_x, -+ info->pixmap.blit_y); -+ if (fb->font) { -+ width = info->var.xres / fb->font->width; -+ height = info->var.yres / fb->font->height; -+ fblog_buf_resize(&fb->buf, width, height); -+ } -+ -+ return; -+ -+out_unref: -+ module_put(info->fbops->owner); -+out_killed: -+ set_bit(FBLOG_KILLED, &fb->flags); -+} -+ -+static void fblog_unregister(struct fblog_fb *fb) -+{ -+ struct fb_info *info; -+ -+ if (!fb) -+ return; -+ -+ info = fb->info; -+ if (!test_bit(FBLOG_KILLED, &fb->flags)) { -+ if (info->fbops->fb_release) -+ info->fbops->fb_release(info, 0); -+ module_put(info->fbops->owner); -+ } -+ -+ fblog_buf_deinit(&fb->buf); -+ fblog_fbs[info->node] = NULL; -+ kfree(fb); -+} -+ - static int __init fblog_init(void) - { - return 0; --- -1.7.10.4 - diff --git a/fblog/0004-fblog-implement-fblog_redraw.patch b/fblog/0004-fblog-implement-fblog_redraw.patch deleted file mode 100644 index 9f481631..00000000 --- a/fblog/0004-fblog-implement-fblog_redraw.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 086525bfbf807d8c2792b18d35127c791289d0b8 Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:01:41 +0200 -Subject: [PATCH 04/10] fblog: implement fblog_redraw() - -This mostly copies the functionality from drivers/video/console/bitblit.c -so we can draw the console content on all available framebuffers. - -All speed optimizations have been removed for simplicity. The original -code depends heavily on CONFIG_VT so we cannot share the codebase here. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 126 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 8038dcc..e790971 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -197,6 +197,131 @@ static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) - } - } - -+static void fblog_redraw_aligned(struct fblog_fb *fb, const char *s, u32 cnt, -+ u32 d_pitch, u32 s_pitch, u32 cellsize, -+ struct fb_image *image, u8 *dst) -+{ -+ struct fb_info *info = fb->info; -+ const struct font_desc *font = fb->font; -+ u32 idx = font->width >> 3; -+ u8 *src; -+ -+ while (cnt--) { -+ src = (void*)(font->data + (*s++ & 0xff) * cellsize); -+ fb_pad_aligned_buffer(dst, d_pitch, src, idx, image->height); -+ dst += s_pitch; -+ } -+ -+ info->fbops->fb_imageblit(info, image); -+} -+ -+static void fblog_redraw_unaligned(struct fblog_fb *fb, const char *s, u32 cnt, -+ u32 d_pitch, u32 s_pitch, u32 cellsize, -+ struct fb_image *image, u8 *dst) -+{ -+ struct fb_info *info = fb->info; -+ const struct font_desc *font = fb->font; -+ u32 shift_low = 0, mod = font->width % 8; -+ u32 shift_high = 8; -+ u32 idx = font->width >> 3; -+ u8 *src; -+ -+ while (cnt--) { -+ src = (void*)(font->data + (*s++ & 0xff) * cellsize); -+ fb_pad_unaligned_buffer(dst, d_pitch, src, idx, -+ image->height, shift_high, -+ shift_low, mod); -+ shift_low += mod; -+ dst += (shift_low >= 8) ? s_pitch : s_pitch - 1; -+ shift_low &= 7; -+ shift_high = 8 - shift_low; -+ } -+ -+ info->fbops->fb_imageblit(info, image); -+} -+ -+static void fblog_redraw_line(struct fblog_fb *fb, size_t line, -+ const char *str, size_t len) -+{ -+ struct fb_info *info = fb->info; -+ const struct font_desc *font = fb->font; -+ struct fb_image image; -+ u32 width = DIV_ROUND_UP(font->width, 8); -+ u32 cellsize = width * font->height; -+ u32 maxcnt = info->pixmap.size / cellsize; -+ u32 scan_align = info->pixmap.scan_align - 1; -+ u32 buf_align = info->pixmap.buf_align - 1; -+ u32 mod = font->width % 8; -+ u32 cnt, pitch, size; -+ u8 *dst; -+ -+ image.fg_color = 7; -+ image.bg_color = 0; -+ image.dx = 0; -+ image.dy = line * font->height; -+ image.height = font->height; -+ image.depth = 1; -+ -+ while (len) { -+ if (len > maxcnt) -+ cnt = maxcnt; -+ else -+ cnt = len; -+ -+ image.width = font->width * cnt; -+ pitch = DIV_ROUND_UP(image.width, 8) + scan_align; -+ pitch &= ~scan_align; -+ size = pitch * image.height + buf_align; -+ size &= ~buf_align; -+ dst = fb_get_buffer_offset(info, &info->pixmap, size); -+ image.data = dst; -+ -+ if (!mod) -+ fblog_redraw_aligned(fb, str, cnt, pitch, width, -+ cellsize, &image, dst); -+ else -+ fblog_redraw_unaligned(fb, str, cnt, pitch, width, -+ cellsize, &image, dst); -+ -+ image.dx += cnt * font->width; -+ len -= cnt; -+ str += cnt; -+ } -+} -+ -+static void fblog_redraw_clear(struct fblog_fb *fb) -+{ -+ struct fb_fillrect region; -+ struct fb_info *info = fb->info; -+ -+ region.color = 0; -+ region.dx = 0; -+ region.dy = 0; -+ region.width = info->var.xres; -+ region.height = info->var.yres; -+ region.rop = ROP_COPY; -+ -+ info->fbops->fb_fillrect(info, ®ion); -+} -+ -+static void fblog_redraw(struct fblog_fb *fb) -+{ -+ size_t i, len; -+ -+ if (!fb || !fb->font || test_bit(FBLOG_KILLED, &fb->flags) || -+ test_bit(FBLOG_SUSPENDED, &fb->flags) || -+ test_bit(FBLOG_BLANKED, &fb->flags)) -+ return; -+ -+ fblog_redraw_clear(fb); -+ -+ for (i = 0; i < fb->buf.height; ++i) { -+ len = strnlen(fb->buf.lines[i], fb->buf.width); -+ if (len) -+ fblog_redraw_line(fb, i, fb->buf.lines[i], len); -+ } -+} -+ - static struct fblog_fb *fblog_info2fb(struct fb_info *info) - { - if (!info || info->node < 0 || info->node >= FB_MAX || -@@ -244,6 +369,7 @@ static void fblog_register(struct fb_info *info) - width = info->var.xres / fb->font->width; - height = info->var.yres / fb->font->height; - fblog_buf_resize(&fb->buf, width, height); -+ fblog_redraw(fb); - } - - return; --- -1.7.10.4 - diff --git a/fblog/0005-fblog-add-framebuffer-helpers.patch b/fblog/0005-fblog-add-framebuffer-helpers.patch deleted file mode 100644 index 69aa09e8..00000000 --- a/fblog/0005-fblog-add-framebuffer-helpers.patch +++ /dev/null @@ -1,60 +0,0 @@ -From c0dbeaf1fa932dbae6027a49ddbff973b2689eea Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:04:48 +0200 -Subject: [PATCH 05/10] fblog: add framebuffer helpers - -These helpers scan the system for all available framebuffers and register -or unregister them. This is needed during startup and stopping fblog so we -are aware of all connected displays. - -The third helper handles mode changes by rescanning the mode and adjusting -the buffer size. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index e790971..7d4032e 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -399,6 +399,35 @@ static void fblog_unregister(struct fblog_fb *fb) - kfree(fb); - } - -+static void fblog_register_all(void) -+{ -+ int i; -+ -+ for (i = 0; i < FB_MAX; ++i) -+ fblog_register(registered_fb[i]); -+} -+ -+static void fblog_unregister_all(void) -+{ -+ int i; -+ -+ for (i = 0; i < FB_MAX; ++i) -+ fblog_unregister(fblog_info2fb(registered_fb[i])); -+} -+ -+static void fblog_refresh(struct fblog_fb *fb) -+{ -+ unsigned int width, height; -+ -+ if (!fb || !fb->font) -+ return; -+ -+ width = fb->info->var.xres / fb->font->width; -+ height = fb->info->var.yres / fb->font->height; -+ fblog_buf_resize(&fb->buf, width, height); -+ fblog_redraw(fb); -+} -+ - static int __init fblog_init(void) - { - return 0; --- -1.7.10.4 - diff --git a/fblog/0006-fblog-allow-enabling-disabling-fblog-on-runtime.patch b/fblog/0006-fblog-allow-enabling-disabling-fblog-on-runtime.patch deleted file mode 100644 index 7204c645..00000000 --- a/fblog/0006-fblog-allow-enabling-disabling-fblog-on-runtime.patch +++ /dev/null @@ -1,117 +0,0 @@ -From cab17dccb6026f9f33717db72f528f3b84d7393f Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:07:50 +0200 -Subject: [PATCH 06/10] fblog: allow enabling/disabling fblog on runtime - -A sysfs file called "active" can be used to enable and disable fblog on -runtime. For example, the init-process can run "echo '0' >.../active" -after booting the system. This will allow other applications like X11 to -use the graphics subsystem. During shutdown, we can write '1' to get -system messages again. - -When disabling fblog, we remove all framebuffers and will prevent new -hotplugged framebuffers from being added. When enabling fblog again, we -rescan the system for all framebuffers and resume operating. - -The sysfs file is not registered, yet, as we do not have a "struct device" -yet. This will follow shortly, though. - -Signed-off-by: David Herrmann ---- - Documentation/ABI/testing/sysfs-fblog | 9 ++++++ - drivers/video/console/fblog.c | 49 +++++++++++++++++++++++++++++++++ - 2 files changed, 58 insertions(+) - create mode 100644 Documentation/ABI/testing/sysfs-fblog - -diff --git a/Documentation/ABI/testing/sysfs-fblog b/Documentation/ABI/testing/sysfs-fblog -new file mode 100644 -index 0000000..596393c ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-fblog -@@ -0,0 +1,9 @@ -+What: /sys/class/graphics/fblog/active -+Date: June 2012 -+KernelVersion: 3.6 -+Contact: David Herrmann -+Description: Enable/Disable fblog. When setting this to 0, fblog will stop -+ writing to framebuffers and other applications can use the -+ graphics subsystem. When setting this to 1, fblog will rescan -+ the system for all framebuffers and resume drawing the kernel -+ log onto all framebuffers. -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 7d4032e..9b05c56 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -92,6 +92,7 @@ struct fblog_fb { - }; - - static struct fblog_fb *fblog_fbs[FB_MAX]; -+static atomic_t fblog_active; - - static void fblog_buf_resize(struct fblog_buf *buf, size_t width, - size_t height) -@@ -338,6 +339,8 @@ static void fblog_register(struct fb_info *info) - const struct fb_videomode *mode; - unsigned int width, height; - -+ if (!atomic_read(&fblog_active)) -+ return; - if (!info || info->node < 0 || info->node >= FB_MAX) - return; - if (!registered_fb[info->node] || fblog_fbs[info->node]) -@@ -428,6 +431,52 @@ static void fblog_refresh(struct fblog_fb *fb) - fblog_redraw(fb); - } - -+static void fblog_activate(void) -+{ -+ if (atomic_read(&fblog_active)) -+ return; -+ -+ atomic_set(&fblog_active, 1); -+ fblog_register_all(); -+} -+ -+static void fblog_deactivate(void) -+{ -+ if (!atomic_read(&fblog_active)) -+ return; -+ -+ atomic_set(&fblog_active, 0); -+ fblog_unregister_all(); -+} -+ -+static ssize_t fblog_dev_active_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&fblog_active)); -+} -+ -+static ssize_t fblog_dev_active_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ unsigned long num; -+ -+ num = simple_strtoul(buf, NULL, 10); -+ console_lock(); -+ if (num) -+ fblog_activate(); -+ else -+ fblog_deactivate(); -+ console_unlock(); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(active, S_IRUGO | S_IWUSR | S_IWGRP, fblog_dev_active_show, -+ fblog_dev_active_store); -+ - static int __init fblog_init(void) - { - return 0; --- -1.7.10.4 - diff --git a/fblog/0007-fblog-forward-kernel-log-messages-to-all-framebuffer.patch b/fblog/0007-fblog-forward-kernel-log-messages-to-all-framebuffer.patch deleted file mode 100644 index 75955f19..00000000 --- a/fblog/0007-fblog-forward-kernel-log-messages-to-all-framebuffer.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 942d4ff8f16fcf9d9fdf50d7241a3a8fb4fec39a Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:20:52 +0200 -Subject: [PATCH 07/10] fblog: forward kernel log messages to all framebuffers - -This provides a console-driver that forwards all log messages to all -framebuffers and redraws them. - -To avoid redrawing multiple times in short intervals, we could use a -work-queue here by simply pushing the task onto the system work-queue. -However, fblog is not performance critical and only used for debugging so -we avoid the complexity for now. This may change in the future, though. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 9b05c56..5297eca 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -449,6 +449,25 @@ static void fblog_deactivate(void) - fblog_unregister_all(); - } - -+static void fblog_con_write(struct console *con, const char *buf, -+ unsigned int len) -+{ -+ int i; -+ -+ for (i = 0; i < FB_MAX; ++i) { -+ if (fblog_fbs[i]) { -+ fblog_buf_write(&fblog_fbs[i]->buf, buf, len); -+ fblog_redraw(fblog_fbs[i]); -+ } -+ } -+} -+ -+static struct console fblog_con_driver = { -+ .name = "fblog", -+ .write = fblog_con_write, -+ .flags = CON_PRINTBUFFER | CON_ENABLED, -+}; -+ - static ssize_t fblog_dev_active_show(struct device *dev, - struct device_attribute *attr, - char *buf) --- -1.7.10.4 - diff --git a/fblog/0008-fblog-react-on-framebuffer-events.patch b/fblog/0008-fblog-react-on-framebuffer-events.patch deleted file mode 100644 index 538eb8c4..00000000 --- a/fblog/0008-fblog-react-on-framebuffer-events.patch +++ /dev/null @@ -1,144 +0,0 @@ -From b74b9f619f1c43d75ed7f6637ef2e9d39799e3a1 Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:24:00 +0200 -Subject: [PATCH 08/10] fblog: react on framebuffer events - -This provides an fb-notifier object that can be registered with the -framebuffer subsystem. We are then notified about events on all -framebuffers. -Most of the events are only of interest for fbcon so we can safely ignore -them. However, we need to handle REGISTERED/UNBIND to add new framebbufers -and we need to react on mode-changes (probably triggered by user-space). - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 113 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 113 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 5297eca..79bfbcc 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -449,6 +449,119 @@ static void fblog_deactivate(void) - fblog_unregister_all(); - } - -+static int fblog_event(struct notifier_block *self, unsigned long action, -+ void *data) -+{ -+ struct fb_event *event = data; -+ struct fb_info *info = event->info; -+ struct fblog_fb *fb = fblog_info2fb(info); -+ int *blank; -+ -+ if (action == FB_EVENT_FB_REGISTERED) { -+ /* This is called when a low-level system driver registers a new -+ * framebuffer. The registration lock is held but the console -+ * lock might not be held when this is called (really?). */ -+ fblog_register(info); -+ return 0; -+ } -+ -+ if (!fb) -+ return 0; -+ -+ switch(action) { -+ case FB_EVENT_FB_UNREGISTERED: -+ /* This is called when a low-level system driver unregisters a -+ * framebuffer. The registration lock is held but the console -+ * lock might not be held (really?). */ -+ /* ignore; see UNBIND */ -+ break; -+ case FB_EVENT_FB_UNBIND: -+ /* Called directly before unregistering an FB. The FB is still -+ * valid here and the registration lock is held but the console -+ * lock might not be held (really?). */ -+ fblog_unregister(fb); -+ break; -+ case FB_EVENT_SUSPEND: -+ /* This is called when the low-level display driver suspends the -+ * video system. We should not access the video system while it -+ * is suspended. This is called with the console lock held. */ -+ set_bit(FBLOG_SUSPENDED, &fb->flags); -+ break; -+ case FB_EVENT_RESUME: -+ /* This is called when the low-level display driver resumes -+ * operating. It is called with the console lock held. */ -+ clear_bit(FBLOG_SUSPENDED, &fb->flags); -+ break; -+ case FB_EVENT_MODE_DELETE: -+ /* This is sent when a video mode is removed. The current video -+ * mode is never removed! The console lock is held while this is -+ * called. */ -+ /* fallthrough */ -+ case FB_EVENT_NEW_MODELIST: -+ /* This is sent when the modelist got changed. The console-lock -+ * is held and we should reset the mode. */ -+ /* fallthrough */ -+ case FB_EVENT_MODE_CHANGE_ALL: -+ /* This is the same as below but notifies us that the user used -+ * the FB_ACTIVATE_ALL flag when setting the video mode. */ -+ /* fallthrough */ -+ case FB_EVENT_MODE_CHANGE: -+ /* This is called when the _user_ changes the video mode via -+ * ioctls. It is not sent, when the kernel changes the mode -+ * internally. This callback is called inside fb_set_var() so -+ * the console lock is held. */ -+ fblog_refresh(fb); -+ break; -+ case FB_EVENT_BLANK: -+ /* This gets called _after_ the framebuffer was successfully -+ * blanked. The console-lock is always held while fb_blank is -+ * called and during this callback. */ -+ blank = (int*)event->data; -+ if (*blank == FB_BLANK_UNBLANK) -+ clear_bit(FBLOG_BLANKED, &fb->flags); -+ else -+ set_bit(FBLOG_BLANKED, &fb->flags); -+ break; -+ case FB_EVENT_GET_REQ: -+ /* When fb_set_var() is called, this callback is called to get -+ * our display requirements. They are then compared with the -+ * display properties and only if they fulfill the requirements, -+ * the new mode is activated. The console-lock should be held -+ * while calling fb_set_var() so we can assume it is locked -+ * here. */ -+ /* ignore */ -+ break; -+ case FB_EVENT_CONBLANK: -+ /* This is sent by fbcon when doing a fake blank. That -+ * is, blanking the screen when the fb driver failed to perform -+ * an fb_blank(). It simply writes empty lines to the screen. -+ * We are not interested in this signal. We should also never -+ * run together with fbcon so this should never be caught. */ -+ /* ignore */ -+ break; -+ case FB_EVENT_GET_CONSOLE_MAP: -+ /* fallthrough */ -+ case FB_EVENT_SET_CONSOLE_MAP: -+ /* Is there any reason why we should support this? We -+ * ignore it as we consider ourself not to be the classic linux -+ * console. Hence, this request is not targeted at us. */ -+ /* ignore */ -+ break; -+ case FB_EVENT_REMAP_ALL_CONSOLE: -+ /* What are we supposed to do here? Do we have to remap -+ * the primary device to the framebuffer given by \info? Like -+ * above we currently ignore it for the same reasons. */ -+ /* ignore */ -+ break; -+ } -+ -+ return 0; -+} -+ -+static struct notifier_block fblog_notifier = { -+ .notifier_call = fblog_event, -+}; -+ - static void fblog_con_write(struct console *con, const char *buf, - unsigned int len) - { --- -1.7.10.4 - diff --git a/fblog/0009-fblog-register-all-handlers-on-module-init.patch b/fblog/0009-fblog-register-all-handlers-on-module-init.patch deleted file mode 100644 index 10ac6410..00000000 --- a/fblog/0009-fblog-register-all-handlers-on-module-init.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 1ca9b0e3d8f11b5fd0ce99511b44b8be2c89d3ba Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:28:18 +0200 -Subject: [PATCH 09/10] fblog: register all handlers on module-init - -We now create a new "fblog" device when initializing the fblog module. We -register the "active" sysfs-file with it so user-space can now access -fblog. We also register the framebuffer-notifier and console-handler so -fblog is ready to go. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 59 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 79bfbcc..9d3b072 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -92,6 +92,7 @@ struct fblog_fb { - }; - - static struct fblog_fb *fblog_fbs[FB_MAX]; -+static struct device *fblog_device; - static atomic_t fblog_active; - - static void fblog_buf_resize(struct fblog_buf *buf, size_t width, -@@ -609,13 +610,71 @@ static ssize_t fblog_dev_active_store(struct device *dev, - static DEVICE_ATTR(active, S_IRUGO | S_IWUSR | S_IWGRP, fblog_dev_active_show, - fblog_dev_active_store); - -+static void fblog_dev_release(struct device *dev) -+{ -+ kfree(dev); -+ module_put(THIS_MODULE); -+} -+ - static int __init fblog_init(void) - { -+ int ret; -+ -+ fblog_device = kzalloc(sizeof(*fblog_device), GFP_KERNEL); -+ if (!fblog_device) { -+ pr_err("fblog: cannot allocate device\n"); -+ ret = -ENOMEM; -+ goto err_out; -+ } -+ -+ __module_get(THIS_MODULE); -+ device_initialize(fblog_device); -+ fblog_device->class = fb_class; -+ fblog_device->release = fblog_dev_release; -+ dev_set_name(fblog_device, "fblog"); -+ -+ ret = device_add(fblog_device); -+ if (ret) { -+ pr_err("fblog: cannot add device\n"); -+ goto err_dev; -+ } -+ -+ ret = fb_register_client(&fblog_notifier); -+ if (ret) { -+ pr_err("fblog: cannot register framebuffer notifier\n"); -+ goto err_dev_rm; -+ } -+ -+ ret = device_create_file(fblog_device, &dev_attr_active); -+ if (ret) { -+ pr_err("fblog: cannot create sysfs entry\n"); -+ goto err_fb; -+ } -+ -+ register_console(&fblog_con_driver); -+ - return 0; -+ -+err_fb: -+ fb_unregister_client(&fblog_notifier); -+err_dev_rm: -+ device_del(fblog_device); -+err_dev: -+ put_device(fblog_device); -+err_out: -+ return ret; - } - - static void __exit fblog_exit(void) - { -+ unregister_console(&fblog_con_driver); -+ device_remove_file(fblog_device, &dev_attr_active); -+ device_del(fblog_device); -+ fb_unregister_client(&fblog_notifier); -+ console_lock(); -+ fblog_deactivate(); -+ console_unlock(); -+ put_device(fblog_device); - } - - module_init(fblog_init); --- -1.7.10.4 - diff --git a/fblog/0010-fblog-add-activate-module-parameter.patch b/fblog/0010-fblog-add-activate-module-parameter.patch deleted file mode 100644 index fcdc0c75..00000000 --- a/fblog/0010-fblog-add-activate-module-parameter.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 308643219b3ec4cb8c772459af6330d06d8bda82 Mon Sep 17 00:00:00 2001 -From: David Herrmann -Date: Sat, 16 Jun 2012 23:31:18 +0200 -Subject: [PATCH 10/10] fblog: add "activate" module parameter - -This new parameter controls whether fblog is automatically activated when -it is loaded. This defaults to "true". - -We can now compile with CONFIG_VT=n and CONFIG_FBLOG=y and control fblog -with fblog.activate=0/1 on the kernel command line to enable/disable -debugging. - -Signed-off-by: David Herrmann ---- - drivers/video/console/fblog.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c -index 9d3b072..cabc550 100644 ---- a/drivers/video/console/fblog.c -+++ b/drivers/video/console/fblog.c -@@ -94,6 +94,7 @@ struct fblog_fb { - static struct fblog_fb *fblog_fbs[FB_MAX]; - static struct device *fblog_device; - static atomic_t fblog_active; -+static bool activate = 1; - - static void fblog_buf_resize(struct fblog_buf *buf, size_t width, - size_t height) -@@ -653,6 +654,12 @@ static int __init fblog_init(void) - - register_console(&fblog_con_driver); - -+ if (activate) { -+ console_lock(); -+ fblog_activate(); -+ console_unlock(); -+ } -+ - return 0; - - err_fb: -@@ -677,6 +684,9 @@ static void __exit fblog_exit(void) - put_device(fblog_device); - } - -+module_param(activate, bool, S_IRUGO); -+MODULE_PARM_DESC(activate, "Activate fblog by default"); -+ - module_init(fblog_init); - module_exit(fblog_exit); - MODULE_LICENSE("GPL"); --- -1.7.10.4 - diff --git a/m4/ax_prog_cc_for_build.m4 b/m4/ax_prog_cc_for_build.m4 deleted file mode 100644 index 6369809a..00000000 --- a/m4/ax_prog_cc_for_build.m4 +++ /dev/null @@ -1,125 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PROG_CC_FOR_BUILD -# -# DESCRIPTION -# -# This macro searches for a C compiler that generates native executables, -# that is a C compiler that surely is not a cross-compiler. This can be -# useful if you have to generate source code at compile-time like for -# example GCC does. -# -# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything -# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). -# The value of these variables can be overridden by the user by specifying -# a compiler with an environment variable (like you do for standard CC). -# -# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object -# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if -# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are -# substituted in the Makefile. -# -# LICENSE -# -# Copyright (c) 2008 Paolo Bonzini -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 5 - -AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) -AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_CPP])dnl -AC_REQUIRE([AC_EXEEXT])dnl -AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl - -dnl Use the standard macros, but make them use other variable names -dnl -pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl -pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl -pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl -pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl -pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl -pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl -pushdef([ac_cv_objext], ac_cv_build_objext)dnl -pushdef([ac_exeext], ac_build_exeext)dnl -pushdef([ac_objext], ac_build_objext)dnl -pushdef([CC], CC_FOR_BUILD)dnl -pushdef([CPP], CPP_FOR_BUILD)dnl -pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl -pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl -pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl -pushdef([host], build)dnl -pushdef([host_alias], build_alias)dnl -pushdef([host_cpu], build_cpu)dnl -pushdef([host_vendor], build_vendor)dnl -pushdef([host_os], build_os)dnl -pushdef([ac_cv_host], ac_cv_build)dnl -pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl -pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl -pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl -pushdef([ac_cv_host_os], ac_cv_build_os)dnl -pushdef([ac_cpp], ac_build_cpp)dnl -pushdef([ac_compile], ac_build_compile)dnl -pushdef([ac_link], ac_build_link)dnl - -save_cross_compiling=$cross_compiling -save_ac_tool_prefix=$ac_tool_prefix -cross_compiling=no -ac_tool_prefix= - -AC_PROG_CC -AC_PROG_CPP -AC_EXEEXT - -ac_tool_prefix=$save_ac_tool_prefix -cross_compiling=$save_cross_compiling - -dnl Restore the old definitions -dnl -popdef([ac_link])dnl -popdef([ac_compile])dnl -popdef([ac_cpp])dnl -popdef([ac_cv_host_os])dnl -popdef([ac_cv_host_vendor])dnl -popdef([ac_cv_host_cpu])dnl -popdef([ac_cv_host_alias])dnl -popdef([ac_cv_host])dnl -popdef([host_os])dnl -popdef([host_vendor])dnl -popdef([host_cpu])dnl -popdef([host_alias])dnl -popdef([host])dnl -popdef([LDFLAGS])dnl -popdef([CPPFLAGS])dnl -popdef([CFLAGS])dnl -popdef([CPP])dnl -popdef([CC])dnl -popdef([ac_objext])dnl -popdef([ac_exeext])dnl -popdef([ac_cv_objext])dnl -popdef([ac_cv_exeext])dnl -popdef([ac_cv_prog_cc_g])dnl -popdef([ac_cv_prog_cc_cross])dnl -popdef([ac_cv_prog_cc_works])dnl -popdef([ac_cv_prog_gcc])dnl -popdef([ac_cv_prog_CPP])dnl - -dnl Finally, set Makefile variables -dnl -BUILD_EXEEXT=$ac_build_exeext -BUILD_OBJEXT=$ac_build_objext -AC_SUBST(BUILD_EXEEXT)dnl -AC_SUBST(BUILD_OBJEXT)dnl -AC_SUBST([CFLAGS_FOR_BUILD])dnl -AC_SUBST([CPPFLAGS_FOR_BUILD])dnl -AC_SUBST([LDFLAGS_FOR_BUILD])dnl -]) diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..a4e3c550 --- /dev/null +++ b/meson.build @@ -0,0 +1,189 @@ +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT + +project('kmscon', 'c', + version: '9.0.0', + license: 'MIT', + # meson 0.58: f-string + # meson 0.62: dependency libdl + meson_version: '>=0.62.0', + default_options: [ + 'warning_level=1', + 'werror=true', + 'buildtype=debugoptimized', + 'c_std=gnu99', + ] +) + +add_project_arguments( + '-ffast-math', + '-fno-strict-aliasing', + '-ffunction-sections', + '-fdata-sections', + '-fstack-protector', + '-fvisibility=hidden', + '-D_GNU_SOURCE', + '-D_POSIX_C_SOURCE=200809L', + language: 'c' +) + +# +# Directory structure +# +prefix = get_option('prefix') +bindir = get_option('bindir') +sysconfdir = get_option('sysconfdir') / meson.project_name() +libexecdir = get_option('libexecdir') / meson.project_name() +mandir = get_option('mandir') +moduledir = get_option('libdir') / meson.project_name() + +# +# Required dependencies +# +fs = import('fs') + +xkbcommon_deps = dependency('xkbcommon', version: '>=0.5.0') +libtsm_deps = dependency('libtsm', version: '>=4.0.0') +libudev_deps = dependency('libudev', version: '>=172') +libdrm_deps = dependency('libdrm') +dl_deps = dependency('dl') +threads_deps = dependency('threads') + +python = find_program('python3') + +# +# Dependencies +# These are controlled by feature options. +# When the feature is disabled, the corresponding dependency is not searched, +# instad, a disabler object is produced to disable anything uses it. +# This also allows early reporting when a feature is enabled but its dependencis +# are not found. +# +require_glesv2 = get_option('video_drm3d').enabled() or get_option('renderer_gltex').enabled() +require_libdrm = get_option('video_drm2d').enabled() or get_option('video_drm3d').enabled() + +libsystemd_deps = dependency('libsystemd', disabler: true, required: get_option('multi_seat')) +libdrm_deps = dependency('libdrm', disabler: true, required: require_libdrm) +gbm_deps = dependency('gbm', disabler: true, required: get_option('video_drm3d')) +egl_deps = dependency('egl', disabler: true, required: get_option('video_drm3d')) +glesv2_deps = dependency('glesv2', disabler: true, required: require_glesv2) +pango_deps = dependency('pangoft2', disabler: true, required: get_option('font_pango')) +pixman_deps = dependency('pixman-1', disabler: true, required: get_option('renderer_pixman')) +xsltproc = find_program('xsltproc', native: true, disabler: true, required: get_option('docs')) + +# +# Handle feature options +# This combines feature option inputs with dependency requirements to derive the +# final set of values that will determine what gets built. +# This will also store the information in a configuration header. +# +sections = { + 'video': 'Video Backends', + 'font': 'Font Backends', + 'renderer': 'Renderers', + 'session': 'Session Types', +} +config = configuration_data() +# Note: keep this in sync with the dependencies above +foreach name, reqs : { + 'multi_seat': [libsystemd_deps], + 'video_fbdev': [], + 'video_drm2d': [], + 'video_drm3d': [gbm_deps, egl_deps, glesv2_deps], + 'renderer_bbulk': [], + 'renderer_gltex': [glesv2_deps], + 'renderer_pixman': [pixman_deps], + 'font_unifont': [], + 'font_pango': [pango_deps], + 'session_dummy': [], + 'session_terminal': [], +} + found = true + foreach req : reqs + found = found and req.found() + endforeach + enabled = get_option(name).require(found).allowed() + upper_name = name.to_upper() + # set a variable for later use + set_variable(f'enable_@name@', enabled) + # set in config header for code use + config.set(f'BUILD_ENABLE_@upper_name@', enabled) + # summary output + summary(name, enabled, section: sections.get(name.split('_')[0], 'Miscellaneous')) +endforeach + +config.set('BUILD_ENABLE_DEBUG', get_option('extra_debug')) +config.set_quoted('BUILD_MODULE_DIR', prefix / moduledir) +config.set_quoted('BUILD_CONFIG_DIR', prefix / sysconfdir) + +# Make all files include "config.h" by default. This shouldn't cause any +# problems and we cannot forget to include it anymore. +config_h = configure_file(configuration: config, output: 'config.h') +abs_config_h = meson.current_build_dir() / '@0@'.format(config_h) +add_project_arguments('-include', abs_config_h, language: 'c') + +# +# Miscellaneous checks +# Not directly related to dependencies but +# +manpages_stylesheet = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' +have_manpages_stylesheet = false +if xsltproc.found() + have_manpages_stylesheet = run_command(xsltproc, '--nonet', manpages_stylesheet, check: false).returncode() == 0 +endif +enable_docs = get_option('docs').require(xsltproc.found() and have_manpages_stylesheet).allowed() + +# Additionally check if glesv2 is needed +enable_glesv2 = enable_video_drm3d and enable_renderer_gltex + +# +# Other configuration output +# Show configuration to the user so they can check whether everything was +# configured as expected. +# +summary({ + 'prefix': prefix, + 'libexecdir': libexecdir, + 'bindir': bindir, + 'sysconfdir': sysconfdir, + 'moduledir': moduledir, + 'mandir': mandir, +}, section: 'Directories') +summary({ + 'extra_debug': get_option('extra_debug'), + 'tests': get_option('tests'), + 'docs': enable_docs, +}, section: 'Miscellaneous') + +# +# Putting code together +# +subdir('external') +subdir('src') + +if get_option('tests') + subdir('tests') +endif +if enable_docs + subdir('docs') +endif + +# +# Process other files +# +dirs_info = configuration_data() +dirs_info.set('libexecdir', prefix / libexecdir) +dirs_info.set('bindir', prefix / bindir) +foreach filename, kwargs : { + 'scripts/kmscon.in': { + 'install_dir': bindir, + 'install_mode': 'rwxr-xr-x', + }, + 'docs/kmscon.service.in': {}, + 'docs/kmsconvt@.service.in': {}, +} + install_data(configure_file(input: filename, output: '@BASENAME@', configuration: dirs_info), + kwargs: kwargs, + ) +endforeach diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..35a10ded --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,38 @@ +option('extra_debug', type: 'boolean', value: false, + description: 'Additional non-standard debug options') +option('tests', type: 'boolean', value: true, + description: 'Build unit tests') +option('docs', type: 'feature', value: 'auto', + description: 'Build documentation') + +# multi-seat +option('multi_seat', type: 'feature', value: 'auto', + description: 'Multi-seat support with systemd') + +# video backends +option('video_fbdev', type: 'feature', value: 'auto', + description: 'fbdev video backend') +option('video_drm2d', type: 'feature', value: 'auto', + description: 'drm2d video backend') +option('video_drm3d', type: 'feature', value: 'auto', + description: 'drm3d video backend') + +# renderers +option('renderer_bbulk', type: 'feature', value: 'auto', + description: 'bbulk renderer') +option('renderer_gltex', type: 'feature', value: 'auto', + description: 'gltex renderer') +option('renderer_pixman', type: 'feature', value: 'auto', + description: 'pixman renderer') + +# font backends +option('font_unifont', type: 'feature', value: 'auto', + description: 'unifont font backend') +option('font_pango', type: 'feature', value: 'auto', + description: 'pango font backend') + +# kmscon sessions +option('session_dummy', type: 'feature', value: 'auto', + description: 'dummy session') +option('session_terminal', type: 'feature', value: 'auto', + description: 'terminal session') diff --git a/scripts/kmscon.in b/scripts/kmscon.in index 4be288fd..61594bf8 100755 --- a/scripts/kmscon.in +++ b/scripts/kmscon.in @@ -22,10 +22,7 @@ # SOFTWARE. # configuration path -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libexecdir=@libexecdir@ -helperdir=${libexecdir}/kmscon +helperdir=@libexecdir@ # Get a property from org.freedesktop.locale1 queryLocale1() { diff --git a/src/font_unifont.c b/src/font_unifont.c index 462bdb30..e75a1504 100644 --- a/src/font_unifont.c +++ b/src/font_unifont.c @@ -47,6 +47,7 @@ #include "shl_hashtable.h" #include "shl_log.h" #include "uterm_video.h" +#include "font_unifont_data.bin.h" #define LOG_SUBSYSTEM "font_unifont" @@ -62,10 +63,6 @@ struct unifont_data { uint8_t data[32]; } __attribute__((__packed__)); -extern const char *_binary_src_font_unifont_data_bin_start; -extern const char *_binary_src_font_unifont_data_bin_end; -extern const size_t _binary_src_font_unifont_data_bin_size; - /* * Global glyph cache * The linked binary glyph data cannot be directly passed to the caller as it @@ -137,8 +134,8 @@ static int find_glyph(uint32_t ch, const struct kmscon_glyph **out) goto out_unlock; } - start = (const struct unifont_data*)_binary_src_font_unifont_data_bin_start; - end = (const struct unifont_data*)_binary_src_font_unifont_data_bin_end; + start = (const struct unifont_data*)_binary_font_unifont_data_start; + end = (const struct unifont_data*)_binary_font_unifont_data_end; d = &start[ch]; if (d >= end) { @@ -213,7 +210,7 @@ static int kmscon_font_unifont_init(struct kmscon_font *out, log_debug("loading static unifont font"); - if (_binary_src_font_unifont_data_bin_size == 0) { + if (_binary_font_unifont_data_size == 0) { log_error("unifont glyph information not found in binary"); return -EFAULT; } diff --git a/src/kmscon_conf.c b/src/kmscon_conf.c index bc6ee941..dc328efb 100644 --- a/src/kmscon_conf.c +++ b/src/kmscon_conf.c @@ -65,7 +65,7 @@ static void print_help() "\t-v, --verbose [off] Print verbose messages\n" "\t --debug [off] Enable debug mode\n" "\t --silent [off] Suppress notices and warnings\n" - "\t-c, --configdir [/etc/kmscon]\n" + "\t-c, --configdir [" BUILD_CONFIG_DIR "]\n" "\t Path to config directory\n" "\t --listen [off] Listen for new seats and spawn\n" "\t sessions accordingly (daemon mode)\n" @@ -687,7 +687,7 @@ int kmscon_conf_new(struct conf_ctx **out) CONF_OPTION_BOOL('v', "verbose", &conf->verbose, false), CONF_OPTION_BOOL_FULL(0, "debug", aftercheck_debug, NULL, NULL, &conf->debug, false), CONF_OPTION_BOOL(0, "silent", &conf->silent, false), - CONF_OPTION_STRING('c', "configdir", &conf->configdir, "/etc/kmscon"), + CONF_OPTION_STRING('c', "configdir", &conf->configdir, BUILD_CONFIG_DIR), CONF_OPTION_BOOL_FULL(0, "listen", aftercheck_listen, NULL, NULL, &conf->listen, false), /* Seat Options */ diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..c18759f4 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,264 @@ +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT + +# +# Git-HEAD helper +# +githead = vcs_tag( + input: 'shl_githead.c.in', + output: 'shl_githead.c', + command: ['git', 'describe'], + fallback: 'v' + meson.project_version(), +) + +# +# Binary File Compiler +# +embed_gen = generator(python, + arguments: [ + meson.project_source_root() / 'tools' / 'embedded_file.py', + '@EXTRA_ARGS@', + '@INPUT@', + '@BUILD_DIR@', + ], + output: ['@PLAINNAME@.bin.h', '@PLAINNAME@.bin.c'], +) +shader_regex = [ + '--regex', '^/\\*.*$', '', # Start of multi-line comment + '--regex', '^ \\*.*$', '', # Multi-line comment body + '--regex', '^[ \\t]*', '', # Indentation whitespace + '--regex', '[\\r\\n]', '', # Newlines +] +keymap_regex = [ + '--regex', '\\s*(=,)\\s*', '\\1', # Whitespace around assignments and commas + '--regex', '\\s*([\\]\\[])\\s*', '\\1', # Whitespace around [] + '--regex', '\\s*([{}])\\s*', '\\1', # Whitespace around {} + '--regex', '\\s*([()])\\s*', '\\1', # Whitespace around () + '--regex', '^\\s*', '', # Indentation whitespace + '--regex', '[\\r\\n]', '', # Newlines + '--zero_term', # append an ASCII 0 so it can be used as regular C-string +] + +# +# SHL - Static Helper Library +# The SHL subsystem contains several small code pieces used all over kmscon and +# other applications. +# +shl_srcs = [ + 'shl_log.c', + githead, +] +shl_dep = [ + htable_deps, + xkbcommon_deps +] +if enable_glesv2 + shl_srcs += [ + 'shl_gl_shader.c', + 'shl_gl_math.c', + ] + shl_dep += [ + glesv2_deps + ] +endif + +shl = static_library('shl', shl_srcs, dependencies: shl_dep) +shl_deps = declare_dependency( + link_with: [shl], + include_directories: [include_directories('.')], + dependencies: shl_dep +) + +# +# libeloop +# This library contains the whole event-loop implementation of kmscon. It is +# compiled into a separate object to allow using it in several other programs. +# +eloop = static_library('eloop', 'eloop.c', dependencies: [shl_deps]) +eloop_deps = declare_dependency( + link_with: [eloop], +) + +# +# libuterm +# The uterm library provides helpers to create terminals in user-space. They +# are not limited to text-based terminals but rather provide graphics contexts +# so arbitrary output can be displayed. Additionally, they provide VT +# abstractions and an input layer +# +uterm_srcs = [ + 'uterm_video.c', + 'uterm_monitor.c', + 'uterm_vt.c', + 'uterm_input.c', + 'uterm_input_uxkb.c', + embed_gen.process('uterm_input_fallback.xkb', extra_args: keymap_regex), +] +uterm_dep = [ + libudev_deps, + xkbcommon_deps, + shl_deps, + eloop_deps, +] + +if enable_multi_seat + uterm_srcs += 'uterm_systemd.c' + uterm_dep += libsystemd_deps +endif +if enable_video_fbdev + uterm_srcs += [ + 'uterm_fbdev_video.c', + 'uterm_fbdev_render.c' + ] +endif +if enable_video_drm2d or enable_video_drm3d + uterm_srcs += 'uterm_drm_shared.c' + uterm_dep += libdrm_deps +endif +if enable_video_drm2d + uterm_srcs += [ + 'uterm_drm2d_video.c', + 'uterm_drm2d_render.c' + ] +endif +if enable_video_drm3d + uterm_srcs += [ + 'uterm_drm3d_video.c', + 'uterm_drm3d_render.c', + embed_gen.process('uterm_drm3d_blend.vert', extra_args: shader_regex), + embed_gen.process('uterm_drm3d_blend.frag', extra_args: shader_regex), + embed_gen.process('uterm_drm3d_blit.vert', extra_args: shader_regex), + embed_gen.process('uterm_drm3d_blit.frag', extra_args: shader_regex), + embed_gen.process('uterm_drm3d_fill.vert', extra_args: shader_regex), + embed_gen.process('uterm_drm3d_fill.frag', extra_args: shader_regex), + ] + uterm_dep += [ + egl_deps, + gbm_deps, + glesv2_deps, + ] +endif +uterm = static_library('uterm', uterm_srcs, + dependencies: uterm_dep +) +uterm_deps = declare_dependency( + link_with: [uterm], + dependencies: uterm_dep +) + +# +# Unifont Generator +# This generates the unifont sources from raw hex-encoded font data. +# +genunifont = executable('genunifont', 'genunifont.c', native: true) + +unifont_bin = custom_target('unifont-bin', + input: ['font_unifont_data.hex'], + output: ['font_unifont_data'], + command: [genunifont, '@OUTPUT@', '@INPUT@'] +) + +# +# Kmscon Modules +# +if enable_font_unifont + mod_unifont = shared_module('mod-unifont', [ + 'font_unifont.c', + 'kmscon_mod_unifont.c', + embed_gen.process(unifont_bin), + ], + name_prefix: '', + dependencies: [libtsm_deps, shl_deps], + install: true, + install_dir: moduledir, + ) +endif + +if enable_font_pango + mod_pango = shared_module('mod-pango', [ + 'font_pango.c', + 'kmscon_mod_pango.c', + ], + name_prefix: '', + dependencies: [libtsm_deps, pango_deps, threads_deps, shl_deps], + install: true, + install_dir: moduledir, + ) +endif + +if enable_renderer_bbulk + mod_bbulk = shared_module('mod-bbulk', [ + 'text_bbulk.c', + 'kmscon_mod_bbulk.c', + ], + name_prefix: '', + dependencies: [libtsm_deps, shl_deps], + install: true, + install_dir: moduledir, + ) +endif + +if enable_renderer_gltex + mod_gltex = shared_module('mod-gltex', [ + 'text_gltex.c', + 'kmscon_mod_gltex.c', + embed_gen.process('text_gltex_atlas.vert', extra_args: shader_regex), + embed_gen.process('text_gltex_atlas.frag', extra_args: shader_regex), + ], + name_prefix: '', + dependencies: [libtsm_deps, glesv2_deps, shl_deps], + install: true, + install_dir: moduledir, + ) +endif + +if enable_renderer_pixman + mod_pixman = shared_module('mod-pixman', [ + 'text_pixman.c', + 'kmscon_mod_pixman.c', + ], + name_prefix: '', + dependencies: [pixman_deps, shl_deps], + install: true, + install_dir: moduledir, + ) +endif + +# +# Binaries +# These are the sources for the main binaries and test programs. They mostly +# consists of a single source file only and include all the libraries that are +# built as part of kmscon. +# + +# conf as a standalone library for use in tests +conf = static_library('conf', 'conf.c') +conf_deps = declare_dependency( + link_with: [conf], + include_directories: [include_directories('.')] +) + +kmscon_srcs = [ + 'pty.c', + 'font.c', + 'font_8x16.c', + 'text.c', + 'text_bblit.c', + 'kmscon_module.c', + 'kmscon_seat.c', + 'kmscon_conf.c', + 'kmscon_main.c', +] +if enable_session_dummy + kmscon_srcs += 'kmscon_dummy.c' +endif +if enable_session_terminal + kmscon_srcs += 'kmscon_terminal.c' +endif +kmscon = executable('kmscon', kmscon_srcs, + dependencies: [xkbcommon_deps, libtsm_deps, threads_deps, dl_deps, conf_deps, shl_deps, eloop_deps, uterm_deps], + export_dynamic: true, + install: true, + install_dir: libexecdir, +) diff --git a/src/shl_githead.c.in b/src/shl_githead.c.in new file mode 100644 index 00000000..3b9c4538 --- /dev/null +++ b/src/shl_githead.c.in @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2022 Aetf + * + * SPDX-License-Identifier: MIT + */ + +const char shl_git_head[] = "@VCS_TAG@"; diff --git a/src/shl_hashtable.h b/src/shl_hashtable.h index 20f47733..e6f05a7f 100644 --- a/src/shl_hashtable.h +++ b/src/shl_hashtable.h @@ -36,7 +36,7 @@ #include #include #include -#include "external/htable.h" +#include "htable.h" struct shl_hashtable; diff --git a/src/text_gltex.c b/src/text_gltex.c index c5a328c8..4b132d21 100644 --- a/src/text_gltex.c +++ b/src/text_gltex.c @@ -52,6 +52,8 @@ #include "shl_misc.h" #include "text.h" #include "uterm_video.h" +#include "text_gltex_atlas.frag.bin.h" +#include "text_gltex_atlas.vert.bin.h" #define LOG_SUBSYSTEM "text_gltex" @@ -141,13 +143,6 @@ static void free_glyph(void *data) free(glyph); } -extern const char *_binary_src_text_gltex_atlas_vert_bin_start; -extern const char *_binary_src_text_gltex_atlas_vert_bin_end; -extern const size_t _binary_src_text_gltex_atlas_vert_bin_size; -extern const char *_binary_src_text_gltex_atlas_frag_bin_start; -extern const char *_binary_src_text_gltex_atlas_frag_bin_end; -extern const size_t _binary_src_text_gltex_atlas_frag_bin_size; - static int gltex_set(struct kmscon_text *txt) { struct gltex *gt = txt->data; @@ -180,10 +175,10 @@ static int gltex_set(struct kmscon_text *txt) goto err_bold_htable; } - vert = _binary_src_text_gltex_atlas_vert_bin_start; - vlen = _binary_src_text_gltex_atlas_vert_bin_size; - frag = _binary_src_text_gltex_atlas_frag_bin_start; - flen = _binary_src_text_gltex_atlas_frag_bin_size; + vert = _binary_text_gltex_atlas_vert_start; + vlen = _binary_text_gltex_atlas_vert_size; + frag = _binary_text_gltex_atlas_frag_start; + flen = _binary_text_gltex_atlas_frag_size; gl_clear_error(); ret = gl_shader_new(>->shader, vert, vlen, frag, flen, attr, 4, diff --git a/src/uterm_drm3d_render.c b/src/uterm_drm3d_render.c index 5e8d550c..f113d700 100644 --- a/src/uterm_drm3d_render.c +++ b/src/uterm_drm3d_render.c @@ -51,28 +51,15 @@ #include "uterm_drm3d_internal.h" #include "uterm_video.h" #include "uterm_video_internal.h" +#include "uterm_drm3d_blend.vert.bin.h" +#include "uterm_drm3d_blend.frag.bin.h" +#include "uterm_drm3d_blit.vert.bin.h" +#include "uterm_drm3d_blit.frag.bin.h" +#include "uterm_drm3d_fill.vert.bin.h" +#include "uterm_drm3d_fill.frag.bin.h" #define LOG_SUBSYSTEM "uterm_drm3d_render" -extern const char *_binary_src_uterm_drm3d_blend_vert_bin_start; -extern const char *_binary_src_uterm_drm3d_blend_vert_bin_end; -extern const size_t _binary_src_uterm_drm3d_blend_vert_bin_size; -extern const char *_binary_src_uterm_drm3d_blend_frag_bin_start; -extern const char *_binary_src_uterm_drm3d_blend_frag_bin_end; -extern const size_t _binary_src_uterm_drm3d_blend_frag_bin_size; -extern const char *_binary_src_uterm_drm3d_blit_vert_bin_start; -extern const char *_binary_src_uterm_drm3d_blit_vert_bin_end; -extern const size_t _binary_src_uterm_drm3d_blit_vert_bin_size; -extern const char *_binary_src_uterm_drm3d_blit_frag_bin_start; -extern const char *_binary_src_uterm_drm3d_blit_frag_bin_end; -extern const size_t _binary_src_uterm_drm3d_blit_frag_bin_size; -extern const char *_binary_src_uterm_drm3d_fill_vert_bin_start; -extern const char *_binary_src_uterm_drm3d_fill_vert_bin_end; -extern const size_t _binary_src_uterm_drm3d_fill_vert_bin_size; -extern const char *_binary_src_uterm_drm3d_fill_frag_bin_start; -extern const char *_binary_src_uterm_drm3d_fill_frag_bin_end; -extern const size_t _binary_src_uterm_drm3d_fill_frag_bin_size; - static int init_shaders(struct uterm_video *video) { struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video); @@ -92,18 +79,18 @@ static int init_shaders(struct uterm_video *video) v3d->sinit = 1; - blend_vert = _binary_src_uterm_drm3d_blend_vert_bin_start; - blend_vlen = _binary_src_uterm_drm3d_blend_vert_bin_size; - blend_frag = _binary_src_uterm_drm3d_blend_frag_bin_start; - blend_flen = _binary_src_uterm_drm3d_blend_frag_bin_size; - blit_vert = _binary_src_uterm_drm3d_blit_vert_bin_start; - blit_vlen = _binary_src_uterm_drm3d_blit_vert_bin_size; - blit_frag = _binary_src_uterm_drm3d_blit_frag_bin_start; - blit_flen = _binary_src_uterm_drm3d_blit_frag_bin_size; - fill_vert = _binary_src_uterm_drm3d_fill_vert_bin_start; - fill_vlen = _binary_src_uterm_drm3d_fill_vert_bin_size; - fill_frag = _binary_src_uterm_drm3d_fill_frag_bin_start; - fill_flen = _binary_src_uterm_drm3d_fill_frag_bin_size; + blend_vert = _binary_uterm_drm3d_blend_vert_start; + blend_vlen = _binary_uterm_drm3d_blend_vert_size; + blend_frag = _binary_uterm_drm3d_blend_frag_start; + blend_flen = _binary_uterm_drm3d_blend_frag_size; + blit_vert = _binary_uterm_drm3d_blit_vert_start; + blit_vlen = _binary_uterm_drm3d_blit_vert_size; + blit_frag = _binary_uterm_drm3d_blit_frag_start; + blit_flen = _binary_uterm_drm3d_blit_frag_size; + fill_vert = _binary_uterm_drm3d_fill_vert_start; + fill_vlen = _binary_uterm_drm3d_fill_vert_size; + fill_frag = _binary_uterm_drm3d_fill_frag_start; + fill_flen = _binary_uterm_drm3d_fill_frag_size; ret = gl_shader_new(&v3d->fill_shader, fill_vert, fill_vlen, fill_frag, fill_flen, fill_attr, 2, log_llog, diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c index e1c55c24..1d28a8da 100644 --- a/src/uterm_input_uxkb.c +++ b/src/uterm_input_uxkb.c @@ -38,13 +38,10 @@ #include "shl_misc.h" #include "uterm_input.h" #include "uterm_input_internal.h" +#include "uterm_input_fallback.xkb.bin.h" #define LLOG_SUBSYSTEM "uterm_uxkb" -extern const char *_binary_src_uterm_input_fallback_xkb_bin_start; -extern const char *_binary_src_uterm_input_fallback_xkb_bin_end; -extern const size_t _binary_src_uterm_input_fallback_xkb_bin_size; - static void uxkb_log(struct xkb_context *context, enum xkb_log_level level, const char *format, va_list args) { @@ -102,7 +99,7 @@ int uxkb_desc_init(struct uterm_input *input, }; const char *fallback; - fallback = _binary_src_uterm_input_fallback_xkb_bin_start; + fallback = _binary_uterm_input_fallback_xkb_start; input->ctx = xkb_context_new(0); if (!input->ctx) { diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..2e759a1e --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT + +foreach name, deps : { + 'output': [uterm_deps], + 'vt': [uterm_deps], + 'input': [uterm_deps], + 'key': [], +} + deps += [ + shl_deps, + conf_deps, + xkbcommon_deps, + ] + test_name = f'test_@name@' + exe = executable(test_name, f'@test_name@.c', + dependencies: deps, + ) + test(test_name, exe) +endforeach diff --git a/tools/embedded_file.py b/tools/embedded_file.py new file mode 100755 index 00000000..ee90bb28 --- /dev/null +++ b/tools/embedded_file.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT +import inspect +import re +from pathlib import Path +from typing import List, Tuple +from itertools import islice + + +def chunk(it, size): + it = iter(it) + return iter(lambda: tuple(islice(it, size)), ()) + + +def make_c_identifier(s): + for ptn, repl in [ + (re.compile(r'[^a-zA-Z0-9_]'), '_'), + (re.compile(r'^(\d)'), r'_\1'), + ]: + s = re.sub(ptn, repl, s) + return s + + +def generate( + src: Path, + dest_dir: Path, + regex: List[Tuple[re.Pattern, str]], + zero_term: bool, +): + # prepare + name = src.name + c_name = make_c_identifier(name) + + # read content + if regex: + with src.open() as f: + lines = [] + for line in f: + for ptn, sub in regex: + line = ptn.sub(sub, line) + lines.append(line) + content = '\n'.join(lines).encode('utf-8') + else: + with src.open('rb') as f: + content = f.read() + + if zero_term: + content = content + b'\x00' + + # format content to c array and 16 bytes per row + content_output = ',\n '.join( + ', '.join(f'{b:#04x}' for b in row) + for row in chunk(content, 16) + ) + + content_c = inspect.cleandoc(f''' + #include + static const unsigned char data[] = {{ + {content_output} + }}; + const char *const _binary_{c_name}_start = (const char*)data; + const char *const _binary_{c_name}_end = (const char*)data + sizeof(data); + const size_t _binary_{c_name}_size = sizeof(data); + ''') + content_h = inspect.cleandoc(f''' + #ifndef {c_name}_H + #define {c_name}_H + #include + extern const char *const _binary_{c_name}_start; + extern const char *const _binary_{c_name}_end; + extern size_t _binary_{c_name}_size; + #endif // {c_name}_H + ''') + + # generate the file + with (dest_dir / f'{name}.bin.c').open('w') as f: + f.write(content_c) + with (dest_dir / f'{name}.bin.h').open('w') as f: + f.write(content_h) + dest_dir.mkdir(exist_ok=True, parents=True) + + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument( + '--zero_term', + action='store_true', + help='Add an additional 0 byte at the end of data' + ) + parser.add_argument( + '--regex', metavar=('pattern', 'replace'), + type=str, nargs = 2, action='append', default=[], + help='Treat the binary as text, and for each line replace all occurance matching the regex' + ) + parser.add_argument( + 'src', + type=Path, + help='The source binary file' + ) + parser.add_argument( + 'dest_dir', + type=Path, + help='The destination directory to put output files' + ) + args = parser.parse_args() + + args.regex = [ + (re.compile(ptn), sub) + for ptn, sub in args.regex + ] + generate(args.src, args.dest_dir, args.regex, args.zero_term) + + +if __name__ == '__main__': + main()