├── .gitignore ├── COPYING ├── Makefile.am ├── NEWS ├── README ├── autogen.sh ├── configure.ac ├── docs ├── kmscon.service ├── kmsconvt@.service ├── man │ └── kmscon.xml ├── unicode-test.txt └── vte.txt ├── external ├── htable.c ├── htable.h ├── wcwidth.c └── wcwidth.h ├── fblog ├── 0001-fblog-new-framebuffer-kernel-log-dummy-driver.patch ├── 0002-fblog-implement-buffer-management.patch ├── 0003-fblog-register-framebuffer-objects.patch ├── 0004-fblog-implement-fblog_redraw.patch ├── 0005-fblog-add-framebuffer-helpers.patch ├── 0006-fblog-allow-enabling-disabling-fblog-on-runtime.patch ├── 0007-fblog-forward-kernel-log-messages-to-all-framebuffer.patch ├── 0008-fblog-react-on-framebuffer-events.patch ├── 0009-fblog-register-all-handlers-on-module-init.patch └── 0010-fblog-add-activate-module-parameter.patch ├── m4 └── ax_prog_cc_for_build.m4 ├── src ├── conf.c ├── conf.h ├── eloop.c ├── eloop.h ├── font.c ├── font.h ├── font_8x16.c ├── font_pango.c ├── font_unifont.c ├── font_unifont_data.hex ├── genunifont.c ├── genversion.sh ├── kmscon_conf.c ├── kmscon_conf.h ├── kmscon_dummy.c ├── kmscon_dummy.h ├── kmscon_main.c ├── kmscon_mod_bbulk.c ├── kmscon_mod_gltex.c ├── kmscon_mod_pango.c ├── kmscon_mod_pixman.c ├── kmscon_mod_unifont.c ├── kmscon_module.c ├── kmscon_module.h ├── kmscon_module_interface.h ├── kmscon_seat.c ├── kmscon_seat.h ├── kmscon_terminal.c ├── kmscon_terminal.h ├── pty.c ├── pty.h ├── shl_array.h ├── shl_dlist.h ├── shl_flagset.h ├── shl_githead.h ├── shl_gl.h ├── shl_gl_math.c ├── shl_gl_shader.c ├── shl_hashtable.h ├── shl_hook.h ├── shl_llog.h ├── shl_log.c ├── shl_log.h ├── shl_misc.h ├── shl_register.h ├── shl_ring.h ├── shl_timer.h ├── text.c ├── text.h ├── text_bblit.c ├── text_bbulk.c ├── text_gltex.c ├── text_gltex_atlas.frag ├── text_gltex_atlas.vert ├── text_pixman.c ├── uterm_drm2d_internal.h ├── uterm_drm2d_render.c ├── uterm_drm2d_video.c ├── uterm_drm3d_blend.frag ├── uterm_drm3d_blend.vert ├── uterm_drm3d_blit.frag ├── uterm_drm3d_blit.vert ├── uterm_drm3d_fill.frag ├── uterm_drm3d_fill.vert ├── uterm_drm3d_internal.h ├── uterm_drm3d_render.c ├── uterm_drm3d_video.c ├── uterm_drm_shared.c ├── uterm_drm_shared_internal.h ├── uterm_fbdev_internal.h ├── uterm_fbdev_render.c ├── uterm_fbdev_video.c ├── uterm_input.c ├── uterm_input.h ├── uterm_input_fallback.xkb ├── uterm_input_internal.h ├── uterm_input_uxkb.c ├── uterm_monitor.c ├── uterm_monitor.h ├── uterm_systemd.c ├── uterm_systemd_internal.h ├── uterm_video.c ├── uterm_video.h ├── uterm_video_internal.h ├── uterm_vt.c └── uterm_vt.h └── tests ├── test_include.h ├── test_input.c ├── test_key.c ├── test_output.c └── test_vt.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | *.o 4 | *.lo 5 | *.la 6 | kmscon 7 | /test_* 8 | Makefile 9 | Makefile.in 10 | aclocal.m4 11 | autom4te.cache/ 12 | build-aux/ 13 | config.h 14 | config.h.in 15 | config.h.in~ 16 | config.log 17 | config.status 18 | configure 19 | *.tar.xz 20 | libtool 21 | libeloop.pc 22 | libuterm.pc 23 | m4/ 24 | stamp-* 25 | .deps 26 | .dirstamp 27 | .libs 28 | .man_fixup 29 | genunifont 30 | src/shl_githead.c 31 | src/font_unifont_data.bin 32 | docs/reference/*.txt 33 | docs/reference/*.bak 34 | docs/reference/kmscon.????* 35 | docs/reference/*.stamp 36 | docs/reference/version.xml 37 | docs/reference/*/ 38 | docs/man/*.1 39 | docs/man/*.3 40 | docs/man/*.5 41 | docs/man/*.7 42 | src/*.vert.bin 43 | src/*.frag.bin 44 | src/*.xkb.bin 45 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | = KMSCON = 2 | 3 | Kmscon is a simple terminal emulator based on linux kernel mode setting (KMS). 4 | It is an attempt to replace the in-kernel VT implementation with a userspace 5 | console. See kmscon(1) man-page for usage information. 6 | 7 | Website: 8 | http://www.freedesktop.org/wiki/Software/kmscon 9 | 10 | == Requirements == 11 | 12 | Kmscon requires the following software: 13 | - libtsm: terminal emulator state machine 14 | http://www.freedesktop.org/wiki/Software/kmscon/libtsm/ 15 | - libudev: providing input, video, etc. device hotplug support (>=v172) 16 | http://www.freedesktop.org/wiki/Software/systemd/ 17 | - libxkbcommon: providing internationalized keyboard handling 18 | http://xkbcommon.org/ 19 | - libdrm: graphics access to DRM/KMS subsystem 20 | - linux-headers: linux kernel headers for ABI definitions 21 | 22 | Everything else is optional: 23 | 24 | For video output at least one of the following is required: 25 | - fbdev: For framebuffer video output the kernel headers must be installed 26 | and located in the default include path. 27 | - DRM: For unaccelerated drm output the "libdrm" library must be installed 28 | and accessible via pkg-config. 29 | - OpenGLES2: For accelerated video output via OpenGLESv2 the following must 30 | be installed: libdrm, libgbm, egl, glesv2 (i.e., mesa) 31 | 32 | For font handling the following is required: 33 | - 8x16: The 8x16 font is a static built-in font which does not require 34 | external dependencies. 35 | - unifont: Static font without external dependencies. 36 | - pango: drawing text with pango 37 | Pango requires: glib, pango, fontconfig, freetype2 and more 38 | 39 | For multi-seat support you need the following packages: 40 | - systemd: Actually only the systemd-logind daemon and library is required. 41 | 42 | == Download == 43 | 44 | Released tarballs can be found at: 45 | http://www.freedesktop.org/software/kmscon/releases 46 | 47 | == Install == 48 | 49 | To compile the kmscon binary, run the standard autotools commands: 50 | $ test -f ./configure || NOCONFIGURE=1 ./autogen.sh 51 | $ ./configure 52 | $ make 53 | $ make install 54 | To compile the test applications, run: 55 | $ make check 56 | 57 | If you want only a very basic kmscon program without any major dependencies, 58 | use: 59 | $ ./configure --with-video=fbdev,drm2d --with-renderers= --with-fonts=unifont --disable-multi-seat --with-sessions=dummy,terminal 60 | However, you will loose a lot of functionality by dropping all dependencies. 61 | 62 | The following configure options are available. If build-time dependencies 63 | cannot be satisfied, an option is automatically turned off, except if you 64 | explicitly enable it via command line: 65 | --enable-multi-seat: This requires the systemd-logind library to provide 66 | multi-seat support for kmscon. [default: on] 67 | --enable-debug: Enable debug mode/messages [default: on] 68 | --enable-optimizations: Enable code optimizations [default: on] 69 | 70 | Backends for several subsystems in kmscon can be selected with the following 71 | options (all of them take a comma-separated list of backend names): 72 | --with-video: Video backens. Available backends are: 73 | - fbdev: Linux fbdev video backend 74 | - drm2d: Linux DRM software-rendering backend 75 | - drm3d: Linux DRM hardware-rendering backend 76 | Default is: fbdev,drm2d,drm3d 77 | --with-fonts: Font renderers. Available backends are: 78 | - unifont: Static built-in non-scalable font (Unicode Unifont) 79 | - pango: Pango based scalable font renderer 80 | Default is: unifont,pango 81 | The 8x16 backend is always built-in. 82 | --with-renderers: Console rendering backends. Available are: 83 | - bbulk: Simple 2D software-renderer (bulk-mode) 84 | - gltex: OpenGLESv2 accelerated renderer 85 | - pixman: pixman based renderer 86 | Default is: bbulk,gltex 87 | The bblit backend is always built-in. 88 | --with-sessions: Built in sessions. Available sessions are: 89 | - dummy: Dummy fallback session 90 | - terminal: Terminal-emulator sessions 91 | 92 | == Running == 93 | 94 | To get usage information, run: 95 | $ ./kmscon --help 96 | You can then run kmscon with: 97 | $ ./kmscon [options] 98 | 99 | For debug output use "--debug". For verbose output use "--verbose". 100 | With "--xkb-layout=" you can switch the keyboard layout. 101 | See "man kmscon" / kmscon(1) for more information. 102 | 103 | == License == 104 | 105 | This software is licensed under the terms of an MIT-like license. Please see 106 | ./COPYING for further information. 107 | 108 | == FAQ == 109 | 110 | Please see: http://www.freedesktop.org/wiki/Software/kmscon 111 | 112 | == Contact == 113 | 114 | This software is maintained by: 115 | David Herrmann 116 | If you have any questions, do not hesitate to contact one of the maintainers. 117 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | mkdir -p m4 4 | autoreconf -i 5 | 6 | if test ! "x$NOCONFIGURE" = "x1" ; then 7 | exec ./configure "$@" 8 | fi 9 | -------------------------------------------------------------------------------- /docs/kmscon.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=KMS System Console 3 | Documentation=man:kmscon(1) 4 | 5 | [Service] 6 | ExecStart=/usr/bin/kmscon -l /bin/login 7 | 8 | [Install] 9 | WantedBy=multi-user.target 10 | -------------------------------------------------------------------------------- /docs/kmsconvt@.service: -------------------------------------------------------------------------------- 1 | # 2 | # KMSCON system console on VTs on seat0 3 | # This unit takes as template argument a VT name (same as getty@.service) and 4 | # spawns KMSCON on this VT. Note that this does automatically limit KMSCON to 5 | # seat0. You cannot spawn KMSCON on other seats with this unit. 6 | # 7 | # You can replace the default getty@.service that is shipped with systemd by 8 | # linking it with: 9 | # ln -s /usr/lib/systemd/system/kmsconvt@.service /etc/systemd/system/autovt@.service 10 | # This will make systemd start KMSCON instead of agetty on each VT. Or more 11 | # precisely, this will make systemd-logind use kmsconvt@.service instead of 12 | # getty@.service for new VTs. In fact, all other units/scripts/... that use 13 | # getty@.service will not be affected by this change. 14 | # 15 | # Note that by default getty@.service installs itself as getty@tty1.service. 16 | # This unit does the same and overrules getty@tty1.service via the "Conflict" 17 | # line below. 18 | # 19 | # If KMSCON cannot start for whatever reason, this unit will cause 20 | # getty@.service to be started instead. So you will always have a safe fallback. 21 | # Furthermore, if no VTs are available, this unit will not start anything. 22 | # 23 | # You can still use getty@.service and kmsconvt@.service simultaneously on 24 | # different VTs, but you cannot use both on the same VT (and this wouldn't make 25 | # any sense). 26 | # 27 | 28 | [Unit] 29 | Description=KMS System Console on %I 30 | Documentation=man:kmscon(1) 31 | After=systemd-user-sessions.service 32 | After=plymouth-quit-wait.service 33 | Before=getty.target 34 | Conflicts=getty@%i.service 35 | OnFailure=getty@%i.service 36 | IgnoreOnIsolate=yes 37 | ConditionPathExists=/dev/tty0 38 | 39 | [Service] 40 | ExecStart=/usr/bin/kmscon "--vt=%I" --seats=seat0 --no-switchvt 41 | UtmpIdentifier=%I 42 | TTYPath=/dev/%I 43 | TTYReset=yes 44 | TTYVHangup=yes 45 | TTYVTDisallocate=yes 46 | 47 | [Install] 48 | WantedBy=getty.target 49 | -------------------------------------------------------------------------------- /docs/unicode-test.txt: -------------------------------------------------------------------------------- 1 | This file contains a collection of common unicode symbols encoded in UTF-8. 2 | Displaying this file can be useful to test terminal/font unicode support. 3 | 4 | 什麽是Unicode(統一碼/標準萬國碼)? 5 | 6 | most wanted symbols: "☺", "☻", "✌", "✍", "✎", "✉", "☀", "☃", "☁", "☂", "★", "☆" 7 | , "☮", "☯", "〠", "☎", "☏", "♕", "❏", "☐", "☑", "☒", "✓", "✗", "¢", "€", "£", 8 | "❤", "❣", "❦", "♣", "♤", "♥", "♦", "♧", "►", "❝", "❞", "☜", "☝", "☞", "☟", "☚", 9 | "☛", "☹", "త", "☣", "☠" 10 | 11 | more symbols: "✑", "✒", "÷", "‰", "√", "≠", "∞", "❛", "❜", "™", "©", "®", "✄", 12 | "✁", "✂", "✇", "✿", "❀", "“", "”", "„", "‟", "«", "»", "♪", "♫", "…", "◆", "◇", 13 | "✣", "✪", "✰", "✧", "✦", "☔", "☕", "☼", "☾", "❆", "❅", "❄", "✵", "♲", "♻", "♿", 14 | "⚅", "⚑", "⚐" 15 | 16 | arrows: "←", "↑", "→", "↓", "↔", "↕", "⇄", "⇅", "↲", "↳", "↴", "↵", "↶", "↷", 17 | "↺", "↻", "➔", "➘", "➙", "➚", "➜", "➟", "➠", "➤", "➥", "➨", "➫", "➬", "➭", "➮", 18 | "➯", "➲", "➳", "➵", "➶", "➷", "➸", "➹", "➺", "➻", "➼", "➽", "➾", "◀", "▶", "◁", 19 | "▷", "◊" 20 | 21 | other symbols: "⚒", "⚓", "⚔", "⚕", "⚘", "⚖", "⚛", "⚚", "⚠", "⚡", "♀", "♂", 22 | "⚢", "⚣", "⚤", "⚰", "⚱", "☢", "☤", "✝", "☦", "☧", "☨", "☩", "☪", "☭", "♈", 23 | "♉", "♊", "♋", "♌", "♍", "♎", "♏", "♐", "♑", "♒", "♓", "⌚", "⌛", "⌨", "⏎", "✈", 24 | "♨", "☸", "⚭", "⚮", "⚯" 25 | 26 | mathematical: "∧", "∨", "∀", "∃", "∄", "¬", "∆", "∇", "∈", "∉", "∋", "∌", "∩", 27 | "∪", "⊂", "⊃", "⊄", "⊅", "⊆", "⊇", "∏", "∑", "Ω", "×", "±", "÷", "∅", "∗", "∙", 28 | "∂", "√", "∛", "∜", "∝", "∞", "∁", "∟", "∠", "∡", "∢", "∥", "∦", "⊕", "⊗", "≤", 29 | "≥", "≪", "≫" 30 | 31 | mathematical 2: "∫", "∬", "∭", "∮", "∯", "∰", "∱", "∲", "∳", "∴", "∵", "∻", "∼", 32 | "∽", "∾", "≀", "≁", "≈", "≂", "≃", "≅", "≡", "≢", "≣", "≉", "≊", "≋", "≌", "≍", 33 | "≎", "≏", "≐", "≑", "≒", "≓", "≖", "≗", "≘", "≙", "≚", "≛", "≜", "≝", "≞", "≟", 34 | "≠", "⊧", "⊥" 35 | 36 | mathematical 3: "¹", "²", "³", "⁴", "⁵", "ⁱ", "⁺", "⁻", "⁼", "⁽", "⁾", "ⁿ", "ℕ", 37 | "ℝ", "ℚ", "ℙ", "ℂ", "ℤ", "½", "¼", "¾", "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", 38 | "λ", "μ", "ξ", "ω", "Φ", "Ψ", "⊨", "⊭", "⊻", "⊼", "⊽", "⋅", "⅀", "⌀", "⌈", "⌉", 39 | "⌊", "⌋", "ₓ" 40 | 41 | mixed symbols: "♔", "♕", "♖", "♗", "♘", "♙", "♚", "♛", "♜", "♝", "♞", "♟", "℗", 42 | "♭", "♮", "♯", "♩", "☊", "♒", "☄", "✆", "ꁚ", "ꀪ", "ꀎ", "ꂔ", "℅", "℆", "℀", "℁", 43 | "№", "℮", "✜", "☇", "☈", "☉", "❖", "❶", "❷", "❸", "☘", "⌖", "ℹ", "⚀", "⚁", "⚂", 44 | "⚃", "⚄", "⚅" 45 | 46 | international: "¡", "¿", "Á", "á", "À", "à", "Å", "å", "Ä", "ä", "Æ", "æ", "Ç", 47 | "ç", "É", "é", "È", "è", "Í", "í", "Ì", "ì", "Î", "î", "Ñ", "ñ", "Ó", "ó", "Ò", 48 | "ò", "Ô", "ô", "Ö", "ö", "Ø", "ø", "Ú", "ú", "Ù", "ù", "Ü", "ü", "Ž", "ž", "ß", 49 | "¥", "€", "£" 50 | 51 | "❶", "❷", "❸", "☘" 52 | -------------------------------------------------------------------------------- /docs/vte.txt: -------------------------------------------------------------------------------- 1 | = KMSCON Virtual Terminal Emulator = 2 | 3 | The KMSCON Virtual Terminal Emulator (VTE) tries to be linux-console, xterm and 4 | vt102 compatible. This documentations contains links to several resources 5 | related to VT100-like terminals. 6 | 7 | Resources: 8 | Terminfo database: 9 | man 5 terminfo 10 | man infocmp 11 | infocmp -L xterm-new 12 | Linux Console Codes: 13 | man console_codes 14 | VT100 User Manual: 15 | http://vt100.net/docs/vt100-ug/chapter3.html 16 | VT510 User Manual: 17 | http://vt100.net/docs/vt510-rm/contents 18 | XTerm Escape Sequences: 19 | http://invisible-island.net/xterm/ctlseqs/ctlseqs.html 20 | C0 and C1 Control Codes: 21 | http://en.wikipedia.org/wiki/C0_and_C1_control_codes 22 | ANSI Escape Sequences / Control Sequence Introducer (CSI) 23 | http://en.wikipedia.org/wiki/Control_Sequence_Introducer 24 | vttest Terminal Tests: 25 | http://invisible-island.net/vttest/ 26 | vt100-vt520 docs: 27 | http://vt100.net/ 28 | 29 | Implementations: 30 | XTerm: 31 | http://invisible-island.net/xterm/ 32 | libVTE: 33 | http://developer.gnome.org/vte/unstable/ 34 | Google JavaScript HTerm: 35 | http://git.chromium.org/gitweb/?p=chromiumos/platform/assets.git;a=tree;f=chromeapps/hterm/js;hb=HEAD 36 | Wayland Terminal Widget: 37 | http://cgit.freedesktop.org/wayland/weston/tree/clients/terminal.c 38 | -------------------------------------------------------------------------------- /external/htable.h: -------------------------------------------------------------------------------- 1 | /* Licensed under LGPLv2+ - see LICENSE file for details */ 2 | #ifndef CCAN_HTABLE_H 3 | #define CCAN_HTABLE_H 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * struct htable - private definition of a htable. 10 | * 11 | * It's exposed here so you can put it in your structures and so we can 12 | * supply inline functions. 13 | */ 14 | struct htable { 15 | size_t (*rehash)(const void *elem, void *priv); 16 | void *priv; 17 | unsigned int bits; 18 | size_t elems, deleted, max, max_with_deleted; 19 | /* These are the bits which are the same in all pointers. */ 20 | uintptr_t common_mask, common_bits; 21 | uintptr_t perfect_bit; 22 | uintptr_t *table; 23 | }; 24 | 25 | /** 26 | * HTABLE_INITIALIZER - static initialization for a hash table. 27 | * @name: name of this htable. 28 | * @rehash: hash function to use for rehashing. 29 | * @priv: private argument to @rehash function. 30 | * 31 | * This is useful for setting up static and global hash tables. 32 | * 33 | * Example: 34 | * // For simplicity's sake, say hash value is contents of elem. 35 | * static size_t rehash(const void *elem, void *unused) 36 | * { 37 | * return *(size_t *)elem; 38 | * } 39 | * static struct htable ht = HTABLE_INITIALIZER(ht, rehash, NULL); 40 | */ 41 | #define HTABLE_INITIALIZER(name, rehash, priv) \ 42 | { rehash, priv, 0, 0, 0, 0, 0, -1, 0, 0, &name.perfect_bit } 43 | 44 | /** 45 | * htable_init - initialize an empty hash table. 46 | * @ht: the hash table to initialize 47 | * @rehash: hash function to use for rehashing. 48 | * @priv: private argument to @rehash function. 49 | */ 50 | void htable_init(struct htable *ht, 51 | size_t (*rehash)(const void *elem, void *priv), void *priv); 52 | 53 | /** 54 | * htable_clear - empty a hash table. 55 | * @ht: the hash table to clear 56 | * 57 | * This doesn't do anything to any pointers left in it. 58 | */ 59 | void htable_clear(struct htable *ht); 60 | 61 | /** 62 | * htable_rehash - use a hashtree's rehash function 63 | * @elem: the argument to rehash() 64 | * 65 | */ 66 | size_t htable_rehash(const void *elem); 67 | 68 | /** 69 | * htable_add - add a pointer into a hash table. 70 | * @ht: the htable 71 | * @hash: the hash value of the object 72 | * @p: the non-NULL pointer 73 | * 74 | * Also note that this can only fail due to allocation failure. Otherwise, it 75 | * returns true. 76 | */ 77 | bool htable_add(struct htable *ht, size_t hash, const void *p); 78 | 79 | /** 80 | * htable_del - remove a pointer from a hash table 81 | * @ht: the htable 82 | * @hash: the hash value of the object 83 | * @p: the pointer 84 | * 85 | * Returns true if the pointer was found (and deleted). 86 | */ 87 | bool htable_del(struct htable *ht, size_t hash, const void *p); 88 | 89 | /** 90 | * struct htable_iter - iterator or htable_first or htable_firstval etc. 91 | * 92 | * This refers to a location inside the hashtable. 93 | */ 94 | struct htable_iter { 95 | size_t off; 96 | }; 97 | 98 | /** 99 | * htable_firstval - find a candidate for a given hash value 100 | * @htable: the hashtable 101 | * @i: the struct htable_iter to initialize 102 | * @hash: the hash value 103 | * 104 | * You'll need to check the value is what you want; returns NULL if none. 105 | * See Also: 106 | * htable_delval() 107 | */ 108 | void *htable_firstval(const struct htable *htable, 109 | struct htable_iter *i, size_t hash); 110 | 111 | /** 112 | * htable_nextval - find another candidate for a given hash value 113 | * @htable: the hashtable 114 | * @i: the struct htable_iter to initialize 115 | * @hash: the hash value 116 | * 117 | * You'll need to check the value is what you want; returns NULL if no more. 118 | */ 119 | void *htable_nextval(const struct htable *htable, 120 | struct htable_iter *i, size_t hash); 121 | 122 | /** 123 | * htable_get - find an entry in the hash table 124 | * @ht: the hashtable 125 | * @h: the hash value of the entry 126 | * @cmp: the comparison function 127 | * @ptr: the pointer to hand to the comparison function. 128 | * 129 | * Convenient inline wrapper for htable_firstval/htable_nextval loop. 130 | */ 131 | static inline void *htable_get(const struct htable *ht, 132 | size_t h, 133 | bool (*cmp)(const void *candidate, void *ptr), 134 | const void *ptr) 135 | { 136 | struct htable_iter i; 137 | void *c; 138 | 139 | for (c = htable_firstval(ht,&i,h); c; c = htable_nextval(ht,&i,h)) { 140 | if (cmp(c, (void *)ptr)) 141 | return c; 142 | } 143 | return NULL; 144 | } 145 | 146 | /** 147 | * htable_first - find an entry in the hash table 148 | * @ht: the hashtable 149 | * @i: the struct htable_iter to initialize 150 | * 151 | * Get an entry in the hashtable; NULL if empty. 152 | */ 153 | void *htable_first(const struct htable *htable, struct htable_iter *i); 154 | 155 | /** 156 | * htable_next - find another entry in the hash table 157 | * @ht: the hashtable 158 | * @i: the struct htable_iter to use 159 | * 160 | * Get another entry in the hashtable; NULL if all done. 161 | * This is usually used after htable_first or prior non-NULL htable_next. 162 | */ 163 | void *htable_next(const struct htable *htable, struct htable_iter *i); 164 | 165 | /** 166 | * htable_delval - remove an iterated pointer from a hash table 167 | * @ht: the htable 168 | * @i: the htable_iter 169 | * 170 | * Usually used to delete a hash entry after it has been found with 171 | * htable_firstval etc. 172 | */ 173 | void htable_delval(struct htable *ht, struct htable_iter *i); 174 | 175 | #endif /* CCAN_HTABLE_H */ 176 | -------------------------------------------------------------------------------- /external/wcwidth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an implementation of wcwidth() and wcswidth() (defined in 3 | * IEEE Std 1002.1-2001) for Unicode. 4 | * 5 | * Markus Kuhn -- 2007-05-26 (Unicode 5.0) 6 | * 7 | * Permission to use, copy, modify, and distribute this software 8 | * for any purpose and without fee is hereby granted. The author 9 | * disclaims all warranties with regard to this software. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | int mk_wcwidth(wchar_t ucs); 16 | int mk_wcswidth(const wchar_t *pwcs, size_t n); 17 | int mk_wcwidth_cjk(wchar_t ucs); 18 | int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n); 19 | -------------------------------------------------------------------------------- /fblog/0002-fblog-implement-buffer-management.patch: -------------------------------------------------------------------------------- 1 | From 71d0022376609edba28571ee1ecab3c4ccfcc009 Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 22:49:35 +0200 4 | Subject: [PATCH 02/10] fblog: implement buffer management 5 | 6 | Each available framebuffer can have a different font and buffer size 7 | inside of fblog. Therefore, we need to remember all the log messages that 8 | are currently printed on screen. We save them as an array of lines which 9 | can be rotated and traversed very fast. 10 | 11 | This also implements a very trivial way of resizing the buffer but still 12 | keeping the content. As there is no need to improve this for speed, we can 13 | keep it this way. 14 | 15 | Signed-off-by: David Herrmann 16 | --- 17 | drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++ 18 | 1 file changed, 126 insertions(+) 19 | 20 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 21 | index ea83643..1504ba9 100644 22 | --- a/drivers/video/console/fblog.c 23 | +++ b/drivers/video/console/fblog.c 24 | @@ -39,6 +39,132 @@ 25 | #include 26 | #include 27 | 28 | +/** 29 | + * struct fblog_buf: Console text buffer 30 | + * 31 | + * Each framebuffer has its own text buffer which contains all characters that 32 | + * are currently printed on screen. The buffers might have different sizes and 33 | + * can be resized during runtime. When the buffer content changes, we redraw the 34 | + * screen. 35 | + * 36 | + * width: Width of buffer in characters 37 | + * height: Height of buffer in characters 38 | + * lines: Array of lines 39 | + * pos_x: Cursor x-position 40 | + * pos_y: Cursor y-position 41 | + */ 42 | +struct fblog_buf { 43 | + size_t width; 44 | + size_t height; 45 | + char **lines; 46 | + size_t pos_x; 47 | + size_t pos_y; 48 | +}; 49 | + 50 | +static void fblog_buf_resize(struct fblog_buf *buf, size_t width, 51 | + size_t height) 52 | +{ 53 | + char **lines = NULL; 54 | + size_t i, j, minw, minh; 55 | + 56 | + if (buf->height == height && buf->width == width) 57 | + return; 58 | + 59 | + if (width && height) { 60 | + lines = kzalloc(height * sizeof(char*), GFP_KERNEL); 61 | + if (!lines) 62 | + return; 63 | + 64 | + for (i = 0; i < height; ++i) { 65 | + lines[i] = kzalloc(width * sizeof(char), GFP_KERNEL); 66 | + if (!lines[i]) { 67 | + while (i--) 68 | + kfree(lines[i]); 69 | + return; 70 | + } 71 | + } 72 | + 73 | + /* copy old lines */ 74 | + minw = min(width, buf->width); 75 | + minh = min(height, buf->height); 76 | + if (height >= buf->height) 77 | + i = 0; 78 | + else 79 | + i = buf->height - height; 80 | + 81 | + for (j = 0; j < minh; ++i, ++j) 82 | + memcpy(lines[j], buf->lines[i], minw * sizeof(char)); 83 | + } else { 84 | + width = 0; 85 | + height = 0; 86 | + } 87 | + 88 | + for (i = 0; i < buf->height; ++i) 89 | + kfree(buf->lines[i]); 90 | + kfree(buf->lines); 91 | + 92 | + buf->lines = lines; 93 | + buf->width = width; 94 | + buf->height = height; 95 | +} 96 | + 97 | +static void fblog_buf_init(struct fblog_buf *buf) 98 | +{ 99 | + fblog_buf_resize(buf, 80, 24); 100 | +} 101 | + 102 | +static void fblog_buf_deinit(struct fblog_buf *buf) 103 | +{ 104 | + fblog_buf_resize(buf, 0, 0); 105 | +} 106 | + 107 | +static void fblog_buf_rotate(struct fblog_buf *buf) 108 | +{ 109 | + char *line; 110 | + 111 | + if (!buf->height) 112 | + return; 113 | + 114 | + line = buf->lines[0]; 115 | + memset(line, 0, sizeof(char) * buf->width); 116 | + 117 | + memmove(buf->lines, &buf->lines[1], sizeof(char*) * (buf->height - 1)); 118 | + buf->lines[buf->height - 1] = line; 119 | +} 120 | + 121 | +static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) 122 | +{ 123 | + char c; 124 | + 125 | + if (!buf->height) 126 | + return; 127 | + 128 | + while (len--) { 129 | + c = *str++; 130 | + 131 | + if (c == '\n') { 132 | + buf->pos_x = 0; 133 | + if (++buf->pos_y >= buf->height) { 134 | + buf->pos_y = buf->height - 1; 135 | + fblog_buf_rotate(buf); 136 | + } 137 | + } else if (c == 0) { 138 | + /* ignore */ 139 | + } else { 140 | + if (buf->pos_x >= buf->width) { 141 | + buf->pos_x = 0; 142 | + ++buf->pos_y; 143 | + } 144 | + if (buf->pos_y >= buf->height) { 145 | + buf->pos_y = buf->height - 1; 146 | + fblog_buf_rotate(buf); 147 | + } 148 | + 149 | + buf->lines[buf->pos_y][buf->pos_x++] = c; 150 | + } 151 | + } 152 | +} 153 | + 154 | static int __init fblog_init(void) 155 | { 156 | return 0; 157 | -- 158 | 1.7.10.4 159 | 160 | -------------------------------------------------------------------------------- /fblog/0003-fblog-register-framebuffer-objects.patch: -------------------------------------------------------------------------------- 1 | From cbb97ae4af35277a5478383045a86438f2e97c71 Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 22:56:55 +0200 4 | Subject: [PATCH 03/10] fblog: register framebuffer objects 5 | 6 | We register each available framebuffer in the system with the fblog driver 7 | so we always know all active devices. We directly open the fb-driver, 8 | initialize the buffer and load a font so we are ready for drawing 9 | operations. If a device cannot be opened, we mark it as dead and ignore it 10 | in all other functions. 11 | 12 | Signed-off-by: David Herrmann 13 | --- 14 | drivers/video/console/fblog.c | 108 +++++++++++++++++++++++++++++++++++++++++ 15 | 1 file changed, 108 insertions(+) 16 | 17 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 18 | index 1504ba9..8038dcc 100644 19 | --- a/drivers/video/console/fblog.c 20 | +++ b/drivers/video/console/fblog.c 21 | @@ -39,6 +39,14 @@ 22 | #include 23 | #include 24 | 25 | +#define FBLOG_STR(x) x, sizeof(x) - 1 26 | + 27 | +enum fblog_flags { 28 | + FBLOG_KILLED, 29 | + FBLOG_SUSPENDED, 30 | + FBLOG_BLANKED, 31 | +}; 32 | + 33 | /** 34 | * struct fblog_buf: Console text buffer 35 | * 36 | @@ -61,6 +69,30 @@ struct fblog_buf { 37 | size_t pos_y; 38 | }; 39 | 40 | +/** 41 | + * struct fblog_fb: Framebuffer object 42 | + * 43 | + * For each framebuffer we register this object. It contains all data we need to 44 | + * display the console log on it. The index of a framebuffer in registered_fb[] 45 | + * is the same as in fblog_fbs[]. So the following must always be true if the 46 | + * pointers are non-NULL: 47 | + * registered_fb[idx] == fblog_fbs[idx]->info 48 | + * fblog_fbs[idx]->info->node == idx 49 | + * 50 | + * flags: Framebuffer flags (see fblog_flags) 51 | + * info: Pointer to the associated framebuffer device 52 | + * font: Currently used font 53 | + * buf: Console text buffer 54 | + */ 55 | +struct fblog_fb { 56 | + unsigned long flags; 57 | + struct fb_info *info; 58 | + const struct font_desc *font; 59 | + struct fblog_buf buf; 60 | +}; 61 | + 62 | +static struct fblog_fb *fblog_fbs[FB_MAX]; 63 | + 64 | static void fblog_buf_resize(struct fblog_buf *buf, size_t width, 65 | size_t height) 66 | { 67 | @@ -165,6 +197,82 @@ static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) 68 | } 69 | } 70 | 71 | +static struct fblog_fb *fblog_info2fb(struct fb_info *info) 72 | +{ 73 | + if (!info || info->node < 0 || info->node >= FB_MAX || 74 | + !registered_fb[info->node]) 75 | + return NULL; 76 | + 77 | + return fblog_fbs[info->node]; 78 | +} 79 | + 80 | +static void fblog_register(struct fb_info *info) 81 | +{ 82 | + struct fblog_fb *fb; 83 | + struct fb_var_screeninfo var; 84 | + const struct fb_videomode *mode; 85 | + unsigned int width, height; 86 | + 87 | + if (!info || info->node < 0 || info->node >= FB_MAX) 88 | + return; 89 | + if (!registered_fb[info->node] || fblog_fbs[info->node]) 90 | + return; 91 | + 92 | + fb = kzalloc(sizeof(*fb), GFP_KERNEL); 93 | + if (!fb) 94 | + return; 95 | + 96 | + fblog_fbs[info->node] = fb; 97 | + fb->info = info; 98 | + fblog_buf_init(&fb->buf); 99 | + fblog_buf_write(&fb->buf, FBLOG_STR("Framebuffer log initialized\n")); 100 | + 101 | + if (!try_module_get(info->fbops->owner)) 102 | + goto out_killed; 103 | + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) 104 | + goto out_unref; 105 | + 106 | + var = info->var; 107 | + mode = fb_find_best_mode(&var, &info->modelist); 108 | + var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 109 | + fb_set_var(info, &var); 110 | + 111 | + fb->font = get_default_font(info->var.xres, info->var.yres, 112 | + info->pixmap.blit_x, 113 | + info->pixmap.blit_y); 114 | + if (fb->font) { 115 | + width = info->var.xres / fb->font->width; 116 | + height = info->var.yres / fb->font->height; 117 | + fblog_buf_resize(&fb->buf, width, height); 118 | + } 119 | + 120 | + return; 121 | + 122 | +out_unref: 123 | + module_put(info->fbops->owner); 124 | +out_killed: 125 | + set_bit(FBLOG_KILLED, &fb->flags); 126 | +} 127 | + 128 | +static void fblog_unregister(struct fblog_fb *fb) 129 | +{ 130 | + struct fb_info *info; 131 | + 132 | + if (!fb) 133 | + return; 134 | + 135 | + info = fb->info; 136 | + if (!test_bit(FBLOG_KILLED, &fb->flags)) { 137 | + if (info->fbops->fb_release) 138 | + info->fbops->fb_release(info, 0); 139 | + module_put(info->fbops->owner); 140 | + } 141 | + 142 | + fblog_buf_deinit(&fb->buf); 143 | + fblog_fbs[info->node] = NULL; 144 | + kfree(fb); 145 | +} 146 | + 147 | static int __init fblog_init(void) 148 | { 149 | return 0; 150 | -- 151 | 1.7.10.4 152 | 153 | -------------------------------------------------------------------------------- /fblog/0004-fblog-implement-fblog_redraw.patch: -------------------------------------------------------------------------------- 1 | From 086525bfbf807d8c2792b18d35127c791289d0b8 Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:01:41 +0200 4 | Subject: [PATCH 04/10] fblog: implement fblog_redraw() 5 | 6 | This mostly copies the functionality from drivers/video/console/bitblit.c 7 | so we can draw the console content on all available framebuffers. 8 | 9 | All speed optimizations have been removed for simplicity. The original 10 | code depends heavily on CONFIG_VT so we cannot share the codebase here. 11 | 12 | Signed-off-by: David Herrmann 13 | --- 14 | drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++ 15 | 1 file changed, 126 insertions(+) 16 | 17 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 18 | index 8038dcc..e790971 100644 19 | --- a/drivers/video/console/fblog.c 20 | +++ b/drivers/video/console/fblog.c 21 | @@ -197,6 +197,131 @@ static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) 22 | } 23 | } 24 | 25 | +static void fblog_redraw_aligned(struct fblog_fb *fb, const char *s, u32 cnt, 26 | + u32 d_pitch, u32 s_pitch, u32 cellsize, 27 | + struct fb_image *image, u8 *dst) 28 | +{ 29 | + struct fb_info *info = fb->info; 30 | + const struct font_desc *font = fb->font; 31 | + u32 idx = font->width >> 3; 32 | + u8 *src; 33 | + 34 | + while (cnt--) { 35 | + src = (void*)(font->data + (*s++ & 0xff) * cellsize); 36 | + fb_pad_aligned_buffer(dst, d_pitch, src, idx, image->height); 37 | + dst += s_pitch; 38 | + } 39 | + 40 | + info->fbops->fb_imageblit(info, image); 41 | +} 42 | + 43 | +static void fblog_redraw_unaligned(struct fblog_fb *fb, const char *s, u32 cnt, 44 | + u32 d_pitch, u32 s_pitch, u32 cellsize, 45 | + struct fb_image *image, u8 *dst) 46 | +{ 47 | + struct fb_info *info = fb->info; 48 | + const struct font_desc *font = fb->font; 49 | + u32 shift_low = 0, mod = font->width % 8; 50 | + u32 shift_high = 8; 51 | + u32 idx = font->width >> 3; 52 | + u8 *src; 53 | + 54 | + while (cnt--) { 55 | + src = (void*)(font->data + (*s++ & 0xff) * cellsize); 56 | + fb_pad_unaligned_buffer(dst, d_pitch, src, idx, 57 | + image->height, shift_high, 58 | + shift_low, mod); 59 | + shift_low += mod; 60 | + dst += (shift_low >= 8) ? s_pitch : s_pitch - 1; 61 | + shift_low &= 7; 62 | + shift_high = 8 - shift_low; 63 | + } 64 | + 65 | + info->fbops->fb_imageblit(info, image); 66 | +} 67 | + 68 | +static void fblog_redraw_line(struct fblog_fb *fb, size_t line, 69 | + const char *str, size_t len) 70 | +{ 71 | + struct fb_info *info = fb->info; 72 | + const struct font_desc *font = fb->font; 73 | + struct fb_image image; 74 | + u32 width = DIV_ROUND_UP(font->width, 8); 75 | + u32 cellsize = width * font->height; 76 | + u32 maxcnt = info->pixmap.size / cellsize; 77 | + u32 scan_align = info->pixmap.scan_align - 1; 78 | + u32 buf_align = info->pixmap.buf_align - 1; 79 | + u32 mod = font->width % 8; 80 | + u32 cnt, pitch, size; 81 | + u8 *dst; 82 | + 83 | + image.fg_color = 7; 84 | + image.bg_color = 0; 85 | + image.dx = 0; 86 | + image.dy = line * font->height; 87 | + image.height = font->height; 88 | + image.depth = 1; 89 | + 90 | + while (len) { 91 | + if (len > maxcnt) 92 | + cnt = maxcnt; 93 | + else 94 | + cnt = len; 95 | + 96 | + image.width = font->width * cnt; 97 | + pitch = DIV_ROUND_UP(image.width, 8) + scan_align; 98 | + pitch &= ~scan_align; 99 | + size = pitch * image.height + buf_align; 100 | + size &= ~buf_align; 101 | + dst = fb_get_buffer_offset(info, &info->pixmap, size); 102 | + image.data = dst; 103 | + 104 | + if (!mod) 105 | + fblog_redraw_aligned(fb, str, cnt, pitch, width, 106 | + cellsize, &image, dst); 107 | + else 108 | + fblog_redraw_unaligned(fb, str, cnt, pitch, width, 109 | + cellsize, &image, dst); 110 | + 111 | + image.dx += cnt * font->width; 112 | + len -= cnt; 113 | + str += cnt; 114 | + } 115 | +} 116 | + 117 | +static void fblog_redraw_clear(struct fblog_fb *fb) 118 | +{ 119 | + struct fb_fillrect region; 120 | + struct fb_info *info = fb->info; 121 | + 122 | + region.color = 0; 123 | + region.dx = 0; 124 | + region.dy = 0; 125 | + region.width = info->var.xres; 126 | + region.height = info->var.yres; 127 | + region.rop = ROP_COPY; 128 | + 129 | + info->fbops->fb_fillrect(info, ®ion); 130 | +} 131 | + 132 | +static void fblog_redraw(struct fblog_fb *fb) 133 | +{ 134 | + size_t i, len; 135 | + 136 | + if (!fb || !fb->font || test_bit(FBLOG_KILLED, &fb->flags) || 137 | + test_bit(FBLOG_SUSPENDED, &fb->flags) || 138 | + test_bit(FBLOG_BLANKED, &fb->flags)) 139 | + return; 140 | + 141 | + fblog_redraw_clear(fb); 142 | + 143 | + for (i = 0; i < fb->buf.height; ++i) { 144 | + len = strnlen(fb->buf.lines[i], fb->buf.width); 145 | + if (len) 146 | + fblog_redraw_line(fb, i, fb->buf.lines[i], len); 147 | + } 148 | +} 149 | + 150 | static struct fblog_fb *fblog_info2fb(struct fb_info *info) 151 | { 152 | if (!info || info->node < 0 || info->node >= FB_MAX || 153 | @@ -244,6 +369,7 @@ static void fblog_register(struct fb_info *info) 154 | width = info->var.xres / fb->font->width; 155 | height = info->var.yres / fb->font->height; 156 | fblog_buf_resize(&fb->buf, width, height); 157 | + fblog_redraw(fb); 158 | } 159 | 160 | return; 161 | -- 162 | 1.7.10.4 163 | 164 | -------------------------------------------------------------------------------- /fblog/0005-fblog-add-framebuffer-helpers.patch: -------------------------------------------------------------------------------- 1 | From c0dbeaf1fa932dbae6027a49ddbff973b2689eea Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:04:48 +0200 4 | Subject: [PATCH 05/10] fblog: add framebuffer helpers 5 | 6 | These helpers scan the system for all available framebuffers and register 7 | or unregister them. This is needed during startup and stopping fblog so we 8 | are aware of all connected displays. 9 | 10 | The third helper handles mode changes by rescanning the mode and adjusting 11 | the buffer size. 12 | 13 | Signed-off-by: David Herrmann 14 | --- 15 | drivers/video/console/fblog.c | 29 +++++++++++++++++++++++++++++ 16 | 1 file changed, 29 insertions(+) 17 | 18 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 19 | index e790971..7d4032e 100644 20 | --- a/drivers/video/console/fblog.c 21 | +++ b/drivers/video/console/fblog.c 22 | @@ -399,6 +399,35 @@ static void fblog_unregister(struct fblog_fb *fb) 23 | kfree(fb); 24 | } 25 | 26 | +static void fblog_register_all(void) 27 | +{ 28 | + int i; 29 | + 30 | + for (i = 0; i < FB_MAX; ++i) 31 | + fblog_register(registered_fb[i]); 32 | +} 33 | + 34 | +static void fblog_unregister_all(void) 35 | +{ 36 | + int i; 37 | + 38 | + for (i = 0; i < FB_MAX; ++i) 39 | + fblog_unregister(fblog_info2fb(registered_fb[i])); 40 | +} 41 | + 42 | +static void fblog_refresh(struct fblog_fb *fb) 43 | +{ 44 | + unsigned int width, height; 45 | + 46 | + if (!fb || !fb->font) 47 | + return; 48 | + 49 | + width = fb->info->var.xres / fb->font->width; 50 | + height = fb->info->var.yres / fb->font->height; 51 | + fblog_buf_resize(&fb->buf, width, height); 52 | + fblog_redraw(fb); 53 | +} 54 | + 55 | static int __init fblog_init(void) 56 | { 57 | return 0; 58 | -- 59 | 1.7.10.4 60 | 61 | -------------------------------------------------------------------------------- /fblog/0006-fblog-allow-enabling-disabling-fblog-on-runtime.patch: -------------------------------------------------------------------------------- 1 | From cab17dccb6026f9f33717db72f528f3b84d7393f Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:07:50 +0200 4 | Subject: [PATCH 06/10] fblog: allow enabling/disabling fblog on runtime 5 | 6 | A sysfs file called "active" can be used to enable and disable fblog on 7 | runtime. For example, the init-process can run "echo '0' >.../active" 8 | after booting the system. This will allow other applications like X11 to 9 | use the graphics subsystem. During shutdown, we can write '1' to get 10 | system messages again. 11 | 12 | When disabling fblog, we remove all framebuffers and will prevent new 13 | hotplugged framebuffers from being added. When enabling fblog again, we 14 | rescan the system for all framebuffers and resume operating. 15 | 16 | The sysfs file is not registered, yet, as we do not have a "struct device" 17 | yet. This will follow shortly, though. 18 | 19 | Signed-off-by: David Herrmann 20 | --- 21 | Documentation/ABI/testing/sysfs-fblog | 9 ++++++ 22 | drivers/video/console/fblog.c | 49 +++++++++++++++++++++++++++++++++ 23 | 2 files changed, 58 insertions(+) 24 | create mode 100644 Documentation/ABI/testing/sysfs-fblog 25 | 26 | diff --git a/Documentation/ABI/testing/sysfs-fblog b/Documentation/ABI/testing/sysfs-fblog 27 | new file mode 100644 28 | index 0000000..596393c 29 | --- /dev/null 30 | +++ b/Documentation/ABI/testing/sysfs-fblog 31 | @@ -0,0 +1,9 @@ 32 | +What: /sys/class/graphics/fblog/active 33 | +Date: June 2012 34 | +KernelVersion: 3.6 35 | +Contact: David Herrmann 36 | +Description: Enable/Disable fblog. When setting this to 0, fblog will stop 37 | + writing to framebuffers and other applications can use the 38 | + graphics subsystem. When setting this to 1, fblog will rescan 39 | + the system for all framebuffers and resume drawing the kernel 40 | + log onto all framebuffers. 41 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 42 | index 7d4032e..9b05c56 100644 43 | --- a/drivers/video/console/fblog.c 44 | +++ b/drivers/video/console/fblog.c 45 | @@ -92,6 +92,7 @@ struct fblog_fb { 46 | }; 47 | 48 | static struct fblog_fb *fblog_fbs[FB_MAX]; 49 | +static atomic_t fblog_active; 50 | 51 | static void fblog_buf_resize(struct fblog_buf *buf, size_t width, 52 | size_t height) 53 | @@ -338,6 +339,8 @@ static void fblog_register(struct fb_info *info) 54 | const struct fb_videomode *mode; 55 | unsigned int width, height; 56 | 57 | + if (!atomic_read(&fblog_active)) 58 | + return; 59 | if (!info || info->node < 0 || info->node >= FB_MAX) 60 | return; 61 | if (!registered_fb[info->node] || fblog_fbs[info->node]) 62 | @@ -428,6 +431,52 @@ static void fblog_refresh(struct fblog_fb *fb) 63 | fblog_redraw(fb); 64 | } 65 | 66 | +static void fblog_activate(void) 67 | +{ 68 | + if (atomic_read(&fblog_active)) 69 | + return; 70 | + 71 | + atomic_set(&fblog_active, 1); 72 | + fblog_register_all(); 73 | +} 74 | + 75 | +static void fblog_deactivate(void) 76 | +{ 77 | + if (!atomic_read(&fblog_active)) 78 | + return; 79 | + 80 | + atomic_set(&fblog_active, 0); 81 | + fblog_unregister_all(); 82 | +} 83 | + 84 | +static ssize_t fblog_dev_active_show(struct device *dev, 85 | + struct device_attribute *attr, 86 | + char *buf) 87 | +{ 88 | + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&fblog_active)); 89 | +} 90 | + 91 | +static ssize_t fblog_dev_active_store(struct device *dev, 92 | + struct device_attribute *attr, 93 | + const char *buf, 94 | + size_t count) 95 | +{ 96 | + unsigned long num; 97 | + 98 | + num = simple_strtoul(buf, NULL, 10); 99 | + console_lock(); 100 | + if (num) 101 | + fblog_activate(); 102 | + else 103 | + fblog_deactivate(); 104 | + console_unlock(); 105 | + 106 | + return count; 107 | +} 108 | + 109 | +static DEVICE_ATTR(active, S_IRUGO | S_IWUSR | S_IWGRP, fblog_dev_active_show, 110 | + fblog_dev_active_store); 111 | + 112 | static int __init fblog_init(void) 113 | { 114 | return 0; 115 | -- 116 | 1.7.10.4 117 | 118 | -------------------------------------------------------------------------------- /fblog/0007-fblog-forward-kernel-log-messages-to-all-framebuffer.patch: -------------------------------------------------------------------------------- 1 | From 942d4ff8f16fcf9d9fdf50d7241a3a8fb4fec39a Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:20:52 +0200 4 | Subject: [PATCH 07/10] fblog: forward kernel log messages to all framebuffers 5 | 6 | This provides a console-driver that forwards all log messages to all 7 | framebuffers and redraws them. 8 | 9 | To avoid redrawing multiple times in short intervals, we could use a 10 | work-queue here by simply pushing the task onto the system work-queue. 11 | However, fblog is not performance critical and only used for debugging so 12 | we avoid the complexity for now. This may change in the future, though. 13 | 14 | Signed-off-by: David Herrmann 15 | --- 16 | drivers/video/console/fblog.c | 19 +++++++++++++++++++ 17 | 1 file changed, 19 insertions(+) 18 | 19 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 20 | index 9b05c56..5297eca 100644 21 | --- a/drivers/video/console/fblog.c 22 | +++ b/drivers/video/console/fblog.c 23 | @@ -449,6 +449,25 @@ static void fblog_deactivate(void) 24 | fblog_unregister_all(); 25 | } 26 | 27 | +static void fblog_con_write(struct console *con, const char *buf, 28 | + unsigned int len) 29 | +{ 30 | + int i; 31 | + 32 | + for (i = 0; i < FB_MAX; ++i) { 33 | + if (fblog_fbs[i]) { 34 | + fblog_buf_write(&fblog_fbs[i]->buf, buf, len); 35 | + fblog_redraw(fblog_fbs[i]); 36 | + } 37 | + } 38 | +} 39 | + 40 | +static struct console fblog_con_driver = { 41 | + .name = "fblog", 42 | + .write = fblog_con_write, 43 | + .flags = CON_PRINTBUFFER | CON_ENABLED, 44 | +}; 45 | + 46 | static ssize_t fblog_dev_active_show(struct device *dev, 47 | struct device_attribute *attr, 48 | char *buf) 49 | -- 50 | 1.7.10.4 51 | 52 | -------------------------------------------------------------------------------- /fblog/0008-fblog-react-on-framebuffer-events.patch: -------------------------------------------------------------------------------- 1 | From b74b9f619f1c43d75ed7f6637ef2e9d39799e3a1 Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:24:00 +0200 4 | Subject: [PATCH 08/10] fblog: react on framebuffer events 5 | 6 | This provides an fb-notifier object that can be registered with the 7 | framebuffer subsystem. We are then notified about events on all 8 | framebuffers. 9 | Most of the events are only of interest for fbcon so we can safely ignore 10 | them. However, we need to handle REGISTERED/UNBIND to add new framebbufers 11 | and we need to react on mode-changes (probably triggered by user-space). 12 | 13 | Signed-off-by: David Herrmann 14 | --- 15 | drivers/video/console/fblog.c | 113 +++++++++++++++++++++++++++++++++++++++++ 16 | 1 file changed, 113 insertions(+) 17 | 18 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 19 | index 5297eca..79bfbcc 100644 20 | --- a/drivers/video/console/fblog.c 21 | +++ b/drivers/video/console/fblog.c 22 | @@ -449,6 +449,119 @@ static void fblog_deactivate(void) 23 | fblog_unregister_all(); 24 | } 25 | 26 | +static int fblog_event(struct notifier_block *self, unsigned long action, 27 | + void *data) 28 | +{ 29 | + struct fb_event *event = data; 30 | + struct fb_info *info = event->info; 31 | + struct fblog_fb *fb = fblog_info2fb(info); 32 | + int *blank; 33 | + 34 | + if (action == FB_EVENT_FB_REGISTERED) { 35 | + /* This is called when a low-level system driver registers a new 36 | + * framebuffer. The registration lock is held but the console 37 | + * lock might not be held when this is called (really?). */ 38 | + fblog_register(info); 39 | + return 0; 40 | + } 41 | + 42 | + if (!fb) 43 | + return 0; 44 | + 45 | + switch(action) { 46 | + case FB_EVENT_FB_UNREGISTERED: 47 | + /* This is called when a low-level system driver unregisters a 48 | + * framebuffer. The registration lock is held but the console 49 | + * lock might not be held (really?). */ 50 | + /* ignore; see UNBIND */ 51 | + break; 52 | + case FB_EVENT_FB_UNBIND: 53 | + /* Called directly before unregistering an FB. The FB is still 54 | + * valid here and the registration lock is held but the console 55 | + * lock might not be held (really?). */ 56 | + fblog_unregister(fb); 57 | + break; 58 | + case FB_EVENT_SUSPEND: 59 | + /* This is called when the low-level display driver suspends the 60 | + * video system. We should not access the video system while it 61 | + * is suspended. This is called with the console lock held. */ 62 | + set_bit(FBLOG_SUSPENDED, &fb->flags); 63 | + break; 64 | + case FB_EVENT_RESUME: 65 | + /* This is called when the low-level display driver resumes 66 | + * operating. It is called with the console lock held. */ 67 | + clear_bit(FBLOG_SUSPENDED, &fb->flags); 68 | + break; 69 | + case FB_EVENT_MODE_DELETE: 70 | + /* This is sent when a video mode is removed. The current video 71 | + * mode is never removed! The console lock is held while this is 72 | + * called. */ 73 | + /* fallthrough */ 74 | + case FB_EVENT_NEW_MODELIST: 75 | + /* This is sent when the modelist got changed. The console-lock 76 | + * is held and we should reset the mode. */ 77 | + /* fallthrough */ 78 | + case FB_EVENT_MODE_CHANGE_ALL: 79 | + /* This is the same as below but notifies us that the user used 80 | + * the FB_ACTIVATE_ALL flag when setting the video mode. */ 81 | + /* fallthrough */ 82 | + case FB_EVENT_MODE_CHANGE: 83 | + /* This is called when the _user_ changes the video mode via 84 | + * ioctls. It is not sent, when the kernel changes the mode 85 | + * internally. This callback is called inside fb_set_var() so 86 | + * the console lock is held. */ 87 | + fblog_refresh(fb); 88 | + break; 89 | + case FB_EVENT_BLANK: 90 | + /* This gets called _after_ the framebuffer was successfully 91 | + * blanked. The console-lock is always held while fb_blank is 92 | + * called and during this callback. */ 93 | + blank = (int*)event->data; 94 | + if (*blank == FB_BLANK_UNBLANK) 95 | + clear_bit(FBLOG_BLANKED, &fb->flags); 96 | + else 97 | + set_bit(FBLOG_BLANKED, &fb->flags); 98 | + break; 99 | + case FB_EVENT_GET_REQ: 100 | + /* When fb_set_var() is called, this callback is called to get 101 | + * our display requirements. They are then compared with the 102 | + * display properties and only if they fulfill the requirements, 103 | + * the new mode is activated. The console-lock should be held 104 | + * while calling fb_set_var() so we can assume it is locked 105 | + * here. */ 106 | + /* ignore */ 107 | + break; 108 | + case FB_EVENT_CONBLANK: 109 | + /* This is sent by fbcon when doing a fake blank. That 110 | + * is, blanking the screen when the fb driver failed to perform 111 | + * an fb_blank(). It simply writes empty lines to the screen. 112 | + * We are not interested in this signal. We should also never 113 | + * run together with fbcon so this should never be caught. */ 114 | + /* ignore */ 115 | + break; 116 | + case FB_EVENT_GET_CONSOLE_MAP: 117 | + /* fallthrough */ 118 | + case FB_EVENT_SET_CONSOLE_MAP: 119 | + /* Is there any reason why we should support this? We 120 | + * ignore it as we consider ourself not to be the classic linux 121 | + * console. Hence, this request is not targeted at us. */ 122 | + /* ignore */ 123 | + break; 124 | + case FB_EVENT_REMAP_ALL_CONSOLE: 125 | + /* What are we supposed to do here? Do we have to remap 126 | + * the primary device to the framebuffer given by \info? Like 127 | + * above we currently ignore it for the same reasons. */ 128 | + /* ignore */ 129 | + break; 130 | + } 131 | + 132 | + return 0; 133 | +} 134 | + 135 | +static struct notifier_block fblog_notifier = { 136 | + .notifier_call = fblog_event, 137 | +}; 138 | + 139 | static void fblog_con_write(struct console *con, const char *buf, 140 | unsigned int len) 141 | { 142 | -- 143 | 1.7.10.4 144 | 145 | -------------------------------------------------------------------------------- /fblog/0009-fblog-register-all-handlers-on-module-init.patch: -------------------------------------------------------------------------------- 1 | From 1ca9b0e3d8f11b5fd0ce99511b44b8be2c89d3ba Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:28:18 +0200 4 | Subject: [PATCH 09/10] fblog: register all handlers on module-init 5 | 6 | We now create a new "fblog" device when initializing the fblog module. We 7 | register the "active" sysfs-file with it so user-space can now access 8 | fblog. We also register the framebuffer-notifier and console-handler so 9 | fblog is ready to go. 10 | 11 | Signed-off-by: David Herrmann 12 | --- 13 | drivers/video/console/fblog.c | 59 +++++++++++++++++++++++++++++++++++++++++ 14 | 1 file changed, 59 insertions(+) 15 | 16 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 17 | index 79bfbcc..9d3b072 100644 18 | --- a/drivers/video/console/fblog.c 19 | +++ b/drivers/video/console/fblog.c 20 | @@ -92,6 +92,7 @@ struct fblog_fb { 21 | }; 22 | 23 | static struct fblog_fb *fblog_fbs[FB_MAX]; 24 | +static struct device *fblog_device; 25 | static atomic_t fblog_active; 26 | 27 | static void fblog_buf_resize(struct fblog_buf *buf, size_t width, 28 | @@ -609,13 +610,71 @@ static ssize_t fblog_dev_active_store(struct device *dev, 29 | static DEVICE_ATTR(active, S_IRUGO | S_IWUSR | S_IWGRP, fblog_dev_active_show, 30 | fblog_dev_active_store); 31 | 32 | +static void fblog_dev_release(struct device *dev) 33 | +{ 34 | + kfree(dev); 35 | + module_put(THIS_MODULE); 36 | +} 37 | + 38 | static int __init fblog_init(void) 39 | { 40 | + int ret; 41 | + 42 | + fblog_device = kzalloc(sizeof(*fblog_device), GFP_KERNEL); 43 | + if (!fblog_device) { 44 | + pr_err("fblog: cannot allocate device\n"); 45 | + ret = -ENOMEM; 46 | + goto err_out; 47 | + } 48 | + 49 | + __module_get(THIS_MODULE); 50 | + device_initialize(fblog_device); 51 | + fblog_device->class = fb_class; 52 | + fblog_device->release = fblog_dev_release; 53 | + dev_set_name(fblog_device, "fblog"); 54 | + 55 | + ret = device_add(fblog_device); 56 | + if (ret) { 57 | + pr_err("fblog: cannot add device\n"); 58 | + goto err_dev; 59 | + } 60 | + 61 | + ret = fb_register_client(&fblog_notifier); 62 | + if (ret) { 63 | + pr_err("fblog: cannot register framebuffer notifier\n"); 64 | + goto err_dev_rm; 65 | + } 66 | + 67 | + ret = device_create_file(fblog_device, &dev_attr_active); 68 | + if (ret) { 69 | + pr_err("fblog: cannot create sysfs entry\n"); 70 | + goto err_fb; 71 | + } 72 | + 73 | + register_console(&fblog_con_driver); 74 | + 75 | return 0; 76 | + 77 | +err_fb: 78 | + fb_unregister_client(&fblog_notifier); 79 | +err_dev_rm: 80 | + device_del(fblog_device); 81 | +err_dev: 82 | + put_device(fblog_device); 83 | +err_out: 84 | + return ret; 85 | } 86 | 87 | static void __exit fblog_exit(void) 88 | { 89 | + unregister_console(&fblog_con_driver); 90 | + device_remove_file(fblog_device, &dev_attr_active); 91 | + device_del(fblog_device); 92 | + fb_unregister_client(&fblog_notifier); 93 | + console_lock(); 94 | + fblog_deactivate(); 95 | + console_unlock(); 96 | + put_device(fblog_device); 97 | } 98 | 99 | module_init(fblog_init); 100 | -- 101 | 1.7.10.4 102 | 103 | -------------------------------------------------------------------------------- /fblog/0010-fblog-add-activate-module-parameter.patch: -------------------------------------------------------------------------------- 1 | From 308643219b3ec4cb8c772459af6330d06d8bda82 Mon Sep 17 00:00:00 2001 2 | From: David Herrmann 3 | Date: Sat, 16 Jun 2012 23:31:18 +0200 4 | Subject: [PATCH 10/10] fblog: add "activate" module parameter 5 | 6 | This new parameter controls whether fblog is automatically activated when 7 | it is loaded. This defaults to "true". 8 | 9 | We can now compile with CONFIG_VT=n and CONFIG_FBLOG=y and control fblog 10 | with fblog.activate=0/1 on the kernel command line to enable/disable 11 | debugging. 12 | 13 | Signed-off-by: David Herrmann 14 | --- 15 | drivers/video/console/fblog.c | 10 ++++++++++ 16 | 1 file changed, 10 insertions(+) 17 | 18 | diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c 19 | index 9d3b072..cabc550 100644 20 | --- a/drivers/video/console/fblog.c 21 | +++ b/drivers/video/console/fblog.c 22 | @@ -94,6 +94,7 @@ struct fblog_fb { 23 | static struct fblog_fb *fblog_fbs[FB_MAX]; 24 | static struct device *fblog_device; 25 | static atomic_t fblog_active; 26 | +static bool activate = 1; 27 | 28 | static void fblog_buf_resize(struct fblog_buf *buf, size_t width, 29 | size_t height) 30 | @@ -653,6 +654,12 @@ static int __init fblog_init(void) 31 | 32 | register_console(&fblog_con_driver); 33 | 34 | + if (activate) { 35 | + console_lock(); 36 | + fblog_activate(); 37 | + console_unlock(); 38 | + } 39 | + 40 | return 0; 41 | 42 | err_fb: 43 | @@ -677,6 +684,9 @@ static void __exit fblog_exit(void) 44 | put_device(fblog_device); 45 | } 46 | 47 | +module_param(activate, bool, S_IRUGO); 48 | +MODULE_PARM_DESC(activate, "Activate fblog by default"); 49 | + 50 | module_init(fblog_init); 51 | module_exit(fblog_exit); 52 | MODULE_LICENSE("GPL"); 53 | -- 54 | 1.7.10.4 55 | 56 | -------------------------------------------------------------------------------- /m4/ax_prog_cc_for_build.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_PROG_CC_FOR_BUILD 8 | # 9 | # DESCRIPTION 10 | # 11 | # This macro searches for a C compiler that generates native executables, 12 | # that is a C compiler that surely is not a cross-compiler. This can be 13 | # useful if you have to generate source code at compile-time like for 14 | # example GCC does. 15 | # 16 | # The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything 17 | # needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). 18 | # The value of these variables can be overridden by the user by specifying 19 | # a compiler with an environment variable (like you do for standard CC). 20 | # 21 | # It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object 22 | # file extensions for the build platform, and GCC_FOR_BUILD to `yes' if 23 | # the compiler we found is GCC. All these variables but GCC_FOR_BUILD are 24 | # substituted in the Makefile. 25 | # 26 | # LICENSE 27 | # 28 | # Copyright (c) 2008 Paolo Bonzini 29 | # 30 | # Copying and distribution of this file, with or without modification, are 31 | # permitted in any medium without royalty provided the copyright notice 32 | # and this notice are preserved. This file is offered as-is, without any 33 | # warranty. 34 | 35 | #serial 5 36 | 37 | AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) 38 | AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl 39 | AC_REQUIRE([AC_PROG_CC])dnl 40 | AC_REQUIRE([AC_PROG_CPP])dnl 41 | AC_REQUIRE([AC_EXEEXT])dnl 42 | AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl 43 | 44 | dnl Use the standard macros, but make them use other variable names 45 | dnl 46 | pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl 47 | pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl 48 | pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl 49 | pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl 50 | pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl 51 | pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl 52 | pushdef([ac_cv_objext], ac_cv_build_objext)dnl 53 | pushdef([ac_exeext], ac_build_exeext)dnl 54 | pushdef([ac_objext], ac_build_objext)dnl 55 | pushdef([CC], CC_FOR_BUILD)dnl 56 | pushdef([CPP], CPP_FOR_BUILD)dnl 57 | pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl 58 | pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl 59 | pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl 60 | pushdef([host], build)dnl 61 | pushdef([host_alias], build_alias)dnl 62 | pushdef([host_cpu], build_cpu)dnl 63 | pushdef([host_vendor], build_vendor)dnl 64 | pushdef([host_os], build_os)dnl 65 | pushdef([ac_cv_host], ac_cv_build)dnl 66 | pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl 67 | pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl 68 | pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl 69 | pushdef([ac_cv_host_os], ac_cv_build_os)dnl 70 | pushdef([ac_cpp], ac_build_cpp)dnl 71 | pushdef([ac_compile], ac_build_compile)dnl 72 | pushdef([ac_link], ac_build_link)dnl 73 | 74 | save_cross_compiling=$cross_compiling 75 | save_ac_tool_prefix=$ac_tool_prefix 76 | cross_compiling=no 77 | ac_tool_prefix= 78 | 79 | AC_PROG_CC 80 | AC_PROG_CPP 81 | AC_EXEEXT 82 | 83 | ac_tool_prefix=$save_ac_tool_prefix 84 | cross_compiling=$save_cross_compiling 85 | 86 | dnl Restore the old definitions 87 | dnl 88 | popdef([ac_link])dnl 89 | popdef([ac_compile])dnl 90 | popdef([ac_cpp])dnl 91 | popdef([ac_cv_host_os])dnl 92 | popdef([ac_cv_host_vendor])dnl 93 | popdef([ac_cv_host_cpu])dnl 94 | popdef([ac_cv_host_alias])dnl 95 | popdef([ac_cv_host])dnl 96 | popdef([host_os])dnl 97 | popdef([host_vendor])dnl 98 | popdef([host_cpu])dnl 99 | popdef([host_alias])dnl 100 | popdef([host])dnl 101 | popdef([LDFLAGS])dnl 102 | popdef([CPPFLAGS])dnl 103 | popdef([CFLAGS])dnl 104 | popdef([CPP])dnl 105 | popdef([CC])dnl 106 | popdef([ac_objext])dnl 107 | popdef([ac_exeext])dnl 108 | popdef([ac_cv_objext])dnl 109 | popdef([ac_cv_exeext])dnl 110 | popdef([ac_cv_prog_cc_g])dnl 111 | popdef([ac_cv_prog_cc_cross])dnl 112 | popdef([ac_cv_prog_cc_works])dnl 113 | popdef([ac_cv_prog_gcc])dnl 114 | popdef([ac_cv_prog_CPP])dnl 115 | 116 | dnl Finally, set Makefile variables 117 | dnl 118 | BUILD_EXEEXT=$ac_build_exeext 119 | BUILD_OBJEXT=$ac_build_objext 120 | AC_SUBST(BUILD_EXEEXT)dnl 121 | AC_SUBST(BUILD_OBJEXT)dnl 122 | AC_SUBST([CFLAGS_FOR_BUILD])dnl 123 | AC_SUBST([CPPFLAGS_FOR_BUILD])dnl 124 | AC_SUBST([LDFLAGS_FOR_BUILD])dnl 125 | ]) 126 | -------------------------------------------------------------------------------- /src/font.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Font Renderer 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Font Renderer 28 | */ 29 | 30 | #ifndef KMSCON_FONT_H 31 | #define KMSCON_FONT_H 32 | 33 | #include 34 | #include 35 | #include "kmscon_module.h" 36 | #include "uterm_video.h" 37 | 38 | /* fonts */ 39 | 40 | struct kmscon_font_attr; 41 | struct kmscon_glyph; 42 | struct kmscon_font; 43 | struct kmscon_font_ops; 44 | 45 | #define KMSCON_FONT_MAX_NAME 128 46 | #define KMSCON_FONT_DEFAULT_NAME "monospace" 47 | #define KMSCON_FONT_DEFAULT_PPI 72 48 | 49 | struct kmscon_font_attr { 50 | char name[KMSCON_FONT_MAX_NAME]; 51 | unsigned int ppi; 52 | unsigned int points; 53 | bool bold; 54 | bool italic; 55 | unsigned int height; 56 | unsigned int width; 57 | }; 58 | 59 | void kmscon_font_attr_normalize(struct kmscon_font_attr *attr); 60 | bool kmscon_font_attr_match(const struct kmscon_font_attr *a1, 61 | const struct kmscon_font_attr *a2); 62 | 63 | struct kmscon_glyph { 64 | struct uterm_video_buffer buf; 65 | unsigned int width; 66 | void *data; 67 | }; 68 | 69 | struct kmscon_font { 70 | unsigned long ref; 71 | struct shl_register_record *record; 72 | const struct kmscon_font_ops *ops; 73 | struct kmscon_font_attr attr; 74 | unsigned int baseline; 75 | void *data; 76 | }; 77 | 78 | struct kmscon_font_ops { 79 | const char *name; 80 | struct kmscon_module *owner; 81 | int (*init) (struct kmscon_font *out, 82 | const struct kmscon_font_attr *attr); 83 | void (*destroy) (struct kmscon_font *font); 84 | int (*render) (struct kmscon_font *font, 85 | uint32_t id, const uint32_t *ch, size_t len, 86 | const struct kmscon_glyph **out); 87 | int (*render_empty) (struct kmscon_font *font, 88 | const struct kmscon_glyph **out); 89 | int (*render_inval) (struct kmscon_font *font, 90 | const struct kmscon_glyph **out); 91 | }; 92 | 93 | int kmscon_font_register(const struct kmscon_font_ops *ops); 94 | void kmscon_font_unregister(const char *name); 95 | 96 | int kmscon_font_find(struct kmscon_font **out, 97 | const struct kmscon_font_attr *attr, 98 | const char *backend); 99 | void kmscon_font_ref(struct kmscon_font *font); 100 | void kmscon_font_unref(struct kmscon_font *font); 101 | 102 | int kmscon_font_render(struct kmscon_font *font, 103 | uint32_t id, const uint32_t *ch, size_t len, 104 | const struct kmscon_glyph **out); 105 | int kmscon_font_render_empty(struct kmscon_font *font, 106 | const struct kmscon_glyph **out); 107 | int kmscon_font_render_inval(struct kmscon_font *font, 108 | const struct kmscon_glyph **out); 109 | 110 | /* modularized backends */ 111 | 112 | extern struct kmscon_font_ops kmscon_font_8x16_ops; 113 | extern struct kmscon_font_ops kmscon_font_unifont_ops; 114 | extern struct kmscon_font_ops kmscon_font_pango_ops; 115 | 116 | #endif /* KMSCON_FONT_H */ 117 | -------------------------------------------------------------------------------- /src/genversion.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Generate $1 with: 5 | # const char shl_git_head[] = ""; 6 | # But do not touch $1 if the git-revision is already up-to-date. 7 | # 8 | 9 | if test "x$1" = "x" ; then 10 | echo "usage: ./genversion " 11 | exit 1 12 | fi 13 | 14 | # 15 | # Check whether this is a valid git repository. 16 | # Set ISGIT to 1=true or 0=false. 17 | # 18 | 19 | ISGIT=0 20 | REV=`git rev-parse --git-dir 2>/dev/null` 21 | if test "x$?" = "x0" ; then 22 | ISGIT=1 23 | fi 24 | 25 | # 26 | # Check the old revision from $1. 27 | # 28 | 29 | if test -f "$1" ; then 30 | OLDREV=`cat "$1"` 31 | else 32 | if test $ISGIT = 0 ; then 33 | echo "WARNING: version file $1 is missing" 34 | echo "const char shl_git_head[] = \"UnknownRevision\";" >"$1" 35 | exit 0 36 | fi 37 | 38 | OLDREV="" 39 | fi 40 | 41 | # 42 | # Check new revision from "git describe". However, if this is no valid 43 | # git-repository, return success and do nothing. 44 | # 45 | 46 | if test $ISGIT = 0 ; then 47 | exit 0 48 | fi 49 | 50 | NEWREV=`git describe` 51 | NEWREV="const char shl_git_head[] = \"$NEWREV\";" 52 | 53 | # 54 | # Exit if the file is already up to date. 55 | # Otherwise, write the new revision into the file. 56 | # 57 | 58 | if test "x$OLDREV" = "x$NEWREV" ; then 59 | exit 0 60 | fi 61 | 62 | echo "$NEWREV" >"$1" 63 | -------------------------------------------------------------------------------- /src/kmscon_conf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Main App 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * This includes global data for the whole kmscon application. For instance, 28 | * global parameters can be accessed via this header. 29 | */ 30 | 31 | #ifndef KMSCON_MAIN_H 32 | #define KMSCON_MAIN_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include "conf.h" 38 | #include "shl_dlist.h" 39 | 40 | enum kmscon_conf_gpu_selection { 41 | KMSCON_GPU_ALL, 42 | KMSCON_GPU_AUX, 43 | KMSCON_GPU_PRIMARY, 44 | }; 45 | 46 | struct kmscon_conf_t { 47 | /* header information */ 48 | bool seat_config; 49 | 50 | /* General Options */ 51 | /* show help/usage information */ 52 | bool help; 53 | /* exit application after parsing options */ 54 | bool exit; 55 | /* enable verbose info messages */ 56 | bool verbose; 57 | /* enable debug messages */ 58 | bool debug; 59 | /* disable notices and warnings */ 60 | bool silent; 61 | /* config directory name */ 62 | char *configdir; 63 | /* listen mode */ 64 | bool listen; 65 | 66 | /* Seat Options */ 67 | /* VT number to run on */ 68 | char *vt; 69 | /* enter new VT directly */ 70 | bool switchvt; 71 | /* seats */ 72 | char **seats; 73 | 74 | /* Session Options */ 75 | /* sessions */ 76 | unsigned int session_max; 77 | /* allow keyboard session control */ 78 | bool session_control; 79 | /* run terminal session */ 80 | bool terminal_session; 81 | 82 | /* Terminal Options */ 83 | /* custom login process */ 84 | bool login; 85 | /* argv for login process */ 86 | char **argv; 87 | /* TERM value */ 88 | char *term; 89 | /* reset environment */ 90 | bool reset_env; 91 | /* color palette */ 92 | char *palette; 93 | /* terminal scroll-back buffer size */ 94 | unsigned int sb_size; 95 | 96 | /* Input Options */ 97 | /* input KBD model */ 98 | char *xkb_model; 99 | /* input KBD layout */ 100 | char *xkb_layout; 101 | /* input KBD variant */ 102 | char *xkb_variant; 103 | /* input KBD options */ 104 | char *xkb_options; 105 | /* input predefined KBD keymap */ 106 | char *xkb_keymap; 107 | /* keyboard key-repeat delay */ 108 | unsigned int xkb_repeat_delay; 109 | /* keyboard key-repeat rate */ 110 | unsigned int xkb_repeat_rate; 111 | 112 | /* Grabs / Keyboard-Shortcuts */ 113 | /* scroll-up grab */ 114 | struct conf_grab *grab_scroll_up; 115 | /* scroll-down grab */ 116 | struct conf_grab *grab_scroll_down; 117 | /* page-up grab */ 118 | struct conf_grab *grab_page_up; 119 | /* page-down grab */ 120 | struct conf_grab *grab_page_down; 121 | /* zoom-in grab */ 122 | struct conf_grab *grab_zoom_in; 123 | /* zoom-out grab */ 124 | struct conf_grab *grab_zoom_out; 125 | /* session-next grab */ 126 | struct conf_grab *grab_session_next; 127 | /* session-prev grab */ 128 | struct conf_grab *grab_session_prev; 129 | /* session-dummy grab */ 130 | struct conf_grab *grab_session_dummy; 131 | /* session-close grab */ 132 | struct conf_grab *grab_session_close; 133 | /* terminal-new grab */ 134 | struct conf_grab *grab_terminal_new; 135 | 136 | /* Video Options */ 137 | /* use DRM if available */ 138 | bool drm; 139 | /* use 3D hardware-acceleration if available */ 140 | bool hwaccel; 141 | /* gpu selection mode */ 142 | unsigned int gpus; 143 | /* render engine */ 144 | char *render_engine; 145 | 146 | /* Font Options */ 147 | /* font engine */ 148 | char *font_engine; 149 | /* font size */ 150 | unsigned int font_size; 151 | /* font name */ 152 | char *font_name; 153 | /* font ppi (overrides per monitor PPI) */ 154 | unsigned int font_ppi; 155 | }; 156 | 157 | int kmscon_conf_new(struct conf_ctx **out); 158 | void kmscon_conf_free(struct conf_ctx *ctx); 159 | int kmscon_conf_load_main(struct conf_ctx *ctx, int argc, char **argv); 160 | int kmscon_conf_load_seat(struct conf_ctx *ctx, const struct conf_ctx *main, 161 | const char *seat); 162 | 163 | static inline bool kmscon_conf_is_current_seat(struct kmscon_conf_t *conf) 164 | { 165 | return conf && shl_string_list_is(conf->seats, "current"); 166 | } 167 | 168 | static inline bool kmscon_conf_is_all_seats(struct kmscon_conf_t *conf) 169 | { 170 | return conf && shl_string_list_is(conf->seats, "all"); 171 | } 172 | 173 | static inline bool kmscon_conf_is_single_seat(struct kmscon_conf_t *conf) 174 | { 175 | return conf && !kmscon_conf_is_all_seats(conf) && 176 | shl_string_list_count(conf->seats, true) == 1; 177 | } 178 | 179 | #endif /* KMSCON_MAIN_H */ 180 | -------------------------------------------------------------------------------- /src/kmscon_dummy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Dummy Session 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Dummy Session 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include "kmscon_dummy.h" 34 | #include "kmscon_seat.h" 35 | #include "shl_dlist.h" 36 | #include "shl_log.h" 37 | 38 | #define LOG_SUBSYSTEM "dummy" 39 | 40 | struct display { 41 | struct shl_dlist list; 42 | struct uterm_display *disp; 43 | }; 44 | 45 | struct kmscon_dummy { 46 | struct kmscon_session *session; 47 | struct shl_dlist displays; 48 | bool active; 49 | }; 50 | 51 | static void dummy_redraw(struct kmscon_dummy *dummy, struct display *d) 52 | { 53 | struct uterm_mode *mode; 54 | unsigned int w, h; 55 | 56 | mode = uterm_display_get_current(d->disp); 57 | w = uterm_mode_get_width(mode); 58 | h = uterm_mode_get_height(mode); 59 | 60 | uterm_display_fill(d->disp, 0, 0, 0, 0, 0, w, h); 61 | uterm_display_swap(d->disp, false); 62 | } 63 | 64 | static int dummy_session_event(struct kmscon_session *session, 65 | struct kmscon_session_event *ev, void *data) 66 | { 67 | struct kmscon_dummy *dummy = data; 68 | struct display *d; 69 | struct shl_dlist *iter; 70 | 71 | switch (ev->type) { 72 | case KMSCON_SESSION_DISPLAY_NEW: 73 | d = malloc(sizeof(*d)); 74 | if (!d) { 75 | log_error("cannot allocate memory for new display"); 76 | break; 77 | } 78 | memset(d, 0, sizeof(*d)); 79 | d->disp = ev->disp; 80 | shl_dlist_link_tail(&dummy->displays, &d->list); 81 | if (dummy->active) 82 | dummy_redraw(dummy, d); 83 | break; 84 | case KMSCON_SESSION_DISPLAY_GONE: 85 | shl_dlist_for_each(iter, &dummy->displays) { 86 | d = shl_dlist_entry(iter, struct display, list); 87 | if (d->disp != ev->disp) 88 | continue; 89 | 90 | shl_dlist_unlink(&d->list); 91 | free(d); 92 | break; 93 | } 94 | break; 95 | case KMSCON_SESSION_DISPLAY_REFRESH: 96 | shl_dlist_for_each(iter, &dummy->displays) { 97 | d = shl_dlist_entry(iter, struct display, list); 98 | if (d->disp != ev->disp) 99 | continue; 100 | 101 | if (dummy->active) 102 | dummy_redraw(dummy, d); 103 | break; 104 | } 105 | break; 106 | case KMSCON_SESSION_ACTIVATE: 107 | dummy->active = true; 108 | shl_dlist_for_each(iter, &dummy->displays) { 109 | d = shl_dlist_entry(iter, struct display, list); 110 | dummy_redraw(dummy, d); 111 | } 112 | break; 113 | case KMSCON_SESSION_DEACTIVATE: 114 | dummy->active = false; 115 | break; 116 | case KMSCON_SESSION_UNREGISTER: 117 | while (!shl_dlist_empty(&dummy->displays)) { 118 | d = shl_dlist_entry(dummy->displays.prev, 119 | struct display, list); 120 | shl_dlist_unlink(&d->list); 121 | free(d); 122 | } 123 | 124 | free(dummy); 125 | break; 126 | } 127 | 128 | return 0; 129 | } 130 | 131 | int kmscon_dummy_register(struct kmscon_session **out, 132 | struct kmscon_seat *seat) 133 | { 134 | struct kmscon_dummy *dummy; 135 | int ret; 136 | 137 | if (!out || !seat) 138 | return -EINVAL; 139 | 140 | dummy = malloc(sizeof(*dummy)); 141 | if (!dummy) 142 | return -ENOMEM; 143 | memset(dummy, 0, sizeof(*dummy)); 144 | shl_dlist_init(&dummy->displays); 145 | 146 | ret = kmscon_seat_register_session(seat, &dummy->session, 147 | dummy_session_event, dummy); 148 | if (ret) { 149 | log_error("cannot register session for dummy: %d", ret); 150 | goto err_free; 151 | } 152 | 153 | *out = dummy->session; 154 | log_debug("new dummy object %p", dummy); 155 | return 0; 156 | 157 | err_free: 158 | free(dummy); 159 | return ret; 160 | } 161 | -------------------------------------------------------------------------------- /src/kmscon_dummy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Dummy Session 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Dummy Session 28 | */ 29 | 30 | #ifndef KMSCON_DUMMY_H 31 | #define KMSCON_DUMMY_H 32 | 33 | #include 34 | #include 35 | #include "kmscon_seat.h" 36 | 37 | #ifdef BUILD_ENABLE_SESSION_DUMMY 38 | 39 | int kmscon_dummy_register(struct kmscon_session **out, 40 | struct kmscon_seat *seat); 41 | 42 | #else /* !BUILD_ENABLE_SESSION_DUMMY */ 43 | 44 | static inline int kmscon_dummy_register(struct kmscon_session **out, 45 | struct kmscon_seat *seat) 46 | { 47 | return -EOPNOTSUPP; 48 | } 49 | 50 | #endif /* BUILD_ENABLE_SESSION_DUMMY */ 51 | 52 | #endif /* KMSCON_DUMMY_H */ 53 | -------------------------------------------------------------------------------- /src/kmscon_mod_bbulk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - BBulk rendering backend module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * BBulk rendering backend module 28 | * This module provides the bbulk renderer backend. 29 | */ 30 | 31 | #include 32 | #include 33 | #include "text.h" 34 | #include "kmscon_module_interface.h" 35 | #include "shl_log.h" 36 | 37 | #define LOG_SUBSYSTEM "mod_bbulk" 38 | 39 | static int kmscon_bbulk_load(void) 40 | { 41 | int ret; 42 | 43 | kmscon_text_bbulk_ops.owner = KMSCON_THIS_MODULE; 44 | ret = kmscon_text_register(&kmscon_text_bbulk_ops); 45 | if (ret) { 46 | log_error("cannot register bbulk renderer"); 47 | return ret; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | static void kmscon_bbulk_unload(void) 54 | { 55 | kmscon_text_unregister(kmscon_text_bbulk_ops.name); 56 | } 57 | 58 | KMSCON_MODULE(NULL, kmscon_bbulk_load, kmscon_bbulk_unload, NULL); 59 | -------------------------------------------------------------------------------- /src/kmscon_mod_gltex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - OpenGL Texture based rendering backend module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * OpenGL Texture based rendering backend module 28 | * This module provides the gltex renderer backend. 29 | */ 30 | 31 | #include 32 | #include 33 | #include "text.h" 34 | #include "kmscon_module_interface.h" 35 | #include "shl_log.h" 36 | 37 | #define LOG_SUBSYSTEM "mod_gltex" 38 | 39 | static int kmscon_gltex_load(void) 40 | { 41 | int ret; 42 | 43 | kmscon_text_gltex_ops.owner = KMSCON_THIS_MODULE; 44 | ret = kmscon_text_register(&kmscon_text_gltex_ops); 45 | if (ret) { 46 | log_error("cannot register gltex renderer"); 47 | return ret; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | static void kmscon_gltex_unload(void) 54 | { 55 | kmscon_text_unregister(kmscon_text_gltex_ops.name); 56 | } 57 | 58 | KMSCON_MODULE(NULL, kmscon_gltex_load, kmscon_gltex_unload, NULL); 59 | -------------------------------------------------------------------------------- /src/kmscon_mod_pango.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Pango font backend module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Pango font backend module 28 | * This module registers the text-font pango backend with kmscon. 29 | */ 30 | 31 | #include 32 | #include 33 | #include "font.h" 34 | #include "kmscon_module_interface.h" 35 | #include "shl_log.h" 36 | 37 | #define LOG_SUBSYSTEM "mod_pango" 38 | 39 | static int kmscon_pango_load(void) 40 | { 41 | int ret; 42 | 43 | kmscon_font_pango_ops.owner = KMSCON_THIS_MODULE; 44 | ret = kmscon_font_register(&kmscon_font_pango_ops); 45 | if (ret) { 46 | log_error("cannot register pango font"); 47 | return ret; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | static void kmscon_pango_unload(void) 54 | { 55 | kmscon_font_unregister(kmscon_font_pango_ops.name); 56 | } 57 | 58 | KMSCON_MODULE(NULL, kmscon_pango_load, kmscon_pango_unload, NULL); 59 | -------------------------------------------------------------------------------- /src/kmscon_mod_pixman.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Pixman based rendering backend module 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Pixman based rendering backend 28 | */ 29 | 30 | #include 31 | #include 32 | #include "text.h" 33 | #include "kmscon_module_interface.h" 34 | #include "shl_log.h" 35 | 36 | #define LOG_SUBSYSTEM "mod_pixman" 37 | 38 | static int kmscon_pixman_load(void) 39 | { 40 | int ret; 41 | 42 | kmscon_text_pixman_ops.owner = KMSCON_THIS_MODULE; 43 | ret = kmscon_text_register(&kmscon_text_pixman_ops); 44 | if (ret) { 45 | log_error("cannot register pixman renderer"); 46 | return ret; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | static void kmscon_pixman_unload(void) 53 | { 54 | kmscon_text_unregister(kmscon_text_pixman_ops.name); 55 | } 56 | 57 | KMSCON_MODULE(NULL, kmscon_pixman_load, kmscon_pixman_unload, NULL); 58 | -------------------------------------------------------------------------------- /src/kmscon_mod_unifont.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Unifont font backend module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Unifont font backend module 28 | * This module registers the unifont font backend with kmscon. 29 | */ 30 | 31 | #include 32 | #include 33 | #include "font.h" 34 | #include "kmscon_module_interface.h" 35 | #include "shl_log.h" 36 | 37 | #define LOG_SUBSYSTEM "mod_unifont" 38 | 39 | static int kmscon_unifont_load(void) 40 | { 41 | int ret; 42 | 43 | kmscon_font_unifont_ops.owner = KMSCON_THIS_MODULE; 44 | ret = kmscon_font_register(&kmscon_font_unifont_ops); 45 | if (ret) { 46 | log_error("cannot register pango font"); 47 | return ret; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | static void kmscon_unifont_unload(void) 54 | { 55 | kmscon_font_unregister(kmscon_font_unifont_ops.name); 56 | } 57 | 58 | KMSCON_MODULE(NULL, kmscon_unifont_load, kmscon_unifont_unload, NULL); 59 | -------------------------------------------------------------------------------- /src/kmscon_module.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Module handling 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Module Handling 28 | * Several subsystems of kmscon provide a generic interface that is implemented 29 | * by different backends. The user can choose a backend that is then used. 30 | * To make out-of-tree development easier and, more importantly, to reduce the 31 | * direct dependencies to external libraries, this subsystem implements a 32 | * dynamically-loadable module system. 33 | * 34 | * Modules can be loaded and unloaded during runtime. A module basically 35 | * provides memory-storage for code. As long as any code of a module is still 36 | * used (that is, registered as callback) we must not unload the module. 37 | * Therefore, we use reference-counting to allow other subsystems to acquire and 38 | * release code sections. 39 | * 40 | * A module needs to provide "module_init". Everything else is optional. 41 | * "module_init" is called after the module has been loaded and should 42 | * initialize the module. "module_exit" is called after the module has been 43 | * unloaded and the last reference to the module has been dropped. Therefore, it 44 | * is safe to release all allocated resources in "module_exit". 45 | * 46 | * "module_load" is called after "module_init". A module should register its 47 | * resources here. "module_unload" is called when the module is scheduled for 48 | * removal. A module should unregister its resources here. However, it must not 49 | * release the resources as there might still be users of it. Only when 50 | * "module_exit" is called, kmscon guarantees that there are no more users and 51 | * the module can release its resources. 52 | */ 53 | 54 | #ifndef KMSCON_MODULE_H 55 | #define KMSCON_MODULE_H 56 | 57 | #include 58 | 59 | struct kmscon_module; 60 | 61 | int kmscon_module_open(struct kmscon_module **out, const char *file); 62 | void kmscon_module_ref(struct kmscon_module *module); 63 | void kmscon_module_unref(struct kmscon_module *module); 64 | 65 | int kmscon_module_load(struct kmscon_module *module); 66 | void kmscon_module_unload(struct kmscon_module *module); 67 | 68 | void kmscon_load_modules(void); 69 | void kmscon_unload_modules(void); 70 | 71 | #endif /* KMSCON_MODULE_H */ 72 | -------------------------------------------------------------------------------- /src/kmscon_module_interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Module Interface 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Public Module Interface 28 | */ 29 | 30 | #ifndef KMSCON_MODULE_INTERFACE_H 31 | #define KMSCON_MODULE_INTERFACE_H 32 | 33 | #include 34 | #include 35 | #include "kmscon_module.h" 36 | #include "shl_dlist.h" 37 | #include "shl_githead.h" 38 | #include "shl_misc.h" 39 | 40 | struct kmscon_module_info { 41 | const char *githead; 42 | const char *date; 43 | const char *time; 44 | int (*init) (void); 45 | int (*load) (void); 46 | void (*unload) (void); 47 | void (*exit) (void); 48 | }; 49 | 50 | struct kmscon_module { 51 | struct kmscon_module_info info; 52 | struct shl_dlist list; 53 | unsigned long ref; 54 | bool loaded; 55 | void *handle; 56 | char *file; 57 | }; 58 | 59 | #define KMSCON_MODULE(_init, _load, _unload, _exit) \ 60 | struct kmscon_module module = { \ 61 | .info = { \ 62 | .githead = shl_git_head, \ 63 | .date = __DATE__, \ 64 | .time = __TIME__, \ 65 | .init = _init, \ 66 | .load = _load, \ 67 | .unload = _unload, \ 68 | .exit = _exit, \ 69 | }, \ 70 | }; 71 | 72 | SHL_EXPORT 73 | extern struct kmscon_module module; 74 | #define KMSCON_THIS_MODULE (&module) 75 | 76 | #endif /* KMSCON_MODULE_INTERFACE_H */ 77 | -------------------------------------------------------------------------------- /src/kmscon_seat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Seats 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Seats 28 | * A seat is a single session that is self-hosting and provides all the 29 | * interaction for a single logged-in user. 30 | */ 31 | 32 | #ifndef KMSCON_SEAT_H 33 | #define KMSCON_SEAT_H 34 | 35 | #include 36 | #include 37 | #include "conf.h" 38 | #include "eloop.h" 39 | #include "uterm_input.h" 40 | #include "uterm_video.h" 41 | #include "uterm_vt.h" 42 | 43 | struct kmscon_seat; 44 | struct kmscon_session; 45 | 46 | enum kmscon_seat_event { 47 | KMSCON_SEAT_WAKE_UP, 48 | KMSCON_SEAT_SLEEP, 49 | KMSCON_SEAT_BACKGROUND, 50 | KMSCON_SEAT_FOREGROUND, 51 | KMSCON_SEAT_HUP, 52 | }; 53 | 54 | typedef int (*kmscon_seat_cb_t) (struct kmscon_seat *seat, 55 | unsigned int event, 56 | void *data); 57 | 58 | enum kmscon_session_event_type { 59 | KMSCON_SESSION_DISPLAY_NEW, 60 | KMSCON_SESSION_DISPLAY_GONE, 61 | KMSCON_SESSION_DISPLAY_REFRESH, 62 | KMSCON_SESSION_ACTIVATE, 63 | KMSCON_SESSION_DEACTIVATE, 64 | KMSCON_SESSION_UNREGISTER, 65 | }; 66 | 67 | struct kmscon_session_event { 68 | unsigned int type; 69 | struct uterm_display *disp; 70 | }; 71 | 72 | typedef int (*kmscon_session_cb_t) (struct kmscon_session *session, 73 | struct kmscon_session_event *event, 74 | void *data); 75 | 76 | int kmscon_seat_new(struct kmscon_seat **out, 77 | struct conf_ctx *main_conf, 78 | struct ev_eloop *eloop, 79 | struct uterm_vt_master *vtm, 80 | unsigned int vt_types, 81 | const char *seatname, 82 | kmscon_seat_cb_t cb, 83 | void *data); 84 | void kmscon_seat_free(struct kmscon_seat *seat); 85 | void kmscon_seat_startup(struct kmscon_seat *seat); 86 | 87 | int kmscon_seat_add_display(struct kmscon_seat *seat, 88 | struct uterm_display *disp); 89 | void kmscon_seat_remove_display(struct kmscon_seat *seat, 90 | struct uterm_display *disp); 91 | void kmscon_seat_refresh_display(struct kmscon_seat *seat, 92 | struct uterm_display *disp); 93 | int kmscon_seat_add_input(struct kmscon_seat *seat, const char *node); 94 | void kmscon_seat_remove_input(struct kmscon_seat *seat, const char *node); 95 | 96 | const char *kmscon_seat_get_name(struct kmscon_seat *seat); 97 | struct uterm_input *kmscon_seat_get_input(struct kmscon_seat *seat); 98 | struct ev_eloop *kmscon_seat_get_eloop(struct kmscon_seat *seat); 99 | struct conf_ctx *kmscon_seat_get_conf(struct kmscon_seat *seat); 100 | 101 | void kmscon_seat_schedule(struct kmscon_seat *seat, unsigned int id); 102 | 103 | int kmscon_seat_register_session(struct kmscon_seat *seat, 104 | struct kmscon_session **out, 105 | kmscon_session_cb_t cb, 106 | void *data); 107 | 108 | void kmscon_session_ref(struct kmscon_session *sess); 109 | void kmscon_session_unref(struct kmscon_session *sess); 110 | void kmscon_session_unregister(struct kmscon_session *sess); 111 | bool kmscon_session_is_registered(struct kmscon_session *sess); 112 | 113 | bool kmscon_session_is_active(struct kmscon_session *sess); 114 | int kmscon_session_set_foreground(struct kmscon_session *sess); 115 | int kmscon_session_set_background(struct kmscon_session *sess); 116 | void kmscon_session_schedule(struct kmscon_session *sess); 117 | 118 | void kmscon_session_enable(struct kmscon_session *sess); 119 | void kmscon_session_disable(struct kmscon_session *sess); 120 | bool kmscon_session_is_enabled(struct kmscon_session *sess); 121 | 122 | void kmscon_session_notify_deactivated(struct kmscon_session *sess); 123 | 124 | #endif /* KMSCON_SEAT_H */ 125 | -------------------------------------------------------------------------------- /src/kmscon_terminal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Terminal 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Terminal 29 | * This provides the basic terminal object. This ties together the vt emulation 30 | * and the output console. 31 | */ 32 | 33 | #ifndef KMSCON_TERMINAL_H 34 | #define KMSCON_TERMINAL_H 35 | 36 | #include 37 | #include 38 | #include "kmscon_seat.h" 39 | 40 | #ifdef BUILD_ENABLE_SESSION_TERMINAL 41 | 42 | int kmscon_terminal_register(struct kmscon_session **out, 43 | struct kmscon_seat *seat, 44 | unsigned int vtnr); 45 | 46 | #else /* !BUILD_ENABLE_SESSION_TERMINAL */ 47 | 48 | static inline int kmscon_terminal_register(struct kmscon_session **out, 49 | struct kmscon_seat *seat, 50 | unsigned int vtnr) 51 | { 52 | return -EOPNOTSUPP; 53 | } 54 | 55 | #endif /* BUILD_ENABLE_SESSION_TERMINAL */ 56 | 57 | #endif /* KMSCON_TERMINAL_H */ 58 | -------------------------------------------------------------------------------- /src/pty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Pseudo Terminal Handling 3 | * 4 | * Copyright (c) 2012 Ran Benita 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * The pty object provides an interface for communicating with a child process 28 | * over a pseudo terminal. The child is the host, we act as the TTY terminal, 29 | * and the kernel is the driver. 30 | * 31 | * To use this, create a new pty object and open it. You will start receiving 32 | * output notifications through the output_cb callback. To communicate with 33 | * the other end of the terminal, use the kmscon_pty_input method. All 34 | * communication is done using byte streams (presumably UTF-8). 35 | * 36 | * The pty can be closed voluntarily using the kmson_pty_close method. The 37 | * child process can also exit at will; this will be communicated through the 38 | * input callback. The pty object does not wait on the child processes it 39 | * spawns; this is the responsibility of the object's user. 40 | */ 41 | 42 | #ifndef KMSCON_PTY_H 43 | #define KMSCON_PTY_H 44 | 45 | #include 46 | #include 47 | 48 | struct kmscon_pty; 49 | 50 | typedef void (*kmscon_pty_input_cb) 51 | (struct kmscon_pty *pty, const char *u8, size_t len, void *data); 52 | 53 | int kmscon_pty_new(struct kmscon_pty **out, kmscon_pty_input_cb input_cb, 54 | void *data); 55 | void kmscon_pty_ref(struct kmscon_pty *pty); 56 | void kmscon_pty_unref(struct kmscon_pty *pty); 57 | int kmscon_pty_set_term(struct kmscon_pty *pty, const char *term); 58 | int kmscon_pty_set_colorterm(struct kmscon_pty *pty, const char *colorterm); 59 | int kmscon_pty_set_argv(struct kmscon_pty *pty, char **argv); 60 | int kmscon_pty_set_seat(struct kmscon_pty *pty, const char *seat); 61 | int kmscon_pty_set_vtnr(struct kmscon_pty *pty, unsigned int vtnr); 62 | void kmscon_pty_set_env_reset(struct kmscon_pty *pty, bool do_reset); 63 | 64 | int kmscon_pty_get_fd(struct kmscon_pty *pty); 65 | void kmscon_pty_dispatch(struct kmscon_pty *pty); 66 | 67 | int kmscon_pty_open(struct kmscon_pty *pty, unsigned short width, 68 | unsigned short height); 69 | void kmscon_pty_close(struct kmscon_pty *pty); 70 | 71 | int kmscon_pty_write(struct kmscon_pty *pty, const char *u8, size_t len); 72 | void kmscon_pty_signal(struct kmscon_pty *pty, int signum); 73 | void kmscon_pty_resize(struct kmscon_pty *pty, 74 | unsigned short width, unsigned short height); 75 | 76 | #endif /* KMSCON_PTY_H */ 77 | -------------------------------------------------------------------------------- /src/shl_array.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Dynamic Array 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * A dynamic array implementation 29 | */ 30 | 31 | #ifndef SHL_ARRAY_H 32 | #define SHL_ARRAY_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "shl_misc.h" 39 | 40 | struct shl_array { 41 | size_t element_size; 42 | size_t length; 43 | size_t size; 44 | void *data; 45 | }; 46 | 47 | #define SHL_ARRAY_AT(_arr, _type, _pos) \ 48 | (&((_type*)shl_array_get_array(_arr))[(_pos)]) 49 | 50 | static inline int shl_array_new(struct shl_array **out, size_t element_size, 51 | size_t initial_size) 52 | { 53 | struct shl_array *arr; 54 | 55 | if (!out || !element_size) 56 | return -EINVAL; 57 | 58 | if (!initial_size) 59 | initial_size = 4; 60 | 61 | arr = malloc(sizeof(*arr)); 62 | if (!arr) 63 | return -ENOMEM; 64 | memset(arr, 0, sizeof(*arr)); 65 | arr->element_size = element_size; 66 | arr->length = 0; 67 | arr->size = initial_size; 68 | 69 | arr->data = malloc(arr->element_size * arr->size); 70 | if (!arr->data) { 71 | free(arr); 72 | return -ENOMEM; 73 | } 74 | 75 | *out = arr; 76 | return 0; 77 | } 78 | 79 | static inline void shl_array_free(struct shl_array *arr) 80 | { 81 | if (!arr) 82 | return; 83 | 84 | free(arr->data); 85 | free(arr); 86 | } 87 | 88 | /* resize to length=size and zero out new array entries */ 89 | static inline int shl_array_zresize(struct shl_array *arr, size_t size) 90 | { 91 | void *tmp; 92 | size_t newsize; 93 | 94 | if (!arr) 95 | return -EINVAL; 96 | 97 | if (size > arr->size) { 98 | newsize = shl_next_pow2(size); 99 | tmp = realloc(arr->data, arr->element_size * newsize); 100 | if (!tmp) 101 | return -ENOMEM; 102 | 103 | arr->data = tmp; 104 | arr->size = newsize; 105 | 106 | memset(((uint8_t*)arr->data) + arr->element_size * arr->length, 107 | 0, arr->element_size * (size - arr->length)); 108 | } 109 | 110 | arr->length = size; 111 | return 0; 112 | } 113 | 114 | static inline int shl_array_push(struct shl_array *arr, const void *data) 115 | { 116 | void *tmp; 117 | size_t newsize; 118 | 119 | if (!arr || !data) 120 | return -EINVAL; 121 | 122 | if (arr->length >= arr->size) { 123 | newsize = arr->size * 2; 124 | tmp = realloc(arr->data, arr->element_size * newsize); 125 | if (!tmp) 126 | return -ENOMEM; 127 | 128 | arr->data = tmp; 129 | arr->size = newsize; 130 | } 131 | 132 | memcpy(((uint8_t*)arr->data) + arr->element_size * arr->length, 133 | data, arr->element_size); 134 | ++arr->length; 135 | 136 | return 0; 137 | } 138 | 139 | static inline void shl_array_pop(struct shl_array *arr) 140 | { 141 | if (!arr || !arr->length) 142 | return; 143 | 144 | --arr->length; 145 | } 146 | 147 | static inline void *shl_array_get_array(struct shl_array *arr) 148 | { 149 | if (!arr) 150 | return NULL; 151 | 152 | return arr->data; 153 | } 154 | 155 | static inline size_t shl_array_get_length(struct shl_array *arr) 156 | { 157 | if (!arr) 158 | return 0; 159 | 160 | return arr->length; 161 | } 162 | 163 | static inline size_t shl_array_get_bsize(struct shl_array *arr) 164 | { 165 | if (!arr) 166 | return 0; 167 | 168 | return arr->length * arr->element_size; 169 | } 170 | 171 | static inline size_t shl_array_get_element_size(struct shl_array *arr) 172 | { 173 | if (!arr) 174 | return 0; 175 | 176 | return arr->element_size; 177 | } 178 | 179 | #endif /* SHL_ARRAY_H */ 180 | -------------------------------------------------------------------------------- /src/shl_dlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Double Linked List 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * A simple double linked list implementation 29 | */ 30 | 31 | #ifndef SHL_DLIST_H 32 | #define SHL_DLIST_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | /* miscellaneous */ 40 | 41 | #define shl_offsetof(pointer, type, member) ({ \ 42 | const typeof(((type*)0)->member) *__ptr = (pointer); \ 43 | (type*)(((char*)__ptr) - offsetof(type, member)); \ 44 | }) 45 | 46 | /* double linked list */ 47 | 48 | struct shl_dlist { 49 | struct shl_dlist *next; 50 | struct shl_dlist *prev; 51 | }; 52 | 53 | #define SHL_DLIST_INIT(head) { &(head), &(head) } 54 | 55 | static inline void shl_dlist_init(struct shl_dlist *list) 56 | { 57 | list->next = list; 58 | list->prev = list; 59 | } 60 | 61 | static inline void shl_dlist__link(struct shl_dlist *prev, 62 | struct shl_dlist *next, 63 | struct shl_dlist *n) 64 | { 65 | next->prev = n; 66 | n->next = next; 67 | n->prev = prev; 68 | prev->next = n; 69 | } 70 | 71 | static inline void shl_dlist_link(struct shl_dlist *head, 72 | struct shl_dlist *n) 73 | { 74 | return shl_dlist__link(head, head->next, n); 75 | } 76 | 77 | static inline void shl_dlist_link_tail(struct shl_dlist *head, 78 | struct shl_dlist *n) 79 | { 80 | return shl_dlist__link(head->prev, head, n); 81 | } 82 | 83 | static inline void shl_dlist__unlink(struct shl_dlist *prev, 84 | struct shl_dlist *next) 85 | { 86 | next->prev = prev; 87 | prev->next = next; 88 | } 89 | 90 | static inline void shl_dlist_unlink(struct shl_dlist *e) 91 | { 92 | shl_dlist__unlink(e->prev, e->next); 93 | e->prev = NULL; 94 | e->next = NULL; 95 | } 96 | 97 | static inline bool shl_dlist_empty(struct shl_dlist *head) 98 | { 99 | return head->next == head; 100 | } 101 | 102 | #define shl_dlist_entry(ptr, type, member) \ 103 | shl_offsetof((ptr), type, member) 104 | 105 | #define shl_dlist_first(head, type, member) \ 106 | shl_dlist_entry((head)->next, type, member) 107 | 108 | #define shl_dlist_last(head, type, member) \ 109 | shl_dlist_entry((head)->prev, type, member) 110 | 111 | #define shl_dlist_for_each(iter, head) \ 112 | for (iter = (head)->next; iter != (head); iter = iter->next) 113 | 114 | #define shl_dlist_for_each_but_one(iter, start, head) \ 115 | for (iter = ((start)->next == (head)) ? \ 116 | (start)->next->next : \ 117 | (start)->next; \ 118 | iter != (start); \ 119 | iter = (iter->next == (head) && (start) != (head)) ? \ 120 | iter->next->next : \ 121 | iter->next) 122 | 123 | #define shl_dlist_for_each_safe(iter, tmp, head) \ 124 | for (iter = (head)->next, tmp = iter->next; iter != (head); \ 125 | iter = tmp, tmp = iter->next) 126 | 127 | #define shl_dlist_for_each_reverse(iter, head) \ 128 | for (iter = (head)->prev; iter != (head); iter = iter->prev) 129 | 130 | #define shl_dlist_for_each_reverse_but_one(iter, start, head) \ 131 | for (iter = ((start)->prev == (head)) ? \ 132 | (start)->prev->prev : \ 133 | (start)->prev; \ 134 | iter != (start); \ 135 | iter = (iter->prev == (head) && (start) != (head)) ? \ 136 | iter->prev->prev : \ 137 | iter->prev) 138 | 139 | #define shl_dlist_for_each_reverse_safe(iter, tmp, head) \ 140 | for (iter = (head)->prev, tmp = iter->prev; iter != (head); \ 141 | iter = tmp, tmp = iter->prev) 142 | 143 | #endif /* SHL_DLIST_H */ 144 | -------------------------------------------------------------------------------- /src/shl_flagset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Flagset 3 | * 4 | * Copyright (c) 2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * A dynamic flagset implementation 28 | */ 29 | 30 | #ifndef SHL_FLAGSET_H 31 | #define SHL_FLAGSET_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "shl_array.h" 39 | #include "shl_misc.h" 40 | 41 | static inline int shl_flagset_new(struct shl_array **out) 42 | { 43 | return shl_array_new(out, sizeof(unsigned long), 1); 44 | } 45 | 46 | static inline void shl_flagset_free(struct shl_array *arr) 47 | { 48 | return shl_array_free(arr); 49 | } 50 | 51 | static inline int shl_flagset_alloc(struct shl_array *arr, unsigned int *out) 52 | { 53 | static const unsigned long one = 1; 54 | unsigned int i, j; 55 | unsigned long *data; 56 | int ret; 57 | 58 | if (!arr) 59 | return -EINVAL; 60 | 61 | for (i = 0; i < arr->length; ++i) { 62 | data = SHL_ARRAY_AT(arr, unsigned long, i); 63 | for (j = 0; j < SHL_ULONG_BITS; ++j) { 64 | if (!(*data & (1UL << j))) { 65 | *data |= 1UL << j; 66 | *out = i * SHL_ULONG_BITS + j; 67 | return 0; 68 | } 69 | } 70 | } 71 | 72 | ret = shl_array_push(arr, &one); 73 | if (ret) 74 | return ret; 75 | 76 | *out = (arr->length - 1) * SHL_ULONG_BITS; 77 | return 0; 78 | } 79 | 80 | static inline int shl_flagset_reserve(struct shl_array *arr, unsigned int num) 81 | { 82 | int ret; 83 | unsigned int idx, off; 84 | unsigned long *data; 85 | 86 | if (!arr) 87 | return -EINVAL; 88 | 89 | idx = num / SHL_ULONG_BITS; 90 | off = num % SHL_ULONG_BITS; 91 | 92 | if (idx >= arr->length) { 93 | ret = shl_array_zresize(arr, idx + 1); 94 | if (ret) 95 | return ret; 96 | } 97 | 98 | data = SHL_ARRAY_AT(arr, unsigned long, idx); 99 | if (*data & (1UL << off)) 100 | return -EEXIST; 101 | 102 | *data |= 1UL << off; 103 | return 0; 104 | } 105 | 106 | static inline int shl_flagset_set(struct shl_array *arr, unsigned int num) 107 | { 108 | int ret; 109 | 110 | ret = shl_flagset_reserve(arr, num); 111 | if (ret == -EEXIST) 112 | return 0; 113 | 114 | return ret; 115 | } 116 | 117 | static inline void shl_flagset_unset(struct shl_array *arr, unsigned int num) 118 | { 119 | unsigned int idx, off; 120 | unsigned long *data; 121 | 122 | if (!arr) 123 | return; 124 | 125 | idx = num / SHL_ULONG_BITS; 126 | off = num % SHL_ULONG_BITS; 127 | 128 | if (idx >= arr->length) 129 | return; 130 | 131 | data = SHL_ARRAY_AT(arr, unsigned long, idx); 132 | *data &= ~(1UL << off); 133 | } 134 | 135 | #endif /* SHL_FLAGSET_H */ 136 | -------------------------------------------------------------------------------- /src/shl_githead.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - GIT-HEAD 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef SHL_GITHEAD_H 27 | #define SHL_GITHEAD_H 28 | 29 | extern const char shl_git_head[]; 30 | 31 | #endif /* SHL_GITHEAD_H */ 32 | -------------------------------------------------------------------------------- /src/shl_gl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - OpenGL Helpers 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * OpenGL Helpers 28 | * This file provides several helper functions that are commonly used when 29 | * working with OpenGL. 30 | * TODO: Rename to shl_gl_* prefix. 31 | */ 32 | 33 | #ifndef SHL_GL_H 34 | #define SHL_GL_H 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "shl_llog.h" 42 | 43 | /* 44 | * Math Helpers 45 | * The gl_m4 type is a 4x4 matrix of floats. The gl_m4_stack is a stack of m4 46 | * matrices where you can only access the top-most member. 47 | */ 48 | 49 | struct gl_m4_stack; 50 | 51 | void gl_m4_identity(float *m); 52 | void gl_m4_copy(float *dest, const float *src); 53 | void gl_m4_mult_dest(float *dest, const float *n, const float *m); 54 | void gl_m4_mult(float *n, const float *m); 55 | void gl_m4_translate(float *m, float x, float y, float z); 56 | void gl_m4_scale(float *m, float x, float y, float z); 57 | void gl_m4_transpose_dest(float *dest, const float *src); 58 | void gl_m4_transpose(float *m); 59 | 60 | int gl_m4_stack_new(struct gl_m4_stack **out); 61 | void gl_m4_stack_free(struct gl_m4_stack *stack); 62 | float *gl_m4_stack_push(struct gl_m4_stack *stack); 63 | float *gl_m4_stack_pop(struct gl_m4_stack *stack); 64 | float *gl_m4_stack_tip(struct gl_m4_stack *stack); 65 | 66 | /* 67 | * Shader Helpers 68 | * These helpers load, compile and link shaders and allow easy attribute/uniform 69 | * access. 70 | */ 71 | 72 | struct gl_shader; 73 | 74 | int gl_shader_new(struct gl_shader **out, const char *vert, int vert_len, 75 | const char *frag, int frag_len, 76 | char **attr, size_t attr_count, llog_submit_t llog, 77 | void *llog_data); 78 | void gl_shader_ref(struct gl_shader *shader); 79 | void gl_shader_unref(struct gl_shader *shader); 80 | GLuint gl_shader_get_uniform(struct gl_shader *shader, const char *name); 81 | void gl_shader_use(struct gl_shader *shader); 82 | 83 | void gl_tex_new(GLuint *tex, size_t num); 84 | void gl_tex_free(GLuint *tex, size_t num); 85 | void gl_tex_load(GLuint tex, unsigned int width, unsigned int stride, 86 | unsigned int height, uint8_t *buf); 87 | 88 | void gl_clear_error(); 89 | bool gl_has_error(struct gl_shader *shader); 90 | const char *gl_err_to_str(GLenum err); 91 | 92 | #endif /* SHL_GL_H */ 93 | -------------------------------------------------------------------------------- /src/shl_hashtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Dynamic Array 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * A dynamic hash table implementation 29 | */ 30 | 31 | #ifndef SHL_HASHTABLE_H 32 | #define SHL_HASHTABLE_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "external/htable.h" 40 | 41 | struct shl_hashtable; 42 | 43 | typedef unsigned int (*shl_hash_cb) (const void *data); 44 | typedef bool (*shl_equal_cb) (const void *data1, const void *data2); 45 | typedef void (*shl_free_cb) (void *data); 46 | 47 | struct shl_hashentry { 48 | void *key; 49 | void *value; 50 | }; 51 | 52 | struct shl_hashtable { 53 | struct htable tbl; 54 | shl_hash_cb hash_cb; 55 | shl_equal_cb equal_cb; 56 | shl_free_cb free_key; 57 | shl_free_cb free_value; 58 | }; 59 | 60 | static inline unsigned int shl_direct_hash(const void *data) 61 | { 62 | return (unsigned int)(unsigned long)data; 63 | } 64 | 65 | static inline bool shl_direct_equal(const void *data1, const void *data2) 66 | { 67 | return data1 == data2; 68 | } 69 | 70 | static size_t shl_rehash(const void *ele, void *priv) 71 | { 72 | struct shl_hashtable *tbl = priv; 73 | const struct shl_hashentry *ent = ele; 74 | 75 | return tbl->hash_cb(ent->key); 76 | } 77 | 78 | static inline int shl_hashtable_new(struct shl_hashtable **out, 79 | shl_hash_cb hash_cb, 80 | shl_equal_cb equal_cb, 81 | shl_free_cb free_key, 82 | shl_free_cb free_value) 83 | { 84 | struct shl_hashtable *tbl; 85 | 86 | if (!out || !hash_cb || !equal_cb) 87 | return -EINVAL; 88 | 89 | tbl = malloc(sizeof(*tbl)); 90 | if (!tbl) 91 | return -ENOMEM; 92 | memset(tbl, 0, sizeof(*tbl)); 93 | tbl->hash_cb = hash_cb; 94 | tbl->equal_cb = equal_cb; 95 | tbl->free_key = free_key; 96 | tbl->free_value = free_value; 97 | 98 | htable_init(&tbl->tbl, shl_rehash, tbl); 99 | 100 | *out = tbl; 101 | return 0; 102 | } 103 | 104 | static inline void shl_hashtable_free(struct shl_hashtable *tbl) 105 | { 106 | struct htable_iter i; 107 | struct shl_hashentry *entry; 108 | 109 | if (!tbl) 110 | return; 111 | 112 | for (entry = htable_first(&tbl->tbl, &i); 113 | entry; 114 | entry = htable_next(&tbl->tbl, &i)) { 115 | htable_delval(&tbl->tbl, &i); 116 | if (tbl->free_key) 117 | tbl->free_key(entry->key); 118 | if (tbl->free_value) 119 | tbl->free_value(entry->value); 120 | free(entry); 121 | } 122 | 123 | htable_clear(&tbl->tbl); 124 | free(tbl); 125 | } 126 | 127 | static inline int shl_hashtable_insert(struct shl_hashtable *tbl, void *key, 128 | void *value) 129 | { 130 | struct shl_hashentry *entry; 131 | size_t hash; 132 | 133 | if (!tbl) 134 | return -EINVAL; 135 | 136 | entry = malloc(sizeof(*entry)); 137 | if (!entry) 138 | return -ENOMEM; 139 | entry->key = key; 140 | entry->value = value; 141 | 142 | hash = tbl->hash_cb(key); 143 | 144 | if (!htable_add(&tbl->tbl, hash, entry)) { 145 | free(entry); 146 | return -ENOMEM; 147 | } 148 | 149 | return 0; 150 | } 151 | 152 | static inline void shl_hashtable_remove(struct shl_hashtable *tbl, void *key) 153 | { 154 | struct htable_iter i; 155 | struct shl_hashentry *entry; 156 | size_t hash; 157 | 158 | if (!tbl) 159 | return; 160 | 161 | hash = tbl->hash_cb(key); 162 | 163 | for (entry = htable_firstval(&tbl->tbl, &i, hash); 164 | entry; 165 | entry = htable_nextval(&tbl->tbl, &i, hash)) { 166 | if (tbl->equal_cb(key, entry->key)) { 167 | htable_delval(&tbl->tbl, &i); 168 | return; 169 | } 170 | } 171 | } 172 | 173 | static inline bool shl_hashtable_find(struct shl_hashtable *tbl, void **out, 174 | void *key) 175 | { 176 | struct htable_iter i; 177 | struct shl_hashentry *entry; 178 | size_t hash; 179 | 180 | if (!tbl) 181 | return false; 182 | 183 | hash = tbl->hash_cb(key); 184 | 185 | for (entry = htable_firstval(&tbl->tbl, &i, hash); 186 | entry; 187 | entry = htable_nextval(&tbl->tbl, &i, hash)) { 188 | if (tbl->equal_cb(key, entry->key)) { 189 | if (out) 190 | *out = entry->value; 191 | return true; 192 | } 193 | } 194 | 195 | return false; 196 | } 197 | 198 | #endif /* SHL_HASHTABLE_H */ 199 | -------------------------------------------------------------------------------- /src/shl_ring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Dynamic Array 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * A circular memory ring implementation 29 | */ 30 | 31 | #ifndef SHL_RING_H 32 | #define SHL_RING_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define SHL_RING_SIZE 512 40 | 41 | struct shl_ring_entry { 42 | struct shl_ring_entry *next; 43 | size_t len; 44 | char buf[]; 45 | }; 46 | 47 | struct shl_ring { 48 | struct shl_ring_entry *first; 49 | struct shl_ring_entry *last; 50 | }; 51 | 52 | static inline int shl_ring_new(struct shl_ring **out) 53 | { 54 | struct shl_ring *ring; 55 | 56 | if (!out) 57 | return -EINVAL; 58 | 59 | ring = malloc(sizeof(*ring)); 60 | if (!ring) 61 | return -ENOMEM; 62 | 63 | memset(ring, 0, sizeof(*ring)); 64 | 65 | *out = ring; 66 | return 0; 67 | } 68 | 69 | static inline void shl_ring_free(struct shl_ring *ring) 70 | { 71 | struct shl_ring_entry *tmp; 72 | 73 | if (!ring) 74 | return; 75 | 76 | while (ring->first) { 77 | tmp = ring->first; 78 | ring->first = tmp->next; 79 | free(tmp); 80 | } 81 | free(ring); 82 | } 83 | 84 | static inline bool shl_ring_is_empty(struct shl_ring *ring) 85 | { 86 | if (!ring) 87 | return true; 88 | 89 | return ring->first == NULL; 90 | } 91 | 92 | static inline int shl_ring_write(struct shl_ring *ring, const char *val, 93 | size_t len) 94 | { 95 | struct shl_ring_entry *ent; 96 | size_t space, cp; 97 | 98 | if (!ring || !val || !len) 99 | return -EINVAL; 100 | 101 | next: 102 | ent = ring->last; 103 | if (!ent || ent->len >= SHL_RING_SIZE) { 104 | ent = malloc(sizeof(*ent) + SHL_RING_SIZE); 105 | if (!ent) 106 | return -ENOMEM; 107 | 108 | ent->len = 0; 109 | ent->next = NULL; 110 | if (ring->last) 111 | ring->last->next = ent; 112 | else 113 | ring->first = ent; 114 | ring->last = ent; 115 | } 116 | 117 | space = SHL_RING_SIZE - ent->len; 118 | if (len >= space) 119 | cp = space; 120 | else 121 | cp = len; 122 | 123 | memcpy(&ent->buf[ent->len], val, cp); 124 | ent->len += cp; 125 | 126 | val = &val[cp]; 127 | len -= cp; 128 | if (len > 0) 129 | goto next; 130 | 131 | return 0; 132 | } 133 | 134 | static inline const char *shl_ring_peek(struct shl_ring *ring, size_t *len, 135 | size_t offset) 136 | { 137 | struct shl_ring_entry *iter; 138 | 139 | if (!ring || !ring->first || !len) { 140 | if (len) 141 | *len = 0; 142 | return NULL; 143 | } 144 | 145 | iter = ring->first; 146 | while (iter->len <= offset) { 147 | if (!iter->next) { 148 | *len = 0; 149 | return NULL; 150 | } 151 | 152 | offset -= iter->len; 153 | iter = iter->next; 154 | } 155 | 156 | *len = ring->first->len - offset; 157 | return &ring->first->buf[offset]; 158 | } 159 | 160 | static inline void shl_ring_drop(struct shl_ring *ring, size_t len) 161 | { 162 | struct shl_ring_entry *ent; 163 | 164 | if (!ring || !len) 165 | return; 166 | 167 | next: 168 | ent = ring->first; 169 | if (!ent) 170 | return; 171 | 172 | if (len >= ent->len) { 173 | len -= ent->len; 174 | ring->first = ent->next; 175 | free(ent); 176 | if (!ring->first) 177 | ring->last = NULL; 178 | 179 | if (len) 180 | goto next; 181 | } else { 182 | memmove(ent->buf, &ent->buf[len], ent->len - len); 183 | ent->len -= len; 184 | } 185 | } 186 | 187 | static inline void shl_ring_flush(struct shl_ring *ring) 188 | { 189 | struct shl_ring_entry *tmp; 190 | 191 | if (!ring) 192 | return; 193 | 194 | while (ring->first) { 195 | tmp = ring->first; 196 | ring->first = tmp->next; 197 | free(tmp); 198 | } 199 | ring->last = NULL; 200 | } 201 | 202 | #endif /* SHL_RING_H */ 203 | -------------------------------------------------------------------------------- /src/shl_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * shl - Timers 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Timers 29 | */ 30 | 31 | #ifndef SHL_TIMER_H 32 | #define SHL_TIMER_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | struct shl_timer { 42 | struct timespec start; 43 | uint64_t elapsed; 44 | }; 45 | 46 | static inline void shl_timer_reset(struct shl_timer *timer) 47 | { 48 | if (!timer) 49 | return; 50 | 51 | clock_gettime(CLOCK_MONOTONIC, &timer->start); 52 | timer->elapsed = 0; 53 | } 54 | 55 | static inline int shl_timer_new(struct shl_timer **out) 56 | { 57 | struct shl_timer *timer; 58 | 59 | if (!out) 60 | return -EINVAL; 61 | 62 | timer = malloc(sizeof(*timer)); 63 | if (!timer) 64 | return -ENOMEM; 65 | memset(timer, 0, sizeof(*timer)); 66 | shl_timer_reset(timer); 67 | 68 | *out = timer; 69 | return 0; 70 | } 71 | 72 | static inline void shl_timer_free(struct shl_timer *timer) 73 | { 74 | if (!timer) 75 | return; 76 | 77 | free(timer); 78 | } 79 | 80 | static inline void shl_timer_start(struct shl_timer *timer) 81 | { 82 | if (!timer) 83 | return; 84 | 85 | clock_gettime(CLOCK_MONOTONIC, &timer->start); 86 | } 87 | 88 | static inline uint64_t shl_timer_stop(struct shl_timer *timer) 89 | { 90 | struct timespec spec; 91 | int64_t off, nsec; 92 | 93 | if (!timer) 94 | return 0; 95 | 96 | clock_gettime(CLOCK_MONOTONIC, &spec); 97 | off = spec.tv_sec - timer->start.tv_sec; 98 | nsec = spec.tv_nsec - timer->start.tv_nsec; 99 | if (nsec < 0) { 100 | --off; 101 | nsec += 1000000000ULL; 102 | } 103 | off *= 1000000; 104 | off += nsec / 1000; 105 | 106 | memcpy(&timer->start, &spec, sizeof(spec)); 107 | timer->elapsed += off; 108 | return timer->elapsed; 109 | } 110 | 111 | static inline uint64_t shl_timer_elapsed(struct shl_timer *timer) 112 | { 113 | struct timespec spec; 114 | int64_t off, nsec; 115 | 116 | if (!timer) 117 | return 0; 118 | 119 | clock_gettime(CLOCK_MONOTONIC, &spec); 120 | off = spec.tv_sec - timer->start.tv_sec; 121 | nsec = spec.tv_nsec - timer->start.tv_nsec; 122 | if (nsec < 0) { 123 | --off; 124 | nsec += 1000000000ULL; 125 | } 126 | off *= 1000000; 127 | off += nsec / 1000; 128 | 129 | return timer->elapsed + off; 130 | } 131 | 132 | #endif /* SHL_TIMER_H */ 133 | -------------------------------------------------------------------------------- /src/text.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Text Renderer 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Text Renderer 28 | * The Text-Renderer subsystem provides a simple way to draw text into a 29 | * framebuffer. The system is modular and several different backends are 30 | * available that can be used. 31 | */ 32 | 33 | #ifndef KMSCON_TEXT_H 34 | #define KMSCON_TEXT_H 35 | 36 | #include 37 | #include 38 | #include 39 | #include "font.h" 40 | #include "kmscon_module.h" 41 | #include "uterm_video.h" 42 | 43 | /* text renderer */ 44 | 45 | struct kmscon_text; 46 | struct kmscon_text_ops; 47 | 48 | struct kmscon_text { 49 | unsigned long ref; 50 | struct shl_register_record *record; 51 | const struct kmscon_text_ops *ops; 52 | void *data; 53 | 54 | struct kmscon_font *font; 55 | struct kmscon_font *bold_font; 56 | struct uterm_display *disp; 57 | unsigned int cols; 58 | unsigned int rows; 59 | bool rendering; 60 | }; 61 | 62 | struct kmscon_text_ops { 63 | const char *name; 64 | struct kmscon_module *owner; 65 | int (*init) (struct kmscon_text *txt); 66 | void (*destroy) (struct kmscon_text *txt); 67 | int (*set) (struct kmscon_text *txt); 68 | void (*unset) (struct kmscon_text *txt); 69 | int (*prepare) (struct kmscon_text *txt); 70 | int (*draw) (struct kmscon_text *txt, 71 | uint32_t id, const uint32_t *ch, size_t len, 72 | unsigned int width, 73 | unsigned int posx, unsigned int posy, 74 | const struct tsm_screen_attr *attr); 75 | int (*render) (struct kmscon_text *txt); 76 | void (*abort) (struct kmscon_text *txt); 77 | }; 78 | 79 | int kmscon_text_register(const struct kmscon_text_ops *ops); 80 | void kmscon_text_unregister(const char *name); 81 | 82 | int kmscon_text_new(struct kmscon_text **out, const char *backend); 83 | void kmscon_text_ref(struct kmscon_text *txt); 84 | void kmscon_text_unref(struct kmscon_text *txt); 85 | 86 | int kmscon_text_set(struct kmscon_text *txt, 87 | struct kmscon_font *font, 88 | struct kmscon_font *bold_font, 89 | struct uterm_display *disp); 90 | void kmscon_text_unset(struct kmscon_text *txt); 91 | unsigned int kmscon_text_get_cols(struct kmscon_text *txt); 92 | unsigned int kmscon_text_get_rows(struct kmscon_text *txt); 93 | 94 | int kmscon_text_prepare(struct kmscon_text *txt); 95 | int kmscon_text_draw(struct kmscon_text *txt, 96 | uint32_t id, const uint32_t *ch, size_t len, 97 | unsigned int width, 98 | unsigned int posx, unsigned int posy, 99 | const struct tsm_screen_attr *attr); 100 | int kmscon_text_render(struct kmscon_text *txt); 101 | void kmscon_text_abort(struct kmscon_text *txt); 102 | 103 | int kmscon_text_draw_cb(struct tsm_screen *con, 104 | uint32_t id, const uint32_t *ch, size_t len, 105 | unsigned int width, 106 | unsigned int posx, unsigned int posy, 107 | const struct tsm_screen_attr *attr, 108 | tsm_age_t age, void *data); 109 | 110 | /* modularized backends */ 111 | 112 | extern struct kmscon_text_ops kmscon_text_bblit_ops; 113 | extern struct kmscon_text_ops kmscon_text_bbulk_ops; 114 | extern struct kmscon_text_ops kmscon_text_gltex_ops; 115 | extern struct kmscon_text_ops kmscon_text_pixman_ops; 116 | 117 | #endif /* KMSCON_TEXT_H */ 118 | -------------------------------------------------------------------------------- /src/text_bblit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Bit-Blitting Text Renderer Backend 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /** 27 | * SECTION:text_bblit.c 28 | * @short_description: Bit-Blitting Text Renderer Backend 29 | * @include: text.h 30 | * 31 | * The bit-blitting renderer requires framebuffer access to the output device 32 | * and simply blits the glyphs into the buffer. 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "shl_log.h" 40 | #include "text.h" 41 | #include "uterm_video.h" 42 | 43 | #define LOG_SUBSYSTEM "text_bblit" 44 | 45 | static int bblit_set(struct kmscon_text *txt) 46 | { 47 | unsigned int sw, sh, fw, fh; 48 | struct uterm_mode *mode; 49 | 50 | fw = txt->font->attr.width; 51 | fh = txt->font->attr.height; 52 | mode = uterm_display_get_current(txt->disp); 53 | if (!mode) 54 | return -EINVAL; 55 | sw = uterm_mode_get_width(mode); 56 | sh = uterm_mode_get_height(mode); 57 | 58 | txt->cols = sw / fw; 59 | txt->rows = sh / fh; 60 | 61 | return 0; 62 | } 63 | 64 | static int bblit_draw(struct kmscon_text *txt, 65 | uint32_t id, const uint32_t *ch, size_t len, 66 | unsigned int width, 67 | unsigned int posx, unsigned int posy, 68 | const struct tsm_screen_attr *attr) 69 | { 70 | const struct kmscon_glyph *glyph; 71 | int ret; 72 | struct kmscon_font *font; 73 | 74 | if (!width) 75 | return 0; 76 | 77 | if (attr->bold) 78 | font = txt->bold_font; 79 | else 80 | font = txt->font; 81 | 82 | if (!len) { 83 | ret = kmscon_font_render_empty(font, &glyph); 84 | } else { 85 | ret = kmscon_font_render(font, id, ch, len, &glyph); 86 | } 87 | 88 | if (ret) { 89 | ret = kmscon_font_render_inval(font, &glyph); 90 | if (ret) 91 | return ret; 92 | } 93 | 94 | /* draw glyph */ 95 | if (attr->inverse) { 96 | ret = uterm_display_fake_blend(txt->disp, &glyph->buf, 97 | posx * txt->font->attr.width, 98 | posy * txt->font->attr.height, 99 | attr->br, attr->bg, attr->bb, 100 | attr->fr, attr->fg, attr->fb); 101 | } else { 102 | ret = uterm_display_fake_blend(txt->disp, &glyph->buf, 103 | posx * txt->font->attr.width, 104 | posy * txt->font->attr.height, 105 | attr->fr, attr->fg, attr->fb, 106 | attr->br, attr->bg, attr->bb); 107 | } 108 | 109 | return ret; 110 | } 111 | 112 | struct kmscon_text_ops kmscon_text_bblit_ops = { 113 | .name = "bblit", 114 | .owner = NULL, 115 | .init = NULL, 116 | .destroy = NULL, 117 | .set = bblit_set, 118 | .unset = NULL, 119 | .prepare = NULL, 120 | .draw = bblit_draw, 121 | .render = NULL, 122 | .abort = NULL, 123 | }; 124 | -------------------------------------------------------------------------------- /src/text_bbulk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Bit-Blitting Bulk Text Renderer Backend 3 | * 4 | * Copyright (c) 2012-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /** 27 | * SECTION:text_bbulk.c 28 | * @short_description: Bit-Blitting Bulk Text Renderer Backend 29 | * @include: text.h 30 | * 31 | * Similar to the bblit renderer but assembles an array of blit-requests and 32 | * pushes all of them at once to the video device. 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "shl_log.h" 40 | #include "text.h" 41 | #include "uterm_video.h" 42 | 43 | #define LOG_SUBSYSTEM "text_bbulk" 44 | 45 | struct bbulk { 46 | struct uterm_video_blend_req *reqs; 47 | }; 48 | 49 | #define FONT_WIDTH(txt) ((txt)->font->attr.width) 50 | #define FONT_HEIGHT(txt) ((txt)->font->attr.height) 51 | 52 | static int bbulk_init(struct kmscon_text *txt) 53 | { 54 | struct bbulk *bb; 55 | 56 | bb = malloc(sizeof(*bb)); 57 | if (!bb) 58 | return -ENOMEM; 59 | 60 | txt->data = bb; 61 | return 0; 62 | } 63 | 64 | static void bbulk_destroy(struct kmscon_text *txt) 65 | { 66 | struct bbulk *bb = txt->data; 67 | 68 | free(bb); 69 | } 70 | 71 | static int bbulk_set(struct kmscon_text *txt) 72 | { 73 | struct bbulk *bb = txt->data; 74 | unsigned int sw, sh, i, j; 75 | struct uterm_video_blend_req *req; 76 | struct uterm_mode *mode; 77 | 78 | memset(bb, 0, sizeof(*bb)); 79 | 80 | mode = uterm_display_get_current(txt->disp); 81 | if (!mode) 82 | return -EINVAL; 83 | sw = uterm_mode_get_width(mode); 84 | sh = uterm_mode_get_height(mode); 85 | 86 | txt->cols = sw / FONT_WIDTH(txt); 87 | txt->rows = sh / FONT_HEIGHT(txt); 88 | 89 | bb->reqs = malloc(sizeof(*bb->reqs) * txt->cols * txt->rows); 90 | if (!bb->reqs) 91 | return -ENOMEM; 92 | memset(bb->reqs, 0, sizeof(*bb->reqs) * txt->cols * txt->rows); 93 | 94 | for (i = 0; i < txt->rows; ++i) { 95 | for (j = 0; j < txt->cols; ++j) { 96 | req = &bb->reqs[i * txt->cols + j]; 97 | req->x = j * FONT_WIDTH(txt); 98 | req->y = i * FONT_HEIGHT(txt); 99 | } 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | static void bbulk_unset(struct kmscon_text *txt) 106 | { 107 | struct bbulk *bb = txt->data; 108 | 109 | free(bb->reqs); 110 | bb->reqs = NULL; 111 | } 112 | 113 | static int bbulk_draw(struct kmscon_text *txt, 114 | uint32_t id, const uint32_t *ch, size_t len, 115 | unsigned int width, 116 | unsigned int posx, unsigned int posy, 117 | const struct tsm_screen_attr *attr) 118 | { 119 | struct bbulk *bb = txt->data; 120 | const struct kmscon_glyph *glyph; 121 | int ret; 122 | struct uterm_video_blend_req *req; 123 | struct kmscon_font *font; 124 | 125 | if (!width) { 126 | bb->reqs[posy * txt->cols + posx].buf = NULL; 127 | return 0; 128 | } 129 | 130 | if (attr->bold) 131 | font = txt->bold_font; 132 | else 133 | font = txt->font; 134 | 135 | if (!len) { 136 | ret = kmscon_font_render_empty(font, &glyph); 137 | } else { 138 | ret = kmscon_font_render(font, id, ch, len, &glyph); 139 | } 140 | 141 | if (ret) { 142 | ret = kmscon_font_render_inval(font, &glyph); 143 | if (ret) 144 | return ret; 145 | } 146 | 147 | req = &bb->reqs[posy * txt->cols + posx]; 148 | req->buf = &glyph->buf; 149 | if (attr->inverse) { 150 | req->fr = attr->br; 151 | req->fg = attr->bg; 152 | req->fb = attr->bb; 153 | req->br = attr->fr; 154 | req->bg = attr->fg; 155 | req->bb = attr->fb; 156 | } else { 157 | req->fr = attr->fr; 158 | req->fg = attr->fg; 159 | req->fb = attr->fb; 160 | req->br = attr->br; 161 | req->bg = attr->bg; 162 | req->bb = attr->bb; 163 | } 164 | 165 | return 0; 166 | } 167 | 168 | static int bbulk_render(struct kmscon_text *txt) 169 | { 170 | struct bbulk *bb = txt->data; 171 | 172 | return uterm_display_fake_blendv(txt->disp, bb->reqs, 173 | txt->cols * txt->rows); 174 | } 175 | 176 | struct kmscon_text_ops kmscon_text_bbulk_ops = { 177 | .name = "bbulk", 178 | .owner = NULL, 179 | .init = bbulk_init, 180 | .destroy = bbulk_destroy, 181 | .set = bbulk_set, 182 | .unset = bbulk_unset, 183 | .prepare = NULL, 184 | .draw = bbulk_draw, 185 | .render = bbulk_render, 186 | .abort = NULL, 187 | }; 188 | -------------------------------------------------------------------------------- /src/text_gltex_atlas.frag: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Fragment Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Fragment Shader 29 | * A basic fragment shader which applies a 2D texture and blends foreground and 30 | * background colors. 31 | */ 32 | 33 | precision mediump float; 34 | 35 | uniform sampler2D atlas; 36 | uniform float advance_htex; 37 | uniform float advance_vtex; 38 | 39 | varying vec2 texpos; 40 | varying vec3 fgcol; 41 | varying vec3 bgcol; 42 | 43 | void main() 44 | { 45 | vec2 pos = vec2(texpos.x * advance_htex, texpos.y * advance_vtex); 46 | float alpha = texture2D(atlas, pos).a; 47 | vec3 val = alpha * fgcol + (1.0 - alpha) * bgcol; 48 | gl_FragColor = vec4(val, 1.0); 49 | } 50 | -------------------------------------------------------------------------------- /src/text_gltex_atlas.vert: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Vertex Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Vertex Shader 29 | * This shader is a very basic vertex shader which forwards all data and 30 | * performs basic matrix multiplications. 31 | */ 32 | 33 | uniform mat4 projection; 34 | 35 | attribute vec2 position; 36 | attribute vec2 texture_position; 37 | attribute vec3 fgcolor; 38 | attribute vec3 bgcolor; 39 | 40 | varying vec2 texpos; 41 | varying vec3 fgcol; 42 | varying vec3 bgcol; 43 | 44 | void main() 45 | { 46 | gl_Position = projection * vec4(position, 0.0, 1.0); 47 | texpos = texture_position; 48 | fgcol = fgcolor; 49 | bgcol = bgcolor; 50 | } 51 | -------------------------------------------------------------------------------- /src/uterm_drm2d_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal drm2d module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_DRM2D_INTERNAL_H 29 | #define UTERM_DRM2D_INTERNAL_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "uterm_video.h" 36 | 37 | struct uterm_drm2d_rb { 38 | uint32_t fb; 39 | uint32_t handle; 40 | uint32_t stride; 41 | uint64_t size; 42 | void *map; 43 | }; 44 | 45 | struct uterm_drm2d_display { 46 | int current_rb; 47 | struct uterm_drm2d_rb rb[2]; 48 | }; 49 | 50 | struct uterm_drm2d_video { 51 | int fd; 52 | struct ev_fd *efd; 53 | }; 54 | 55 | int uterm_drm2d_display_blit(struct uterm_display *disp, 56 | const struct uterm_video_buffer *buf, 57 | unsigned int x, unsigned int y); 58 | int uterm_drm2d_display_fake_blendv(struct uterm_display *disp, 59 | const struct uterm_video_blend_req *req, 60 | size_t num); 61 | int uterm_drm2d_display_fill(struct uterm_display *disp, 62 | uint8_t r, uint8_t g, uint8_t b, 63 | unsigned int x, unsigned int y, 64 | unsigned int width, unsigned int height); 65 | 66 | #endif /* UTERM_DRM2D_INTERNAL_H */ 67 | -------------------------------------------------------------------------------- /src/uterm_drm2d_render.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal drm2d module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * DRM2D Video backend rendering functions 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include "eloop.h" 41 | #include "shl_log.h" 42 | #include "uterm_drm_shared_internal.h" 43 | #include "uterm_drm2d_internal.h" 44 | #include "uterm_video.h" 45 | #include "uterm_video_internal.h" 46 | 47 | #define LOG_SUBSYSTEM "uterm_drm2d_render" 48 | 49 | int uterm_drm2d_display_blit(struct uterm_display *disp, 50 | const struct uterm_video_buffer *buf, 51 | unsigned int x, unsigned int y) 52 | { 53 | unsigned int tmp; 54 | uint8_t *dst, *src; 55 | unsigned int width, height; 56 | unsigned int sw, sh; 57 | struct uterm_drm2d_rb *rb; 58 | struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp); 59 | 60 | if (!buf || buf->format != UTERM_FORMAT_XRGB32) 61 | return -EINVAL; 62 | 63 | rb = &d2d->rb[d2d->current_rb ^ 1]; 64 | sw = uterm_drm_mode_get_width(disp->current_mode); 65 | sh = uterm_drm_mode_get_height(disp->current_mode); 66 | 67 | tmp = x + buf->width; 68 | if (tmp < x || x >= sw) 69 | return -EINVAL; 70 | if (tmp > sw) 71 | width = sw - x; 72 | else 73 | width = buf->width; 74 | 75 | tmp = y + buf->height; 76 | if (tmp < y || y >= sh) 77 | return -EINVAL; 78 | if (tmp > sh) 79 | height = sh - y; 80 | else 81 | height = buf->height; 82 | 83 | dst = rb->map; 84 | dst = &dst[y * rb->stride + x * 4]; 85 | src = buf->data; 86 | 87 | while (height--) { 88 | memcpy(dst, src, 4 * width); 89 | dst += rb->stride; 90 | src += buf->stride; 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | int uterm_drm2d_display_fake_blendv(struct uterm_display *disp, 97 | const struct uterm_video_blend_req *req, 98 | size_t num) 99 | { 100 | unsigned int tmp; 101 | uint8_t *dst, *src; 102 | unsigned int width, height, i, j; 103 | unsigned int sw, sh; 104 | uint_fast32_t r, g, b, out; 105 | struct uterm_drm2d_rb *rb; 106 | struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp); 107 | 108 | if (!req) 109 | return -EINVAL; 110 | 111 | rb = &d2d->rb[d2d->current_rb ^ 1]; 112 | sw = uterm_drm_mode_get_width(disp->current_mode); 113 | sh = uterm_drm_mode_get_height(disp->current_mode); 114 | 115 | for (j = 0; j < num; ++j, ++req) { 116 | if (!req->buf) 117 | continue; 118 | 119 | if (req->buf->format != UTERM_FORMAT_GREY) 120 | return -EOPNOTSUPP; 121 | 122 | tmp = req->x + req->buf->width; 123 | if (tmp < req->x || req->x >= sw) 124 | return -EINVAL; 125 | if (tmp > sw) 126 | width = sw - req->x; 127 | else 128 | width = req->buf->width; 129 | 130 | tmp = req->y + req->buf->height; 131 | if (tmp < req->y || req->y >= sh) 132 | return -EINVAL; 133 | if (tmp > sh) 134 | height = sh - req->y; 135 | else 136 | height = req->buf->height; 137 | 138 | dst = rb->map; 139 | dst = &dst[req->y * rb->stride + req->x * 4]; 140 | src = req->buf->data; 141 | 142 | while (height--) { 143 | for (i = 0; i < width; ++i) { 144 | /* Division by 255 (t /= 255) is done with: 145 | * t += 0x80 146 | * t = (t + (t >> 8)) >> 8 147 | * This speeds up the computation by ~20% as the 148 | * division is not needed. */ 149 | if (src[i] == 0) { 150 | r = req->br; 151 | g = req->bg; 152 | b = req->bb; 153 | out = (r << 16) | (g << 8) | b; 154 | } else if (src[i] == 255) { 155 | r = req->fr; 156 | g = req->fg; 157 | b = req->fb; 158 | out = (r << 16) | (g << 8) | b; 159 | } else { 160 | r = req->fr * src[i] + 161 | req->br * (255 - src[i]); 162 | r += 0x80; 163 | r = (r + (r >> 8)) >> 8; 164 | 165 | g = req->fg * src[i] + 166 | req->bg * (255 - src[i]); 167 | g += 0x80; 168 | g = (g + (g >> 8)) >> 8; 169 | 170 | b = req->fb * src[i] + 171 | req->bb * (255 - src[i]); 172 | b += 0x80; 173 | b = (b + (b >> 8)) >> 8; 174 | out = (r << 16) | (g << 8) | b; 175 | } 176 | 177 | ((uint32_t*)dst)[i] = out; 178 | } 179 | dst += rb->stride; 180 | src += req->buf->stride; 181 | } 182 | } 183 | 184 | return 0; 185 | } 186 | 187 | int uterm_drm2d_display_fill(struct uterm_display *disp, 188 | uint8_t r, uint8_t g, uint8_t b, 189 | unsigned int x, unsigned int y, 190 | unsigned int width, unsigned int height) 191 | { 192 | unsigned int tmp, i; 193 | uint8_t *dst; 194 | unsigned int sw, sh; 195 | struct uterm_drm2d_rb *rb; 196 | struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp); 197 | 198 | rb = &d2d->rb[d2d->current_rb ^ 1]; 199 | sw = uterm_drm_mode_get_width(disp->current_mode); 200 | sh = uterm_drm_mode_get_height(disp->current_mode); 201 | 202 | tmp = x + width; 203 | if (tmp < x || x >= sw) 204 | return -EINVAL; 205 | if (tmp > sw) 206 | width = sw - x; 207 | tmp = y + height; 208 | if (tmp < y || y >= sh) 209 | return -EINVAL; 210 | if (tmp > sh) 211 | height = sh - y; 212 | 213 | dst = rb->map; 214 | dst = &dst[y * rb->stride + x * 4]; 215 | 216 | while (height--) { 217 | for (i = 0; i < width; ++i) 218 | ((uint32_t*)dst)[i] = (r << 16) | (g << 8) | b; 219 | dst += rb->stride; 220 | } 221 | 222 | return 0; 223 | } 224 | -------------------------------------------------------------------------------- /src/uterm_drm3d_blend.frag: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Fragment Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Fragment Shader 29 | * A basic fragment shader which applies a 2D texture. 30 | */ 31 | 32 | precision mediump float; 33 | 34 | uniform sampler2D texture; 35 | uniform vec3 fgcolor; 36 | uniform vec3 bgcolor; 37 | varying vec2 texpos; 38 | 39 | void main() 40 | { 41 | float alpha = texture2D(texture, texpos).a; 42 | vec3 val = alpha * fgcolor + (1.0 - alpha) * bgcolor; 43 | gl_FragColor = vec4(val, 1.0); 44 | } 45 | -------------------------------------------------------------------------------- /src/uterm_drm3d_blend.vert: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Vertex Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Vertex Shader 29 | * This shader is a very basic vertex shader which forwards all data and 30 | * performs basic matrix multiplications. 31 | */ 32 | 33 | uniform mat4 projection; 34 | attribute vec2 position; 35 | attribute vec2 texture_position; 36 | varying vec2 texpos; 37 | 38 | void main() 39 | { 40 | gl_Position = projection * vec4(position, 0.0, 1.0); 41 | texpos = texture_position; 42 | } 43 | -------------------------------------------------------------------------------- /src/uterm_drm3d_blit.frag: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Fragment Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Fragment Shader 29 | * A basic fragment shader which applies a 2D texture. 30 | */ 31 | 32 | precision mediump float; 33 | 34 | uniform sampler2D texture; 35 | varying vec2 texpos; 36 | 37 | void main() 38 | { 39 | gl_FragColor = texture2D(texture, texpos); 40 | } 41 | -------------------------------------------------------------------------------- /src/uterm_drm3d_blit.vert: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Vertex Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Vertex Shader 29 | * This shader is a very basic vertex shader which forwards all data and 30 | * performs basic matrix multiplications. 31 | */ 32 | 33 | uniform mat4 projection; 34 | attribute vec2 position; 35 | attribute vec2 texture_position; 36 | varying vec2 texpos; 37 | 38 | void main() 39 | { 40 | gl_Position = projection * vec4(position, 0.0, 1.0); 41 | texpos = texture_position; 42 | } 43 | -------------------------------------------------------------------------------- /src/uterm_drm3d_fill.frag: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Fragment Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Default Fragment Shader 29 | * A basic fragment shader which applies a color directly. 30 | */ 31 | 32 | precision mediump float; 33 | 34 | varying vec4 col; 35 | 36 | void main() 37 | { 38 | gl_FragColor = col; 39 | } 40 | -------------------------------------------------------------------------------- /src/uterm_drm3d_fill.vert: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Vertex Shader 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Default Vertex Shader 29 | * This shader is a very basic vertex shader which forwards all data and 30 | * performs basic matrix multiplications. 31 | */ 32 | 33 | uniform mat4 projection; 34 | attribute vec2 position; 35 | attribute vec4 color; 36 | varying vec4 col; 37 | 38 | void main() 39 | { 40 | col = color; 41 | gl_Position = projection * vec4(position, 0.0, 1.0); 42 | } 43 | -------------------------------------------------------------------------------- /src/uterm_drm3d_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal drm3d module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_DRM3D_INTERNAL_H 29 | #define UTERM_DRM3D_INTERNAL_H 30 | 31 | #define EGL_EGLEXT_PROTOTYPES 32 | #define GL_GLEXT_PROTOTYPES 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include "uterm_video.h" 49 | 50 | /* thanks khronos for breaking backwards compatibility.. */ 51 | #if !defined(GL_UNPACK_ROW_LENGTH) && defined(GL_UNPACK_ROW_LENGTH_EXT) 52 | # define GL_UNPACK_ROW_LENGTH GL_UNPACK_ROW_LENGTH_EXT 53 | #endif 54 | 55 | struct uterm_drm3d_rb { 56 | struct uterm_display *disp; 57 | struct gbm_bo *bo; 58 | uint32_t fb; 59 | }; 60 | 61 | struct uterm_drm3d_display { 62 | struct gbm_surface *gbm; 63 | EGLSurface surface; 64 | struct uterm_drm3d_rb *current; 65 | struct uterm_drm3d_rb *next; 66 | }; 67 | 68 | struct uterm_drm3d_video { 69 | struct gbm_device *gbm; 70 | EGLDisplay disp; 71 | EGLConfig conf; 72 | EGLContext ctx; 73 | 74 | unsigned int sinit; 75 | bool supports_rowlen; 76 | GLuint tex; 77 | 78 | struct gl_shader *fill_shader; 79 | GLuint uni_fill_proj; 80 | 81 | struct gl_shader *blend_shader; 82 | GLuint uni_blend_proj; 83 | GLuint uni_blend_tex; 84 | GLuint uni_blend_fgcol; 85 | GLuint uni_blend_bgcol; 86 | 87 | struct gl_shader *blit_shader; 88 | GLuint uni_blit_proj; 89 | GLuint uni_blit_tex; 90 | }; 91 | 92 | int uterm_drm3d_display_use(struct uterm_display *disp, bool *opengl); 93 | void uterm_drm3d_deinit_shaders(struct uterm_video *video); 94 | int uterm_drm3d_display_blit(struct uterm_display *disp, 95 | const struct uterm_video_buffer *buf, 96 | unsigned int x, unsigned int y); 97 | int uterm_drm3d_display_fake_blendv(struct uterm_display *disp, 98 | const struct uterm_video_blend_req *req, 99 | size_t num); 100 | int uterm_drm3d_display_fill(struct uterm_display *disp, 101 | uint8_t r, uint8_t g, uint8_t b, 102 | unsigned int x, unsigned int y, 103 | unsigned int width, unsigned int height); 104 | 105 | #endif /* UTERM_DRM3D_INTERNAL_H */ 106 | -------------------------------------------------------------------------------- /src/uterm_drm_shared_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_DRM_SHARED_INTERNAL_H 29 | #define UTERM_DRM_SHARED_INTERNAL_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include "eloop.h" 35 | #include "shl_timer.h" 36 | #include "uterm_video.h" 37 | #include "uterm_video_internal.h" 38 | 39 | /* drm mode */ 40 | 41 | struct uterm_drm_mode { 42 | drmModeModeInfo info; 43 | }; 44 | 45 | int uterm_drm_mode_init(struct uterm_mode *mode); 46 | void uterm_drm_mode_destroy(struct uterm_mode *mode); 47 | const char *uterm_drm_mode_get_name(const struct uterm_mode *mode); 48 | unsigned int uterm_drm_mode_get_width(const struct uterm_mode *mode); 49 | unsigned int uterm_drm_mode_get_height(const struct uterm_mode *mode); 50 | void uterm_drm_mode_set(struct uterm_mode *mode, drmModeModeInfo *info); 51 | 52 | static inline drmModeModeInfo *uterm_drm_mode_get_info(struct uterm_mode *m) 53 | { 54 | struct uterm_drm_mode *mode = m->data; 55 | 56 | return &mode->info; 57 | } 58 | 59 | extern const struct mode_ops uterm_drm_mode_ops; 60 | 61 | /* drm dpms */ 62 | 63 | int uterm_drm_set_dpms(int fd, uint32_t conn_id, int state); 64 | int uterm_drm_get_dpms(int fd, drmModeConnector *conn); 65 | 66 | /* drm display */ 67 | 68 | struct uterm_drm_display { 69 | uint32_t conn_id; 70 | int crtc_id; 71 | drmModeCrtc *saved_crtc; 72 | void *data; 73 | }; 74 | 75 | int uterm_drm_display_init(struct uterm_display *disp, void *data); 76 | void uterm_drm_display_destroy(struct uterm_display *disp); 77 | int uterm_drm_display_activate(struct uterm_display *disp, int fd); 78 | void uterm_drm_display_deactivate(struct uterm_display *disp, int fd); 79 | int uterm_drm_display_set_dpms(struct uterm_display *disp, int state); 80 | int uterm_drm_display_wait_pflip(struct uterm_display *disp); 81 | int uterm_drm_display_swap(struct uterm_display *disp, uint32_t fb, 82 | bool immediate); 83 | 84 | static inline void *uterm_drm_display_get_data(struct uterm_display *disp) 85 | { 86 | struct uterm_drm_display *d = disp->data; 87 | 88 | return d->data; 89 | } 90 | 91 | /* drm video */ 92 | 93 | typedef void (*uterm_drm_page_flip_t) (struct uterm_display *disp); 94 | 95 | struct uterm_drm_video { 96 | int fd; 97 | struct ev_fd *efd; 98 | uterm_drm_page_flip_t page_flip; 99 | void *data; 100 | struct shl_timer *timer; 101 | struct ev_timer *vt_timer; 102 | const struct display_ops *display_ops; 103 | }; 104 | 105 | int uterm_drm_video_init(struct uterm_video *video, const char *node, 106 | const struct display_ops *display_ops, 107 | uterm_drm_page_flip_t pflip, void *data); 108 | void uterm_drm_video_destroy(struct uterm_video *video); 109 | int uterm_drm_video_find_crtc(struct uterm_video *video, drmModeRes *res, 110 | drmModeEncoder *enc); 111 | int uterm_drm_video_hotplug(struct uterm_video *video, bool read_dpms, 112 | bool modeset); 113 | int uterm_drm_video_wake_up(struct uterm_video *video); 114 | void uterm_drm_video_sleep(struct uterm_video *video); 115 | int uterm_drm_video_poll(struct uterm_video *video); 116 | int uterm_drm_video_wait_pflip(struct uterm_video *video, 117 | unsigned int *mtimeout); 118 | void uterm_drm_video_arm_vt_timer(struct uterm_video *video); 119 | 120 | static inline void *uterm_drm_video_get_data(struct uterm_video *video) 121 | { 122 | struct uterm_drm_video *v = video->data; 123 | 124 | return v->data; 125 | } 126 | 127 | #endif /* UTERM_DRM_SHARED_INTERNAL_H */ 128 | -------------------------------------------------------------------------------- /src/uterm_fbdev_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal fbdev module 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_FBDEV_INTERNAL_H 29 | #define UTERM_FBDEV_INTERNAL_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "uterm_video.h" 37 | 38 | struct fbdev_mode { 39 | unsigned int width; 40 | unsigned int height; 41 | }; 42 | 43 | struct fbdev_display { 44 | int fd; 45 | struct fb_fix_screeninfo finfo; 46 | struct fb_var_screeninfo vinfo; 47 | unsigned int rate; 48 | const char *node; 49 | 50 | unsigned int bufid; 51 | size_t xres; 52 | size_t yres; 53 | size_t len; 54 | uint8_t *map; 55 | unsigned int stride; 56 | 57 | bool xrgb32; 58 | bool rgb16; 59 | unsigned int Bpp; 60 | unsigned int off_r; 61 | unsigned int off_g; 62 | unsigned int off_b; 63 | unsigned int len_r; 64 | unsigned int len_g; 65 | unsigned int len_b; 66 | int_fast32_t dither_r; 67 | int_fast32_t dither_g; 68 | int_fast32_t dither_b; 69 | }; 70 | 71 | struct fbdev_video { 72 | char *node; 73 | bool pending_intro; 74 | }; 75 | 76 | int uterm_fbdev_display_blit(struct uterm_display *disp, 77 | const struct uterm_video_buffer *buf, 78 | unsigned int x, unsigned int y); 79 | int uterm_fbdev_display_fake_blendv(struct uterm_display *disp, 80 | const struct uterm_video_blend_req *req, 81 | size_t num); 82 | int uterm_fbdev_display_fill(struct uterm_display *disp, 83 | uint8_t r, uint8_t g, uint8_t b, 84 | unsigned int x, unsigned int y, 85 | unsigned int width, unsigned int height); 86 | 87 | #endif /* UTERM_FBDEV_INTERNAL_H */ 88 | -------------------------------------------------------------------------------- /src/uterm_input.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal Input Handling 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Input Devices 28 | * This input object can combine multiple linux input devices into a single 29 | * device and notifies the application about events. It has several different 30 | * keyboard backends so the full XKB feature set is available. 31 | */ 32 | 33 | #ifndef UTERM_UTERM_INPUT_H 34 | #define UTERM_UTERM_INPUT_H 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | struct uterm_input; 42 | 43 | typedef void (*uterm_input_log_t) (void *data, 44 | const char *file, 45 | int line, 46 | const char *func, 47 | const char *subs, 48 | unsigned int sev, 49 | const char *format, 50 | va_list args); 51 | 52 | /* keep in sync with shl_xkb_mods */ 53 | enum uterm_input_modifier { 54 | UTERM_SHIFT_MASK = (1 << 0), 55 | UTERM_LOCK_MASK = (1 << 1), 56 | UTERM_CONTROL_MASK = (1 << 2), 57 | UTERM_ALT_MASK = (1 << 3), 58 | UTERM_LOGO_MASK = (1 << 4), 59 | }; 60 | 61 | /* keep in sync with TSM_VTE_INVALID */ 62 | #define UTERM_INPUT_INVALID 0xffffffff 63 | 64 | struct uterm_input_event { 65 | bool handled; /* user-controlled, default is false */ 66 | uint16_t keycode; /* linux keycode - KEY_* - linux/input.h */ 67 | uint32_t ascii; /* ascii keysym for @keycode */ 68 | unsigned int mods; /* active modifiers - uterm_modifier mask */ 69 | 70 | unsigned int num_syms; /* number of keysyms */ 71 | uint32_t *keysyms; /* XKB-common keysym-array - XKB_KEY_* */ 72 | uint32_t *codepoints; /* ucs4 unicode value or UTERM_INPUT_INVALID */ 73 | }; 74 | 75 | #define UTERM_INPUT_HAS_MODS(_ev, _mods) (((_ev)->mods & (_mods)) == (_mods)) 76 | 77 | typedef void (*uterm_input_cb) (struct uterm_input *input, 78 | struct uterm_input_event *ev, 79 | void *data); 80 | 81 | int uterm_input_new(struct uterm_input **out, struct ev_eloop *eloop, 82 | const char *model, const char *layout, const char *variant, 83 | const char *options, const char *keymap, 84 | unsigned int repeat_delay, unsigned int repeat_rate, 85 | uterm_input_log_t log, void *log_data); 86 | void uterm_input_ref(struct uterm_input *input); 87 | void uterm_input_unref(struct uterm_input *input); 88 | 89 | void uterm_input_add_dev(struct uterm_input *input, const char *node); 90 | void uterm_input_remove_dev(struct uterm_input *input, const char *node); 91 | 92 | int uterm_input_register_cb(struct uterm_input *input, uterm_input_cb cb, 93 | void *data); 94 | void uterm_input_unregister_cb(struct uterm_input *input, uterm_input_cb cb, 95 | void *data); 96 | 97 | void uterm_input_sleep(struct uterm_input *input); 98 | void uterm_input_wake_up(struct uterm_input *input); 99 | bool uterm_input_is_awake(struct uterm_input *input); 100 | 101 | #endif /* UTERM_UTERM_INPUT_H */ 102 | -------------------------------------------------------------------------------- /src/uterm_input_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_INPUT_INTERNAL_H 29 | #define UTERM_INPUT_INTERNAL_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "eloop.h" 37 | #include "shl_dlist.h" 38 | #include "shl_llog.h" 39 | #include "shl_misc.h" 40 | #include "uterm_input.h" 41 | 42 | enum uterm_input_device_capability { 43 | UTERM_DEVICE_HAS_KEYS = (1 << 0), 44 | UTERM_DEVICE_HAS_LEDS = (1 << 1), 45 | }; 46 | 47 | struct uterm_input_dev { 48 | struct shl_dlist list; 49 | struct uterm_input *input; 50 | 51 | unsigned int capabilities; 52 | int rfd; 53 | char *node; 54 | struct ev_fd *fd; 55 | struct xkb_state *state; 56 | /* Used in sleep/wake up to store the key's pressed/released state. */ 57 | char key_state_bits[SHL_DIV_ROUND_UP(KEY_CNT, CHAR_BIT)]; 58 | 59 | unsigned int num_syms; 60 | struct uterm_input_event event; 61 | struct uterm_input_event repeat_event; 62 | 63 | bool repeating; 64 | struct ev_timer *repeat_timer; 65 | }; 66 | 67 | struct uterm_input { 68 | unsigned long ref; 69 | llog_submit_t llog; 70 | void *llog_data; 71 | struct ev_eloop *eloop; 72 | int awake; 73 | unsigned int repeat_rate; 74 | unsigned int repeat_delay; 75 | 76 | struct shl_hook *hook; 77 | struct xkb_context *ctx; 78 | struct xkb_keymap *keymap; 79 | 80 | struct shl_dlist devices; 81 | }; 82 | 83 | static inline bool input_bit_is_set(const unsigned long *array, int bit) 84 | { 85 | return !!(array[bit / LONG_BIT] & (1LL << (bit % LONG_BIT))); 86 | } 87 | 88 | int uxkb_desc_init(struct uterm_input *input, 89 | const char *model, 90 | const char *layout, 91 | const char *variant, 92 | const char *options, 93 | const char *keymap); 94 | void uxkb_desc_destroy(struct uterm_input *input); 95 | 96 | int uxkb_dev_init(struct uterm_input_dev *dev); 97 | void uxkb_dev_destroy(struct uterm_input_dev *dev); 98 | int uxkb_dev_process(struct uterm_input_dev *dev, 99 | uint16_t key_state, 100 | uint16_t code); 101 | void uxkb_dev_sleep(struct uterm_input_dev *dev); 102 | void uxkb_dev_wake_up(struct uterm_input_dev *dev); 103 | 104 | #endif /* UTERM_INPUT_INTERNAL_H */ 105 | -------------------------------------------------------------------------------- /src/uterm_monitor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal System Monitor 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * System Monitor 28 | * This watches the system for new seats, graphics devices or other devices that 29 | * are used by terminals. 30 | */ 31 | 32 | #ifndef UTERM_UTERM_MONITOR_H 33 | #define UTERM_UTERM_MONITOR_H 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | struct uterm_monitor; 41 | struct uterm_monitor_seat; 42 | struct uterm_monitor_dev; 43 | 44 | enum uterm_monitor_event_type { 45 | UTERM_MONITOR_NEW_SEAT, 46 | UTERM_MONITOR_FREE_SEAT, 47 | UTERM_MONITOR_NEW_DEV, 48 | UTERM_MONITOR_FREE_DEV, 49 | UTERM_MONITOR_HOTPLUG_DEV, 50 | }; 51 | 52 | enum uterm_monitor_dev_type { 53 | UTERM_MONITOR_DRM, 54 | UTERM_MONITOR_FBDEV, 55 | UTERM_MONITOR_INPUT, 56 | }; 57 | 58 | enum uterm_monitor_dev_flag { 59 | UTERM_MONITOR_DRM_BACKED = 0x01, 60 | UTERM_MONITOR_PRIMARY = 0x02, 61 | UTERM_MONITOR_AUX = 0x04, 62 | }; 63 | 64 | struct uterm_monitor_event { 65 | unsigned int type; 66 | 67 | struct uterm_monitor_seat *seat; 68 | const char *seat_name; 69 | void *seat_data; 70 | 71 | struct uterm_monitor_dev *dev; 72 | unsigned int dev_type; 73 | unsigned int dev_flags; 74 | const char *dev_node; 75 | void *dev_data; 76 | }; 77 | 78 | typedef void (*uterm_monitor_cb) (struct uterm_monitor *mon, 79 | struct uterm_monitor_event *event, 80 | void *data); 81 | 82 | int uterm_monitor_new(struct uterm_monitor **out, struct ev_eloop *eloop, 83 | uterm_monitor_cb cb, void *data); 84 | void uterm_monitor_ref(struct uterm_monitor *mon); 85 | void uterm_monitor_unref(struct uterm_monitor *mon); 86 | void uterm_monitor_scan(struct uterm_monitor *mon); 87 | 88 | void uterm_monitor_set_seat_data(struct uterm_monitor_seat *seat, void *data); 89 | void uterm_monitor_set_dev_data(struct uterm_monitor_dev *dev, void *data); 90 | 91 | #endif /* UTERM_UTERM_MONITOR_H */ 92 | -------------------------------------------------------------------------------- /src/uterm_systemd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Systemd integration 28 | * Systemd provides multi-seat support and other helpers that we can use in 29 | * uterm. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "shl_log.h" 40 | #include "uterm_monitor.h" 41 | #include "uterm_systemd_internal.h" 42 | 43 | #define LOG_SUBSYSTEM "systemd" 44 | 45 | struct uterm_sd { 46 | sd_login_monitor *mon; 47 | }; 48 | 49 | int uterm_sd_new(struct uterm_sd **out) 50 | { 51 | int ret; 52 | struct uterm_sd *sd; 53 | 54 | if (!out) 55 | return -EINVAL; 56 | 57 | ret = sd_booted(); 58 | if (ret < 0) { 59 | log_warning("cannot determine whether system booted with systemd (%d): %s", 60 | ret, strerror(-ret)); 61 | return -EOPNOTSUPP; 62 | } else if (!ret) { 63 | log_info("system not booted with systemd, disabling multi-seat support"); 64 | return -EOPNOTSUPP; 65 | } 66 | 67 | log_info("system booted with systemd, enabling multi-seat support"); 68 | 69 | sd = malloc(sizeof(*sd)); 70 | if (!sd) 71 | return -ENOMEM; 72 | memset(sd, 0, sizeof(*sd)); 73 | 74 | ret = sd_login_monitor_new("seat", &sd->mon); 75 | if (ret) { 76 | log_err("cannot create systemd login monitor (%d): %s", 77 | ret, strerror(-ret)); 78 | ret = -EFAULT; 79 | goto err_free; 80 | } 81 | 82 | *out = sd; 83 | return 0; 84 | 85 | err_free: 86 | free(sd); 87 | return ret; 88 | } 89 | 90 | void uterm_sd_free(struct uterm_sd *sd) 91 | { 92 | if (!sd) 93 | return; 94 | 95 | sd_login_monitor_unref(sd->mon); 96 | free(sd); 97 | } 98 | 99 | int uterm_sd_get_fd(struct uterm_sd *sd) 100 | { 101 | if (!sd) 102 | return -EINVAL; 103 | 104 | return sd_login_monitor_get_fd(sd->mon); 105 | } 106 | 107 | void uterm_sd_flush(struct uterm_sd *sd) 108 | { 109 | if (!sd) 110 | return; 111 | 112 | sd_login_monitor_flush(sd->mon); 113 | } 114 | 115 | int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats) 116 | { 117 | int ret; 118 | char **s; 119 | 120 | if (!sd || !seats) 121 | return -EINVAL; 122 | 123 | ret = sd_get_seats(&s); 124 | if (ret < 0) { 125 | log_warning("cannot read seat information from systemd: %d", 126 | ret); 127 | return -EFAULT; 128 | } 129 | 130 | *seats = s; 131 | return ret; 132 | } 133 | -------------------------------------------------------------------------------- /src/uterm_systemd_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Systemd integration 28 | * Systemd provides multi-seat support and other helpers that we can use in 29 | * uterm. 30 | */ 31 | 32 | #ifndef UTERM_SYSTEMD_H 33 | #define UTERM_SYSTEMD_H 34 | 35 | #include 36 | #include "uterm_monitor.h" 37 | 38 | struct uterm_sd; 39 | 40 | #ifdef BUILD_ENABLE_MULTI_SEAT 41 | 42 | int uterm_sd_new(struct uterm_sd **out); 43 | void uterm_sd_free(struct uterm_sd *sd); 44 | int uterm_sd_get_fd(struct uterm_sd *sd); 45 | void uterm_sd_flush(struct uterm_sd *sd); 46 | int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats); 47 | 48 | #else 49 | 50 | static inline int uterm_sd_new(struct uterm_sd **out) 51 | { 52 | return -EOPNOTSUPP; 53 | } 54 | 55 | static inline void uterm_sd_free(struct uterm_sd *sd) 56 | { 57 | } 58 | 59 | static inline int uterm_sd_get_fd(struct uterm_sd *sd) 60 | { 61 | return -1; 62 | } 63 | 64 | static inline void uterm_sd_flush(struct uterm_sd *sd) 65 | { 66 | } 67 | 68 | static inline int uterm_sd_get_seats(struct uterm_sd *sd, char ***seats) 69 | { 70 | return -EINVAL; 71 | } 72 | 73 | #endif 74 | 75 | #endif /* UTERM_SYSTEMD_H */ 76 | -------------------------------------------------------------------------------- /src/uterm_video_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* Internal definitions */ 27 | 28 | #ifndef UTERM_VIDEO_INTERNAL_H 29 | #define UTERM_VIDEO_INTERNAL_H 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "eloop.h" 36 | #include "shl_dlist.h" 37 | #include "shl_hook.h" 38 | #include "uterm_video.h" 39 | 40 | /* backend-operations */ 41 | 42 | struct mode_ops { 43 | int (*init) (struct uterm_mode *mode); 44 | void (*destroy) (struct uterm_mode *mode); 45 | const char *(*get_name) (const struct uterm_mode *mode); 46 | unsigned int (*get_width) (const struct uterm_mode *mode); 47 | unsigned int (*get_height) (const struct uterm_mode *mode); 48 | }; 49 | 50 | struct display_ops { 51 | int (*init) (struct uterm_display *display); 52 | void (*destroy) (struct uterm_display *display); 53 | int (*activate) (struct uterm_display *disp, struct uterm_mode *mode); 54 | void (*deactivate) (struct uterm_display *disp); 55 | int (*set_dpms) (struct uterm_display *disp, int state); 56 | int (*use) (struct uterm_display *disp, bool *opengl); 57 | int (*get_buffers) (struct uterm_display *disp, 58 | struct uterm_video_buffer *buffer, 59 | unsigned int formats); 60 | int (*swap) (struct uterm_display *disp, bool immediate); 61 | int (*blit) (struct uterm_display *disp, 62 | const struct uterm_video_buffer *buf, 63 | unsigned int x, unsigned int y); 64 | int (*fake_blendv) (struct uterm_display *disp, 65 | const struct uterm_video_blend_req *req, 66 | size_t num); 67 | int (*fill) (struct uterm_display *disp, 68 | uint8_t r, uint8_t g, uint8_t b, unsigned int x, 69 | unsigned int y, unsigned int width, unsigned int height); 70 | }; 71 | 72 | struct video_ops { 73 | int (*init) (struct uterm_video *video, const char *node); 74 | void (*destroy) (struct uterm_video *video); 75 | void (*segfault) (struct uterm_video *video); 76 | int (*poll) (struct uterm_video *video); 77 | void (*sleep) (struct uterm_video *video); 78 | int (*wake_up) (struct uterm_video *video); 79 | }; 80 | 81 | struct uterm_video_module { 82 | const struct video_ops *ops; 83 | }; 84 | 85 | #define VIDEO_CALL(func, els, ...) (func ? func(__VA_ARGS__) : els) 86 | 87 | /* uterm_mode */ 88 | 89 | struct uterm_mode { 90 | struct shl_dlist list; 91 | unsigned long ref; 92 | struct uterm_display *disp; 93 | 94 | const struct mode_ops *ops; 95 | void *data; 96 | }; 97 | 98 | int mode_new(struct uterm_mode **out, const struct mode_ops *ops); 99 | int uterm_mode_bind(struct uterm_mode *mode, struct uterm_display *disp); 100 | void uterm_mode_unbind(struct uterm_mode *mode); 101 | 102 | /* uterm_display */ 103 | 104 | #define DISPLAY_ONLINE 0x01 105 | #define DISPLAY_VSYNC 0x02 106 | #define DISPLAY_AVAILABLE 0x04 107 | #define DISPLAY_OPEN 0x08 108 | #define DISPLAY_DBUF 0x10 109 | #define DISPLAY_DITHERING 0x20 110 | #define DISPLAY_PFLIP 0x40 111 | 112 | struct uterm_display { 113 | struct shl_dlist list; 114 | unsigned long ref; 115 | unsigned int flags; 116 | struct uterm_video *video; 117 | 118 | struct shl_hook *hook; 119 | struct shl_dlist modes; 120 | struct uterm_mode *default_mode; 121 | struct uterm_mode *current_mode; 122 | int dpms; 123 | 124 | bool vblank_scheduled; 125 | struct itimerspec vblank_spec; 126 | struct ev_timer *vblank_timer; 127 | 128 | const struct display_ops *ops; 129 | void *data; 130 | }; 131 | 132 | int display_new(struct uterm_display **out, const struct display_ops *ops); 133 | void display_set_vblank_timer(struct uterm_display *disp, 134 | unsigned int msecs); 135 | int display_schedule_vblank_timer(struct uterm_display *disp); 136 | int uterm_display_bind(struct uterm_display *disp, struct uterm_video *video); 137 | void uterm_display_unbind(struct uterm_display *disp); 138 | 139 | #define DISPLAY_CB(disp, act) shl_hook_call((disp)->hook, (disp), \ 140 | &(struct uterm_display_event){ \ 141 | .action = (act), \ 142 | }) 143 | 144 | static inline bool display_is_online(const struct uterm_display *disp) 145 | { 146 | return disp->video && (disp->flags & DISPLAY_ONLINE); 147 | } 148 | 149 | /* uterm_video */ 150 | 151 | #define VIDEO_AWAKE 0x01 152 | #define VIDEO_HOTPLUG 0x02 153 | 154 | struct uterm_video { 155 | unsigned long ref; 156 | unsigned int flags; 157 | struct ev_eloop *eloop; 158 | 159 | struct shl_dlist displays; 160 | struct shl_hook *hook; 161 | 162 | const struct uterm_video_module *mod; 163 | const struct video_ops *ops; 164 | void *data; 165 | }; 166 | 167 | static inline bool video_is_awake(const struct uterm_video *video) 168 | { 169 | return video->flags & VIDEO_AWAKE; 170 | } 171 | 172 | static inline bool video_need_hotplug(const struct uterm_video *video) 173 | { 174 | return video->flags & VIDEO_HOTPLUG; 175 | } 176 | 177 | #define VIDEO_CB(vid, disp, act) shl_hook_call((vid)->hook, (vid), \ 178 | &(struct uterm_video_hotplug){ \ 179 | .display = (disp), \ 180 | .action = (act), \ 181 | }) 182 | 183 | #if defined(BUILD_ENABLE_VIDEO_DRM3D) || defined(BUILD_ENABLE_VIDEO_DRM2D) 184 | 185 | #include 186 | 187 | static inline bool video_drm_available(void) 188 | { 189 | return drmAvailable(); 190 | } 191 | 192 | #else 193 | 194 | static inline bool video_drm_available(void) 195 | { 196 | return false; 197 | } 198 | 199 | #endif 200 | 201 | #endif /* UTERM_VIDEO_INTERNAL_H */ 202 | -------------------------------------------------------------------------------- /src/uterm_vt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uterm - Linux User-Space Terminal VT API 3 | * 4 | * Copyright (c) 2011-2013 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /* 27 | * Virtual Terminals 28 | * Virtual terminals allow controlling multiple virtual terminals on one real 29 | * terminal. It is multi-seat capable and fully asynchronous. 30 | */ 31 | 32 | #ifndef UTERM_UTERM_VT_H 33 | #define UTERM_UTERM_VT_H 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | struct uterm_vt; 42 | struct uterm_vt_master; 43 | 44 | enum uterm_vt_action { 45 | UTERM_VT_ACTIVATE, 46 | UTERM_VT_DEACTIVATE, 47 | UTERM_VT_HUP, 48 | }; 49 | 50 | enum uterm_vt_flags { 51 | UTERM_VT_FORCE = 0x01, 52 | }; 53 | 54 | struct uterm_vt_event { 55 | unsigned int action; 56 | unsigned int flags; 57 | int target; 58 | }; 59 | 60 | enum uterm_vt_type { 61 | UTERM_VT_REAL = 0x01, 62 | UTERM_VT_FAKE = 0x02, 63 | }; 64 | 65 | typedef int (*uterm_vt_cb) (struct uterm_vt *vt, struct uterm_vt_event *ev, 66 | void *data); 67 | 68 | int uterm_vt_master_new(struct uterm_vt_master **out, 69 | struct ev_eloop *eloop); 70 | void uterm_vt_master_ref(struct uterm_vt_master *vtm); 71 | void uterm_vt_master_unref(struct uterm_vt_master *vtm); 72 | 73 | int uterm_vt_master_activate_all(struct uterm_vt_master *vtm); 74 | int uterm_vt_master_deactivate_all(struct uterm_vt_master *vtm); 75 | 76 | int uterm_vt_allocate(struct uterm_vt_master *vt, struct uterm_vt **out, 77 | unsigned int allowed_types, 78 | const char *seat, struct uterm_input *input, 79 | const char *vt_name, uterm_vt_cb cb, void *data); 80 | void uterm_vt_deallocate(struct uterm_vt *vt); 81 | void uterm_vt_ref(struct uterm_vt *vt); 82 | void uterm_vt_unref(struct uterm_vt *vt); 83 | 84 | int uterm_vt_activate(struct uterm_vt *vt); 85 | int uterm_vt_deactivate(struct uterm_vt *vt); 86 | void uterm_vt_retry(struct uterm_vt *vt); 87 | unsigned int uterm_vt_get_type(struct uterm_vt *vt); 88 | unsigned int uterm_vt_get_num(struct uterm_vt *vt); 89 | 90 | #endif /* UTERM_UTERM_VT_H */ 91 | -------------------------------------------------------------------------------- /tests/test_include.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kmscon - Common test functions 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "conf.h" 33 | #include "eloop.h" 34 | #include "shl_log.h" 35 | 36 | #define TEST_HELP \ 37 | "\t-h, --help [off] Print this help and exit\n" \ 38 | "\t-v, --verbose [off] Print verbose messages\n" \ 39 | "\t --debug [off] Enable debug mode\n" \ 40 | "\t --silent [off] Suppress notices and warnings\n" 41 | 42 | static struct { 43 | bool help; 44 | bool exit; 45 | bool verbose; 46 | bool debug; 47 | bool silent; 48 | } test_conf; 49 | 50 | static struct conf_ctx *test_ctx; 51 | 52 | static int aftercheck_debug(struct conf_option *opt, int argc, char **argv, 53 | int idx) 54 | { 55 | /* --debug implies --verbose */ 56 | if (test_conf.debug) 57 | test_conf.verbose = 1; 58 | 59 | return 0; 60 | } 61 | 62 | static int aftercheck_help(struct conf_option *opt, int argc, char **argv, 63 | int idx) 64 | { 65 | /* exit after printing --help information */ 66 | if (test_conf.help) { 67 | print_help(); 68 | test_conf.exit = true; 69 | } 70 | 71 | return 0; 72 | } 73 | 74 | #define TEST_OPTIONS \ 75 | CONF_OPTION_BOOL_FULL('h', "help", aftercheck_help, NULL, NULL, &test_conf.help, false), \ 76 | CONF_OPTION_BOOL('v', "verbose", &test_conf.verbose, false), \ 77 | CONF_OPTION_BOOL_FULL(0, "debug", aftercheck_debug, NULL, NULL, &test_conf.debug, false), \ 78 | CONF_OPTION_BOOL(0, "silent", &test_conf.silent, false) 79 | 80 | static void sig_generic(struct ev_eloop *p, struct signalfd_siginfo *info, 81 | void *data) 82 | { 83 | struct ev_eloop *eloop = data; 84 | 85 | ev_eloop_exit(eloop); 86 | log_info("terminating due to caught signal %d", info->ssi_signo); 87 | } 88 | 89 | static int test_prepare(struct conf_option *opts, size_t len, 90 | int argc, char **argv, struct ev_eloop **out) 91 | { 92 | int ret; 93 | struct ev_eloop *eloop; 94 | 95 | ret = conf_ctx_new(&test_ctx, opts, len, &test_conf); 96 | if (ret) 97 | return ret; 98 | 99 | ret = conf_ctx_parse_argv(test_ctx, argc, argv); 100 | if (ret) 101 | goto err_out; 102 | 103 | if (test_conf.exit) { 104 | ret = -ECANCELED; 105 | goto err_out; 106 | } 107 | 108 | if (!test_conf.debug && !test_conf.verbose && test_conf.silent) 109 | log_set_config(&LOG_CONFIG_WARNING(0, 0, 0, 0)); 110 | else 111 | log_set_config(&LOG_CONFIG_INFO(test_conf.debug, 112 | test_conf.verbose)); 113 | 114 | log_print_init(argv[0]); 115 | 116 | ret = ev_eloop_new(&eloop, log_llog, NULL); 117 | if (ret) 118 | goto err_out; 119 | 120 | ret = ev_eloop_register_signal_cb(eloop, SIGTERM, sig_generic, eloop); 121 | if (ret) 122 | goto err_unref; 123 | 124 | ret = ev_eloop_register_signal_cb(eloop, SIGINT, sig_generic, eloop); 125 | if (ret) { 126 | ev_eloop_unregister_signal_cb(eloop, SIGTERM, 127 | sig_generic, eloop); 128 | goto err_unref; 129 | } 130 | 131 | *out = eloop; 132 | return 0; 133 | 134 | err_unref: 135 | ev_eloop_unref(eloop); 136 | err_out: 137 | conf_ctx_free(test_ctx); 138 | return ret; 139 | } 140 | 141 | static void test_fail(int ret) 142 | { 143 | if (ret) 144 | log_err("init failed, errno %d: %s", ret, strerror(-ret)); 145 | } 146 | 147 | static void test_exit(struct conf_option *opts, size_t len, 148 | struct ev_eloop *eloop) 149 | { 150 | ev_eloop_unregister_signal_cb(eloop, SIGINT, sig_generic, eloop); 151 | ev_eloop_unregister_signal_cb(eloop, SIGTERM, sig_generic, eloop); 152 | ev_eloop_unref(eloop); 153 | conf_ctx_free(test_ctx); 154 | } 155 | -------------------------------------------------------------------------------- /tests/test_key.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test_key - Test client key-input 3 | * 4 | * Copyright (c) 2012 David Herrmann 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | int main() 33 | { 34 | int res; 35 | unsigned char buf; 36 | struct termios omode, nmode; 37 | bool reset = false; 38 | 39 | fprintf(stderr, "Quit with 'q' (maybe followed by 'enter'/'return')\r\n"); 40 | fprintf(stderr, "Maybe your terminal may be unusable after this, use 'reset' to fix it\r\n"); 41 | 42 | if (tcgetattr(0, &omode) < 0) { 43 | fprintf(stderr, "cannot retrieve terminal attributes (%d): %m\r\n", 44 | errno); 45 | } else { 46 | memcpy(&nmode, &omode, sizeof(nmode)); 47 | cfmakeraw(&nmode); 48 | if (tcsetattr(0, TCSANOW, &nmode) < 0) 49 | fprintf(stderr, "cannot set terminal attributes (%d): %m\r\n", 50 | errno); 51 | else 52 | reset = true; 53 | } 54 | 55 | while (1) { 56 | res = fread(&buf, 1, 1, stdin); 57 | if (res != 1) { 58 | fprintf(stderr, "error on stdin: %d %d: %m\r\n", 59 | res, errno); 60 | break; 61 | } 62 | 63 | if (buf == '\n') 64 | fprintf(stderr, "key: \r\n"); 65 | else 66 | fprintf(stderr, "key: %x %u %o '%c'\r\n", 67 | (int)buf, buf, buf, buf); 68 | 69 | if (buf == 'q') 70 | break; 71 | } 72 | 73 | if (reset && tcsetattr(0, TCSANOW, &omode) < 0) 74 | fprintf(stderr, "cannot reset terminal attributes (%d): %m\r\n", 75 | errno); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/test_vt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test_console - Test VT Layer 3 | * 4 | * Copyright (c) 2011-2012 David Herrmann 5 | * Copyright (c) 2011 University of Tuebingen 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining 8 | * a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, 11 | * distribute, sublicense, and/or sell copies of the Software, and to 12 | * permit persons to whom the Software is furnished to do so, subject to 13 | * the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Test VT Layer 29 | * This opens a new VT and prints some text on it. You can then change the VT 30 | * and change back. This is only to test the VT subsystem and event engine. 31 | * This automatically switches to the new VT. Currently, the display gets 32 | * frozen because we aren't painting to the framebuffer yet. Use 33 | * ctrl+alt+FX (or some equivalent) to switch back to X/VT. 34 | */ 35 | 36 | static void print_help(); 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include "eloop.h" 46 | #include "shl_log.h" 47 | #include "uterm_input.h" 48 | #include "uterm_vt.h" 49 | #include "test_include.h" 50 | 51 | static void print_help() 52 | { 53 | /* 54 | * Usage/Help information 55 | * This should be scaled to a maximum of 80 characters per line: 56 | * 57 | * 80 char line: 58 | * | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 59 | * "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n" 60 | * 80 char line starting with tab: 61 | * |10| 20 | 30 | 40 | 50 | 60 | 70 | 80 | 62 | * "\t901234567890123456789012345678901234567890123456789012345678901234567890\n" 63 | */ 64 | fprintf(stderr, 65 | "Usage:\n" 66 | "\t%1$s [options]\n" 67 | "\t%1$s -h [options]\n" 68 | "\n" 69 | "You can prefix boolean options with \"no-\" to negate it. If an argument is\n" 70 | "given multiple times, only the last argument matters if not otherwise stated.\n" 71 | "\n" 72 | "General Options:\n" 73 | TEST_HELP 74 | "\n" 75 | "VT Options:\n" 76 | "\t --vt [-] Path to VT to use\n" 77 | "\t-s, --switchvt [off] Switch automatically to the new VT\n", 78 | "test_vt"); 79 | /* 80 | * 80 char line: 81 | * | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 82 | * "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n" 83 | * 80 char line starting with tab: 84 | * |10| 20 | 30 | 40 | 50 | 60 | 70 | 80 | 85 | * "\t901234567890123456789012345678901234567890123456789012345678901234567890\n" 86 | */ 87 | } 88 | 89 | static const char *vtpath = NULL; 90 | static bool switchvt = false; 91 | 92 | struct conf_option options[] = { 93 | TEST_OPTIONS, 94 | CONF_OPTION_STRING(0, "vt", &vtpath, NULL), 95 | CONF_OPTION_BOOL('s', "switchvt", &switchvt, false), 96 | }; 97 | 98 | int main(int argc, char **argv) 99 | { 100 | int ret; 101 | struct ev_eloop *eloop; 102 | struct uterm_vt_master *vtm; 103 | struct uterm_input *input; 104 | struct uterm_vt *vt; 105 | size_t onum; 106 | 107 | onum = sizeof(options) / sizeof(*options); 108 | ret = test_prepare(options, onum, argc, argv, &eloop); 109 | if (ret) 110 | goto err_fail; 111 | 112 | ret = uterm_vt_master_new(&vtm, eloop); 113 | if (ret) 114 | goto err_exit; 115 | 116 | ret = uterm_input_new(&input, eloop, "", "", "", "", "", 0, 0, 117 | log_llog, NULL); 118 | if (ret) 119 | goto err_vtm; 120 | 121 | ret = uterm_vt_allocate(vtm, &vt, UTERM_VT_FAKE | UTERM_VT_REAL, 122 | "seat0", input, vtpath, NULL, NULL); 123 | if (ret) 124 | goto err_input; 125 | 126 | if (switchvt) { 127 | ret = uterm_vt_activate(vt); 128 | if (ret == -EINPROGRESS) 129 | log_debug("VT switch in progress"); 130 | else if (ret) 131 | log_warn("cannot switch to VT: %d", ret); 132 | } 133 | 134 | ev_eloop_run(eloop, -1); 135 | 136 | log_debug("Terminating"); 137 | 138 | /* switch back to previous VT but wait for eloop to process SIGUSR0 */ 139 | if (switchvt) { 140 | ret = uterm_vt_deactivate(vt); 141 | if (ret == -EINPROGRESS) 142 | ev_eloop_run(eloop, 50); 143 | } 144 | 145 | uterm_vt_unref(vt); 146 | err_input: 147 | uterm_input_unref(input); 148 | err_vtm: 149 | uterm_vt_master_unref(vtm); 150 | err_exit: 151 | test_exit(options, onum, eloop); 152 | err_fail: 153 | if (ret != -ECANCELED) 154 | test_fail(ret); 155 | return abs(ret); 156 | } 157 | --------------------------------------------------------------------------------