├── .clang-format
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE.md
├── pull_request_template.md
└── workflows
│ ├── Build Test.yml
│ └── codeql-analysis.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG
├── I3LOCK_VERSION
├── LICENSE
├── Makefile.am
├── README.md
├── SECURITY.md
├── _config.yml
├── blur.c
├── blur.h
├── blur_simd.c
├── build.sh
├── configure.ac
├── cursors.h
├── dpi.c
├── dpi.h
├── examples
├── lock.sh
├── lock_bar.sh
├── screenshot.png
└── screenshot_2017.png
├── fonts.h
├── i3lock-bash
├── i3lock-zsh
├── i3lock.1
├── i3lock.c
├── i3lock.h
├── install-i3lock-color.sh
├── jpg.c
├── jpg.h
├── m4
├── ax_append_flag.m4
├── ax_cflags_warn_all.m4
├── ax_check_bash_completion.m4
├── ax_check_compile_flag.m4
├── ax_check_enable_debug.m4
├── ax_check_gnu_make.m4
├── ax_check_link_flag.m4
├── ax_check_zsh_completion.m4
├── ax_code_coverage.m4
├── ax_configure_args.m4
├── ax_enable_builddir.m4
├── ax_extend_srcdir.m4
├── ax_require_defined.m4
└── ax_sanitizers.m4
├── pam
└── i3lock
├── randr.c
├── randr.h
├── rgba.h
├── tinyexpr.c
├── tinyexpr.h
├── travis
└── Dockerfile
├── unlock_indicator.c
├── unlock_indicator.h
├── xcb.c
└── xcb.h
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: google
2 | AllowShortIfStatementsOnASingleLine: false
3 | AllowShortLoopsOnASingleLine: false
4 | AllowShortFunctionsOnASingleLine: None
5 | AllowShortBlocksOnASingleLine: false
6 | AlwaysBreakBeforeMultilineStrings: false
7 | IndentWidth: 4
8 | PointerBindsToType: false
9 | ColumnLimit: 0
10 | SpaceBeforeParens: ControlStatements
11 | SortIncludes: false
12 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | text eol=lf
5 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [Raymo111]
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | ## This issue is a....
6 |
7 |
8 | [ ] Bug
9 | [ ] Other kind of issue (Please describe in detail)
10 |
11 |
12 | ## Current Behavior
13 |
14 |
15 | ## Expected Behavior
16 |
17 |
18 | ## Reproduction Instructions
19 |
23 |
24 | ## Environment
25 | Output of `i3lock --version`:
26 |
27 | i3lock version:
28 |
29 |
30 | Where'd you get i3lock-color from?
31 |
32 |
33 | [ ] AUR package (which one?)
34 | [ ] Built from source yourself
35 | [ ] Other (Please describe in detail)
36 |
37 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
4 | Closes #[issue number]
5 |
6 | ## Description
7 | -
8 |
9 | ### Screenshots/screencaps
10 |
13 |
14 | ## Release notes
15 |
19 | Notes:
20 |
--------------------------------------------------------------------------------
/.github/workflows/Build Test.yml:
--------------------------------------------------------------------------------
1 | name: Build Test
2 |
3 | on: [push, pull_request]
4 | jobs:
5 | build:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v2
9 | - name: Install deps
10 | run: |
11 | sudo apt update
12 | sudo apt install pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev libgif-dev
13 | - name: Build
14 | run: ./build.sh
15 | - name: Check and distcheck
16 | run: |
17 | cd build
18 | make check
19 | make distcheck
20 | - name: Upload binary artifact
21 | uses: actions/upload-artifact@v4
22 | with:
23 | name: i3lock
24 | path: /home/runner/work/i3lock-color/i3lock-color/build/i3lock
25 | - run: ./install-i3lock-color.sh
26 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | name: "CodeQL"
7 |
8 | on:
9 | push:
10 | branches: [master]
11 | pull_request:
12 | # The branches below must be a subset of the branches above
13 | branches: [master]
14 | schedule:
15 | - cron: '0 16 * * 4'
16 |
17 | jobs:
18 | analyze:
19 | name: Analyze
20 | runs-on: ubuntu-latest
21 |
22 | strategy:
23 | fail-fast: false
24 | # matrix:
25 | # Override automatic language detection by changing the below list
26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
27 | # language: ['cpp']
28 | # Learn more...
29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
30 |
31 | steps:
32 | - name: Checkout repository
33 | uses: actions/checkout@v2
34 | with:
35 | # We must fetch at least the immediate parents so that if this is
36 | # a pull request then we can checkout the head.
37 | fetch-depth: 2
38 |
39 | # If this run was triggered by a pull request event, then checkout
40 | # the head of the pull request instead of the merge commit.
41 | # CodeQL apparently deprecated this feature and now warns on running this command
42 | # - run: git checkout HEAD^2
43 | # if: ${{ github.event_name == 'pull_request' }}
44 |
45 | # Initializes the CodeQL tools for scanning.
46 | - name: Initialize CodeQL
47 | uses: github/codeql-action/init@v1
48 | with:
49 | languages: ${{ matrix.language }}
50 | # If you wish to specify custom queries, you can do so here or in a config file.
51 | # By default, queries listed here will override any specified in a config file.
52 | # Prefix the list here with "+" to use these queries and those in the config file.
53 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
54 |
55 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
56 | # If this step fails, then you should remove it and run the build manually (see below)
57 | #- name: Autobuild
58 | # uses: github/codeql-action/autobuild@v1
59 |
60 | # ℹ️ Command-line programs to run using the OS shell.
61 | # 📚 https://git.io/JvXDl
62 |
63 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
64 | # and modify them (or add more) to build your code if your project
65 | # uses a compiled language
66 |
67 | - run: |
68 | sudo apt-get update
69 | sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev libgif-dev
70 | ./build.sh
71 |
72 | - name: Perform CodeQL Analysis
73 | uses: github/codeql-action/analyze@v1
74 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | i3lock
2 | *.o
3 | tags
4 | *.swp
5 | *.gz
6 | *~
7 | x86_64-pc-linux-gnu
8 |
9 | ################################################################################
10 | # https://raw.githubusercontent.com/github/gitignore/master/Autotools.gitignore
11 | ################################################################################
12 |
13 | # http://www.gnu.org/software/automake
14 |
15 | Makefile.in
16 | /ar-lib
17 | /test-driver
18 |
19 | # http://www.gnu.org/software/autoconf
20 |
21 | /autom4te.cache
22 | /autoscan.log
23 | /autoscan-*.log
24 | /aclocal.m4
25 | /compile
26 | /config.h.in
27 | /config.guess
28 | /config.sub
29 | /configure
30 | /configure.scan
31 | /depcomp
32 | /install-sh
33 | /missing
34 | /stamp-h1
35 | aminclude_static.am
36 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # Use Ubuntu 14.04 (trusty), as per http://blog.travis-ci.com/2015-10-14-opening-up-ubuntu-trusty-beta/
2 | sudo: false
3 | dist: trusty
4 | services:
5 | - docker
6 | language: c
7 | compiler:
8 | - gcc
9 | - clang
10 | script:
11 | - docker build --pull --no-cache --rm -t=i3lock -f travis/Dockerfile .
12 | - docker run -e CC=$CC -v $PWD:/usr/src:rw i3lock /bin/sh -c 'clang-format-9 -i *.[ch] && git diff --exit-code || (echo "Code was not formatted using clang-format!"; false)'
13 | - docker run -e CC=$CC -v $PWD:/usr/src:rw i3lock /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j V=1 CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror"'
14 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 2020-10-27 i3lock 2.13
2 |
3 | • Throw error when trying to start on Wayland
4 | • Use explicit_bzero() where available, not just on OpenBSD
5 | • avoid pixmap allocations in the redraw path
6 | • make --debug output go to stderr
7 | • unlock_indicator.c: fix build failure against gcc-10
8 | • fix: call pam_end in cleanup in main, not in event loop
9 | • set _NET_WM_BYPASS_COMPOSITOR hint to avoid flickering
10 |
11 | 2019-07-21 i3lock 2.12
12 |
13 | • remove stray \n from error messages
14 | • capitalize unlock indicator contents
15 | • set WM_CLASS property
16 | • reference modifier as “Super”, not “Win”
17 | • add --raw option to read image as raw bytes
18 |
19 | 2018-10-18 i3lock 2.11.1
20 |
21 | • Fix dist tarball by including I3LOCK_VERSION
22 |
23 | 2018-10-10 i3lock 2.11
24 |
25 | • Switch to autotools
26 | • Display an error when backspace is pressed without any input
27 | • Print an error when a non-PNG file is opened
28 | (i3lock only supports PNG files) (Thanks eplanet)
29 | • Don’t unnecessarily check the xcb_connect return value,
30 | it is known never to be NULL (Thanks SegFault42)
31 | • Fix memory leak when grabbing fails (Thanks karulont)
32 | • Respect Xft.dpi for determining the unlock indicator’s scale factor
33 | • Discard pending password verification attempts
34 | when a new password is entered (Thanks layus)
35 |
36 | 2017-11-25 i3lock 2.10
37 |
38 | • Only use -lpam when not on OpenBSD (Thanks Kaashif)
39 | • locale: treat empty string same as unset (Thanks Ran)
40 | • Fix overwrite of getopt optind (Thanks jakob)
41 | • Immediately hide the unlock indicator after ESC / C-u (Thanks Orestis)
42 | • Measure wall-clock time instead of CPU time for “locking” indicator.
43 | • SetInputFocus to the i3lock window to force-close context menus
44 | • Use RandR for learning about attached monitors
45 |
46 | 2017-06-21 i3lock 2.9.1
47 |
48 | • Fix version number mechanism (for --version)
49 | • Revert the fix for composited notifications, as it causes more issues than
50 | it solves:
51 | https://github.com/i3/i3lock/issues/130
52 | https://github.com/i3/i3lock/issues/128
53 |
54 | 2017-05-26 i3lock 2.9
55 |
56 | • i3lock.1: use signal names without SIG prefix
57 | • Removed obsolete inactivity timeout
58 | • Added version files for release tarball.
59 | • Set font face
60 | • Automatically unlock (without having to press ) one attempt which was
61 | entered while authenticating
62 | • Stop leaking the image_path dup
63 | • Displaying locking message when grabbing the pointer/keyboard
64 | • Display error message when locking failed
65 | • Add Enter on C-m
66 | • Change input slices to be exactly pi/3 in size instead of slightly more
67 | • Fix covering of composited notifications using the XComposite extension
68 | • Remove last traces of DPMS
69 | • Use bsd_auth(3) instead of PAM on OpenBSD
70 | • Restore intended behaviour and don't use mlock(2) on OpenBSD.
71 |
72 | 2016-06-04 i3lock 2.8
73 |
74 | • Remove DPMS support in favor of a wrapper script and xset(1).
75 | • Indicate that the --inactivity-timeout option takes an argument. (Thanks
76 | Kenneth Lyons)
77 | • fix pam_securetty: set PAM_TTY to getenv("DISPLAY")
78 | • Eat XKB_KEY_Delete and XKB_KEY_KP_Delete (Thanks bebehei)
79 | • Show unlock indicator if password was entered during PAM verification
80 | • Allow CTRL+J as enter and CTRL+H as backspace (Thanks Karl Tarbe)
81 | • Flush xcb connection after opening fullscreen window (Thanks martin)
82 | • Add support for `xss-lock --transfer-sleep-lock'
83 |
84 | 2015-05-20 i3lock 2.7
85 |
86 | • Die when the X11 connection breaks during runtime (Thanks Eduan)
87 | • Implement logging the number of failed attempts (Thanks koebi)
88 | • Ignore password validation is pam is in wrong state (Thanks Neodyblue)
89 | • Get current user with getpwuid() instead of using $ENV{USER} (Thanks Martin)
90 | • Add support for Compose and dead-keys with libxkbcommon.
91 | Requires libxkbcommon ≥ 0.5.0 (Thanks Daniel)
92 | • Format the source using clang-format.
93 | • Refresh pam credentials on successful authentication (for Kerberos and the
94 | like) (Thanks James)
95 | • List pressed modifiers on failed authentication (Thanks Deiz, Alexandre)
96 | • Only redraw the screen if the unlock indicator is actually used
97 | (Thanks Ingo)
98 | • Make pkg-config configurable for cross-compilation (Thanks Nikolay)
99 |
100 | 2014-07-18 i3lock 2.6
101 |
102 | • NEW DEPENDENCY: use libxkbcommon-x11 instead of libX11
103 | This helps us get rid of all code that directly uses libX11
104 | • Use cairo_status_to_string for descriptive errors.
105 | • Add `-e` option to not validate empty password.
106 | • Bugfix: update the initial keyboard modifier state (Thanks lee, Ran)
107 | • Re-raise i3lock when obscured in a separate process
108 | • Turn on the screen on successful authentication
109 | • Delay to turn off the screen after wrong passwd
110 | • Discard half-entered passwd after some inactivity
111 | • Ignore empty passwd after repeated Enter keypress
112 | • Scale the unlock indicator (for retina displays)
113 |
114 | 2013-06-09 i3lock 2.5
115 |
116 | • NEW DEPENDENCY: Use libxkbcommon for input handling
117 | This makes input handling much better for many edge cases.
118 | • Bugfix: fix argument parsing on ARM (s/char/int/)
119 | • Bugfix: free(reply) to avoid memory leak
120 | • Bugfix: Use ev_loop_fork after fork, fixes forking on kqueue based OSes
121 | • Bugfix: Fix centering the indicator in the no-xinerama case
122 | • Only use mlock() on Linux, FreeBSD (for example) requires root
123 | • promote the "could not load image" message from debug to normal
124 | • s/pam_message/pam_response/ (Thanks Tucos)
125 | • remove support for NOLIBCAIRO, cairo-xcb is widespread by now
126 | • Allow XKB_KEY_XF86ScreenSaver as synonym for enter
127 | This keysym is generated on convertible tablets by pressing a hardware
128 | lock/unlock button.
129 | • Allow passwordless PAM conversations (e.g. fingerprint)
130 | • Add ctrl+u password reset
131 | • Set window name to i3lock
132 |
133 | 2012-06-02 i3lock 2.4.1
134 |
135 | • Bugfix: Correctly center unlock indicator after reconfiguring screens
136 | (Thanks xeen)
137 | • Bugfix: Revert shift lock handling (broke uppercase letters)
138 | • Bugfix: Skip shift when getting the modifier mask (Thanks SardemFF7)
139 |
140 | 2012-04-01 i3lock 2.4
141 |
142 | • Bugfix: Fix background color when using cairo (Thanks Pascal)
143 | • Only output text when in debug mode (fixes problems with xautolock)
144 | • fallback when the image cannot be loaded
145 | • Use (void) instead of () for functions without args (Thanks fernandotcl)
146 |
147 | 2012-03-15 i3lock 2.3.1
148 |
149 | • Fix compilation on some systems
150 |
151 | 2012-03-15 i3lock 2.3
152 |
153 | • Implement a visual unlock indicator
154 | • Support ISO_Level5_Shift and Caps Lock
155 | • Lock the password buffer in memory, clear it in RAM after verifying
156 | • Fork after the window is visible, not before
157 | • Bugfix: Copy the color depth from parent (root) window instead of
158 | hardcoding a depth of 24
159 |
160 | 2011-11-06 i3lock 2.2
161 |
162 | • Don’t re-grab pointer/keyboard on MappingNotify. In some rare situations,
163 | this lead to some keypresses "slipping through" to the last focused window.
164 | • Correctly handle Mode_switch/ISO_Level3_Shift
165 | • Render to a pixmap which is used as background for the window instead of
166 | copying contents on every expose event
167 | • Handle screen resolution changes while screen is locked
168 | • Manpage: document arguments for every option
169 |
170 | 2011-05-13 i3lock 2.1
171 |
172 | • Accept return/backspace when the buffer of 512 bytes is full
173 | • Handle numpad keys correctly
174 | • Handle MappingNotify events
175 | • Correctly check for errors when connecting to X11
176 | • Add i3lock.pam to not rely on debian’s /etc/pam.d/other anymore
177 | • don’t display debug output
178 | • add NOLIBCAIRO flag to permit compilation without cairo
179 |
180 | 2010-09-05 i3lock 2.0
181 |
182 | • Complete rewrite of i3lock. Now using xcb instead of Xlib.
183 | • When a window obscures i3lock, it pushes itself back to the top again.
184 | • Display version when starting with -v
185 |
186 | 2009-08-02 i3lock 1.1
187 |
188 | • Implement background pictures (-i) and colors (-c)
189 |
190 | 2009-05-10 i3lock 1.0
191 |
192 | • Implement PAM support
193 | • Implement options for forking, beeping, DPMS
194 |
195 | 2009-05-01 i3lock 0.9
196 |
197 | • First release, forked from slock 0.9
198 |
--------------------------------------------------------------------------------
/I3LOCK_VERSION:
--------------------------------------------------------------------------------
1 | 2.13.c.5
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2010-2011, Michael Stapelberg
2 | Copyright © 2015, Cassandra Fox
3 | Copyright © 2021, Raymond Li
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | * Neither the name of Michael Stapelberg, nor the name of Raymond Li,
17 | nor the names of contributors may be used to endorse or promote
18 | products derived from this software without specific prior written
19 | permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY Michael Stapelberg/Cassandra Fox/Raymond Li
22 | ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 | PURPOSE ARE DISCLAIMED.
25 | IN NO EVENT SHALL Michael Stapelberg/Cassandra Fox/Raymond Li BE LIABLE FOR
26 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | @CODE_COVERAGE_RULES@
2 |
3 | echo-version:
4 | @echo "@I3LOCK_VERSION@"
5 |
6 | bin_PROGRAMS = i3lock
7 |
8 | dist_man1_MANS = i3lock.1
9 |
10 | DISTCLEANFILES = i3lock-color-*.tar.bz2
11 |
12 | pamddir = $(sysconfdir)/pam.d
13 | pamd_files = pam/i3lock
14 | pamd_DATA = $(pamd_files)
15 |
16 | if ENABLE_BASH_COMPLETION
17 | bashcompletiondir = $(BASH_COMPLETION_DIR)
18 | dist_bashcompletion_DATA = i3lock-bash
19 | endif
20 |
21 | if ENABLE_ZSH_COMPLETION
22 | zshcompletiondir = $(ZSH_COMPLETION_DIR)
23 | dist_zshcompletion_DATA = i3lock-zsh
24 | endif
25 |
26 | install-data-hook:
27 | if ENABLE_BASH_COMPLETION
28 | test -f "${BASH_COMPLETION_DIR}/i3lock-bash" && mv -f "${BASH_COMPLETION_DIR}/i3lock-bash" "${BASH_COMPLETION_DIR}/i3lock" || true
29 | endif
30 | if ENABLE_ZSH_COMPLETION
31 | test -f "${ZSH_COMPLETION_DIR}/i3lock-zsh" && mv -f "${ZSH_COMPLETION_DIR}/i3lock-zsh" "${ZSH_COMPLETION_DIR}/_i3lock" || true
32 | endif
33 |
34 | uninstall-hook:
35 | if ENABLE_BASH_COMPLETION
36 | rm -f ${BASH_COMPLETION_DIR}/i3lock
37 | endif
38 | if ENABLE_ZSH_COMPLETION
39 | rm -f ${ZSH_COMPLETION_DIR}/_i3lock
40 | endif
41 |
42 |
43 | AM_CPPFLAGS = \
44 | @AX_EXTEND_SRCDIR_CPPFLAGS@
45 |
46 | i3lock_CFLAGS = \
47 | $(AM_CFLAGS) \
48 | $(XCB_CFLAGS) \
49 | $(XCB_IMAGE_CFLAGS) \
50 | $(XCB_UTIL_CFLAGS) \
51 | $(XCB_UTIL_XRM_CFLAGS) \
52 | $(XKBCOMMON_CFLAGS) \
53 | $(CAIRO_CFLAGS) \
54 | $(FONTCONFIG_CFLAGS) \
55 | $(JPEG_CFLAGS) \
56 | $(CODE_COVERAGE_CFLAGS)
57 |
58 | i3lock_CPPFLAGS = \
59 | $(AM_CPPFLAGS) \
60 | $(CODE_COVERAGE_CPPFLAGS)
61 |
62 | i3lock_LDADD = \
63 | $(XCB_LIBS) \
64 | $(XCB_IMAGE_LIBS) \
65 | $(XCB_UTIL_LIBS) \
66 | $(XCB_UTIL_XRM_LIBS) \
67 | $(XKBCOMMON_LIBS) \
68 | $(CAIRO_LIBS) \
69 | $(JPEG_LIBS) \
70 | $(FONTCONFIG_LIBS) \
71 | $(CODE_COVERAGE_LDFLAGS)
72 |
73 | i3lock_SOURCES = \
74 | blur.c \
75 | blur.h \
76 | blur_simd.c \
77 | cursors.h \
78 | dpi.c \
79 | dpi.h \
80 | fonts.h \
81 | jpg.c \
82 | jpg.h \
83 | i3lock.c \
84 | i3lock.h \
85 | randr.c \
86 | randr.h \
87 | rgba.h \
88 | tinyexpr.c \
89 | tinyexpr.h \
90 | unlock_indicator.c \
91 | unlock_indicator.h \
92 | xcb.c \
93 | xcb.h
94 |
95 | EXTRA_DIST = \
96 | $(pamd_files) \
97 | CHANGELOG \
98 | LICENSE \
99 | README.md \
100 | I3LOCK_VERSION
101 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # i3lock-color
2 |
3 | 
4 | [](https://github.com/Raymo111/i3lock-color/search?l=c)
5 | 
6 | [](https://github.com/Raymo111/i3lock-color/issues?q=is%3Aopen+is%3Aissue)
7 | [](https://github.com/Raymo111/i3lock-color/issues?q=is%3Aissue+is%3Aclosed)
8 | [](https://github.com/Raymo111/i3lock-color/pulls?q=is%3Aopen+is%3Apr)
9 | [](https://github.com/Raymo111/i3lock-color/pulls?q=is%3Apr+is%3Aclosed)
10 | [](https://github.com/Raymo111/i3lock-color/graphs/contributors)
11 | [](https://github.com/Raymo111/i3lock-color/releases/latest)
12 | [](https://github.com/Raymo111/i3lock-color/commits/master)
13 | 
14 | [](https://aur.archlinux.org/packages/i3lock-color/)
15 | [](https://aur.archlinux.org/packages/i3lock-color-git/)
16 | 
17 | [](https://github.com/Raymo111/i3lock-color/network/members)
18 | [](https://github.com/Raymo111/i3lock-color/stargazers)
19 | [](https://github.com/Raymo111/i3lock-color/watchers)
20 | [](https://discord.gg/FzVPghyDt2)
21 | 
22 |
23 |
24 | ### The world's most popular non-default computer lockscreen.
25 | **A modern version of i3lock with color functionality and other features.**
26 |
27 | 
28 |
29 | **NEW: Official Discord server at https://discord.gg/FzVPghyDt2**
30 |
31 | i3lock is a simple screen locker like slock. After starting it, you will see a white screen (you can configure the color/an image). You can return to your screen by entering your password.
32 |
33 | Many little improvements have been made to i3lock over time:
34 |
35 | - i3lock forks, so you can combine it with an alias to suspend to RAM (run "i3lock && echo mem > /sys/power/state" to get a locked screen after waking up your computer from suspend to RAM)
36 | - You can specify either a background color or an image (JPG or PNG), which will be displayed while your screen is locked. Note that i3lock is not an image manipulation software. If you need to resize the image to fill the screen, you can use something like ImageMagick combined with `xdpyinfo`:
37 | ```bash
38 | convert image.jpg -resize $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/') RGB:- | i3lock --raw $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/'):rgb --image /dev/stdin
39 | ```
40 | - You can specify whether i3lock should bell upon a wrong password.
41 | - i3lock uses PAM and therefore is compatible with LDAP etc. On OpenBSD, i3lock uses the bsd\_auth(3) framework.
42 |
43 | ## Additional features in i3lock-color
44 | You can also specify additional options, as detailed in the manpage. This includes, but is not limited to:
45 |
46 | - Color options for:
47 | - Verification ring
48 | - Interior ring color
49 | - Ring interior line color
50 | - Key highlight color
51 | - Backspace highlight color
52 | - Text colors for most/all strings
53 | - Outline colors
54 | - Changing all of the above depending on PAM's authentication status
55 | - Blurring the current screen and using that as the lock background
56 | - Showing a clock in the indicator
57 | - Refreshing on a timer, instead of on each keypress
58 | - Positioning the various UI elements
59 | - Changing the ring radius and thickness, as well as text size
60 | - Options for passwordless auth, removing modkey indicator
61 | - Passing through media keys
62 | - A new bar indicator, which replaces the ring indicator with its own set of options
63 | - An experimental thread for driving the redraw ticks, so that things like the bar/clock still update when PAM is blocking
64 | - Any other feature you want (add it yourself through a PR or make a feature request issue!)
65 |
66 | ## Dependencies
67 | The following dependencies will need to be installed for a successful build, depending on your OS/distro.
68 |
69 | ### Arch Linux
70 | - autoconf
71 | - cairo
72 | - fontconfig
73 | - gcc
74 | - libev
75 | - libjpeg-turbo
76 | - libxinerama
77 | - libxkbcommon-x11
78 | - libxrandr
79 | - pam
80 | - pkgconf
81 | - xcb-util-image
82 | - xcb-util-xrm
83 |
84 | ### Debian
85 | Run this command to install all dependencies:
86 | ```
87 | sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util0-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev libgif-dev
88 | ```
89 | If you still see missing packages during build after installing all of these dependencies, try following the steps [here](https://github.com/Raymo111/i3lock-color/issues/211#issuecomment-809891727).
90 |
91 | ### Fedora
92 | Run this command to install all dependencies:
93 |
94 | ```sh
95 | sudo dnf install -y autoconf automake cairo-devel fontconfig gcc libev-devel libjpeg-turbo-devel libXinerama libxkbcommon-devel libxkbcommon-x11-devel libXrandr pam-devel pkgconf xcb-util-image-devel xcb-util-xrm-devel
96 | ```
97 |
98 | ### Ubuntu 18/20.04 LTS
99 | Run this command to install all dependencies:
100 | ```
101 | sudo apt install autoconf gcc make pkg-config libpam0g-dev libcairo2-dev libfontconfig1-dev libxcb-composite0-dev libev-dev libx11-xcb-dev libxcb-xkb-dev libxcb-xinerama0-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev libjpeg-dev libgif-dev
102 | ```
103 |
104 | ## Building i3lock-color
105 | Before you build - check and see if there's a packaged version available for your distro (there usually is, either in a community repo/PPA).
106 |
107 | **If you want to build a non-debug version, you should tag your build before configuring.**
108 |
109 | For example: `git tag -f "git-$(git rev-parse --short HEAD)"` will add a tag with the short commit ID, which will be used for the version info.
110 |
111 | i3lock-color uses GNU autotools for building.
112 |
113 | To build/install i3lock-color, first install the dependencies listed above, then clone the repo:
114 | ```
115 | git clone https://github.com/Raymo111/i3lock-color.git
116 | cd i3lock-color
117 | ```
118 | To build without installing, run:
119 | ```
120 | ./build.sh
121 | ```
122 | To build AND install, run:
123 | ```
124 | ./install-i3lock-color.sh
125 | ```
126 | You may choose to modify the script based on your needs/OS/distro.
127 |
128 | ## Alpine Linux Packages
129 | Alpine packages i3lock-color for a variety of architectures. A full list can be found on [pkgs.alpinelinux.org](https://pkgs.alpinelinux.org/packages?name=i3lock-color&branch=edge).
130 |
131 | ## Arch Linux Packages
132 | ~~[Stable version in Community](https://www.archlinux.org/packages/community/x86_64/i3lock-color/)~~
133 |
134 | Unfortunately the previous maintainer left, and the package got dumped back into the AUR where I'm now maintaining it. You can get it on AUR:
135 | - [Release Version on AUR](https://aur.archlinux.org/packages/i3lock-color/)
136 | - [Git Version on AUR](https://aur.archlinux.org/packages/i3lock-color-git/)
137 |
138 | If you're an Arch TU and you're reading this please consider sponsoring it into Community again!
139 |
140 | ## Gentoo Linux Package
141 | i3lock-color is available on **GURU**, under [`x11-misc/i3lock-color`](https://github.com/gentoo/guru/tree/master/x11-misc/i3lock-color).
142 |
143 | ## Kali Linux Package
144 | A Debian/Kali package is available: https://gitlab.com/kalilinux/packages/i3lock-color.
145 |
146 | ## NixOS Package
147 | A NixOS package is available. To install, run
148 | ```
149 | nix-env -iA nixos.i3lock-color
150 | ```
151 |
152 | ## Void Linux Package
153 | A Void Linux package is available at https://github.com/void-linux/void-packages/tree/master/srcpkgs/i3lock-color.
154 |
155 | ## FreeBSD port
156 | A FreeBSD port is available on freshports: [x11/i3lock-color/](https://www.freshports.org/x11/i3lock-color/).
157 |
158 | ## Running i3lock-color
159 | Simply invoke the 'i3lock' command. To get out of it, enter your password and press enter.
160 |
161 | A [sample script](examples/lock.sh) is included in this repository.
162 |
163 | On OpenBSD the `i3lock` binary needs to be setgid `auth` to call the authentication helpers, e.g. `/usr/libexec/auth/login_passwd`.
164 |
165 | ## Contributors
166 | This project was started by [eBrnd](https://github.com/eBrnd/i3lock-color), maintained for a few years by [PandorasFox](https://github.com/PandorasFox) and now maintained and being developed by [Raymo111](https://github.com/Raymo111). The full list of contributors can be found [here](https://github.com/Raymo111/i3lock-color/graphs/contributors).
167 |
168 | ## Upstream
169 | Please submit pull requests for i3lock things to [https://github.com/i3/i3lock](https://github.com/i3/i3lock) and pull requests for additional features on top of regular i3lock at [https://github.com/Raymo111/i3lock-color](https://github.com/Raymo111/i3lock-color).
170 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ---------- | ------------------ |
10 | | 2.12.c.5 | :white_check_mark: |
11 | | < 2.12.c.5 | :x: |
12 |
13 | ## Reporting a Vulnerability
14 |
15 | If there's a severe security vulnerability in the latest version of i3lock-color, don't post a public issue. Either email me directly at [i3lock-color@raymond.li](mailto:i3lock@raymond.li?subject=i3lock-color%20security%20vulnerability), or encrypt the issue text with my PGP public key:
16 | ```
17 | -----BEGIN PGP PUBLIC KEY BLOCK-----
18 |
19 | mQINBF3PSOoBEADQP/vqo3XMOntXWo/IOy0jDCicWycWbwU1UfsZYt4MNAf1/M6t
20 | yBEKt+U94diDoD4JDDaWPdbHEyQ/6AqRqzUO+dcO19pmFc5p0nj4sPQ+iMJ95I63
21 | FW3ZSq//1vf33sNWA773YBJOD0s02dDtuCriUd+06zHXd92+9Vm+wvsP0yaPUC3g
22 | KVgN9IcdKYS6HsBuncfBFVzE/wf9BL3YHwvGgqS+XcQ2mPizy6Ddc/zXfn43zXLT
23 | Q/nYb7Gt34EdP2J31ypuLFrVE3oSA9hK4SSvV8Z4INRELYhSjLVYt9S/NuhpIo8T
24 | wOirZFKVfeBvtoog0LX1isFmGdje3ML20IH9bOqp7UcmsXbYqmza3xrOUdHQpqe2
25 | Idz5O3XOrlcqcVbeeNNcqeUBr/u5XScYGIyDr9+b4utis/PxnqE6hoiwSrwsLZ6Q
26 | QYHcsR+rwLujfxQf3k1emMLkrS+sd61WFGB4ZAvHpdpNtfym/c5g+CTA2SEjhM7+
27 | g0qvT9guEhLk/mEgtXvCCkcESAIZMnk1xUkXldqofl5Vr8r2B6oEw2hmwwcTJrHJ
28 | 4x9IfcgrJDlyxcUQJ2UJzmtn/D6L7OdG465cdVZ+8QQRmf4IQV+6SXEqb1s9hFDj
29 | sahJIdgftDDYmgaEzNYz09z/obAgUho5stsW7Ah/D8C1DsfD3DMNs5IS7QARAQAB
30 | tCdSYXltb25kIExpICgoUmF5bW8xMTEpKSA8aGlAcmF5bW9uZC5saT6JAk4EEwEI
31 | ADgWIQRkwvsY4QR1Ip//JdHwWN+YLbQvnQUCXc9I6gIbLwULCQgHAgYVCgkICwIE
32 | FgIDAQIeAQIXgAAKCRDwWN+YLbQvndhCEAC1HRAXV2i6pQ6c6frCwAQSbMLiRiqd
33 | OYyipejmjkF04wm3Zb4MMfzSWLoVXbHcX8NX8+i/VjMBgoPyLd/XutdDD8qq1TVb
34 | paIbN+fIgniMMwW0X/8LRm6jqhlO8Z4igzExHF+GLG2NRMIhTaNdRp51x7Lc5iOu
35 | PgR8p1Ql5+vhIb9WdNUq2L74JW7BSqb1Xit86NtJI723gbg+Xwbv60uuzPHhd0bN
36 | jHHHJ1f9YSlPPZH5iMlBcl3iNoMfIbCp1G179IaK/sN5C4hPhVvy8GmoTlTIQ6If
37 | gs2x1xFwoIMlz8SFX4KJwnIIXZz6JBzpGRNIXV5fhwrzLpvY19iKh+JIHOtxcovy
38 | YjKOFe4+dOgBade29C+RyJ+i21cijTzsn8nE7COt49N3gXl+sXHUv4kSUVkGEmNY
39 | VtMLFJbjTxDxb/V25iWov23Gz9DhWcl/oCmCnLhi+7YZtmNpCbFrZSkGVq0VNfBE
40 | f6Mh96ugGbehg0tbbiLf0hdHMO0qi5DXP3Lfyy7Mw20YlOWiLqyTCs+HgVBXP783
41 | n1SfQrswbObOj7z+Bg8iQvYwKhU2A6sgToROYeZ3mV4kuTEcqpJhfGBXD6xraUm1
42 | kSg3Xc8A/3G1z34uHXGPb5sQx3eu+LbaSfDLTLObfy+ef+Z2fqt8Q8SVzTInnUQq
43 | k8K700ofB9zOw7kCDQRdz0jqARAAqfyjVbId7hc4tL9H0rpGr4A2NFdjvs7ktf9L
44 | 63/GtzyTJ5oFa2jOMtmU4PDbgwOAHXFZJEQ9etzPsIxZOrH0uuOO/5WPxu+n+mEz
45 | M+mnV6YA/wGu/IUKcbpOHMjinH6uaNlJ/PErJkHkGPCb97c/HFYROBoSBPtRW+8q
46 | Qdlaq4cccwE93pindt1aoE7nHFlsxuQG0s8fQ8qX7SgO2okve3OJnstADpcpMX5x
47 | VausXoGc3h6BQexaAnsIJ574ov5vNxFOHG/22RSsyf+Xd8MPqQv5Znk2lQD9EwzS
48 | m15jy008jpkV7kByZHDNuiTjxfrhkCy6gS3RlCgnKZlyTqkjuU1vQ12S/xXZJzwD
49 | IBfbxZQP9dfxYo4Pusd7bMlptkJTUmjr5JeLAcfNWyDTvwZ/ea+2gdrXedUYlYNS
50 | m984ZIwLjDxC/PjwXyURCTNamYibGgnMHwD8Fr2czszBQxwM/ThGkgN6fdwyvGzL
51 | AfeYAjZrZfTtA/OV7fpBR+hUAJcFJCSiHzIOyDlAMYVIaRnAfCGvCnE4ksUWP6so
52 | vBBLQsF+XmCw5GhzDC26UV3Cyu/bJ0AXKVYtoKungixjrhwcZ6icAXiAvF6ZtfnA
53 | xxqkgmm4lDbLJN9wbInhAVK5fiN+phbFDPgEorpyoxdsJtwmN0AAYHO+leBMFMfQ
54 | RsEkPLcAEQEAAYkEbAQYAQgAIBYhBGTC+xjhBHUin/8l0fBY35gttC+dBQJdz0jq
55 | AhsuAkAJEPBY35gttC+dwXQgBBkBCAAdFiEEs9q7pbmssSalH+X5oBTqibYruxsF
56 | Al3PSOoACgkQoBTqibYruxuEmg/8D06MiJ7G9hZpENphSl3YcfGYgmHIfCPdc+D4
57 | mMO50ychMGPMDlsDHtVSpUbTrvPtzNlulYfREAm9LsuFQRvYHOVNQ9rbI7gEo3ga
58 | K4LrcCsYkG27TiMeiljgqN2qWHYJAHDdAPbmAEawCMo9Y3uiMvcs8Gt9lFjIiIa9
59 | jfs+rBCw2yJwP2HlYjK7CyIgNvjiMjDbWNIeQY6ONlR+ojDR52bcPljyT4rQ+XTq
60 | t2/ArCwcFciX25EoQ4ncl5F44GqwWDkdpj8/HCfNQkRPN7nR9LGftyFCWUxZLZUQ
61 | Ux0Is6wubu0KxE3P1Xvz2HDhKZVBiR5P4TiC79CgSpENFyAvmCt4tnsnTu7UGYzj
62 | JWl/Lvi+dirC+THmOj00sbTzyKnMn7896hgSiKlgkl968JfTf4SsDmySftg+894f
63 | PZizZt8v3jjEy8oRvQ4S619Visz+3fxrM2mKbBXW33G+cWIyVkKqzUQgdI+itaO8
64 | iLDP5HjMNSJd2VvvwswnJq0KnyMCRY2QzJ90E2FPTcl9Ltv1zEl16GqCWyQtSrma
65 | tEKZAFTdFVMwdLbggFlWnLx7qOfTs7nBIXGmfi25DmPcufNskmq8RiTSxXyFRBJS
66 | OMYP+xkxNR4JSOA+Clt20zclknX6HA9877vWy9Gnqm+gWu5PIfiDvxitQukc+e5B
67 | N3WQfnEUxQ/8CN1ncUHk4JlP25vjFS9/eK+yTqR8AEEr20DD0cSNvRtpjwiaIZaf
68 | Up9SQTtz2RuqiIl7+Hak8VCAKvYWHXy5BjId73x5SfnT9wuic+/jAaUi+5Ypo/Lh
69 | R/LfsWPsE1EGtmcmRwltNjxL32gpiD4LS7TuY5XVvmVBUh5185Y/t5WkP3kv4FB6
70 | uA2g8kADHQbLtcpVc7c510Ru3MQ8HSmyGKO/3K++itNTST70RV36SOCNfG3WDSBD
71 | yO8t2RKzH6Q+f4a2pWJafuknvvMsTf11YRZBBZUVF1XVTABtEu/fucbTMjVHh2gd
72 | 69iICS0KTL6sf6K3fclPQiqKIbCFgf/CGWUaAyzWBM8bWsxD2kywrdf1qY+UU1AF
73 | vV+RmvVjcr1o3V6fZNDSlXET8w7jHjddTBstiCEK4aQCds6DDJU2+Ucqw5sqzwr3
74 | 9LKbph/uibQxJC/AYNMiCH5OHDknhnyAwNmn+KMXHyJkqGoqB5zXVfsxrHroEBHR
75 | Sl77//DFlSl06lLee97HiSoKckpFrsmjpSbkQ+wFcb0x4lRbN5vRx8oUvagpGJ2D
76 | mLhEcizl8EB9RwneaN6AfJg0BIikKpxl/K/gf7wr8fdsEgK0WIgCb60Ed8VEd9+l
77 | rnKFFKw58bCu0PS5Uk6Lnb/jbbWOaB4ngOeOEGPoeT1vdDI6hkkEma4=
78 | =HNQH
79 | -----END PGP PUBLIC KEY BLOCK-----
80 | ```
81 | You can also get my key directly from the [GNUPG keyserver](http://keys.gnupg.net/pks/lookup?op=vindex&fingerprint=on&search=0xF058DF982DB42F9D).
82 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-midnight
--------------------------------------------------------------------------------
/blur.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2008 Kristian Høgsberg
3 | * Copyright © 2009 Chris Wilson
4 | *
5 | * Permission to use, copy, modify, distribute, and sell this software and its
6 | * documentation for any purpose is hereby granted without fee, provided that
7 | * the above copyright notice appear in all copies and that both that copyright
8 | * notice and this permission notice appear in supporting documentation, and
9 | * that the name of the copyright holders not be used in advertising or
10 | * publicity pertaining to distribution of the software without specific,
11 | * written prior permission. The copyright holders make no representations
12 | * about the suitability of this software for any purpose. It is provided "as
13 | * is" without express or implied warranty.
14 | *
15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 | * OF THIS SOFTWARE.
22 | */
23 |
24 | #include
25 | #include "blur.h"
26 | /* Performs a simple 2D Gaussian blur of standard devation @sigma surface @surface. */
27 | void
28 | blur_image_surface (cairo_surface_t *surface, int sigma)
29 | {
30 | cairo_surface_t *tmp;
31 | int width, height;
32 | uint32_t *src, *dst;
33 |
34 | if (cairo_surface_status (surface))
35 | return;
36 |
37 | width = cairo_image_surface_get_width (surface);
38 | height = cairo_image_surface_get_height (surface);
39 |
40 | switch (cairo_image_surface_get_format (surface)) {
41 | case CAIRO_FORMAT_A1:
42 | default:
43 | /* Don't even think about it! */
44 | return;
45 |
46 | case CAIRO_FORMAT_A8:
47 | /* Handle a8 surfaces by effectively unrolling the loops by a
48 | * factor of 4 - this is safe since we know that stride has to be a
49 | * multiple of uint32_t. */
50 | width /= 4;
51 | break;
52 |
53 | case CAIRO_FORMAT_RGB24:
54 | case CAIRO_FORMAT_ARGB32:
55 | break;
56 | }
57 |
58 | tmp = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
59 | if (cairo_surface_status (tmp))
60 | return;
61 |
62 | src = (uint32_t*)cairo_image_surface_get_data (surface);
63 | dst = (uint32_t*)cairo_image_surface_get_data (tmp);
64 |
65 | // according to a paper by Peter Kovesi [1], box filter of width w, equals to Gaussian blur of following sigma:
66 | // σ_av = sqrt((w*w-1)/12)
67 | // for our 7x7 filter we have σ_av = 2.0.
68 | // applying the same Gaussian filter n times results in σ_n = sqrt(n*σ_av*σ_av) [2]
69 | // after some trivial math, we arrive at n = ((σ_d)/(σ_av))^2
70 | // since it's a box blur filter, n >= 3
71 | //
72 | // [1]: http://www.peterkovesi.com/papers/FastGaussianSmoothing.pdf
73 | // [2]: https://en.wikipedia.org/wiki/Gaussian_blur#Mathematics
74 |
75 | int n = lrintf((sigma*sigma)/(SIGMA_AV*SIGMA_AV));
76 | if (n < 3) n = 3;
77 |
78 | for (int i = 0; i < n; i++)
79 | {
80 | // horizontal pass includes image transposition:
81 | // instead of writing pixel src[x] to dst[x],
82 | // we write it to transposed location.
83 | // (to be exact: dst[height * current_column + current_row])
84 | #ifdef __SSE2__
85 | blur_impl_horizontal_pass_sse2(src, dst, width, height);
86 | blur_impl_horizontal_pass_sse2(dst, src, height, width);
87 | #else
88 | blur_impl_horizontal_pass_generic(src, dst, width, height);
89 | blur_impl_horizontal_pass_generic(dst, src, height, width);
90 | #endif
91 | }
92 |
93 | cairo_surface_destroy (tmp);
94 | cairo_surface_flush (surface);
95 | cairo_surface_mark_dirty (surface);
96 | }
97 |
98 | void blur_impl_horizontal_pass_generic(uint32_t *src, uint32_t *dst, int width, int height) {
99 | uint32_t *o_src = src;
100 | for (int row = 0; row < height; row++) {
101 | for (int column = 0; column < width; column++, src++) {
102 | uint32_t rgbaIn[KERNEL_SIZE + 1];
103 |
104 | // handle borders
105 | int leftBorder = column < HALF_KERNEL;
106 | int rightBorder = column > width - HALF_KERNEL;
107 | int i = 0;
108 | if (leftBorder) {
109 | // for kernel size 7x7 and column == 0, we have:
110 | // x x x P0 P1 P2 P3
111 | // first loop mirrors P{0..3} to fill x's,
112 | // second one loads P{0..3}
113 | for (; i < HALF_KERNEL - column; i++)
114 | rgbaIn[i] = *(src + (HALF_KERNEL - i));
115 | for (; i < KERNEL_SIZE; i++)
116 | rgbaIn[i] = *(src - (HALF_KERNEL - i));
117 | } else if (rightBorder) {
118 | for (; i < width - column; i++)
119 | rgbaIn[i] = *(src + i);
120 | for (int k = 0; i < KERNEL_SIZE; i++, k++)
121 | rgbaIn[i] = *(src - k);
122 | } else {
123 | for (; i < KERNEL_SIZE; i++) {
124 | if ((uintptr_t) ((src + 4*i - HALF_KERNEL) + 1)
125 | > (uintptr_t) (o_src + (height * width)))
126 | break;
127 | rgbaIn[i] = *(src + i - HALF_KERNEL);
128 | }
129 | }
130 |
131 | uint32_t acc[4] = {0};
132 |
133 | for (i = 0; i < KERNEL_SIZE; i++) {
134 | acc[0] += (rgbaIn[i] & 0xFF000000) >> 24;
135 | acc[1] += (rgbaIn[i] & 0x00FF0000) >> 16;
136 | acc[2] += (rgbaIn[i] & 0x0000FF00) >> 8;
137 | acc[3] += (rgbaIn[i] & 0x000000FF) >> 0;
138 | }
139 |
140 | for(i = 0; i < 4; i++)
141 | acc[i] *= 1.0/KERNEL_SIZE;
142 |
143 | *(dst + height * column + row) = (acc[0] << 24) |
144 | (acc[1] << 16) |
145 | (acc[2] << 8 ) |
146 | (acc[3] << 0);
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/blur.h:
--------------------------------------------------------------------------------
1 | #ifndef _BLUR_H
2 | #define _BLUR_H
3 |
4 | #include
5 | #include
6 |
7 | #define KERNEL_SIZE 7
8 | #define SIGMA_AV 2
9 | #define HALF_KERNEL KERNEL_SIZE / 2
10 |
11 | void blur_image_surface(cairo_surface_t *surface, int sigma);
12 | #ifdef __SSE2__
13 | void blur_impl_horizontal_pass_sse2(uint32_t *src, uint32_t *dst, int width, int height);
14 | #endif
15 | void blur_impl_horizontal_pass_generic(uint32_t *src, uint32_t *dst, int width, int height);
16 | #endif
17 |
--------------------------------------------------------------------------------
/blur_simd.c:
--------------------------------------------------------------------------------
1 | /*
2 | * vim:ts=4:sw=4:expandtab
3 | *
4 | * © 2016 Sebastian Frysztak
5 | *
6 | * See LICENSE for licensing information
7 | *
8 | */
9 |
10 |
11 | // number of xmm registers needed to store input pixels for given kernel size
12 | #ifdef __SSE2__
13 | #include "blur.h"
14 | #define REGISTERS_CNT (KERNEL_SIZE + 4/2) / 4
15 | #include
16 | void blur_impl_horizontal_pass_sse2(uint32_t *src, uint32_t *dst, int width, int height) {
17 | uint32_t* o_src = src;
18 | for (int row = 0; row < height; row++) {
19 | for (int column = 0; column < width; column++, src++) {
20 | __m128i rgbaIn[REGISTERS_CNT];
21 |
22 | // handle borders
23 | int leftBorder = column < HALF_KERNEL;
24 | int rightBorder = column > width - HALF_KERNEL;
25 | uint32_t _rgbaIn[KERNEL_SIZE + 1] __attribute__((aligned(16)));
26 | int i = 0;
27 | if (leftBorder) {
28 | // for kernel size 7x7 and column == 0, we have:
29 | // x x x P0 P1 P2 P3
30 | // first loop mirrors P{0..3} to fill x's,
31 | // second one loads P{0..3}
32 | for (; i < HALF_KERNEL - column; i++)
33 | _rgbaIn[i] = *(src + (HALF_KERNEL - i));
34 | for (; i < KERNEL_SIZE; i++)
35 | _rgbaIn[i] = *(src - (HALF_KERNEL - i));
36 |
37 | for (int k = 0; k < REGISTERS_CNT; k++)
38 | rgbaIn[k] = _mm_load_si128((__m128i*)(_rgbaIn + 4*k));
39 | } else if (rightBorder) {
40 | for (; i < width - column; i++)
41 | _rgbaIn[i] = *(src + i);
42 | for (int k = 0; i < KERNEL_SIZE; i++, k++)
43 | _rgbaIn[i] = *(src - k);
44 |
45 | for (int k = 0; k < REGISTERS_CNT; k++)
46 | rgbaIn[k] = _mm_load_si128((__m128i*)(_rgbaIn + 4*k));
47 | } else {
48 | for (int k = 0; k < REGISTERS_CNT; k++) {
49 | if ((uintptr_t) (((__m128i*) src + 4*k - HALF_KERNEL) + 1)
50 | > (uintptr_t) (o_src + (height * width)))
51 | break;
52 | rgbaIn[k] = _mm_loadu_si128((__m128i*)(src + 4*k - HALF_KERNEL));
53 | }
54 | }
55 |
56 | __m128i zero = _mm_setzero_si128();
57 | __m128i acc = _mm_setzero_si128();
58 |
59 | acc = _mm_add_epi16(acc, _mm_unpacklo_epi8(rgbaIn[0], zero));
60 | acc = _mm_add_epi16(acc, _mm_unpackhi_epi8(rgbaIn[0], zero));
61 | acc = _mm_add_epi16(acc, _mm_unpacklo_epi8(rgbaIn[1], zero));
62 |
63 | // kernel size equals to 7, but we can only load multiples of 4 pixels
64 | // we have to set 8th pixel to zero
65 | acc = _mm_add_epi16(acc, _mm_andnot_si128(_mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0, 0),
66 | _mm_unpackhi_epi8(rgbaIn[1], zero)));
67 | acc = _mm_add_epi32(_mm_unpacklo_epi16(acc, zero),
68 | _mm_unpackhi_epi16(acc, zero));
69 |
70 | // multiplication is significantly faster than division
71 | acc = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(acc),
72 | _mm_set1_ps(1.0/KERNEL_SIZE)));
73 |
74 | *(dst + height * column + row) =
75 | _mm_cvtsi128_si32(_mm_packus_epi16(_mm_packs_epi32(acc, zero), zero));
76 | }
77 | }
78 | }
79 | #endif
80 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -x
2 |
3 | configureOpts=""
4 |
5 | while getopts ":hd" opt; do
6 | case ${opt} in
7 | h ) echo "Use -d to turn on sanitizers (for debugging only)"
8 | exit;;
9 | d ) configureOpts="--enable-debug"
10 | ;;
11 | \? ) echo "Usage: $0 [-h] [-d]"
12 | exit;;
13 | esac
14 | done
15 |
16 | configureOpts="${configureOpts} --prefix=/usr --sysconfdir=/etc"
17 |
18 | autoreconf -fiv
19 |
20 | BUILD_DIR=build/
21 | rm -rf $BUILD_DIR
22 | mkdir -vp $BUILD_DIR
23 | cd $BUILD_DIR || { echo "cd $BUILD_DIR"; exit 127; }
24 |
25 | ../configure ${configureOpts}
26 |
27 | make
28 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Run autoreconf -fi to generate a configure script from this file.
3 |
4 | AC_PREREQ([2.69])
5 | AC_INIT([i3lock-color],[m4_esyscmd_s([cat I3LOCK_VERSION])],[https://github.com/Raymo11/i3lock-color/issues])
6 | # For AX_EXTEND_SRCDIR
7 | AX_ENABLE_BUILDDIR
8 | AM_INIT_AUTOMAKE([foreign subdir-objects -Wall no-dist-gzip dist-bzip2])
9 | # Default to silent rules, use V=1 to get verbose compilation output.
10 | AM_SILENT_RULES([yes])
11 | # Make it possible to disable maintainer mode to disable re-generation of build
12 | # system files.
13 | AM_MAINTAINER_MODE([enable])
14 | AC_CONFIG_SRCDIR([i3lock.c])
15 | AC_CONFIG_HEADERS([config.h])
16 | AC_CONFIG_MACRO_DIR([m4])
17 |
18 | dnl Verify macros defined in m4/ such as AX_SANITIZERS are not present in the
19 | dnl output, i.e. are replaced as expected. This line results in a better error
20 | dnl message when using aclocal < 1.13 (which does not understand
21 | dnl AC_CONFIG_MACRO_DIR) without passing the -I m4 parameter.
22 | m4_pattern_forbid([AX_SANITIZERS])
23 |
24 | # Verify we are using GNU make because we use '%'-style pattern rules in
25 | # Makefile.am, which are a GNU make extension. Pull requests to replace
26 | # '%'-style pattern rules with a more portable alternative are welcome.
27 | AX_CHECK_GNU_MAKE
28 | AS_VAR_IF([_cv_gnu_make_command], [""], [AC_MSG_ERROR([the i3lock Makefile.am requires GNU make])])
29 |
30 | AX_EXTEND_SRCDIR
31 |
32 | AS_IF([test -d ${srcdir}/.git],
33 | [
34 | VERSION="$(git -C ${srcdir} describe --tags --abbrev=0)"
35 | I3LOCK_VERSION="$(git -C ${srcdir} describe --tags --always) ($(git -C ${srcdir} rev-list --pretty=format:%cd --date=short -n1 HEAD | tail -n1))"
36 | # Mirrors what libi3/is_debug_build.c does:
37 | is_release=$(test $(echo "${I3LOCK_VERSION}" | cut -d ' ' -f 1 | wc -m) -lt 13 && echo yes || echo no)
38 | ],
39 | [
40 | VERSION="$(cut -d '-' -f 1 ${srcdir}/I3LOCK_VERSION | cut -d ' ' -f 1)"
41 | I3LOCK_VERSION="$(sed -e 's/@<:@\"?\\@:>@/\\&/g' ${srcdir}/I3LOCK_VERSION)"
42 | is_release="$(grep -q non-git ${srcdir}/I3LOCK_VERSION && echo no || echo yes)"
43 | ])
44 | AC_SUBST([I3LOCK_VERSION], [$I3LOCK_VERSION])
45 | AC_DEFINE_UNQUOTED([I3LOCK_VERSION], ["${I3LOCK_VERSION}"], [i3lock version])
46 |
47 | AX_CODE_COVERAGE
48 |
49 | dnl is_release must be lowercase because AX_CHECK_ENABLE_DEBUG calls m4_tolower
50 | dnl on its fourth argument.
51 | AX_CHECK_ENABLE_DEBUG([no], , , [$is_release])
52 |
53 | AC_PROG_CC
54 |
55 | # For strnlen() and vasprintf().
56 | AC_USE_SYSTEM_EXTENSIONS
57 |
58 | # Checks for typedefs, structures, and compiler characteristics.
59 | AC_CHECK_HEADER_STDBOOL
60 | dnl The error message should include the specific type which could not be
61 | dnl found, but I do not see a way to achieve that.
62 | AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t], , [AC_MSG_FAILURE([cannot find required type])])
63 |
64 | # Checks for library functions.
65 | AC_FUNC_FORK
66 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
67 | AC_FUNC_STRNLEN
68 | AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strndup strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3lock requires])])
69 | AC_CHECK_FUNCS([explicit_bzero])
70 |
71 | # Check for libraries
72 | AC_SEARCH_LIBS([floor], [m], , [AC_MSG_FAILURE([cannot find the required floor() function despite trying to link with -lm])])
73 |
74 | # libev does not ship with a pkg-config file :(.
75 | AC_SEARCH_LIBS([ev_run], [ev], , [AC_MSG_FAILURE([cannot find the required ev_run() function despite trying to link with -lev])])
76 |
77 | AC_SEARCH_LIBS([shm_open], [rt])
78 |
79 | AC_SEARCH_LIBS([DGifOpenFileName], [gif])
80 | # Use system-local-login instead of login on Arch and Gentoo
81 | if [[ -f /etc/arch-release ]] || [[ -f /etc/gentoo-release ]]; then
82 | echo "Using PAM for Arch/Gentoo"
83 | sed -i "s/^#auth include system-local-login/auth include system-local-login/g" ../pam/i3lock
84 | sed -i "s/^auth include login/#auth include login/g" ../pam/i3lock
85 | fi
86 |
87 | # Only disable PAM on OpenBSD where i3lock uses BSD Auth instead
88 | case "$host" in
89 | *-openbsd*)
90 | # Nothing yet.
91 | ;;
92 | *)
93 | AC_SEARCH_LIBS([pam_authenticate], [pam])
94 | ;;
95 | esac
96 |
97 | AC_SEARCH_LIBS([iconv_open], [iconv], , [AC_MSG_FAILURE([cannot find the required iconv_open() function despite trying to link with -liconv])])
98 |
99 | dnl Each prefix corresponds to a source tarball which users might have
100 | dnl downloaded in a newer version and would like to overwrite.
101 | PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-composite])
102 | PKG_CHECK_MODULES([XCB_IMAGE], [xcb-image])
103 | PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util xcb-atom])
104 | PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm])
105 | PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon xkbcommon-x11])
106 | PKG_CHECK_MODULES([CAIRO], [cairo])
107 | PKG_CHECK_MODULES([JPEG], [libjpeg])
108 | PKG_CHECK_MODULES([FONTCONFIG], [fontconfig])
109 |
110 |
111 | # Checks for programs.
112 | AC_PROG_AWK
113 | AC_PROG_CPP
114 | AC_PROG_INSTALL
115 | AC_PROG_MAKE_SET
116 | AC_PROG_RANLIB
117 | AC_PROG_LN_S
118 |
119 | AM_PROG_AR
120 |
121 | AX_FLAGS_WARN_ALL
122 | AX_APPEND_FLAG([-O2], [AM_CFLAGS])
123 | AX_APPEND_FLAG([-funroll-loops], [AM_CFLAGS])
124 | AX_APPEND_FLAG([-pthread], [AM_CFLAGS])
125 | AX_CHECK_COMPILE_FLAG([-Wunused-value], [AX_APPEND_FLAG([-Wunused-value], [AM_CFLAGS])])
126 | AC_SUBST(AM_CFLAGS)
127 |
128 | AX_CHECK_BASH_COMPLETION
129 | AX_CHECK_ZSH_COMPLETION
130 |
131 | # Checks for header files.
132 | AC_CHECK_HEADERS([fcntl.h float.h inttypes.h limits.h locale.h netinet/in.h paths.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h gif_lib.h], , [AC_MSG_FAILURE([cannot find the $ac_header header, which i3lock requires])])
133 |
134 | AC_CONFIG_FILES([Makefile])
135 |
136 | # Enable address sanitizer for debug builds. The performance hit is a
137 | # 50% increase of wallclock time for the testsuite on my machine.
138 | if test "x$ax_enable_debug" = "xyes"; then
139 | default_sanitizers=address
140 | else
141 | default_sanitizers=
142 | fi
143 | AX_SANITIZERS(, [$default_sanitizers])
144 |
145 | AC_OUTPUT
146 |
147 | in_git_worktree=`git rev-parse --is-inside-work-tree 2>/dev/null`
148 | if [[ "$in_git_worktree" = "true" ]]; then
149 | git_dir=`git rev-parse --git-dir 2>/dev/null`
150 | srcdir=`dirname "$git_dir"`
151 | exclude_dir=`pwd | sed "s,^$srcdir,,g"`
152 | if ! grep -q "^$exclude_dir" "$git_dir/info/exclude"; then
153 | echo "$exclude_dir" >> "$git_dir/info/exclude"
154 | fi
155 | fi
156 |
157 | echo \
158 | "--------------------------------------------------------------------------------
159 | build configured:
160 |
161 | AS_HELP_STRING([i3lock version:], [`echo ${I3LOCK_VERSION} | sed 's,\\\\,,g'`])
162 | AS_HELP_STRING([is release version:], [${is_release}])
163 |
164 | AS_HELP_STRING([enable debug flags:], [${ax_enable_debug}])
165 | AS_HELP_STRING([code coverage:], [${CODE_COVERAGE_ENABLED}])
166 | AS_HELP_STRING([enabled sanitizers:], [${ax_enabled_sanitizers}])"
167 |
168 | #To compile, run:
169 | #
170 | # cd `pwd` && make
171 | echo \
172 | "--------------------------------------------------------------------------------"
173 |
--------------------------------------------------------------------------------
/cursors.h:
--------------------------------------------------------------------------------
1 | #ifndef _CURSORS_H
2 | #define _CURSORS_H
3 |
4 | #define CURS_NONE 0
5 | #define CURS_WIN 1
6 | #define CURS_DEFAULT 2
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/dpi.c:
--------------------------------------------------------------------------------
1 | /*
2 | * vim:ts=4:sw=4:expandtab
3 | *
4 | * i3 - an improved dynamic tiling window manager
5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6 | *
7 | */
8 | #include "dpi.h"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include "xcb.h"
15 | #include "i3lock.h"
16 |
17 | extern bool debug_mode;
18 |
19 | static long dpi;
20 |
21 | extern xcb_screen_t *screen;
22 |
23 | static long init_dpi_fallback(void) {
24 | return (double)screen->height_in_pixels * 25.4 / (double)screen->height_in_millimeters;
25 | }
26 |
27 | /*
28 | * Initialize the DPI setting.
29 | * This will use the 'Xft.dpi' X resource if available and fall back to
30 | * guessing the correct value otherwise.
31 | */
32 | void init_dpi(void) {
33 | xcb_xrm_database_t *database = NULL;
34 | char *resource = NULL;
35 |
36 | if (conn == NULL) {
37 | goto init_dpi_end;
38 | }
39 |
40 | database = xcb_xrm_database_from_default(conn);
41 | if (database == NULL) {
42 | DEBUG("Failed to open the resource database.\n");
43 | goto init_dpi_end;
44 | }
45 |
46 | xcb_xrm_resource_get_string(database, "Xft.dpi", NULL, &resource);
47 | if (resource == NULL) {
48 | DEBUG("Resource Xft.dpi not specified, skipping.\n");
49 | goto init_dpi_end;
50 | }
51 |
52 | char *endptr;
53 | double in_dpi = strtod(resource, &endptr);
54 | if (in_dpi == HUGE_VAL || dpi < 0 || *endptr != '\0' || endptr == resource) {
55 | DEBUG("Xft.dpi = %s is an invalid number and couldn't be parsed.\n", resource);
56 | dpi = 0;
57 | goto init_dpi_end;
58 | }
59 | dpi = (long)round(in_dpi);
60 |
61 | DEBUG("Found Xft.dpi = %ld.\n", dpi);
62 |
63 | init_dpi_end:
64 | if (resource != NULL) {
65 | free(resource);
66 | }
67 |
68 | if (database != NULL) {
69 | xcb_xrm_database_free(database);
70 | }
71 |
72 | if (dpi == 0) {
73 | DEBUG("Using fallback for calculating DPI.\n");
74 | dpi = init_dpi_fallback();
75 | DEBUG("Using dpi = %ld\n", dpi);
76 | }
77 | }
78 |
79 | /*
80 | * This function returns the value of the DPI setting.
81 | *
82 | */
83 | long get_dpi_value(void) {
84 | return dpi;
85 | }
86 |
87 | /*
88 | * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI
89 | * screen) to a corresponding amount of physical pixels on a standard or retina
90 | * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen.
91 | *
92 | */
93 | int logical_px(const int logical) {
94 | if (screen == NULL) {
95 | /* Dpi info may not be available when parsing a config without an X
96 | * server, such as for config file validation. */
97 | return logical;
98 | }
99 |
100 | /* There are many misconfigurations out there, i.e. systems with screens
101 | * whose dpi is in fact higher than 96 dpi, but not significantly higher,
102 | * so software was never adapted. We could tell people to reconfigure their
103 | * systems to 96 dpi in order to get the behavior they expect/are used to,
104 | * but since we can easily detect this case in code, let’s do it for them.
105 | */
106 | if ((dpi / 96.0) < 1.25)
107 | return logical;
108 | return ceil((dpi / 96.0) * logical);
109 | }
110 |
--------------------------------------------------------------------------------
/dpi.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /**
4 | * Initialize the DPI setting.
5 | * This will use the 'Xft.dpi' X resource if available and fall back to
6 | * guessing the correct value otherwise.
7 | */
8 | void init_dpi(void);
9 |
10 | /**
11 | * This function returns the value of the DPI setting.
12 | *
13 | */
14 | long get_dpi_value(void);
15 |
16 | /**
17 | * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI
18 | * screen) to a corresponding amount of physical pixels on a standard or retina
19 | * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen.
20 | *
21 | */
22 | int logical_px(const int logical);
23 |
--------------------------------------------------------------------------------
/examples/lock.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | BLANK='#00000000'
4 | CLEAR='#ffffff22'
5 | DEFAULT='#ff00ffcc'
6 | TEXT='#ee00eeee'
7 | WRONG='#880000bb'
8 | VERIFYING='#bb00bbbb'
9 |
10 | i3lock \
11 | --insidever-color=$CLEAR \
12 | --ringver-color=$VERIFYING \
13 | \
14 | --insidewrong-color=$CLEAR \
15 | --ringwrong-color=$WRONG \
16 | \
17 | --inside-color=$BLANK \
18 | --ring-color=$DEFAULT \
19 | --line-color=$BLANK \
20 | --separator-color=$DEFAULT \
21 | \
22 | --verif-color=$TEXT \
23 | --wrong-color=$TEXT \
24 | --time-color=$TEXT \
25 | --date-color=$TEXT \
26 | --layout-color=$TEXT \
27 | --keyhl-color=$WRONG \
28 | --bshl-color=$WRONG \
29 | \
30 | --screen 1 \
31 | --blur 5 \
32 | --clock \
33 | --indicator \
34 | --time-str="%H:%M:%S" \
35 | --date-str="%A, %Y-%m-%d" \
36 | --keylayout 1 \
37 |
--------------------------------------------------------------------------------
/examples/lock_bar.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | i3lock \
4 | --blur 5 \
5 | --bar-indicator \
6 | --bar-pos y+h \
7 | --bar-direction 1 \
8 | --bar-max-height 50 \
9 | --bar-base-width 50 \
10 | --bar-color 000000cc \
11 | --keyhl-color 880088cc \
12 | --bar-periodic-step 50 \
13 | --bar-step 50 \
14 | --redraw-thread \
15 | \
16 | --clock \
17 | --force-clock \
18 | --time-pos x+5:y+h-80 \
19 | --time-color 880088ff \
20 | --date-pos tx:ty+15 \
21 | --date-color 990099ff \
22 | --date-align 1 \
23 | --time-align 1 \
24 | --ringver-color 8800ff88 \
25 | --ringwrong-color ff008888 \
26 | --status-pos x+5:y+h-16 \
27 | --verif-align 1 \
28 | --wrong-align 1 \
29 | --verif-color ffffffff \
30 | --wrong-color ffffffff \
31 | --modif-pos -50:-50
32 |
--------------------------------------------------------------------------------
/examples/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Raymo111/i3lock-color/7d337d9133853109d7443a0150ccd26a6b1c02da/examples/screenshot.png
--------------------------------------------------------------------------------
/examples/screenshot_2017.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Raymo111/i3lock-color/7d337d9133853109d7443a0150ccd26a6b1c02da/examples/screenshot_2017.png
--------------------------------------------------------------------------------
/fonts.h:
--------------------------------------------------------------------------------
1 | #ifndef FONTS_H
2 | #define FONTS_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | #define VERIF_FONT 0
11 | #define WRONG_FONT 1
12 | #define LAYOUT_FONT 2
13 | #define TIME_FONT 3
14 | #define DATE_FONT 4
15 | #define GREETER_FONT 5
16 |
17 | typedef struct text {
18 | bool show;
19 |
20 | char str[512];
21 | double size;
22 | double outline_width;
23 |
24 | cairo_font_face_t *font;
25 |
26 | rgba_t color;
27 | rgba_t outline_color;
28 | double x, y;
29 |
30 | int align;
31 | } text_t;
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/i3lock-bash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # bash completion for i3lock-color
3 |
4 | _i3lock() {
5 | local cur="${COMP_WORDS[COMP_CWORD]}"
6 | local last="${COMP_WORDS[COMP_CWORD - 1]}"
7 | local -a options=(
8 | "--version -v"
9 | "--nofork -n"
10 | "--beep -b"
11 | "--no-unlock-indicator -u"
12 | "--image -i"
13 | "--raw"
14 | "--color -c"
15 | "--tiling -t"
16 | "--centered -C"
17 | "--fill -F"
18 | "--max -M"
19 | "--scale -L"
20 | "--pointer -p"
21 | "--ignore-empty-password -e"
22 | "--show-failed-attempts"
23 | "--debug"
24 |
25 | # i3lock-color OPTIONS
26 | "--screen -S"
27 | "--blur -B"
28 | "--clock --force-clocl -k"
29 | "--indicator"
30 | "--radius"
31 | "--ring-width"
32 | # Colors
33 | "--inside-color"
34 | "--ring-color"
35 | "--insidever-color"
36 | "--ringver-color"
37 | "--insidewrong-color"
38 | "--ringwrong-color"
39 | "--line-color"
40 | "--line-uses-inside"
41 | "--line-uses-ring"
42 | "--keyhl-color"
43 | "--bshl-color"
44 | "--separator-color"
45 | "--verif-color"
46 | "--wrong-color"
47 | "--modif-color"
48 | "--layout-color"
49 | "--time-color"
50 | "--date-color"
51 | "--greeter-color"
52 | # Text
53 | "--time-str"
54 | "--date-str"
55 | "--verif-text"
56 | "--wrong-text"
57 | "--keylayout"
58 | "--noinput-text"
59 | "--lock-text"
60 | "--lockfailed-text"
61 | "--greeter-text"
62 | "--no-modkey-text"
63 | # Align
64 | "--time-align --date-align --layout-align --verif-align --wrong-algin --modif-align --greeter-align"
65 | # Outline
66 | "--timeoutlinecolor --dateoutlinecolor --layoutoutlinecolor --verifoutlinecolor --wrongoutlinecolor --modifoutline-color --greeteroutlinecolor"
67 | # Fonts
68 | "--time-font --date-font --layout-font --verif-font --wrong-font --greeter-font"
69 | # Size
70 | "--timesize --datesize --layoutsize --verifsize --wrongsize --greetersize"
71 | # Outline width
72 | "--timeoutlinewidth --dateoutlinewidth --layoutoutlinewidth --verifoutlinewidth --wrongoutlinewidth --modifieroutline-width --greeteroutlinewidth"
73 | # Position
74 | "--ind-pos"
75 | "--time-pos"
76 | "--date-pos"
77 | "--greeter-pos"
78 | # Media keys
79 | "--pass-media-keys"
80 | "--pass-screen-keys"
81 | "--pass-power-keys"
82 | "--pass-volume-keys"
83 | "--custom-key-commands"
84 | "--cmd-brightness-up"
85 | "--cmd-brightness-down"
86 | "--cmd-media-play"
87 | "--cmd-media-pause"
88 | "--cmd-media-stop"
89 | "--cmd-media-next"
90 | "--cmd-media-prev"
91 | "--cmd-audio-mute"
92 | "--cmd-volume-up"
93 | "--cmd-volume-down"
94 | "--cmd-mic-mute"
95 | "--cmd-power-down"
96 | "--cmd-power-off"
97 | "--cmd-power-sleep"
98 | # Bar mode
99 | "--bar-indicator"
100 | "--bar-direction"
101 | "--bar-orientation"
102 | "--bar-step"
103 | "--bar-max-height"
104 | "--bar-base-width"
105 | "--bar-color"
106 | "--bar-periodic-step"
107 | "--bar-pos"
108 | "--bar-count"
109 | "--bar-total-width"
110 | # Extra configs
111 | "--redraw-thread"
112 | "--refresh-rate"
113 | "--composite"
114 | "--no-verify"
115 | "--slideshow-interval"
116 | "--slideshow-random-selection"
117 | )
118 | local args=""
119 | for i in "${options[@]}"; do
120 | args+="$i "
121 | done
122 | COMPREPLY=( $(compgen -W "${args}" -- ${cur}) )
123 |
124 | }
125 |
126 | complete -F _i3lock i3lock
127 |
--------------------------------------------------------------------------------
/i3lock-zsh:
--------------------------------------------------------------------------------
1 | #compdef i3lock
2 |
3 | _i3lock() {
4 | integer ret=1
5 | local -a args
6 | zstyle ':completion:*:*:i3lock:*:descriptions' format ''
7 | args+=(
8 | "(--version -v)"{--version,-v}"[Display the version of i3lock]"
9 | "(--nofork -n)"{--nofork,-n}"[Don't fork after starting]"
10 | "(--beep -b)"{--beeping,-b}"[Enable beeping]"
11 | "(--no-unlock-indicator -u)"{--no-unlock-indicator,-u}"[Disable the unlock indicator]"
12 | "(--image -i)"{--image,-i}"[Display the given PNG image instead of a blank screen]:filename:_files -g '*.(png|jpg)'"
13 | "--raw[Read the image given by --image as a raw image instead of PNG]:raw:"
14 | "(--color -c)"{--color,-c}"[Turn the screen into the given hex color]:hex:->hex"
15 | "(--tiling -t)"{--tiling,-t}"[Image will be displayed tiled all over the screen]"
16 | "(--centered -C)"{--centered,-C}"[Image will be displayed centered on the screen]"
17 | "(--fill -F)"{--fill,-F}"[Image will fill all over the screen]"
18 | "(--max -M)"{--max,-M}"[Image will fit the screen at width or height]"
19 | "(--scale -L)"{--scale,-L}"[Image will be stretched on the screen]"
20 | "(--pointer -p)"{--pointer,-p}"[Sets mouse pointer type]:pointer:(win default)"
21 | "(--ignore-empty-password -e)"{--ignore-empty-password,-e}"[Do not validate empty password]"
22 | "(--show-failed-attempts -f)"{--show-failed-attempts,-f}"[Show the number of failed attemps]"
23 | "--debug[Enables debug logging.]"
24 |
25 | # i3lock-color OPTIONS
26 |
27 | "(--screen -S)"{--screen,-S}"[Specifies which display to draw the unlock indicator]:int:"
28 | "(--blur -B)"{--blur,-B}"[Captures the screen and blurs it using the given sigma]:sigma:"
29 | "(--clock --force-clock -k)"{--clock,--force-clock,-k}"[Displays the clock]"
30 | "--indicator[Forces the indicator to always be visible]"
31 | "--radius[The radius of the circle]:float:"
32 | "--ring-width[The width of the ring unlock indicator]:float:"
33 | # Colors
34 | "--inside-color[Sets the default \"resting\" color for the interior circle]:hex:->hex"
35 | "--ring-color[Sets the default ring color]:hex:->hex"
36 | "--insidever-color[Sets the interior circle color while the password is being verified]:hex:->hex"
37 | "--ringver-color[Sets the ring color while the password is being verified]:hex:->hex"
38 | "--insidewrong-color[Sets the interior circle color for suring flash for an incorrect password]:hex:->hex"
39 | "--ringwrong-color[Sets the ring color during the flas for an incorrect password]:hex:->hex"
40 | "--line-color[Sets the color for the line separating the inside circle, and the outer ring]:hex:->hex"
41 | "--line-uses-inside[Conflicts with --line-uses-ring. Overrides --linecolor; the line will match the inside color]"
42 | "--line-uses-ring[Conflicts with --line-uses-inside. Overrides --linecolor; The line will match the ring color]"
43 | "--keyhl-color[Sets the color of the ring 'highlight' strokes that appear upon keypress]:hex:->hex"
44 | "--bshl-color[Sets the color of the ring 'highlight' strokes that appear upon backspace]:hex:->hex"
45 | "--separator-color[Sets the color of the 'separator', which is at both ends of the ring highlights]:hex:->hex"
46 | "--verif-color[Sets the color of the status text while verifying]:hex:->hex"
47 | "--wrong-color[Sets the color of the status when \"wrong\"]:hex:->hex"
48 | "--modif-color[Sets the color of the status text while verifying]:hex:->hex"
49 | "--layout-color[Sets the color of the keyboard layout text]:hex:->hex"
50 | "--time-color[Sets te color of the time in the clock]:hex:->hex"
51 | "--date-color[Sets the color of the date in the clock]:hex:->hex"
52 | "--greeter-color[Sets the color of the greeter text]:hex:->hex"
53 | # Text
54 | "--time-str[Sets the format used for generating the time string]:str:"
55 | "--date-str[Sets the format used for generating the date string]:str:"
56 | "--verif-text[Sets the string to be shown while verifying]:str:"
57 | "--wrong-text[Sets the string to be shown upon entering an incorrect password]:str:"
58 | "--keylayout[Displays the keylayout]:mode:((0\:'Displays the full string returned by the query, i.e. English (US)' 1\:'Displays up until the first parenthesis, i.e. English' 2\:'Displays just the contents of the parenthesis, i.e US'))"
59 | "--noinput-text[Sets the string to be shown upon pressing backspace whithout anything to delete]:str:"
60 | "--lock-text[Sets the string to be shown while acquiring pointer and keyboard focus]:str:"
61 | "--lockfailed-text[Sets the string to be shown after failing to acquire pointer and keyboard focus]:str:"
62 | "--greeter-text[Sets the greeter text]:str:"
63 | "--no-modkey-text[Hides the modkey indicator]"
64 | # Align
65 | "(--time-align --date-align --layout-align --verif-align --wrong-align --modif-align --greeter-align)"{--time-align,--date-align,--layout-align,--verif-align,--wrong-align,--modif-align,--greeter-align}"[Sets the text alignment]:alignment:((0\:'default' 1\:'left aligned' 2\:'right aligned'))"
66 | # Outline color
67 | "(--timeoutline-color --dateoutline-color --layoutoutline-color --verifoutline-color --wrongoutline-color --modifoutline-color --greeteroutline-color)"{--timeoutline-color,--dateoutline-color,--layoutoutline-color,--verifoutline-color,--wrongoutline-color,--modifoutline-color,--greeteroutline-color}"[Sets the color of the outline]:hex:->hex"
68 | # Fonts
69 | "(--time-font --date-font --layout-font --verif-font --wrong-font --greeter-font)"{--time-font,--date-font,--layout-font,--verif-font,--wrong-font,--greeter-font}"[Sets the font used to render various strings]:str:"
70 | # Size
71 | "(--time-size --date-size --layout-size --verif-size --wrong-size --greeter-size)"{--time-size,--date-size,--layout-size,--verif-size,--wrong-size,--greeter-size}"[Sets the font size used to render various strings]:int:"
72 | # Outline width
73 | "(--timeoutline-width --dateoutline-width --layoutoutline-width --verifoutline-width --wrongoutline-width --modifieroutline-width --greeteroutline-width)"{--timeoutline-width,--dateoutline-width,--layoutoutline-width,--verifoutline-width,--wrongoutline-width,--modifieroutline-width,--greeteroutline-width}"[Sets the width of the outline]:float:"
74 | # Position
75 | "--ind-pos[Sets the position for the unlock indicator]:pos:->ind_pos"
76 | "--time-pos[Sets the position for the time string]:pos:->time_pos"
77 | "--date-pos[Sets the position for the date string]:pos:->date_pos"
78 | "--greeter-pos[Sets the position for the greeter string]:pos:->greeter_pos"
79 | # Media keys
80 | "--pass-media-keys[Allow media keys to be used while the screen is locked]"
81 | "--pass-screen-keys[Allow screen keys to be used while the screen is locked]"
82 | "--pass-power-keys[Allow power keys to be used while the screen is locked]"
83 | "--pass-volume-keys[Allow volume keys to be used while the screen is locked]"
84 | "--custom-key-commands[Enable shell commands for media keys]"
85 | "--cmd-brightness-up[Command for XF86MonBrightnessUp]"
86 | "--cmd-brightness-down[Command for XF86MonBrightnessDown]"
87 | "--cmd-media-play[Command for XF86AudioPlay]"
88 | "--cmd-media-pause[Command for XF86AudioPause]"
89 | "--cmd-media-stop[Command for XF86AudioStop]"
90 | "--cmd-media-next[Command for XF86AudioNext]"
91 | "--cmd-media-prev[Command for XF86AudioPrev]"
92 | "--cmd-audio-mute[Command for XF86AudioMute]"
93 | "--cmd-volume-up[Command for XF86AudioRaiseVolume]"
94 | "--cmd-volume-down[Command for XF86AudioLowerVolume]"
95 | "--cmd-mic-mute[Command for XF86AudioMicMute]"
96 | "--cmd-power-down[Command for XF86PowerDown]"
97 | "--cmd-power-off[Command for XF86PowerOff]"
98 | "--cmd-power-sleep[Command for XF86Sleep]"
99 | # Bar mode
100 | "--bar-indicator[Replaces the usual ring indicator with a bar indicator]"
101 | "--bar-direction[Sets the direction the bars grow in]:direction:((0\:'default' 1\:'reverse' 2\:'both'))"
102 | "--bar-orientation[Sets whether the bar is vertically or horizontally oriented]:orientation:(vertical horizontal)"
103 | "--bar-step[Sets the step that each bar decreases by when a key is pressed]:int:"
104 | "--bar-max-height[The maximum height a bar can get to]:float:"
105 | "--bar-base-width[The thickness of the \"base\" bar that all the bar originate from]:float:"
106 | "--bar-color[Sets the default color of the bar base]:hex:->hex"
107 | "--bar-periodic-step[The value by which the bars decrease each time the screen is redrawn]:int:"
108 | "--bar-pos[Sets the bar position]:pos:->bar_pos"
109 | "--bar-count[Sets the number of minibars to draw on each screen]:int:"
110 | "--bar-total-width[The total width of the bar]:float:"
111 | # Extra configs
112 | "--redraw-thread[Starts a separate thread for redrawing the screen]"
113 | "--refresh-rate[The refresh rate of the indicator]:double:"
114 | "--composite"
115 | "--no-verify[Do not verify the password provided by the user and unlock inmediately]"
116 | # Slideshow
117 | "--slideshow-interval[The interval to wait until switching to the nex image]:double:"
118 | "--slideshow-random-selection[Randomize the order of the images]"
119 |
120 |
121 | )
122 | _arguments $args[@] && ret=0
123 |
124 | case "$state" in
125 | hex)
126 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%d'
127 | _message "Color in hexadecimal rrggbbaa, like #ff0000ff or #354F9AFF"
128 | ;;
129 | ind_pos)
130 | zstyle ':completion:*:*:i3lock:*:normal' format '%d'
131 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%B%d%b'
132 |
133 | _message "\"x position:y position\""
134 | _message -e "normal" "'x' - x position of the current display. Corresponds to the left-most row of pixels"
135 | _message -e "normal" "'y' - y position of the current display. Corresponds to the topmost row of pixels"
136 | _message -e "normal" "'w' - width of the current display"
137 | _message -e "normal" "'w' - height of the current display"
138 | _message -e "normal" "'r' - unlock indicator radius"
139 | ;;
140 | time_pos)
141 | zstyle ':completion:*:*:i3lock:*:normal' format '%d'
142 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%B%d%b'
143 |
144 | _message "\"x position:y position\""
145 | _message -e "normal" "All the variables from --ind-pos may be used, in addition to:"
146 | _message -e "normal" "'ix' - x position of the indicator on the current display"
147 | _message -e "normal" "'iy' - y position of the indicator on the current display"
148 | _message -e "normal" "If the --bar-indicator option is used, the following may be used"
149 | _message -e "normal" "'bw' - width od the bar indicator"
150 | _message -e "normal" "'bx' - x position of the bar indicator on the current display"
151 | _message -e "normal" "'by' - y position of the bar indicator on the current display"
152 | ;;
153 | date_pos)
154 | zstyle ':completion:*:*:i3lock:*:normal' format '%d'
155 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%B%d%b'
156 |
157 | _message "\"x position:y position\""
158 | _message -e "normal" "All the variables from --ind-pos and --time-pos may be used, in addition to:"
159 | _message -e "normal" "'tx' - x position of the timestring on the current display"
160 | _message -e "normal" "'ty' - y position of the timestring on the current display"
161 | ;;
162 | greeter_pos)
163 | zstyle ':completion:*:*:i3lock:*:normal' format '%d'
164 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%B%d%b'
165 |
166 | _message "\"x position:y position\""
167 | _message -e "normal" "All the variables from --ind-pos and --time-pos may be used"
168 | ;;
169 | bar_pos)
170 | zstyle ':completion:*:*:i3lock:*:normal' format '%d'
171 | zstyle ':completion:*:*:i3lock:*:descriptions' format '%B%d%b'
172 |
173 | _message "\"x position:y position\""
174 | _message -e "normal" "All the variables from --ind-pos and --time-pos may be used"
175 | _message -e "normal" "If only one number is provided, sets the vertical offset from the top or left edge"
176 | _message -e "normal" "If two numbers are provided, sets the starting position of the bar"
177 | ;;
178 |
179 |
180 | esac
181 |
182 | return ret
183 | }
184 |
185 | _i3lock
186 |
--------------------------------------------------------------------------------
/i3lock.1:
--------------------------------------------------------------------------------
1 | .de Vb \" Begin verbatim text
2 | .ft CW
3 | .nf
4 | .ne \\$1
5 | ..
6 | .de Ve \" End verbatim text
7 | .ft R
8 | .fi
9 | ..
10 |
11 | .TH i3lock-color 1 "MAR 2025" Linux "User Manuals"
12 |
13 | .SH NAME
14 | i3lock-color \- improved screen locker
15 |
16 | .SH SYNOPSIS
17 | .B i3lock
18 | .RB [\|\-v\|]
19 | .RB [\|\-n\|]
20 | .RB [\|\-b\|]
21 | .RB [\|\-i
22 | .IR image.png \|]
23 | .RB [\|\-c
24 | .IR color \|]
25 | .RB [\|\-t\|]
26 | .RB [\|\-p
27 | .IR pointer\|]
28 | .RB [\|\-u\|]
29 | .RB [\|\-e\|]
30 | .RB [\|\-f\|]
31 | .RB [\|\-m\|]
32 |
33 | .SH DESCRIPTION
34 | .B i3lock\-color
35 | is a simple screen locker like slock. After starting it, you will see a white
36 | screen (you can configure the color/an image). You can return to your screen by
37 | entering your password.
38 |
39 | .SH FEATURES
40 | .IP \[bu] 2
41 | i3lock forks, so you can combine it with an alias to suspend to RAM
42 | (run "i3lock && echo mem > /sys/power/state" to get a locked screen after waking
43 | up your computer from suspend to RAM)
44 | .IP \[bu]
45 | You can specify either a PNG or JPG image, a GIF animation or a background
46 | color which will be displayed while your screen is locked.
47 | .IP \[bu]
48 | You can specify whether i3lock should bell upon a wrong password.
49 | .IP \[bu]
50 | i3lock uses PAM and therefore is compatible with LDAP, etc.
51 |
52 | .SH OPTIONS
53 | .TP
54 | .B \-v, \-\-version
55 | Display the version of your
56 | .B i3lock
57 |
58 | .TP
59 | .B \-n, \-\-nofork
60 | Don't fork after starting.
61 |
62 | .TP
63 | .B \-b, \-\-beep
64 | Enable beeping. Be sure to not do this when you are about to annoy other people,
65 | like when opening your laptop in a boring lecture.
66 |
67 | .TP
68 | .B \-u, \-\-no\-unlock\-indicator
69 | Disable the unlock indicator. i3lock will by default show an unlock indicator
70 | after pressing keys. This will give feedback for every keypress and it will
71 | show you the current PAM state (whether your password is currently being
72 | verified or whether it is wrong).
73 |
74 | .TP
75 | .BI \-i\ path \fR,\ \fB\-\-image= path
76 | Display the given PNG/JPG image or GIF animation instead of a blank screen.
77 |
78 | .TP
79 | .BI \fB\-\-raw= format
80 | Read the image given by \-\-image as a raw image instead of PNG/JPG/GIF. The
81 | argument is the image's format as x:.
82 | The supported pixel formats are:
83 | \'native', 'rgb', 'xrgb', 'rgbx', 'bgr', 'xbgr', and 'bgrx'.
84 | The "native" pixel format expects a pixel as a 32-bit (4-byte) integer in
85 | the machine's native endianness, with the upper 8 bits unused.
86 | Red, green and blue are stored in the remaining bits, in that order.
87 |
88 | .BR Example:
89 | .Vb 6
90 | \& --raw=1920x1080:rgb
91 | .Ve
92 | You can use ImageMagick’s
93 | .IR convert(1)
94 | program to feed raw images into i3lock:
95 |
96 | .Vb 6
97 | \& convert wallpaper.jpg RGB:- | i3lock --raw 3840x2160:rgb --image /dev/stdin
98 | .Ve
99 | This allows you to load a variety of image formats without i3lock having to
100 | support each one explicitly.
101 | You can also use it to resize images to the screen ratio:
102 |
103 | .Vb 6
104 | \& convert wallpaper.jpg -resize $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/') RGB:- | i3lock --raw $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/'):rgb --image /dev/stdin
105 | .Ve
106 | Note that $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/')
107 | gets you the current screen dimensions in the wxh (e.g. 1920x1080) format.
108 |
109 | .TP
110 | .BI \-c\ rrggbbaa \fR,\ \fB\-\-color= rrggbbaa
111 | Turn the screen into the given color instead of white. Color must be given in
112 | 4-byte format: rrggbbaa (i.e. ff0000ff is opaque red).
113 | Use the last byte for alpha. Setting this below FF (i.e. ff000088) will allow
114 | your screen to be shown translucently if you use a compositor (e.g. compton,
115 | xcompmgr).
116 |
117 | .TP
118 | .B \-t, \-\-tiling
119 | If an image is specified (via \-i) it will display the image tiled all over the
120 | screen.
121 |
122 | Note: For all image options, with a multi-monitor setup, the image is visible on
123 | all screens.
124 |
125 | .TP
126 | .B \-C, \-\-centered
127 | If an image is specified (via \-i) it will display the image centered on the
128 | screen.
129 |
130 | .TP
131 | .B \-F, \-\-fill
132 | If an image is specified (via \-i) it will scale the image until it fills the
133 | screen. A portion of the image will be cropped.
134 |
135 | .TP
136 | .B \-M, \-\-max
137 | If an image is specified (via \-i) it will scale the image until either the
138 | width or the height fits the screen without being cropped. The border color
139 | can be set via \-c.
140 |
141 | .TP
142 | .B \-L, \-\-scale
143 | If an image is specified (via \-i) it will stretch the image until both the
144 | width and the height fits the screen.
145 |
146 | .TP
147 | .BI \-p\ win|default \fR,\ \fB\-\-pointer= win|default
148 | If you specify "default",
149 | .B i3lock
150 | does not hide your mouse pointer. If you specify "win",
151 | .B i3lock
152 | displays a hardcoded Windows-Pointer (thus enabling you to mess with your
153 | friends by using a screenshot of a Windows desktop as a locking-screen).
154 |
155 | .TP
156 | .B \-e, \-\-ignore\-empty\-password
157 | When an empty password is provided by the user, do not validate it. Without this
158 | option, the empty password will be provided to PAM and, if invalid, the user
159 | will have to wait a few seconds before another try. This can be useful if the
160 | XF86ScreenSaver key is used to put a laptop to sleep and bounce on resume or if
161 | you happen to wake up your computer with the enter key.
162 |
163 | .TP
164 | .B \-f, \-\-show\-failed\-attempts
165 | Show the number of failed attempts, if any.
166 |
167 | .TP
168 | .B \-\-debug
169 | Enables debug logging.
170 | Note, that this will log the password used for authentication to stdout.
171 |
172 | .SH i3lock-color OPTIONS
173 | .TP
174 | .B \-S number, \-\-screen=number
175 | Specifies which display to draw the unlock indicator and clock on. By default,
176 | they'll be placed on every screen.
177 | Note that this number is zero indexed. The ordering is dependent on libxinerama.
178 |
179 | .TP
180 | .B \-B sigma, \-\-blur=sigma
181 | Captures the screen and blurs it using the given sigma (radius).
182 | Images may still be overlaid over the blurred screenshot.
183 | As an alternative to this option, you could specify a translucent background
184 | color (-c option) with a fully transparent or translucent color, and use a
185 | compositor to perform blurring (e.g. compton, picom).
186 |
187 | .TP
188 | .B \-k, \-\-clock, \-\-force\-clock
189 | Displays the clock. \-\-force\-clock also displays the clock when there's
190 | indicator text (useful for when the clock is not positioned with the indicator).
191 |
192 | .TP
193 | .B \-\-indicator
194 | Forces the indicator to always be visible, instead of only showing on activity.
195 |
196 | .TP
197 | .B \-\-radius
198 | The radius of the circle. Defaults to 90.
199 |
200 | .TP
201 | .B \-\-ring\-width
202 | The width of the ring unlock indicator. Defaults to 7.0.
203 |
204 | .TP
205 | .B \-\-{inside, ring}\-color=rrggbbaa
206 | Sets the idle color for the interior circle and ring. Note: use individual
207 | options per element unless the shell supports brace expansion (in which case
208 | remove the spaces inside the curly braces).
209 |
210 | .TP
211 | .B \-\-{inside, ring}ver\-color=rrggbbaa
212 | Sets the interior circle and ring color while the password is being verified.
213 |
214 | .TP
215 | .B \-\-{inside, ring}wrong\-color=rrggbbaa
216 | Sets the interior circle and ring color for during incorrect password flashes.
217 |
218 | .TP
219 | .B \-\-line\-color=rrggbbaa
220 | Sets the color for the line separating the inside circle and the outer ring.
221 |
222 | .TP
223 | .B \-\-line\-uses\-{inside, ring}
224 | Overrides \-\-line\-color. The line will match the {inside, ring} color.
225 | Note: these two options conflict with each other.
226 |
227 | .TP
228 | .B \-\-{key, bs}hl\-color=rrggbbaa
229 | Sets the color of highlight arcs on the ring upon keypress and backspace.
230 |
231 | .TP
232 | .B \-\-separator\-color=rrggbbaa
233 | Sets the color of the seperators at both ends of the highlight arcs on the ring.
234 |
235 | .TP
236 | .B \-\-{verif, wrong, modif}\-color=rrggbbaa
237 | Sets the color of the status text while verifying and when password is wrong.
238 |
239 | .TP
240 | .B \-\-{layout, time, date, greeter}\-color=rrggbbaa
241 | Sets text colors.
242 |
243 | .TP
244 | .B \-\-keylayout mode
245 | Displays the keylayout. Positionable similar to date, time, and indicator.
246 | Modes are as follows:
247 | .RS
248 | .IP \[bu] 2
249 | 0 - Displays the full string returned by the query, i.e. "English (US)"
250 | .IP \[bu]
251 | 1 - Displays up until the first parenthesis, i.e. "English"
252 | .IP \[bu]
253 | 2 - Displays just the contents of the parenthesis, i.e. "US"
254 | .RE
255 |
256 | .B For all following -str or -text options, some control characters
257 | .B (i.e. \\\\n, \\\\t) are supported. See \fBCONTROL CHARACTERS\fR
258 | .B for more details.
259 |
260 | .TP
261 | .B \-\-time\-str="%H:%M:%S"
262 | Sets the format used for generating the time string.
263 | See strftime(3) for a full list of format specifiers.
264 |
265 | .TP
266 | .B \-\-date\-str="%A, %m %Y"
267 | Sets the format used for generating the date string.
268 |
269 | .TP
270 | .B \-\-verif\-text="verifying…"
271 | Sets the string to be shown while verifying the password/input/key/etc.
272 |
273 | .TP
274 | .B \-\-wrong\-text="wrong!"
275 | Sets the string to be shown upon entering an incorrect password.
276 |
277 | .TP
278 | .B \-\-noinput\-text="no input"
279 | Sets the string to be shown upon pressing backspace without anything to delete.
280 |
281 | .TP
282 | .B \-\-lock\-text="locking…"
283 | Sets the string to be shown while acquiring pointer and keyboard focus.
284 |
285 | .TP
286 | .B \-\-lockfailed\-text="lock failed!"
287 | Sets the string to be shown after failing to acquire pointer and keyboard focus.
288 |
289 | .TP
290 | .B \-\-greeter\-text=""
291 | Sets the greeter text.
292 |
293 | .TP
294 | .B \-\-no\-modkey\-text
295 | Hides the modkey indicator (Num, Caps Lock ...)
296 |
297 | .TP
298 | .B \-\-{time, date, layout, verif, wrong, modif, greeter}\-align
299 | Sets the text alignment of the time, date, keylayout, verification, wrong,
300 | modifier and greeter texts.
301 | .RS
302 | .IP \[bu] 2
303 | 0 - centered (default)
304 | .IP \[bu]
305 | 1 - left aligned
306 | .IP \[bu]
307 | 2 - right aligned
308 | .RE
309 |
310 | .TP
311 | .B \-\-{time, date, layout, verif, wrong, greeter, modif}outline\-color=rrggbbaa
312 | Sets the color of the outlines.
313 |
314 | .TP
315 | .B \-\-{time, date, layout, verif, wrong, greeter}\-font=sans\-serif
316 | Sets the font used to render various strings.
317 |
318 | .TP
319 | .B \-\-{time, date, layout, verif, wrong, greeter}\-size=number
320 | Sets the font size used to render various strings.
321 |
322 | .TP
323 | .B \-\-{time, date, layout, verif, wrong, greeter, modifier}outline\-width=number
324 | Sets the width of the outline.
325 |
326 | .TP
327 | .B \-\-ind\-pos="x\-position:y\-position"
328 | Sets the position for the unlock indicator. Valid variables include:
329 | .RS
330 | .IP \[bu] 2
331 | x - x position of the current display.
332 | Corresponds to the leftmost column of pixels on that display.
333 | .IP \[bu]
334 | y - y position of the current display.
335 | Corresponds to the topmost row of pixels on that display.
336 | .IP \[bu]
337 | w - width of the current display.
338 | .IP \[bu]
339 | h - height of the current display.
340 | .IP \[bu]
341 | r - unlock indicator radius.
342 | .RE
343 |
344 | .TP
345 | .B \-\-time\-pos="x\-position:y\-position"
346 | Sets the position for the time string. All the variables from \-\-ind\-pos may
347 | be used, in addition to:
348 | .RS
349 | .IP \[bu] 2
350 | ix - x position of the indicator on the current display.
351 | .IP \[bu]
352 | iy - y position of the indicator on the current display.
353 |
354 | If the \-\-bar\-indicator option is used, the following variables may be used:
355 | .IP \[bu] 2
356 | bw - width of the bar indicator.
357 | .IP \[bu]
358 | bx - x position of the bar indicator on the current display.
359 | .IP \[bu]
360 | by - y position of the bar indicator on the current display.
361 | .RE
362 |
363 | .TP
364 | .B \-\-date\-pos="x\-position:y\-position"
365 | Sets the position for the date string. All the variables from \-\-ind\-pos and
366 | \-\-time\-pos may be used, in addition to:
367 | .RS
368 | .IP \[bu] 2
369 | tx - x position of the timestring on the current display.
370 | .IP \[bu]
371 | ty - y position of the timestring on the current display.
372 | .RE
373 |
374 | .TP
375 | .B \-\-greeter\-pos="x\-position:y\-position"
376 | Sets the position for the greeter string. All the variables from \-\-ind\-pos and
377 | \-\-time\-pos may be used.
378 |
379 | .TP
380 | .B \-\-pass\-{media, screen, power, volume}\-keys
381 | Allow the following keys to be used normally while the screen is locked by
382 | passing them through:
383 | .RS
384 | .IP \[bu] 2
385 | media - XF86AudioPlay, XF86AudioPause, XF86AudioStop, XF86AudioPrev,
386 | XF86AudioNext, XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume,
387 | XF86AudioMicMute
388 | .IP \[bu]
389 | screen - XF86MonBrightnessUp, XF86MonBrightnessDown
390 | .IP \[bu]
391 | power - XF86PowerDown, XF86PowerOff, XF86Sleep
392 | .IP \[bu]
393 | volume - XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume
394 | .RE
395 |
396 |
397 | .TP
398 | .B \-\-custom\-key\-commands
399 | Enables custom shell commands for media, screen, power and volume keys. An alternative to \-\-pass\-media\0keys that will work in any environment.
400 |
401 | .TP
402 | .B \-\-cmd\-**
403 | Shell command to run when the corresponding key is pressed. Requires \-\-custom\-key\-commands
404 | .RS
405 | .IP \[bu] 2
406 | brightness\-up - XF86MonBrightnessUp
407 | .IP \[bu]
408 | brightness\-down - XF86MonBrightnessDown
409 | .IP \[bu]
410 | media\-play - XF86AudioPlay
411 | .IP \[bu]
412 | media\-pause - XF86AudioPause
413 | .IP \[bu]
414 | media\-stop - XF86AudioStop
415 | .IP \[bu]
416 | media\-next - XF86AudioNext
417 | .IP \[bu]
418 | media\-prev - XF86AudioPrev
419 | .IP \[bu]
420 | audio\-mute - XF86AudioMute
421 | .IP \[bu]
422 | volume\-up - XF86AudioRaiseVolume
423 | .IP \[bu]
424 | volume\-down - XF86AudioLowerVolume
425 | .IP \[bu]
426 | mic\-mute - XF86AudioMicMute
427 | .IP \[bu]
428 | power\-down - XF86PowerDown
429 | .IP \[bu]
430 | power\-off - XF86PowerOff
431 | .IP \[bu]
432 | power\-sleep - XF86Sleep
433 | .RE
434 |
435 | .TP
436 | .B \-\-bar\-indicator
437 | Replaces the usual ring indicator with a bar indicator. Comes with perks.
438 |
439 | .TP
440 | .B \-\-bar\-direction={0, 1, 2}
441 | Sets the direction the bars grow in. 0 is the default (downwards, or rightwards,
442 | depending on the bar orientation). 1 is the reverse, and 2 is both.
443 |
444 | .TP
445 | .B \-\-bar\-orientation={vertical,horizontal}
446 | Sets whether the bar is vertically or horizontally oriented.
447 | Defaults to horizontal.
448 |
449 | .TP
450 | .B \-\-bar\-step
451 | Sets the step that each bar decreases by when a key is pressed. A random bar is
452 | set to its max height, then each neighbor is set to (height - step*distance).
453 |
454 | .TP
455 | .B \-\-bar\-max\-height
456 | The maximum height a bar can get to. When a key is pressed, a random bar is set
457 | to this value, then its neighbors are set to its height, minus the step value.
458 |
459 | .TP
460 | .B \-\-bar\-base\-width
461 | The thickness of the "base" bar that all the bars originate from.
462 | This bar also takes on the ring verification and wrong colors to give
463 | authentication feedback.
464 |
465 | .TP
466 | .B \-\-bar\-color
467 | Sets the default color of the bar base.
468 |
469 | .TP
470 | .B \-\-bar\-periodic\-step
471 | The value by which the bars decrease each time the screen is redrawn.
472 |
473 | .TP
474 | .B \-\-bar\-pos
475 | Works similarly to the time/date/indicator expressions. If only one number is
476 | provided, this sets the vertical offset from the top or left edge. If two
477 | numbers are provided in the form of x:y, sets the starting position of the bar.
478 |
479 | .TP
480 | .B \-\-bar\-count
481 | Sets the number of minibars to draw on each screen.
482 |
483 | .TP
484 | .B \-\-bar\-total\-width
485 | The total width of the bar. Can be an expression.
486 |
487 | .TP
488 | .B \-\-redraw\-thread
489 | Starts a separate thread for redrawing the screen. Potentially worse from a
490 | security standpoint, but makes the bar indicator still do its usual periodic
491 | redraws when PAM is authenticating.
492 |
493 | .TP
494 | .B \-\-refresh\-rate=seconds\-as\-double
495 | The refresh rate of the indicator, given in seconds. This should automatically
496 | align itself, but is somewhat buggy currently.
497 | Values less than one will work, but may result in poor system performance.
498 |
499 | .TP
500 | .B \-\-composite
501 | Some compositors have problems with i3lock trying to render over them, so this
502 | argument is disabled by default. However, some will work properly with it, so
503 | it's been left enabled.
504 |
505 | .TP
506 | .B \-\-no\-verify
507 | Do not verify the password entered by the user and unlock immediately.
508 | .B Use only for quickly testing new configurations and remember to remove to
509 | .B actually lock your screen!
510 |
511 | .TP
512 | .B \-\-slideshow\-interval
513 | The interval to wait until switching to the next image.
514 |
515 | .TP
516 | .B \-\-slideshow\-random\-selection
517 | Randomize the order of the images.
518 |
519 | .SH CONTROL CHARACTERS
520 | Control characters (\\r \\n \\b \\t) are supported in text OPTIONS. Their behavior
521 | are almost as same as anywhere else.
522 | .TP
523 | .B Carriage Return(\\\\r)
524 | Move to the start of line (left edge).
525 | Notes: The rendered characters would still live there.
526 | .TP
527 | .B Line Feed(\\\\n)
528 | Move to start of next line (left edge).
529 | .TP
530 | .B Backspace(\\\\b)
531 | Overwrite last one char if exists.
532 | Notes: The rendered character would still live there.
533 | .TP
534 | .B Tab(\\\\t)
535 | Move to next tab stop position.The width of one character for moving is as same as character 'a'.
536 | Note: The width may be strange if the font is not mono-spaced.
537 |
538 | .SH SEE ALSO
539 | .IR xautolock(1)
540 | \- use i3lock as your screen saver
541 |
542 | .IR convert(1)
543 | \- feed a wide variety of image formats to i3lock
544 |
545 | .SH HOMEPAGE
546 | https://github.com/Raymo111/i3lock-color
547 |
548 | Please report bugs and submit pull-requests as follows:
549 | For i3lock (upstream): https://github.com/i3/i3lock
550 | For i3lock-color (enhancements on top of i3lock): https://github.com/Raymo111/i3lock-color
551 |
552 | .SH AUTHORS
553 | Michael Stapelberg
554 |
555 | Jan-Erik Rediger
556 |
557 | Pandora
558 |
559 | Raymond Li
560 |
--------------------------------------------------------------------------------
/i3lock.h:
--------------------------------------------------------------------------------
1 | #ifndef _I3LOCK_H
2 | #define _I3LOCK_H
3 |
4 | // boy i sure hope this doesnt change in the future
5 | #define NANOSECONDS_IN_SECOND 1000000000
6 |
7 | /* This macro will only print debug output when started with --debug.
8 | * This is important because xautolock (for example) closes stdout/stderr by
9 | * default, so just printing something to stdout will lead to the data ending
10 | * up on the X11 socket (!). */
11 | #define DEBUG(fmt, ...) \
12 | do { \
13 | if (debug_mode) { \
14 | fprintf(stderr, "[i3lock-debug] " fmt, ##__VA_ARGS__); \
15 | } \
16 | } while (0)
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/install-i3lock-color.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | LICENSE='/usr/share/licenses/i3lock-color/LICENSE'
4 |
5 | ./build.sh
6 | cd build
7 | sudo make install
8 | sudo install -Dm644 ../LICENSE "$LICENSE"
9 |
10 | echo "i3lock-color installed. The binary and manpage listing are \`i3lock'.
11 | The license can be found at $LICENSE
12 | GitHub repo: https://github.com/Raymo111/i3lock-color
13 | Discord server: https://discord.gg/FzVPghyDt2"
14 |
--------------------------------------------------------------------------------
/jpg.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "jpg.h"
12 |
13 | /*
14 | * Checks if the file is a JPEG by looking for a valid JPEG header.
15 | */
16 | bool file_is_jpg(FILE* image_file) {
17 | uint16_t file_header;
18 | size_t read_count;
19 | // TODO: Consider endianess on non-x86 platforms
20 | uint16_t jpg_magick = 0xd8ff;
21 |
22 | fseek(image_file, 0, SEEK_SET);
23 | read_count = fread(&file_header, sizeof(file_header), 1, image_file);
24 |
25 | if (read_count < 1) {
26 | fprintf(stderr, "Error searching for JPEG header\n");
27 | return false;
28 | }
29 |
30 | return file_header == jpg_magick;
31 | }
32 |
33 | /*
34 | * Reads a JPEG from a file into memory, in a format that Cairo can create a
35 | * surface from.
36 | */
37 | void* read_JPEG_file(char *file_path, JPEG_INFO *jpg_info) {
38 | int img_err;
39 | struct jpeg_decompress_struct cinfo;
40 | struct jpeg_error_mgr jerr;
41 | FILE *infile; /* source file */
42 | void *img; /* decompressed image data pointer */
43 |
44 | if ((infile = fopen(file_path, "rb")) == NULL) {
45 | img_err = errno;
46 | fprintf(stderr, "Could not open image file %s: %s\n",
47 | file_path, strerror(img_err));
48 | return NULL;
49 | }
50 |
51 | cinfo.err = jpeg_std_error(&jerr);
52 | jpeg_create_decompress(&cinfo);
53 |
54 | jpeg_stdio_src(&cinfo, infile);
55 |
56 | (void) jpeg_read_header(&cinfo, TRUE);
57 |
58 | // BGRA + endianness change = RGBA?
59 | // TODO: Test this code on non-x86_64 platforms
60 | cinfo.out_color_space = JCS_EXT_BGRA;
61 |
62 | (void) jpeg_start_decompress(&cinfo);
63 |
64 | jpg_info->height = cinfo.output_height;
65 | jpg_info->width = cinfo.output_width;
66 |
67 | /* Get the *cairo* stride rather than the stride from the image. This is
68 | * the space needed in memory for each row for optimized Cairo rendering. */
69 | int cairo_stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
70 | cinfo.output_width);
71 | jpg_info->stride = cairo_stride;
72 | if (cairo_stride < jpg_info->width) {
73 | /* This should never happen, but if it does then the following code
74 | * will potentially write into unallocated memory */
75 | fprintf(
76 | stderr,
77 | "WARNING: Cairo stride shorter than JPEG width. Aborting JPEG read."
78 | );
79 | return NULL;
80 | }
81 |
82 | // Allocate storage for the final, decompressed image.
83 | img = calloc(cairo_stride, cinfo.output_height);
84 | if (img == NULL) {
85 | fprintf(stderr, "Could not allocate memory for JPEG decode\n");
86 |
87 | (void) jpeg_finish_decompress(&cinfo);
88 | jpeg_destroy_decompress(&cinfo);
89 | fclose(infile);
90 |
91 | return NULL;
92 | }
93 |
94 | while (cinfo.output_scanline < cinfo.output_height) {
95 | /* Normally, you would allocate a buffer using libJPEG's memory
96 | * management and write into it, but since we're reading one row at a
97 | * time, we just write it directly into the image memory space */
98 | unsigned char* pos = img + (cairo_stride * (cinfo.output_scanline));
99 | (void) jpeg_read_scanlines(&cinfo, &pos, 1);
100 | }
101 |
102 | (void) jpeg_finish_decompress(&cinfo);
103 |
104 | jpeg_destroy_decompress(&cinfo);
105 | fclose(infile);
106 |
107 | return img;
108 | }
109 |
--------------------------------------------------------------------------------
/jpg.h:
--------------------------------------------------------------------------------
1 | #ifndef _JPG_H
2 | #define _JPG_H
3 |
4 | #include
5 |
6 | #define _GNU_SOURCE 1
7 | typedef struct {
8 | uint height;
9 | uint width;
10 | uint stride; // The width of each row in memory, in bytes
11 | } JPEG_INFO;
12 |
13 | /*
14 | * Checks if the file is a JPEG by looking for a valid JPEG header.
15 | */
16 | bool file_is_jpg(FILE* image_file);
17 |
18 | /*
19 | * Reads a JPEG from a file into memory, in a format that Cairo can create a
20 | * surface from.
21 | */
22 | void* read_JPEG_file(char *filename, JPEG_INFO *jpg_info);
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/m4/ax_append_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
8 | #
9 | # DESCRIPTION
10 | #
11 | # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
12 | # added in between.
13 | #
14 | # If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
15 | # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
16 | # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
17 | # FLAG.
18 | #
19 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
20 | #
21 | # LICENSE
22 | #
23 | # Copyright (c) 2008 Guido U. Draheim
24 | # Copyright (c) 2011 Maarten Bosmans
25 | #
26 | # This program is free software: you can redistribute it and/or modify it
27 | # under the terms of the GNU General Public License as published by the
28 | # Free Software Foundation, either version 3 of the License, or (at your
29 | # option) any later version.
30 | #
31 | # This program is distributed in the hope that it will be useful, but
32 | # WITHOUT ANY WARRANTY; without even the implied warranty of
33 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
34 | # Public License for more details.
35 | #
36 | # You should have received a copy of the GNU General Public License along
37 | # with this program. If not, see .
38 | #
39 | # As a special exception, the respective Autoconf Macro's copyright owner
40 | # gives unlimited permission to copy, distribute and modify the configure
41 | # scripts that are the output of Autoconf when processing the Macro. You
42 | # need not follow the terms of the GNU General Public License when using
43 | # or distributing such scripts, even though portions of the text of the
44 | # Macro appear in them. The GNU General Public License (GPL) does govern
45 | # all other use of the material that constitutes the Autoconf Macro.
46 | #
47 | # This special exception to the GPL applies to versions of the Autoconf
48 | # Macro released by the Autoconf Archive. When you make and distribute a
49 | # modified version of the Autoconf Macro, you may extend this special
50 | # exception to the GPL to apply to your modified version as well.
51 |
52 | #serial 6
53 |
54 | AC_DEFUN([AX_APPEND_FLAG],
55 | [dnl
56 | AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
57 | AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
58 | AS_VAR_SET_IF(FLAGS,[
59 | AS_CASE([" AS_VAR_GET(FLAGS) "],
60 | [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
61 | [
62 | AS_VAR_APPEND(FLAGS,[" $1"])
63 | AC_RUN_LOG([: FLAGS="$FLAGS"])
64 | ])
65 | ],
66 | [
67 | AS_VAR_SET(FLAGS,[$1])
68 | AC_RUN_LOG([: FLAGS="$FLAGS"])
69 | ])
70 | AS_VAR_POPDEF([FLAGS])dnl
71 | ])dnl AX_APPEND_FLAG
72 |
--------------------------------------------------------------------------------
/m4/ax_cflags_warn_all.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
8 | # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
9 | # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
10 | #
11 | # DESCRIPTION
12 | #
13 | # Try to find a compiler option that enables most reasonable warnings.
14 | #
15 | # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
16 | # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
17 | #
18 | # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
19 | # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
20 | # Intel compilers. For a given compiler, the Fortran flags are much more
21 | # experimental than their C equivalents.
22 | #
23 | # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
24 | # - $2 add-value-if-not-found : nothing
25 | # - $3 action-if-found : add value to shellvariable
26 | # - $4 action-if-not-found : nothing
27 | #
28 | # NOTE: These macros depend on AX_APPEND_FLAG.
29 | #
30 | # LICENSE
31 | #
32 | # Copyright (c) 2008 Guido U. Draheim
33 | # Copyright (c) 2010 Rhys Ulerich
34 | #
35 | # This program is free software; you can redistribute it and/or modify it
36 | # under the terms of the GNU General Public License as published by the
37 | # Free Software Foundation; either version 3 of the License, or (at your
38 | # option) any later version.
39 | #
40 | # This program is distributed in the hope that it will be useful, but
41 | # WITHOUT ANY WARRANTY; without even the implied warranty of
42 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
43 | # Public License for more details.
44 | #
45 | # You should have received a copy of the GNU General Public License along
46 | # with this program. If not, see .
47 | #
48 | # As a special exception, the respective Autoconf Macro's copyright owner
49 | # gives unlimited permission to copy, distribute and modify the configure
50 | # scripts that are the output of Autoconf when processing the Macro. You
51 | # need not follow the terms of the GNU General Public License when using
52 | # or distributing such scripts, even though portions of the text of the
53 | # Macro appear in them. The GNU General Public License (GPL) does govern
54 | # all other use of the material that constitutes the Autoconf Macro.
55 | #
56 | # This special exception to the GPL applies to versions of the Autoconf
57 | # Macro released by the Autoconf Archive. When you make and distribute a
58 | # modified version of the Autoconf Macro, you may extend this special
59 | # exception to the GPL to apply to your modified version as well.
60 |
61 | #serial 15
62 |
63 | AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
64 | AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
65 | AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
66 | AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
67 | VAR,[VAR="no, unknown"
68 | ac_save_[]FLAGS="$[]FLAGS"
69 | for ac_arg dnl
70 | in "-warn all % -warn all" dnl Intel
71 | "-pedantic % -Wall" dnl GCC
72 | "-xstrconst % -v" dnl Solaris C
73 | "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
74 | "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
75 | "-ansi -ansiE % -fullwarn" dnl IRIX
76 | "+ESlit % +w1" dnl HP-UX C
77 | "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
78 | "-h conform % -h msglevel 2" dnl Cray C (Unicos)
79 | #
80 | do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
81 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
82 | [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
83 | done
84 | FLAGS="$ac_save_[]FLAGS"
85 | ])
86 | AS_VAR_POPDEF([FLAGS])dnl
87 | AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
88 | case ".$VAR" in
89 | .ok|.ok,*) m4_ifvaln($3,$3) ;;
90 | .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
91 | *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
92 | esac
93 | AS_VAR_POPDEF([VAR])dnl
94 | ])dnl AX_FLAGS_WARN_ALL
95 | dnl implementation tactics:
96 | dnl the for-argument contains a list of options. The first part of
97 | dnl these does only exist to detect the compiler - usually it is
98 | dnl a global option to enable -ansi or -extrawarnings. All other
99 | dnl compilers will fail about it. That was needed since a lot of
100 | dnl compilers will give false positives for some option-syntax
101 | dnl like -Woption or -Xoption as they think of it is a pass-through
102 | dnl to later compile stages or something. The "%" is used as a
103 | dnl delimiter. A non-option comment can be given after "%%" marks
104 | dnl which will be shown but not added to the respective C/CXXFLAGS.
105 |
106 | AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
107 | AC_LANG_PUSH([C])
108 | AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
109 | AC_LANG_POP([C])
110 | ])
111 |
112 | AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
113 | AC_LANG_PUSH([C++])
114 | AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
115 | AC_LANG_POP([C++])
116 | ])
117 |
118 | AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
119 | AC_LANG_PUSH([Fortran])
120 | AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
121 | AC_LANG_POP([Fortran])
122 | ])
123 |
--------------------------------------------------------------------------------
/m4/ax_check_bash_completion.m4:
--------------------------------------------------------------------------------
1 | # SYNOPSIS
2 | #
3 | # AX_CHECK_BASH_COMPLETION()
4 | #
5 | # DESCRIPTION
6 | #
7 | # Checks for the presence of an --with-bash-completion-dir option to set a
8 | # custom path to bash completions. If no specified, it will use the default
9 | # path as long as bash-completion is available.
10 | #
11 |
12 | #serial 1
13 |
14 | AC_DEFUN([AX_CHECK_BASH_COMPLETION], [
15 | AC_ARG_WITH([bash-completion-dir],
16 | AS_HELP_STRING([--with-bash-completion-dir[=PATH]],
17 | [Install the bash auto-completion script in this directory. @<:@default=yes@:>@]),
18 | [],
19 | [with_bash_completion_dir=yes])
20 |
21 | # Check bash-completion
22 | if test "x$with_bash_completion_dir" = "xyes"; then
23 | PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], [
24 | BASH_COMPLETION_DIR="$datadir/bash-completion/completions"
25 | ], [
26 | BASH_COMPLETION_DIR=""
27 | ])
28 | else
29 | BASH_COMPLETION_DIR="$with_bash_completion_dir"
30 | fi
31 | AC_SUBST([BASH_COMPLETION_DIR])
32 | AM_CONDITIONAL([ENABLE_BASH_COMPLETION], [test "x$with_bash_completion_dir" != "xno" && test "$BASH_COMPLETION_DIR" != ""])
33 | ])
34 |
35 |
--------------------------------------------------------------------------------
/m4/ax_check_compile_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check whether the given FLAG works with the current language's compiler
12 | # or gives an error. (Warnings, however, are ignored)
13 | #
14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
15 | # success/failure.
16 | #
17 | # If EXTRA-FLAGS is defined, it is added to the current language's default
18 | # flags (e.g. CFLAGS) when the check is done. The check is thus made with
19 | # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
20 | # force the compiler to issue an error when a bad flag is given.
21 | #
22 | # INPUT gives an alternative input source to AC_COMPILE_IFELSE.
23 | #
24 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
25 | # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
26 | #
27 | # LICENSE
28 | #
29 | # Copyright (c) 2008 Guido U. Draheim
30 | # Copyright (c) 2011 Maarten Bosmans
31 | #
32 | # This program is free software: you can redistribute it and/or modify it
33 | # under the terms of the GNU General Public License as published by the
34 | # Free Software Foundation, either version 3 of the License, or (at your
35 | # option) any later version.
36 | #
37 | # This program is distributed in the hope that it will be useful, but
38 | # WITHOUT ANY WARRANTY; without even the implied warranty of
39 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
40 | # Public License for more details.
41 | #
42 | # You should have received a copy of the GNU General Public License along
43 | # with this program. If not, see .
44 | #
45 | # As a special exception, the respective Autoconf Macro's copyright owner
46 | # gives unlimited permission to copy, distribute and modify the configure
47 | # scripts that are the output of Autoconf when processing the Macro. You
48 | # need not follow the terms of the GNU General Public License when using
49 | # or distributing such scripts, even though portions of the text of the
50 | # Macro appear in them. The GNU General Public License (GPL) does govern
51 | # all other use of the material that constitutes the Autoconf Macro.
52 | #
53 | # This special exception to the GPL applies to versions of the Autoconf
54 | # Macro released by the Autoconf Archive. When you make and distribute a
55 | # modified version of the Autoconf Macro, you may extend this special
56 | # exception to the GPL to apply to your modified version as well.
57 |
58 | #serial 4
59 |
60 | AC_DEFUN([AX_CHECK_COMPILE_FLAG],
61 | [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
62 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
63 | AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
64 | ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
65 | _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
66 | AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
67 | [AS_VAR_SET(CACHEVAR,[yes])],
68 | [AS_VAR_SET(CACHEVAR,[no])])
69 | _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
70 | AS_VAR_IF(CACHEVAR,yes,
71 | [m4_default([$2], :)],
72 | [m4_default([$3], :)])
73 | AS_VAR_POPDEF([CACHEVAR])dnl
74 | ])dnl AX_CHECK_COMPILE_FLAGS
75 |
--------------------------------------------------------------------------------
/m4/ax_check_enable_debug.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check for the presence of an --enable-debug option to configure, with
12 | # the specified default value used when the option is not present. Return
13 | # the value in the variable $ax_enable_debug.
14 | #
15 | # Specifying 'yes' adds '-g -O0' to the compilation flags for all
16 | # languages. Specifying 'info' adds '-g' to the compilation flags.
17 | # Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to
18 | # the linking flags. Otherwise, nothing is added.
19 | #
20 | # Define the variables listed in the second argument if debug is enabled,
21 | # defaulting to no variables. Defines the variables listed in the third
22 | # argument if debug is disabled, defaulting to NDEBUG. All lists of
23 | # variables should be space-separated.
24 | #
25 | # If debug is not enabled, ensure AC_PROG_* will not add debugging flags.
26 | # Should be invoked prior to any AC_PROG_* compiler checks.
27 | #
28 | # IS-RELEASE can be used to change the default to 'no' when making a
29 | # release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it
30 | # uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE
31 | # macro, there is no need to pass this parameter.
32 | #
33 | # AX_IS_RELEASE([git-directory])
34 | # AX_CHECK_ENABLE_DEBUG()
35 | #
36 | # LICENSE
37 | #
38 | # Copyright (c) 2011 Rhys Ulerich
39 | # Copyright (c) 2014, 2015 Philip Withnall
40 | #
41 | # Copying and distribution of this file, with or without modification, are
42 | # permitted in any medium without royalty provided the copyright notice
43 | # and this notice are preserved.
44 |
45 | #serial 5
46 |
47 | AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[
48 | AC_BEFORE([$0],[AC_PROG_CC])dnl
49 | AC_BEFORE([$0],[AC_PROG_CXX])dnl
50 | AC_BEFORE([$0],[AC_PROG_F77])dnl
51 | AC_BEFORE([$0],[AC_PROG_FC])dnl
52 |
53 | AC_MSG_CHECKING(whether to enable debugging)
54 |
55 | ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1])))
56 | ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],,
57 | [$ax_is_release],
58 | [$4])))
59 |
60 | # If this is a release, override the default.
61 | AS_IF([test "$ax_enable_debug_is_release" = "yes"],
62 | [ax_enable_debug_default="no"])
63 |
64 | m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))])
65 | m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))])
66 |
67 | AC_ARG_ENABLE(debug,
68 | [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])],
69 | [],enable_debug=$ax_enable_debug_default)
70 |
71 | # empty mean debug yes
72 | AS_IF([test "x$enable_debug" = "x"],
73 | [enable_debug="yes"])
74 |
75 | # case of debug
76 | AS_CASE([$enable_debug],
77 | [yes],[
78 | AC_MSG_RESULT(yes)
79 | CFLAGS="${CFLAGS} -g -O0"
80 | CXXFLAGS="${CXXFLAGS} -g -O0"
81 | FFLAGS="${FFLAGS} -g -O0"
82 | FCFLAGS="${FCFLAGS} -g -O0"
83 | OBJCFLAGS="${OBJCFLAGS} -g -O0"
84 | ],
85 | [info],[
86 | AC_MSG_RESULT(info)
87 | CFLAGS="${CFLAGS} -g"
88 | CXXFLAGS="${CXXFLAGS} -g"
89 | FFLAGS="${FFLAGS} -g"
90 | FCFLAGS="${FCFLAGS} -g"
91 | OBJCFLAGS="${OBJCFLAGS} -g"
92 | ],
93 | [profile],[
94 | AC_MSG_RESULT(profile)
95 | CFLAGS="${CFLAGS} -g -pg"
96 | CXXFLAGS="${CXXFLAGS} -g -pg"
97 | FFLAGS="${FFLAGS} -g -pg"
98 | FCFLAGS="${FCFLAGS} -g -pg"
99 | OBJCFLAGS="${OBJCFLAGS} -g -pg"
100 | LDFLAGS="${LDFLAGS} -pg"
101 | ],
102 | [
103 | AC_MSG_RESULT(no)
104 | dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags
105 | dnl by setting any unset environment flag variables
106 | AS_IF([test "x${CFLAGS+set}" != "xset"],
107 | [CFLAGS=""])
108 | AS_IF([test "x${CXXFLAGS+set}" != "xset"],
109 | [CXXFLAGS=""])
110 | AS_IF([test "x${FFLAGS+set}" != "xset"],
111 | [FFLAGS=""])
112 | AS_IF([test "x${FCFLAGS+set}" != "xset"],
113 | [FCFLAGS=""])
114 | AS_IF([test "x${OBJCFLAGS+set}" != "xset"],
115 | [OBJCFLAGS=""])
116 | ])
117 |
118 | dnl Define various variables if debugging is disabled.
119 | dnl assert.h is a NOP if NDEBUG is defined, so define it by default.
120 | AS_IF([test "x$enable_debug" = "xyes"],
121 | [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])],
122 | [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])])
123 | ax_enable_debug=$enable_debug
124 | ])
125 |
--------------------------------------------------------------------------------
/m4/ax_check_gnu_make.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_GNU_MAKE()
8 | #
9 | # DESCRIPTION
10 | #
11 | # This macro searches for a GNU version of make. If a match is found:
12 | #
13 | # * The makefile variable `ifGNUmake' is set to the empty string, otherwise
14 | # it is set to "#". This is useful for including a special features in a
15 | # Makefile, which cannot be handled by other versions of make.
16 | # * The variable `_cv_gnu_make_command` is set to the command to invoke
17 | # GNU make if it exists, the empty string otherwise.
18 | # * The variable `ax_cv_gnu_make_command` is set to the command to invoke
19 | # GNU make by copying `_cv_gnu_make_command`, otherwise it is unset.
20 | # * If GNU Make is found, its version is extracted from the output of
21 | # `make --version` as the last field of a record of space-separated
22 | # columns and saved into the variable `ax_check_gnu_make_version`.
23 | #
24 | # Here is an example of its use:
25 | #
26 | # Makefile.in might contain:
27 | #
28 | # # A failsafe way of putting a dependency rule into a makefile
29 | # $(DEPEND):
30 | # $(CC) -MM $(srcdir)/*.c > $(DEPEND)
31 | #
32 | # @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND)))
33 | # @ifGNUmake@ include $(DEPEND)
34 | # @ifGNUmake@ endif
35 | #
36 | # Then configure.in would normally contain:
37 | #
38 | # AX_CHECK_GNU_MAKE()
39 | # AC_OUTPUT(Makefile)
40 | #
41 | # Then perhaps to cause gnu make to override any other make, we could do
42 | # something like this (note that GNU make always looks for GNUmakefile
43 | # first):
44 | #
45 | # if ! test x$_cv_gnu_make_command = x ; then
46 | # mv Makefile GNUmakefile
47 | # echo .DEFAULT: > Makefile ;
48 | # echo \ $_cv_gnu_make_command \$@ >> Makefile;
49 | # fi
50 | #
51 | # Then, if any (well almost any) other make is called, and GNU make also
52 | # exists, then the other make wraps the GNU make.
53 | #
54 | # LICENSE
55 | #
56 | # Copyright (c) 2008 John Darrington
57 | # Copyright (c) 2015 Enrico M. Crisostomo
58 | #
59 | # Copying and distribution of this file, with or without modification, are
60 | # permitted in any medium without royalty provided the copyright notice
61 | # and this notice are preserved. This file is offered as-is, without any
62 | # warranty.
63 |
64 | #serial 8
65 |
66 | AC_DEFUN([AX_CHECK_GNU_MAKE],dnl
67 | [AC_PROG_AWK
68 | AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl
69 | _cv_gnu_make_command="" ;
70 | dnl Search all the common names for GNU make
71 | for a in "$MAKE" make gmake gnumake ; do
72 | if test -z "$a" ; then continue ; fi ;
73 | if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then
74 | _cv_gnu_make_command=$a ;
75 | AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make")
76 | ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }')
77 | break ;
78 | fi
79 | done ;])
80 | dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise
81 | AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])])
82 | AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])])
83 | AC_SUBST([ifGNUmake])
84 | ])
85 |
--------------------------------------------------------------------------------
/m4/ax_check_link_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check whether the given FLAG works with the linker or gives an error.
12 | # (Warnings, however, are ignored)
13 | #
14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
15 | # success/failure.
16 | #
17 | # If EXTRA-FLAGS is defined, it is added to the linker's default flags
18 | # when the check is done. The check is thus made with the flags: "LDFLAGS
19 | # EXTRA-FLAGS FLAG". This can for example be used to force the linker to
20 | # issue an error when a bad flag is given.
21 | #
22 | # INPUT gives an alternative input source to AC_LINK_IFELSE.
23 | #
24 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
25 | # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
26 | #
27 | # LICENSE
28 | #
29 | # Copyright (c) 2008 Guido U. Draheim
30 | # Copyright (c) 2011 Maarten Bosmans
31 | #
32 | # This program is free software: you can redistribute it and/or modify it
33 | # under the terms of the GNU General Public License as published by the
34 | # Free Software Foundation, either version 3 of the License, or (at your
35 | # option) any later version.
36 | #
37 | # This program is distributed in the hope that it will be useful, but
38 | # WITHOUT ANY WARRANTY; without even the implied warranty of
39 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
40 | # Public License for more details.
41 | #
42 | # You should have received a copy of the GNU General Public License along
43 | # with this program. If not, see .
44 | #
45 | # As a special exception, the respective Autoconf Macro's copyright owner
46 | # gives unlimited permission to copy, distribute and modify the configure
47 | # scripts that are the output of Autoconf when processing the Macro. You
48 | # need not follow the terms of the GNU General Public License when using
49 | # or distributing such scripts, even though portions of the text of the
50 | # Macro appear in them. The GNU General Public License (GPL) does govern
51 | # all other use of the material that constitutes the Autoconf Macro.
52 | #
53 | # This special exception to the GPL applies to versions of the Autoconf
54 | # Macro released by the Autoconf Archive. When you make and distribute a
55 | # modified version of the Autoconf Macro, you may extend this special
56 | # exception to the GPL to apply to your modified version as well.
57 |
58 | #serial 4
59 |
60 | AC_DEFUN([AX_CHECK_LINK_FLAG],
61 | [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
62 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
63 | AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
64 | ax_check_save_flags=$LDFLAGS
65 | LDFLAGS="$LDFLAGS $4 $1"
66 | AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
67 | [AS_VAR_SET(CACHEVAR,[yes])],
68 | [AS_VAR_SET(CACHEVAR,[no])])
69 | LDFLAGS=$ax_check_save_flags])
70 | AS_VAR_IF(CACHEVAR,yes,
71 | [m4_default([$2], :)],
72 | [m4_default([$3], :)])
73 | AS_VAR_POPDEF([CACHEVAR])dnl
74 | ])dnl AX_CHECK_LINK_FLAGS
75 |
--------------------------------------------------------------------------------
/m4/ax_check_zsh_completion.m4:
--------------------------------------------------------------------------------
1 | # SYNOPSIS
2 | #
3 | # AX_CHECK_ZSH_COMPLETION()
4 | #
5 | # DESCRIPTION
6 | #
7 | # Checks for the presence of an --with-zsh-completion-dir option to set a
8 | # custom path to zsh completions. If no specified, it will use the default
9 | # path as long as zsh is available.
10 | #
11 |
12 | #serial 1
13 |
14 | AC_DEFUN([AX_CHECK_ZSH_COMPLETION], [
15 | AC_ARG_WITH([zsh-completion-dir],
16 | AS_HELP_STRING([--with-zsh-completion-dir[=PATH]],
17 | [Install the zsh auto-completion script in this directory. @<:@default=yes@:>@]),
18 | [],
19 | [with_zsh_completion_dir=yes])
20 |
21 | # Check zsh-completion
22 | if test "x$with_zsh_completion_dir" = "xyes"; then
23 | AC_ARG_VAR([ZSH_AVAILABLE], [])
24 | AC_CHECK_PROG([ZSH_AVAILABLE], [zsh], [yes], [no])
25 |
26 | AS_IF([test "$ZSH_AVAILABLE" = "yes"], [
27 | ZSH_COMPLETION_DIR="$datadir/zsh/vendor-completions"
28 | ], [
29 | ZSH_COMPLETION_DIR=""
30 | ])
31 | else
32 | ZSH_COMPLETION_DIR="$with_zsh_completion_dir"
33 | fi
34 | AC_SUBST([ZSH_COMPLETION_DIR])
35 | AM_CONDITIONAL([ENABLE_ZSH_COMPLETION], [test "x$with_zsh_completion_dir" != "xno" && test "$ZSH_COMPLETION_DIR" != ""])
36 | ])
37 |
38 |
--------------------------------------------------------------------------------
/m4/ax_code_coverage.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CODE_COVERAGE()
8 | #
9 | # DESCRIPTION
10 | #
11 | # Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
12 | # CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
13 | # included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
14 | # every build target (program or library) which should be built with code
15 | # coverage support. Also defines CODE_COVERAGE_RULES which should be
16 | # substituted in your Makefile; and $enable_code_coverage which can be
17 | # used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
18 | # and substituted, and corresponds to the value of the
19 | # --enable-code-coverage option, which defaults to being disabled.
20 | #
21 | # Test also for gcov program and create GCOV variable that could be
22 | # substituted.
23 | #
24 | # Note that all optimisation flags in CFLAGS must be disabled when code
25 | # coverage is enabled.
26 | #
27 | # Usage example:
28 | #
29 | # configure.ac:
30 | #
31 | # AX_CODE_COVERAGE
32 | #
33 | # Makefile.am:
34 | #
35 | # @CODE_COVERAGE_RULES@
36 | # my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
37 | # my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
38 | # my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
39 | # my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
40 | #
41 | # This results in a "check-code-coverage" rule being added to any
42 | # Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
43 | # has been configured with --enable-code-coverage). Running `make
44 | # check-code-coverage` in that directory will run the module's test suite
45 | # (`make check`) and build a code coverage report detailing the code which
46 | # was touched, then print the URI for the report.
47 | #
48 | # This code was derived from Makefile.decl in GLib, originally licenced
49 | # under LGPLv2.1+.
50 | #
51 | # LICENSE
52 | #
53 | # Copyright (c) 2012, 2016 Philip Withnall
54 | # Copyright (c) 2012 Xan Lopez
55 | # Copyright (c) 2012 Christian Persch
56 | # Copyright (c) 2012 Paolo Borelli
57 | # Copyright (c) 2012 Dan Winship
58 | # Copyright (c) 2015 Bastien ROUCARIES
59 | #
60 | # This library is free software; you can redistribute it and/or modify it
61 | # under the terms of the GNU Lesser General Public License as published by
62 | # the Free Software Foundation; either version 2.1 of the License, or (at
63 | # your option) any later version.
64 | #
65 | # This library is distributed in the hope that it will be useful, but
66 | # WITHOUT ANY WARRANTY; without even the implied warranty of
67 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
68 | # General Public License for more details.
69 | #
70 | # You should have received a copy of the GNU Lesser General Public License
71 | # along with this program. If not, see .
72 |
73 | #serial 15
74 |
75 | AC_DEFUN([AX_CODE_COVERAGE],[
76 | dnl Check for --enable-code-coverage
77 | AC_REQUIRE([AC_PROG_SED])
78 |
79 | # allow to override gcov location
80 | AC_ARG_WITH([gcov],
81 | [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
82 | [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
83 | [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
84 |
85 | AC_MSG_CHECKING([whether to build with code coverage support])
86 | AC_ARG_ENABLE([code-coverage],
87 | AS_HELP_STRING([--enable-code-coverage],
88 | [Whether to enable code coverage support]),,
89 | enable_code_coverage=no)
90 |
91 | AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
92 | AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
93 | AC_MSG_RESULT($enable_code_coverage)
94 |
95 | AS_IF([ test "$enable_code_coverage" = "yes" ], [
96 | # check for gcov
97 | AC_CHECK_TOOL([GCOV],
98 | [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
99 | [:])
100 | AS_IF([test "X$GCOV" = "X:"],
101 | [AC_MSG_ERROR([gcov is needed to do coverage])])
102 | AC_SUBST([GCOV])
103 |
104 | dnl Check if gcc is being used
105 | AS_IF([ test "$GCC" = "no" ], [
106 | AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
107 | ])
108 |
109 | # List of supported lcov versions.
110 | lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12"
111 |
112 | AC_CHECK_PROG([LCOV], [lcov], [lcov])
113 | AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
114 |
115 | AS_IF([ test "$LCOV" ], [
116 | AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
117 | ax_cv_lcov_version=invalid
118 | lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
119 | for lcov_check_version in $lcov_version_list; do
120 | if test "$lcov_version" = "$lcov_check_version"; then
121 | ax_cv_lcov_version="$lcov_check_version (ok)"
122 | fi
123 | done
124 | ])
125 | ], [
126 | lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
127 | AC_MSG_ERROR([$lcov_msg])
128 | ])
129 |
130 | case $ax_cv_lcov_version in
131 | ""|invalid[)]
132 | lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
133 | AC_MSG_ERROR([$lcov_msg])
134 | LCOV="exit 0;"
135 | ;;
136 | esac
137 |
138 | AS_IF([ test -z "$GENHTML" ], [
139 | AC_MSG_ERROR([Could not find genhtml from the lcov package])
140 | ])
141 |
142 | dnl Build the code coverage flags
143 | CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
144 | CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
145 | CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
146 | CODE_COVERAGE_LDFLAGS="-lgcov"
147 |
148 | AC_SUBST([CODE_COVERAGE_CPPFLAGS])
149 | AC_SUBST([CODE_COVERAGE_CFLAGS])
150 | AC_SUBST([CODE_COVERAGE_CXXFLAGS])
151 | AC_SUBST([CODE_COVERAGE_LDFLAGS])
152 | ])
153 |
154 | [CODE_COVERAGE_RULES='
155 | # Code coverage
156 | #
157 | # Optional:
158 | # - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
159 | # Multiple directories may be specified, separated by whitespace.
160 | # (Default: $(top_builddir))
161 | # - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
162 | # by lcov for code coverage. (Default:
163 | # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
164 | # - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
165 | # reports to be created. (Default:
166 | # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
167 | # - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
168 | # set to 0 to disable it and leave empty to stay with the default.
169 | # (Default: empty)
170 | # - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
171 | # instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
172 | # - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
173 | # instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
174 | # - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
175 | # - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
176 | # collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
177 | # - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
178 | # instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
179 | # - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
180 | # lcov instance. (Default: empty)
181 | # - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
182 | # instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
183 | # - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
184 | # genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
185 | # - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
186 | # instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
187 | # - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
188 | #
189 | # The generated report will be titled using the $(PACKAGE_NAME) and
190 | # $(PACKAGE_VERSION). In order to add the current git hash to the title,
191 | # use the git-version-gen script, available online.
192 |
193 | # Optional variables
194 | CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
195 | CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
196 | CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
197 | CODE_COVERAGE_BRANCH_COVERAGE ?=
198 | CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
199 | --rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
200 | CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
201 | CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
202 | CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
203 | CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
204 | CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
205 | CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
206 | CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
207 | $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
208 | --rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
209 | CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
210 | CODE_COVERAGE_IGNORE_PATTERN ?=
211 |
212 | code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
213 | code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
214 | code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\
215 | $(CODE_COVERAGE_OUTPUT_FILE);
216 | code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
217 | code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
218 | code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\
219 | $(CODE_COVERAGE_IGNORE_PATTERN);
220 | code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
221 | code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
222 | code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
223 | code_coverage_quiet = $(code_coverage_quiet_$(V))
224 | code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
225 | code_coverage_quiet_0 = --quiet
226 |
227 | # sanitizes the test-name: replaces with underscores: dashes and dots
228 | code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
229 |
230 | # Use recursive makes in order to ignore errors during check
231 | check-code-coverage:
232 | ifeq ($(CODE_COVERAGE_ENABLED),yes)
233 | -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
234 | $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
235 | else
236 | @echo "Need to reconfigure with --enable-code-coverage"
237 | endif
238 |
239 | # Capture code coverage data
240 | code-coverage-capture: code-coverage-capture-hook
241 | ifeq ($(CODE_COVERAGE_ENABLED),yes)
242 | $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
243 | $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
244 | -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
245 | $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
246 | @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
247 | else
248 | @echo "Need to reconfigure with --enable-code-coverage"
249 | endif
250 |
251 | # Hook rule executed before code-coverage-capture, overridable by the user
252 | code-coverage-capture-hook:
253 |
254 | ifeq ($(CODE_COVERAGE_ENABLED),yes)
255 | clean: code-coverage-clean
256 | code-coverage-clean:
257 | -$(LCOV) --directory $(top_builddir) -z
258 | -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
259 | -find . -name "*.gcda" -o -name "*.gcov" -delete
260 | endif
261 |
262 | GITIGNOREFILES ?=
263 | GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
264 |
265 | A''M_DISTCHECK_CONFIGURE_FLAGS ?=
266 | A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
267 |
268 | .PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
269 | ']
270 |
271 | AC_SUBST([CODE_COVERAGE_RULES])
272 | m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
273 | ])
274 |
--------------------------------------------------------------------------------
/m4/ax_configure_args.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_configure_args.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CONFIGURE_ARGS
8 | #
9 | # DESCRIPTION
10 | #
11 | # Helper macro for AX_ENABLE_BUILDDIR.
12 | #
13 | # The traditional way of starting a subdir-configure is running the script
14 | # with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have
15 | # to rely on eval'ing $ac_configure_args however some old autoconf
16 | # versions do not provide that. To ensure maximum portability of autoconf
17 | # extension macros this helper can be AC_REQUIRE'd so that
18 | # $ac_configure_args will alsways be present.
19 | #
20 | # Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
21 | # spoiled now and must be replaced by "eval + exit $?".
22 | #
23 | # Example:
24 | #
25 | # AC_DEFUN([AX_ENABLE_SUBDIR],[dnl
26 | # AC_REQUIRE([AX_CONFIGURE_ARGS])dnl
27 | # eval $SHELL $ac_configure_args || exit $?
28 | # ...])
29 | #
30 | # LICENSE
31 | #
32 | # Copyright (c) 2008 Guido U. Draheim
33 | #
34 | # This program is free software; you can redistribute it and/or modify it
35 | # under the terms of the GNU General Public License as published by the
36 | # Free Software Foundation; either version 3 of the License, or (at your
37 | # option) any later version.
38 | #
39 | # This program is distributed in the hope that it will be useful, but
40 | # WITHOUT ANY WARRANTY; without even the implied warranty of
41 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
42 | # Public License for more details.
43 | #
44 | # You should have received a copy of the GNU General Public License along
45 | # with this program. If not, see .
46 | #
47 | # As a special exception, the respective Autoconf Macro's copyright owner
48 | # gives unlimited permission to copy, distribute and modify the configure
49 | # scripts that are the output of Autoconf when processing the Macro. You
50 | # need not follow the terms of the GNU General Public License when using
51 | # or distributing such scripts, even though portions of the text of the
52 | # Macro appear in them. The GNU General Public License (GPL) does govern
53 | # all other use of the material that constitutes the Autoconf Macro.
54 | #
55 | # This special exception to the GPL applies to versions of the Autoconf
56 | # Macro released by the Autoconf Archive. When you make and distribute a
57 | # modified version of the Autoconf Macro, you may extend this special
58 | # exception to the GPL to apply to your modified version as well.
59 |
60 | #serial 9
61 |
62 | AC_DEFUN([AX_CONFIGURE_ARGS],[
63 | # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args
64 | if test "${ac_configure_args+set}" != "set" ; then
65 | ac_configure_args=
66 | for ac_arg in ${1+"[$]@"}; do
67 | ac_configure_args="$ac_configure_args '$ac_arg'"
68 | done
69 | fi
70 | ])
71 |
--------------------------------------------------------------------------------
/m4/ax_enable_builddir.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])]
8 | #
9 | # DESCRIPTION
10 | #
11 | # If the current configure was run within the srcdir then we move all
12 | # configure-files into a subdir and let the configure steps continue
13 | # there. We provide an option --disable-builddir to suppress the move into
14 | # a separate builddir.
15 | #
16 | # Defaults:
17 | #
18 | # $1 = $host (overridden with $HOST)
19 | # $2 = Makefile.mk
20 | # $3 = -all
21 | #
22 | # This macro must be called before AM_INIT_AUTOMAKE. It creates a default
23 | # toplevel srcdir Makefile from the information found in the created
24 | # toplevel builddir Makefile. It just copies the variables and
25 | # rule-targets, each extended with a default rule-execution that recurses
26 | # into the build directory of the current "HOST". You can override the
27 | # auto-dection through `config.guess` and build-time of course, as in
28 | #
29 | # make HOST=i386-mingw-cross
30 | #
31 | # which can of course set at configure time as well using
32 | #
33 | # configure --host=i386-mingw-cross
34 | #
35 | # After the default has been created, additional rules can be appended
36 | # that will not just recurse into the subdirectories and only ever exist
37 | # in the srcdir toplevel makefile - these parts are read from the $2 =
38 | # Makefile.mk file
39 | #
40 | # The automatic rules are usually scanning the toplevel Makefile for lines
41 | # like '#### $host |$builddir' to recognize the place where to recurse
42 | # into. Usually, the last one is the only one used. However, almost all
43 | # targets have an additional "*-all" rule which makes the script to
44 | # recurse into _all_ variants of the current HOST (!!) setting. The "-all"
45 | # suffix can be overriden for the macro as well.
46 | #
47 | # a special rule is only given for things like "dist" that will copy the
48 | # tarball from the builddir to the sourcedir (or $(PUB)) for reason of
49 | # convenience.
50 | #
51 | # LICENSE
52 | #
53 | # Copyright (c) 2009 Guido U. Draheim
54 | # Copyright (c) 2009 Alan Jenkins
55 | #
56 | # This program is free software; you can redistribute it and/or modify it
57 | # under the terms of the GNU General Public License as published by the
58 | # Free Software Foundation; either version 3 of the License, or (at your
59 | # option) any later version.
60 | #
61 | # This program is distributed in the hope that it will be useful, but
62 | # WITHOUT ANY WARRANTY; without even the implied warranty of
63 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
64 | # Public License for more details.
65 | #
66 | # You should have received a copy of the GNU General Public License along
67 | # with this program. If not, see .
68 | #
69 | # As a special exception, the respective Autoconf Macro's copyright owner
70 | # gives unlimited permission to copy, distribute and modify the configure
71 | # scripts that are the output of Autoconf when processing the Macro. You
72 | # need not follow the terms of the GNU General Public License when using
73 | # or distributing such scripts, even though portions of the text of the
74 | # Macro appear in them. The GNU General Public License (GPL) does govern
75 | # all other use of the material that constitutes the Autoconf Macro.
76 | #
77 | # This special exception to the GPL applies to versions of the Autoconf
78 | # Macro released by the Autoconf Archive. When you make and distribute a
79 | # modified version of the Autoconf Macro, you may extend this special
80 | # exception to the GPL to apply to your modified version as well.
81 |
82 | #serial 25
83 |
84 | AC_DEFUN([AX_ENABLE_BUILDDIR],[
85 | AC_REQUIRE([AC_CANONICAL_HOST])[]dnl
86 | AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl
87 | AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl
88 | AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl
89 | AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
90 | AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
91 | AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
92 | AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
93 | SUB="."
94 | AC_ARG_ENABLE([builddir], AS_HELP_STRING(
95 | [--disable-builddir],[disable automatic build in subdir of sources])
96 | ,[SUB="$enableval"], [SUB="auto"])
97 | if test ".$ac_srcdir_defaulted" != ".no" ; then
98 | if test ".$srcdir" = ".." ; then
99 | if test -f config.status ; then
100 | AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build)
101 | else
102 | test ".$SUB" = "." && SUB="."
103 | test ".$SUB" = ".no" && SUB="."
104 | test ".$TARGET" = "." && TARGET="$target"
105 | test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])"
106 | if test ".$SUB" != ".." ; then # we know where to go and
107 | AS_MKDIR_P([$SUB])
108 | echo __.$SUB.__ > $SUB/conftest.tmp
109 | cd $SUB
110 | if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then
111 | rm conftest.tmp
112 | AC_MSG_RESULT([continue configure in default builddir "./$SUB"])
113 | else
114 | AC_MSG_ERROR([could not change to default builddir "./$SUB"])
115 | fi
116 | srcdir=`echo "$SUB" |
117 | sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'`
118 | # going to restart from subdirectory location
119 | test -f $srcdir/config.log && mv $srcdir/config.log .
120 | test -f $srcdir/confdefs.h && mv $srcdir/confdefs.h .
121 | test -f $srcdir/conftest.log && mv $srcdir/conftest.log .
122 | test -f $srcdir/$cache_file && mv $srcdir/$cache_file .
123 | AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})
124 | case "[$]0" in # restart
125 | [[\\/]]* | ?:[[\\/]]*) # Asbolute name
126 | eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
127 | *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
128 | esac ; exit $?
129 | fi
130 | fi
131 | fi fi
132 | test ".$SUB" = ".auto" && SUB="."
133 | dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"
134 | AC_PATH_PROG(SED,gsed sed, sed)
135 | AUX="$am_aux_dir"
136 | AS_VAR_POPDEF([SED])dnl
137 | AS_VAR_POPDEF([AUX])dnl
138 | AS_VAR_POPDEF([SUB])dnl
139 | AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status ..............
140 | AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
141 | AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl
142 | AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl
143 | AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
144 | AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
145 | pushdef([END],[Makefile.mk])dnl
146 | pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl
147 | SRC="$ax_enable_builddir_srcdir"
148 | if test ".$SUB" = ".." ; then
149 | if test -f "$TOP/Makefile" ; then
150 | AC_MSG_NOTICE([skipping TOP/Makefile - left untouched])
151 | else
152 | AC_MSG_NOTICE([skipping TOP/Makefile - not created])
153 | fi
154 | else
155 | if test -f "$SRC/Makefile" ; then
156 | a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile`
157 | test "$a" != "$b" && rm "$SRC/Makefile"
158 | fi
159 | if test -f "$SRC/Makefile" ; then
160 | echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk
161 | echo " []@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk
162 | eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"
163 | if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null
164 | then rm $SRC/Makefile ; fi
165 | cp $tmp/conftemp.mk $SRC/makefiles.mk~ ## DEBUGGING
166 | fi
167 | if test ! -f "$SRC/Makefile" ; then
168 | AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile])
169 | x='`' ; cat >$tmp/conftemp.sed <<_EOF
170 | /^\$/n
171 | x
172 | /^\$/bS
173 | x
174 | /\\\\\$/{H;d;}
175 | {H;s/.*//;x;}
176 | bM
177 | :S
178 | x
179 | /\\\\\$/{h;d;}
180 | {h;s/.*//;x;}
181 | :M
182 | s/\\(\\n\\) /\\1 /g
183 | /^ /d
184 | /^[[ ]]*[[\\#]]/d
185 | /^VPATH *=/d
186 | s/^srcdir *=.*/srcdir = ./
187 | s/^top_srcdir *=.*/top_srcdir = ./
188 | /[[:=]]/!d
189 | /^\\./d
190 | dnl Now handle rules (i.e. lines containing ":" but not " = ").
191 | / = /b
192 | / .= /b
193 | /:/!b
194 | s/:.*/:/
195 | s/ / /g
196 | s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g
197 | s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/
198 | s/ / /g
199 | /^all all[]_ALL[[ :]]/i\\
200 | all-configured : all[]_ALL
201 | dnl dist-all exists... and would make for dist-all-all
202 | s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g
203 | /[]_ALL[]_ALL/d
204 | a\\
205 | @ HOST="\$(HOST)\" \\\\\\
206 | ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
207 | ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
208 | ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
209 | ; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\
210 | ; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\
211 | ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
212 | ; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\
213 | ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
214 | ; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done
215 | dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree)
216 | /dist[]_ALL *:/a\\
217 | @ HOST="\$(HOST)\" \\\\\\
218 | ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
219 | ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
220 | ; found=$x echo \$\$BUILD | wc -w $x \\\\\\
221 | ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\
222 | ; if test "\$\$found" -eq "0" ; then : \\\\\\
223 | ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
224 | ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
225 | ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\
226 | ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
227 | dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree)
228 | /dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\
229 | @ HOST="\$(HOST)\" \\\\\\
230 | ; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\
231 | ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
232 | ; found=$x echo \$\$BUILD | wc -w $x \\\\\\
233 | ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\
234 | ; if test "\$\$found" -eq "0" ; then : \\\\\\
235 | ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
236 | ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
237 | ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\
238 | ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
239 | dnl special rule add-on: "distclean" removes all local builddirs completely
240 | /distclean[]_ALL *:/a\\
241 | @ HOST="\$(HOST)\" \\\\\\
242 | ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
243 | ; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\
244 | ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
245 | ; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\
246 | ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
247 | ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
248 | ; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\
249 | ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
250 | ; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\
251 | ; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\
252 | ; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile
253 | _EOF
254 | cp "$tmp/conftemp.sed" "$SRC/makefile.sed~" ## DEBUGGING
255 | $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile
256 | if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then
257 | AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])])
258 | cat $SRC/END >>$SRC/Makefile
259 | fi ; xxxx="####"
260 | echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile
261 | # sanity check
262 | if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then
263 | AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts])
264 | $SED -e '/^@ HOST=/s/^/ /' -e '/^; /s/^/ /' $SRC/Makefile \
265 | >$SRC/Makefile~
266 | (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null
267 | fi
268 | else
269 | xxxx="\\#\\#\\#\\#"
270 | # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed
271 | echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed
272 | $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp
273 | cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~" ## DEBUGGING
274 | cp "$tmp/mkfile.tmp" "$SRC/makefiles.out~" ## DEBUGGING
275 | if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then
276 | AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure])
277 | rm "$tmp/mkfile.tmp"
278 | else
279 | AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure])
280 | mv "$tmp/mkfile.tmp" "$SRC/Makefile"
281 | fi
282 | fi
283 | AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)])
284 | xxxx="####"
285 | echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile
286 | fi
287 | popdef([END])dnl
288 | AS_VAR_POPDEF([SED])dnl
289 | AS_VAR_POPDEF([AUX])dnl
290 | AS_VAR_POPDEF([SRC])dnl
291 | AS_VAR_POPDEF([TOP])dnl
292 | AS_VAR_POPDEF([SUB])dnl
293 | ],[dnl
294 | ax_enable_builddir_srcdir="$srcdir" # $srcdir
295 | ax_enable_builddir_host="$HOST" # $HOST / $host
296 | ax_enable_builddir_version="$VERSION" # $VERSION
297 | ax_enable_builddir_package="$PACKAGE" # $PACKAGE
298 | ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX
299 | ax_enable_builddir_sed="$ax_enable_builddir_sed" # $SED
300 | ax_enable_builddir="$ax_enable_builddir" # $SUB
301 | ])dnl
302 | ])
303 |
--------------------------------------------------------------------------------
/m4/ax_extend_srcdir.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_extend_srcdir.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_EXTEND_SRCDIR
8 | #
9 | # DESCRIPTION
10 | #
11 | # The AX_EXTEND_SRCDIR macro extends $srcdir by one path component.
12 | #
13 | # As an example, when working in /home/michael/i3-4.12/build and calling
14 | # ../configure, your $srcdir is "..". After calling AX_EXTEND_SRCDIR,
15 | # $srcdir will be set to "../../i3-4.12".
16 | #
17 | # The result of extending $srcdir is that filenames (e.g. in the output of
18 | # the "backtrace" gdb command) will include one more path component of the
19 | # absolute source path. The additional path component makes it easy for
20 | # users to recognize which files belong to the PACKAGE, and -- provided a
21 | # dist tarball was unpacked -- which version of PACKAGE was used.
22 | #
23 | # As an example, in "backtrace", you will see:
24 | #
25 | # #0 main (argc=1, argv=0x7fffffff1fc8) at ../../i3-4.12/src/main.c:187
26 | #
27 | # instead of:
28 | #
29 | # #0 main (argc=1, argv=0x7fffffff1fc8) at ../src/main.c:187
30 | #
31 | # In case your code uses the __FILE__ preprocessor directive to refer to
32 | # the filename of the current source file (e.g. in debug messages), using
33 | # the extended path might be undesirable. For this purpose,
34 | # AX_EXTEND_SRCDIR defines the output variable AX_EXTEND_SRCDIR_CPPFLAGS,
35 | # which can be added to AM_CPPFLAGS in Makefile.am in order to define the
36 | # preprocessor directive STRIPPED__FILE__. As an example, when compiling
37 | # the file "../../i3-4.12/src/main.c", STRIPPED__FILE__ evaluates to
38 | # "main.c".
39 | #
40 | # There are some caveats: When $srcdir is "." (i.e. when ./configure was
41 | # called instead of ../configure in a separate build directory),
42 | # AX_EXTEND_SRCDIR will still extend $srcdir, but the intended effect will
43 | # not be achieved because of the way automake specifies file paths:
44 | # automake defines COMPILE to use "`test -f '$source' || echo
45 | # '\$(srcdir)/'`$source" in order to prefer files in the current directory
46 | # over specifying $srcdir explicitly.
47 | #
48 | # The AX_EXTEND_SRCDIR author is not aware of any way to influence this
49 | # automake behavior. Patches very welcome.
50 | #
51 | # To work around this issue, you can use AX_ENABLE_BUILDDIR i.e. by adding
52 | # the following code to configure.ac:
53 | #
54 | # AX_ENABLE_BUILDDIR
55 | # dnl ...
56 | # AX_EXTEND_SRCDIR
57 | #
58 | # Then also add this bit to Makefile.am (if you wish to use
59 | # STRIPPED__FILE__ in your code):
60 | #
61 | # AM_CPPFLAGS = @AX_EXTEND_SRCDIR_CPPFLAGS@
62 | #
63 | # LICENSE
64 | #
65 | # Copyright (c) 2016 Michael Stapelberg
66 | # Copyright (c) 2021 Raymond Li
67 | #
68 | # Copying and distribution of this file, with or without modification, are
69 | # permitted in any medium without royalty provided the copyright notice
70 | # and this notice are preserved. This file is offered as-is, without any
71 | # warranty.
72 |
73 | #serial 3
74 |
75 | AC_DEFUN([AX_EXTEND_SRCDIR],
76 | [dnl
77 | AS_CASE([$srcdir],
78 | [.|.*|/*],
79 | [
80 | # pwd -P is specified in IEEE 1003.1 from 2004
81 | as_dir=`cd "$srcdir" && pwd -P`
82 | as_base=`AS_BASENAME([$as_dir])`
83 | srcdir=${srcdir}/../${as_base}
84 |
85 | AC_SUBST([AX_EXTEND_SRCDIR_CPPFLAGS], ["-DSTRIPPED__FILE__=AS_ESCAPE([\"$$(basename $<)\"])"])
86 | ])
87 | ])dnl AX_EXTEND_SRCDIR
88 |
--------------------------------------------------------------------------------
/m4/ax_require_defined.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_REQUIRE_DEFINED(MACRO)
8 | #
9 | # DESCRIPTION
10 | #
11 | # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
12 | # been defined and thus are available for use. This avoids random issues
13 | # where a macro isn't expanded. Instead the configure script emits a
14 | # non-fatal:
15 | #
16 | # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
17 | #
18 | # It's like AC_REQUIRE except it doesn't expand the required macro.
19 | #
20 | # Here's an example:
21 | #
22 | # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
23 | #
24 | # LICENSE
25 | #
26 | # Copyright (c) 2014 Mike Frysinger
27 | #
28 | # Copying and distribution of this file, with or without modification, are
29 | # permitted in any medium without royalty provided the copyright notice
30 | # and this notice are preserved. This file is offered as-is, without any
31 | # warranty.
32 |
33 | #serial 1
34 |
35 | AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
36 | m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
37 | ])dnl AX_REQUIRE_DEFINED
38 |
--------------------------------------------------------------------------------
/m4/ax_sanitizers.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_sanitizers.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_SANITIZERS([SANITIZERS], [ENABLED-BY-DEFAULT], [ACTION-SUCCESS])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Offers users to enable one or more sanitizers (see
12 | # https://github.com/google/sanitizers) with the corresponding
13 | # --enable--sanitizer option.
14 | #
15 | # SANITIZERS is a whitespace-separated list of sanitizers to offer via
16 | # --enable--sanitizer options, e.g. "address memory" for the
17 | # address sanitizer and the memory sanitizer. If SANITIZERS is not specified,
18 | # all known sanitizers to AX_SANITIZERS will be offered, which at the time of
19 | # writing are "address memory undefined".
20 | # NOTE that SANITIZERS is expanded at autoconf time, not at configure time,
21 | # i.e. you cannot use shell variables in SANITIZERS.
22 | #
23 | # ENABLED-BY-DEFAULT is a whitespace-separated list of sanitizers which
24 | # should be enabled by default, e.g. "memory undefined". Note that not all
25 | # sanitizers can be combined, e.g. memory sanitizer cannot be enabled when
26 | # address sanitizer is already enabled.
27 | # Set ENABLED-BY-DEFAULT to a single whitespace in order to disable all
28 | # sanitizers by default.
29 | # ENABLED-BY-DEFAULT is expanded at configure time, so you can use shell
30 | # variables.
31 | #
32 | # ACTION-SUCCESS allows to specify shell commands to execute on success, i.e.
33 | # when one of the sanitizers was successfully enabled. This is a good place
34 | # to call AC_DEFINE for any precompiler constants you might need to make your
35 | # code play nice with sanitizers.
36 | #
37 | # The variable ax_enabled_sanitizers contains a whitespace-separated list of
38 | # all enabled sanitizers, so that you can print them at the end of configure,
39 | # if you wish.
40 | #
41 | # The additional --enable-sanitizers option allows users to enable/disable
42 | # all sanitizers, effectively overriding ENABLED-BY-DEFAULT.
43 | #
44 | # EXAMPLES
45 | #
46 | # AX_SANITIZERS([address])
47 | # dnl offer users to enable address sanitizer via --enable-address-sanitizer
48 | #
49 | # is_debug_build=…
50 | # if test "x$is_debug_build" = "xyes"; then
51 | # default_sanitizers="address memory"
52 | # else
53 | # default_sanitizers=
54 | # fi
55 | # AX_SANITIZERS([address memory], [$default_sanitizers])
56 | # dnl enable address sanitizer and memory sanitizer by default for debug
57 | # dnl builds, e.g. when building from git instead of a dist tarball.
58 | #
59 | # AX_SANITIZERS(, , [
60 | # AC_DEFINE([SANITIZERS_ENABLED],
61 | # [],
62 | # [At least one sanitizer was enabled])])
63 | # dnl enable all sanitizers known to AX_SANITIZERS by default and set the
64 | # dnl SANITIZERS_ENABLED precompiler constant.
65 | #
66 | # AX_SANITIZERS(, [ ])
67 | # dnl provide all sanitizers, but enable none by default.
68 | #
69 | # LICENSE
70 | #
71 | # Copyright (c) 2016 Michael Stapelberg
72 | # Copyright (c) 2021 Raymond Li
73 | #
74 | # Copying and distribution of this file, with or without modification,
75 | # are permitted in any medium without royalty provided the copyright
76 | # notice and this notice are preserved. This file is offered as-is,
77 | # without any warranty.
78 |
79 | AC_DEFUN([AX_SANITIZERS],
80 | [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
81 | AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
82 | AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
83 | AC_ARG_ENABLE(sanitizers,
84 | AS_HELP_STRING(
85 | [--enable-sanitizers],
86 | [enable all known sanitizers]),
87 | [ax_sanitizers_default=$enableval],
88 | [ax_sanitizers_default=])
89 | ax_enabled_sanitizers=
90 | m4_foreach_w([mysan], m4_default($1, [address memory undefined]), [
91 | dnl If ax_sanitizers_default is unset, i.e. the user neither explicitly
92 | dnl enabled nor explicitly disabled all sanitizers, we get the default value
93 | dnl for this sanitizer based on whether it is listed in ENABLED-BY-DEFAULT.
94 | AS_IF([test "x$ax_sanitizers_default" = "x"], [dnl
95 | ax_sanitizer_default=
96 | for mycheck in m4_default([$2], [address memory undefined]); do
97 | AS_IF([test "x$mycheck" = "x[]mysan"], [ax_sanitizer_default=yes])
98 | done
99 | AS_IF([test "x$ax_sanitizer_default" = "x"], [ax_sanitizer_default=no])
100 | ],
101 | [ax_sanitizer_default=$ax_sanitizers_default])
102 | AC_ARG_ENABLE(mysan[]-sanitizer,
103 | AS_HELP_STRING(
104 | [--enable-[]mysan[]-sanitizer],
105 | [enable -fsanitize=mysan]),
106 | [ax_sanitizer_enabled=$enableval],
107 | [ax_sanitizer_enabled=$ax_sanitizer_default])
108 |
109 | AS_IF([test "x$ax_sanitizer_enabled" = "xyes"], [
110 | dnl Not using AX_APPEND_COMPILE_FLAGS and AX_APPEND_LINK_FLAGS because they
111 | dnl lack the ability to specify ACTION-SUCCESS.
112 | AX_CHECK_COMPILE_FLAG([-fsanitize=[]mysan], [
113 | AX_CHECK_LINK_FLAG([-fsanitize=[]mysan], [
114 | AX_APPEND_FLAG([-fsanitize=[]mysan], [])
115 | dnl If and only if libtool is being used, LDFLAGS needs to contain -Wc,-fsanitize=….
116 | dnl See e.g. https://sources.debian.net/src/systemd/231-7/configure.ac/?hl=128#L135
117 | dnl TODO: how can recognize that situation and add -Wc,?
118 | AX_APPEND_FLAG([-fsanitize=[]mysan], [LDFLAGS])
119 | dnl TODO: add -fPIE -pie for memory
120 | # -fno-omit-frame-pointer results in nicer stack traces in error
121 | # messages, see http://clang.llvm.org/docs/AddressSanitizer.html#usage
122 | AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [
123 | AX_APPEND_FLAG([-fno-omit-frame-pointer], [])])
124 | dnl TODO: at least for clang, we should specify exactly -O1, not -O2 or -O0, so that performance is reasonable but stacktraces are not tampered with (due to inlining), see http://clang.llvm.org/docs/AddressSanitizer.html#usage
125 | m4_default([$3], :)
126 | ax_enabled_sanitizers="[]mysan $ax_enabled_sanitizers"
127 | ])
128 | ])
129 | ])
130 | ])dnl
131 | ])dnl AX_SANITIZERS
132 |
--------------------------------------------------------------------------------
/pam/i3lock:
--------------------------------------------------------------------------------
1 | #
2 | # PAM configuration file for the i3lock-color screen locker. By default, it includes
3 | # the 'system-local-login' configuration file (see /etc/pam.d/system-local-login)
4 | # for Arch and Gentoo and 'login' for Debian. Note that upstream uses only 'login',
5 | # which doesn't work on Arch and Gentoo.
6 | #
7 |
8 | #auth include system-local-login # For Arch/Gentoo
9 | auth include login # For Debian
10 |
--------------------------------------------------------------------------------
/randr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * vim:ts=4:sw=4:expandtab
3 | *
4 | * © 2010 Michael Stapelberg
5 | * © 2021 Raymond Li
6 | *
7 | * See LICENSE for licensing information
8 | *
9 | */
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "i3lock.h"
19 | #include "xcb.h"
20 | #include "randr.h"
21 |
22 | /* Number of Xinerama screens which are currently present. */
23 | int xr_screens = 0;
24 |
25 | /* The resolutions of the currently present Xinerama screens. */
26 | Rect *xr_resolutions = NULL;
27 |
28 | static bool xinerama_active;
29 | static bool has_randr = false;
30 | static bool has_randr_1_5 = false;
31 | extern bool debug_mode;
32 |
33 | void _xinerama_init(void);
34 |
35 | void randr_init(int *event_base, xcb_window_t root) {
36 | const xcb_query_extension_reply_t *extreply;
37 |
38 | extreply = xcb_get_extension_data(conn, &xcb_randr_id);
39 | if (!extreply->present) {
40 | DEBUG("RandR is not present, falling back to Xinerama.\n");
41 | _xinerama_init();
42 | return;
43 | }
44 |
45 | xcb_generic_error_t *err;
46 | xcb_randr_query_version_reply_t *randr_version =
47 | xcb_randr_query_version_reply(
48 | conn, xcb_randr_query_version(conn, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &err);
49 | if (err != NULL) {
50 | DEBUG("Could not query RandR version: X11 error code %d\n", err->error_code);
51 | _xinerama_init();
52 | return;
53 | }
54 |
55 | has_randr = true;
56 |
57 | has_randr_1_5 = (randr_version->major_version >= 1) &&
58 | (randr_version->minor_version >= 5);
59 |
60 | free(randr_version);
61 |
62 | if (event_base != NULL)
63 | *event_base = extreply->first_event;
64 |
65 | xcb_randr_select_input(conn, root,
66 | XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
67 | XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
68 | XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
69 | XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
70 |
71 | xcb_flush(conn);
72 | }
73 |
74 | void _xinerama_init(void) {
75 | if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) {
76 | DEBUG("Xinerama extension not found, disabling.\n");
77 | return;
78 | }
79 |
80 | xcb_xinerama_is_active_cookie_t cookie;
81 | xcb_xinerama_is_active_reply_t *reply;
82 |
83 | cookie = xcb_xinerama_is_active(conn);
84 | reply = xcb_xinerama_is_active_reply(conn, cookie, NULL);
85 | if (!reply)
86 | return;
87 |
88 | if (!reply->state) {
89 | free(reply);
90 | return;
91 | }
92 |
93 | xinerama_active = true;
94 | free(reply);
95 | }
96 |
97 | /*
98 | * randr_query_outputs_15 uses RandR ≥ 1.5 to update outputs.
99 | *
100 | */
101 | static bool _randr_query_monitors_15(xcb_window_t root) {
102 | #if XCB_RANDR_MINOR_VERSION < 5
103 | return false;
104 | #else
105 | /* RandR 1.5 available at compile-time, i.e. libxcb is new enough */
106 | if (!has_randr_1_5) {
107 | return false;
108 | }
109 | /* RandR 1.5 available at run-time (supported by the server) */
110 | DEBUG("Querying monitors using RandR 1.5\n");
111 | xcb_generic_error_t *err;
112 | xcb_randr_get_monitors_reply_t *monitors =
113 | xcb_randr_get_monitors_reply(
114 | conn, xcb_randr_get_monitors(conn, root, true), &err);
115 | if (err != NULL) {
116 | DEBUG("Could not get RandR monitors: X11 error code %d\n", err->error_code);
117 | free(err);
118 | /* Fall back to RandR ≤ 1.4 */
119 | return false;
120 | }
121 |
122 | int screens = xcb_randr_get_monitors_monitors_length(monitors);
123 | DEBUG("%d RandR monitors found (timestamp %d)\n",
124 | screens, monitors->timestamp);
125 |
126 | Rect *resolutions = malloc(screens * sizeof(Rect));
127 | /* No memory? Just keep on using the old information. */
128 | if (!resolutions) {
129 | free(monitors);
130 | return true;
131 | }
132 |
133 | xcb_randr_monitor_info_iterator_t iter;
134 | int screen;
135 | for (iter = xcb_randr_get_monitors_monitors_iterator(monitors), screen = 0;
136 | iter.rem;
137 | xcb_randr_monitor_info_next(&iter), screen++) {
138 | const xcb_randr_monitor_info_t *monitor_info = iter.data;
139 |
140 | resolutions[screen].x = monitor_info->x;
141 | resolutions[screen].y = monitor_info->y;
142 | resolutions[screen].width = monitor_info->width;
143 | resolutions[screen].height = monitor_info->height;
144 | DEBUG("found RandR monitor: %d x %d at %d x %d\n",
145 | monitor_info->width, monitor_info->height,
146 | monitor_info->x, monitor_info->y);
147 | }
148 | free(xr_resolutions);
149 | xr_resolutions = resolutions;
150 | xr_screens = screens;
151 |
152 | free(monitors);
153 | return true;
154 | #endif
155 | }
156 |
157 | /*
158 | * randr_query_outputs_14 uses RandR ≤ 1.4 to update outputs.
159 | *
160 | */
161 | static bool _randr_query_outputs_14(xcb_window_t root) {
162 | if (!has_randr) {
163 | return false;
164 | }
165 | DEBUG("Querying outputs using RandR ≤ 1.4\n");
166 |
167 | /* Get screen resources (primary output, crtcs, outputs, modes) */
168 | xcb_randr_get_screen_resources_current_cookie_t rcookie;
169 | rcookie = xcb_randr_get_screen_resources_current(conn, root);
170 |
171 | xcb_randr_get_screen_resources_current_reply_t *res =
172 | xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL);
173 | if (res == NULL) {
174 | DEBUG("Could not query screen resources.\n");
175 | return false;
176 | }
177 |
178 | /* timestamp of the configuration so that we get consistent replies to all
179 | * requests (if the configuration changes between our different calls) */
180 | const xcb_timestamp_t cts = res->config_timestamp;
181 |
182 | const int len = xcb_randr_get_screen_resources_current_outputs_length(res);
183 |
184 | /* an output is VGA-1, LVDS-1, etc. (usually physical video outputs) */
185 | xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(res);
186 |
187 | /* Request information for each output */
188 | xcb_randr_get_output_info_cookie_t ocookie[len];
189 | for (int i = 0; i < len; i++) {
190 | ocookie[i] = xcb_randr_get_output_info(conn, randr_outputs[i], cts);
191 | }
192 | Rect *resolutions = malloc(len * sizeof(Rect));
193 | /* No memory? Just keep on using the old information. */
194 | if (!resolutions) {
195 | free(res);
196 | return true;
197 | }
198 |
199 | /* Loop through all outputs available for this X11 screen */
200 | int screen = 0;
201 |
202 | for (int i = 0; i < len; i++) {
203 | xcb_randr_get_output_info_reply_t *output;
204 |
205 | if ((output = xcb_randr_get_output_info_reply(conn, ocookie[i], NULL)) == NULL) {
206 | continue;
207 | }
208 |
209 | if (output->crtc == XCB_NONE) {
210 | free(output);
211 | continue;
212 | }
213 |
214 | xcb_randr_get_crtc_info_cookie_t icookie;
215 | xcb_randr_get_crtc_info_reply_t *crtc;
216 | icookie = xcb_randr_get_crtc_info(conn, output->crtc, cts);
217 | if ((crtc = xcb_randr_get_crtc_info_reply(conn, icookie, NULL)) == NULL) {
218 | DEBUG("Skipping output: could not get CRTC (0x%08x)\n", output->crtc);
219 | free(output);
220 | continue;
221 | }
222 |
223 | resolutions[screen].x = crtc->x;
224 | resolutions[screen].y = crtc->y;
225 | resolutions[screen].width = crtc->width;
226 | resolutions[screen].height = crtc->height;
227 |
228 | DEBUG("found RandR output: %d x %d at %d x %d\n",
229 | crtc->width, crtc->height,
230 | crtc->x, crtc->y);
231 |
232 | screen++;
233 |
234 | free(crtc);
235 |
236 | free(output);
237 | }
238 | free(xr_resolutions);
239 | xr_resolutions = resolutions;
240 | xr_screens = screen;
241 | free(res);
242 | return true;
243 | }
244 |
245 | void _xinerama_query_screens(void) {
246 | if (!xinerama_active) {
247 | return;
248 | }
249 |
250 | xcb_xinerama_query_screens_cookie_t cookie;
251 | xcb_xinerama_query_screens_reply_t *reply;
252 | xcb_xinerama_screen_info_t *screen_info;
253 | xcb_generic_error_t *err;
254 | cookie = xcb_xinerama_query_screens_unchecked(conn);
255 | reply = xcb_xinerama_query_screens_reply(conn, cookie, &err);
256 | if (!reply) {
257 | DEBUG("Couldn't get Xinerama screens: X11 error code %d\n", err->error_code);
258 | free(err);
259 | return;
260 | }
261 | screen_info = xcb_xinerama_query_screens_screen_info(reply);
262 | int screens = xcb_xinerama_query_screens_screen_info_length(reply);
263 |
264 | Rect *resolutions = malloc(screens * sizeof(Rect));
265 | /* No memory? Just keep on using the old information. */
266 | if (!resolutions) {
267 | free(reply);
268 | return;
269 | }
270 |
271 | for (int screen = 0; screen < xr_screens; screen++) {
272 | resolutions[screen].x = screen_info[screen].x_org;
273 | resolutions[screen].y = screen_info[screen].y_org;
274 | resolutions[screen].width = screen_info[screen].width;
275 | resolutions[screen].height = screen_info[screen].height;
276 | DEBUG("found Xinerama screen: %d x %d at %d x %d\n",
277 | screen_info[screen].width, screen_info[screen].height,
278 | screen_info[screen].x_org, screen_info[screen].y_org);
279 | }
280 |
281 | free(xr_resolutions);
282 | xr_resolutions = resolutions;
283 | xr_screens = screens;
284 |
285 | free(reply);
286 | }
287 |
288 | void randr_query(xcb_window_t root) {
289 | if (_randr_query_monitors_15(root)) {
290 | return;
291 | }
292 |
293 | if (_randr_query_outputs_14(root)) {
294 | return;
295 | }
296 |
297 | _xinerama_query_screens();
298 | }
299 |
--------------------------------------------------------------------------------
/randr.h:
--------------------------------------------------------------------------------
1 | #ifndef _XINERAMA_H
2 | #define _XINERAMA_H
3 |
4 | typedef struct Rect {
5 | int16_t x;
6 | int16_t y;
7 | uint16_t width;
8 | uint16_t height;
9 | } Rect;
10 |
11 | extern int xr_screens;
12 | extern Rect *xr_resolutions;
13 |
14 | void randr_init(int *event_base, xcb_window_t root);
15 | void randr_query(xcb_window_t root);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/rgba.h:
--------------------------------------------------------------------------------
1 | #ifndef RGBA_H
2 | #define RGBA_H
3 |
4 | typedef struct rgb {
5 | double red;
6 | double green;
7 | double blue;
8 | } rgb_t;
9 |
10 | typedef struct rgb_str {
11 | char red[3];
12 | char green[3];
13 | char blue[3];
14 | } rgb_str_t;
15 |
16 | typedef struct rgba {
17 | double red;
18 | double green;
19 | double blue;
20 | double alpha;
21 | } rgba_t;
22 |
23 | typedef struct rgba_str {
24 | char red[3];
25 | char green[3];
26 | char blue[3];
27 | char alpha[3];
28 | } rgba_str_t;
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/tinyexpr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * TINYEXPR - Tiny recursive descent parser and evaluation engine in C
3 | *
4 | * Copyright (c) 2015, 2016 Lewis Van Winkle
5 | *
6 | * http://CodePlea.com
7 | *
8 | * This software is provided 'as-is', without any express or implied
9 | * warranty. In no event will the authors be held liable for any damages
10 | * arising from the use of this software.
11 | *
12 | * Permission is granted to anyone to use this software for any purpose,
13 | * including commercial applications, and to alter it and redistribute it
14 | * freely, subject to the following restrictions:
15 | *
16 | * 1. The origin of this software must not be misrepresented; you must not
17 | * claim that you wrote the original software. If you use this software
18 | * in a product, an acknowledgement in the product documentation would be
19 | * appreciated but is not required.
20 | * 2. Altered source versions must be plainly marked as such, and must not be
21 | * misrepresented as being the original software.
22 | * 3. This notice may not be removed or altered from any source distribution.
23 | */
24 |
25 | #ifndef __TINYEXPR_H__
26 | #define __TINYEXPR_H__
27 |
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 |
34 |
35 | typedef struct te_expr {
36 | int type;
37 | union {double value; const double *bound; const void *function;};
38 | void *parameters[1];
39 | } te_expr;
40 |
41 |
42 | enum {
43 | TE_VARIABLE = 0,
44 |
45 | TE_FUNCTION0 = 8, TE_FUNCTION1, TE_FUNCTION2, TE_FUNCTION3,
46 | TE_FUNCTION4, TE_FUNCTION5, TE_FUNCTION6, TE_FUNCTION7,
47 |
48 | TE_CLOSURE0 = 16, TE_CLOSURE1, TE_CLOSURE2, TE_CLOSURE3,
49 | TE_CLOSURE4, TE_CLOSURE5, TE_CLOSURE6, TE_CLOSURE7,
50 |
51 | TE_FLAG_PURE = 32
52 | };
53 |
54 | typedef struct te_variable {
55 | const char *name;
56 | const void *address;
57 | int type;
58 | void *context;
59 | } te_variable;
60 |
61 |
62 |
63 | /* Parses the input expression, evaluates it, and frees it. */
64 | /* Returns NaN on error. */
65 | double te_interp(const char *expression, int *error);
66 |
67 | /* Parses the input expression and binds variables. */
68 | /* Returns NULL on error. */
69 | te_expr *te_compile(const char *expression, const te_variable *variables, int var_count, int *error);
70 |
71 | /* Evaluates the expression. */
72 | double te_eval(const te_expr *n);
73 |
74 | /* Prints debugging information on the syntax tree. */
75 | void te_print(const te_expr *n);
76 |
77 | /* Frees the expression. */
78 | /* This is safe to call on NULL pointers. */
79 | void te_free(te_expr *n);
80 |
81 |
82 | #ifdef __cplusplus
83 | }
84 | #endif
85 |
86 | #endif /*__TINYEXPR_H__*/
87 |
--------------------------------------------------------------------------------
/travis/Dockerfile:
--------------------------------------------------------------------------------
1 | # vim:ft=Dockerfile
2 | FROM debian:sid
3 |
4 | RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
5 | # Paper over occasional network flakiness of some mirrors.
6 | RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
7 |
8 | # NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
9 | # instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
10 | # kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
11 | # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
12 |
13 | # Install mk-build-deps (for installing the i3 build dependencies),
14 | # clang and clang-format-9 (for checking formatting and building with clang),
15 | # lintian (for checking spelling errors),
16 | # test suite dependencies (for running tests)
17 | RUN apt-get update && \
18 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
19 | build-essential clang git autoconf automake libxcb-randr0-dev pkg-config libpam0g-dev \
20 | libcairo2-dev libxcb1-dev libxcb-dpms0-dev libxcb-image0-dev libxcb-util0-dev \
21 | libxcb-xrm-dev libev-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \
22 | libxkbcommon-x11-dev clang-format-9 libgif-dev && \
23 | rm -rf /var/lib/apt/lists/*
24 |
25 | WORKDIR /usr/src
26 |
--------------------------------------------------------------------------------
/unlock_indicator.h:
--------------------------------------------------------------------------------
1 | #ifndef _UNLOCK_INDICATOR_H
2 | #define _UNLOCK_INDICATOR_H
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | typedef enum {
10 | STATE_STARTED = 0, /* default state */
11 | STATE_KEY_PRESSED = 1, /* key was pressed, show unlock indicator */
12 | STATE_KEY_ACTIVE = 2, /* a key was pressed recently, highlight part
13 | of the unlock indicator. */
14 | STATE_BACKSPACE_ACTIVE = 3, /* backspace was pressed recently, highlight
15 | part of the unlock indicator in red. */
16 | STATE_NOTHING_TO_DELETE = 4, /* backspace was pressed, but there is nothing to delete. */
17 | } unlock_state_t;
18 |
19 | typedef enum {
20 | STATE_AUTH_IDLE = 0, /* no authenticator interaction at the moment */
21 | STATE_AUTH_VERIFY = 1, /* currently verifying the password via authenticator */
22 | STATE_AUTH_LOCK = 2, /* currently locking the screen */
23 | STATE_AUTH_WRONG = 3, /* the password was wrong */
24 | STATE_I3LOCK_LOCK_FAILED = 4, /* i3lock failed to load */
25 | } auth_state_t;
26 |
27 | typedef struct {
28 | text_t status_text;
29 | text_t mod_text;
30 | text_t keylayout_text;
31 | text_t time_text;
32 | text_t date_text;
33 | text_t greeter_text;
34 |
35 | double indicator_x, indicator_y;
36 |
37 | double screen_x, screen_y;
38 | double bar_x, bar_y, bar_width;
39 | } DrawData;
40 |
41 | typedef enum {
42 | NONE,
43 | TILE,
44 | CENTER,
45 | FILL,
46 | SCALE,
47 | MAX,
48 | } background_type_t;
49 |
50 |
51 | typedef enum {
52 | CC_POS_RESET,
53 | CC_POS_CHANGE,
54 | CC_POS_KEEP,
55 | CC_POS_TAB
56 | } control_char_pos_t;
57 |
58 | typedef struct {
59 | char character;
60 | control_char_pos_t x_behavior;
61 | int x_behavior_arg;
62 | control_char_pos_t y_behavior;
63 | int y_behavior_arg;
64 | } control_char_config_t;
65 |
66 | void render_lock(uint32_t* resolution, xcb_drawable_t drawable);
67 | void draw_image(uint32_t* resolution, cairo_surface_t* img, cairo_t* xcb_ctx);
68 | void init_colors_once(void);
69 | void redraw_screen(void);
70 | void clear_indicator(void);
71 | void start_time_redraw_timeout(void);
72 | void* start_time_redraw_tick_pthread(void* arg);
73 | void start_time_redraw_tick(struct ev_loop* main_loop);
74 | #endif
75 |
--------------------------------------------------------------------------------
/xcb.c:
--------------------------------------------------------------------------------
1 | /*
2 | * vim:ts=4:sw=4:expandtab
3 | *
4 | * © 2010 Michael Stapelberg
5 | * © 2021 Raymond Li
6 | *
7 | * xcb.c: contains all functions which use XCB to talk to X11. Mostly wrappers
8 | * around the rather complicated/ugly parts of the XCB API.
9 | *
10 | */
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "cursors.h"
30 | #include "i3lock.h"
31 | #include "xcb.h"
32 | #include "unlock_indicator.h"
33 |
34 | extern auth_state_t auth_state;
35 | extern bool composite;
36 | extern bool debug_mode;
37 |
38 | xcb_connection_t *conn;
39 | xcb_screen_t *screen;
40 |
41 | static xcb_atom_t _NET_WM_BYPASS_COMPOSITOR = XCB_NONE;
42 | void _init_net_wm_bypass_compositor(xcb_connection_t *conn) {
43 | if (_NET_WM_BYPASS_COMPOSITOR != XCB_NONE) {
44 | /* already initialized */
45 | return;
46 | }
47 | xcb_generic_error_t *err;
48 | xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(
49 | conn,
50 | xcb_intern_atom(conn, 0, strlen("_NET_WM_BYPASS_COMPOSITOR"), "_NET_WM_BYPASS_COMPOSITOR"),
51 | &err);
52 | if (atom_reply == NULL) {
53 | fprintf(stderr, "X11 Error %d\n", err->error_code);
54 | free(err);
55 | return;
56 | }
57 | _NET_WM_BYPASS_COMPOSITOR = atom_reply->atom;
58 | free(atom_reply);
59 | }
60 |
61 | #define curs_invisible_width 8
62 | #define curs_invisible_height 8
63 |
64 | static unsigned char curs_invisible_bits[] = {
65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
66 |
67 | #define curs_windows_width 11
68 | #define curs_windows_height 19
69 |
70 | static unsigned char curs_windows_bits[] = {
71 | 0xfe, 0x07, 0xfc, 0x07, 0xfa, 0x07, 0xf6, 0x07, 0xee, 0x07, 0xde, 0x07,
72 | 0xbe, 0x07, 0x7e, 0x07, 0xfe, 0x06, 0xfe, 0x05, 0x3e, 0x00, 0xb6, 0x07,
73 | 0x6a, 0x07, 0x6c, 0x07, 0xde, 0x06, 0xdf, 0x06, 0xbf, 0x05, 0xbf, 0x05,
74 | 0x7f, 0x06};
75 |
76 | #define mask_windows_width 11
77 | #define mask_windows_height 19
78 |
79 | static unsigned char mask_windows_bits[] = {
80 | 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00,
81 | 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0x7f, 0x00,
82 | 0xf7, 0x00, 0xf3, 0x00, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x03, 0xc0, 0x03,
83 | 0x80, 0x01};
84 |
85 | static uint32_t get_colorpixel(char *hex) {
86 | char strgroups[4][3] = {{hex[0], hex[1], '\0'},
87 | {hex[2], hex[3], '\0'},
88 | {hex[4], hex[5], '\0'},
89 | {hex[6], hex[4], '\0'}};
90 | uint32_t rgb16[4] = {(strtol(strgroups[0], NULL, 16)),
91 | (strtol(strgroups[1], NULL, 16)),
92 | (strtol(strgroups[2], NULL, 16)),
93 | (strtol(strgroups[3], NULL, 16))};
94 |
95 | return (rgb16[3] << 24) + (rgb16[0] << 16) + (rgb16[1] << 8) + rgb16[2];
96 | }
97 |
98 | xcb_visualtype_t *get_visualtype_by_depth(uint16_t depth, xcb_screen_t *root_screen) {
99 | xcb_depth_iterator_t depth_iter;
100 |
101 | depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
102 | for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
103 | if (depth_iter.data->depth != depth)
104 | continue;
105 |
106 | xcb_visualtype_iterator_t visual_iter;
107 |
108 | visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
109 | if (!visual_iter.rem)
110 | continue;
111 | return visual_iter.data;
112 | }
113 | return NULL;
114 | }
115 |
116 |
117 | xcb_visualtype_t *get_root_visual_type(xcb_screen_t *screen) {
118 | xcb_visualtype_t *visual_type = NULL;
119 | xcb_depth_iterator_t depth_iter;
120 | xcb_visualtype_iterator_t visual_iter;
121 |
122 | for (depth_iter = xcb_screen_allowed_depths_iterator(screen);
123 | depth_iter.rem;
124 | xcb_depth_next(&depth_iter)) {
125 | for (visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
126 | visual_iter.rem;
127 | xcb_visualtype_next(&visual_iter)) {
128 | if (screen->root_visual != visual_iter.data->visual_id)
129 | continue;
130 |
131 | visual_type = visual_iter.data;
132 | return visual_type;
133 | }
134 | }
135 |
136 | return NULL;
137 | }
138 |
139 | xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_drawable_t win, u_int32_t *resolution, char *color) {
140 | xcb_pixmap_t bg_pixmap = xcb_generate_id(conn);
141 | xcb_create_pixmap(conn, 32, bg_pixmap, win, resolution[0], resolution[1]);
142 |
143 | /* Generate a Graphics Context and fill the pixmap with background color
144 | * (for images that are smaller than your screen) */
145 | xcb_gcontext_t gc = xcb_generate_id(conn);
146 | uint32_t values[] = {get_colorpixel(color)};
147 | xcb_create_gc(conn, gc, bg_pixmap, XCB_GC_FOREGROUND, values);
148 | xcb_rectangle_t rect = {0, 0, resolution[0], resolution[1]};
149 | xcb_poly_fill_rectangle(conn, bg_pixmap, gc, 1, &rect);
150 | xcb_free_gc(conn, gc);
151 |
152 | return bg_pixmap;
153 | }
154 |
155 | xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color) {
156 | uint32_t mask = 0;
157 | uint32_t values[5];
158 | xcb_window_t win = xcb_generate_id(conn);
159 | xcb_window_t parent_win = scr->root;
160 |
161 | if (composite) {
162 | /* Check whether the composite extension is available */
163 | const xcb_query_extension_reply_t *extension_query = NULL;
164 | xcb_generic_error_t *error = NULL;
165 | xcb_composite_get_overlay_window_cookie_t cookie;
166 | xcb_composite_get_overlay_window_reply_t *composite_reply = NULL;
167 |
168 | extension_query = xcb_get_extension_data(conn, &xcb_composite_id);
169 | if (extension_query && extension_query->present) {
170 | /* When composition is used, we need to use the composite overlay
171 | * window instead of the normal root window to be able to cover
172 | * composited windows */
173 | cookie = xcb_composite_get_overlay_window(conn, scr->root);
174 | composite_reply = xcb_composite_get_overlay_window_reply(conn, cookie, &error);
175 |
176 | if (!error && composite_reply) {
177 | parent_win = composite_reply->overlay_win;
178 | }
179 |
180 | free(composite_reply);
181 | free(error);
182 | }
183 | }
184 |
185 |
186 | xcb_visualid_t visual = get_visualtype_by_depth(32, scr)->visual_id;
187 | xcb_colormap_t win_colormap = xcb_generate_id(conn);
188 | xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, win_colormap, scr->root, visual);
189 |
190 | mask |= XCB_CW_BACK_PIXEL;
191 | values[0] = get_colorpixel(color);
192 |
193 | mask |= XCB_CW_BORDER_PIXEL;
194 | values[1] = 0x00000000;
195 |
196 | mask |= XCB_CW_OVERRIDE_REDIRECT;
197 | values[2] = 1;
198 |
199 | mask |= XCB_CW_EVENT_MASK;
200 | values[3] = XCB_EVENT_MASK_EXPOSURE |
201 | XCB_EVENT_MASK_KEY_PRESS |
202 | XCB_EVENT_MASK_KEY_RELEASE |
203 | XCB_EVENT_MASK_VISIBILITY_CHANGE |
204 | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
205 |
206 | mask |= XCB_CW_COLORMAP;
207 | values[4] = win_colormap;
208 |
209 | xcb_create_window(conn,
210 | 32,
211 | win, /* the window id */
212 | parent_win,
213 | 0, 0,
214 | scr->width_in_pixels,
215 | scr->height_in_pixels, /* dimensions */
216 | 0, /* border = 0, we draw our own */
217 | XCB_WINDOW_CLASS_INPUT_OUTPUT,
218 | visual, /* copy visual from parent */
219 | mask,
220 | values);
221 |
222 | char *name = "i3lock";
223 | xcb_change_property(conn,
224 | XCB_PROP_MODE_REPLACE,
225 | win,
226 | XCB_ATOM_WM_NAME,
227 | XCB_ATOM_STRING,
228 | 8,
229 | strlen(name),
230 | name);
231 |
232 | xcb_change_property(conn,
233 | XCB_PROP_MODE_REPLACE,
234 | win,
235 | XCB_ATOM_WM_CLASS,
236 | XCB_ATOM_STRING,
237 | 8,
238 | 2 * (strlen("i3lock") + 1),
239 | "i3lock\0i3lock\0");
240 |
241 | const uint32_t bypass_compositor = 1; /* disable compositing */
242 | _init_net_wm_bypass_compositor(conn);
243 | xcb_change_property(conn,
244 | XCB_PROP_MODE_REPLACE,
245 | win,
246 | _NET_WM_BYPASS_COMPOSITOR,
247 | XCB_ATOM_CARDINAL,
248 | 32,
249 | 1,
250 | &bypass_compositor);
251 |
252 | /* Map the window (= make it visible) */
253 | xcb_map_window(conn, win);
254 |
255 | /* Raise window (put it on top) */
256 | values[0] = XCB_STACK_MODE_ABOVE;
257 | xcb_configure_window(conn, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
258 |
259 | /* Ensure that the window is created and set up before returning */
260 | xcb_aux_sync(conn);
261 |
262 | return win;
263 | }
264 |
265 | /*
266 | * Repeatedly tries to grab pointer and keyboard (up to the specified number of
267 | * tries).
268 | *
269 | * Returns true if the grab succeeded, false if not.
270 | *
271 | */
272 | bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor, int tries) {
273 | xcb_grab_pointer_cookie_t pcookie;
274 | xcb_grab_pointer_reply_t *preply;
275 |
276 | xcb_grab_keyboard_cookie_t kcookie;
277 | xcb_grab_keyboard_reply_t *kreply;
278 |
279 | const suseconds_t screen_redraw_timeout = 100000; /* 100ms */
280 |
281 | /* Using few variables to trigger a redraw_screen() if too many tries */
282 | bool redrawn = false;
283 | struct timeval start;
284 | if (gettimeofday(&start, NULL) == -1) {
285 | err(EXIT_FAILURE, "gettimeofday");
286 | }
287 |
288 | while (tries-- > 0) {
289 | pcookie = xcb_grab_pointer(
290 | conn,
291 | false, /* get all pointer events specified by the following mask */
292 | screen->root, /* grab the root window */
293 | XCB_NONE, /* which events to let through */
294 | XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
295 | XCB_GRAB_MODE_ASYNC, /* keyboard mode */
296 | XCB_NONE, /* confine_to = in which window should the cursor stay */
297 | cursor, /* we change the cursor to whatever the user wanted */
298 | XCB_CURRENT_TIME);
299 |
300 | if ((preply = xcb_grab_pointer_reply(conn, pcookie, NULL)) &&
301 | preply->status == XCB_GRAB_STATUS_SUCCESS) {
302 | free(preply);
303 | break;
304 | }
305 |
306 | /* In case the grab failed, we still need to free the reply */
307 | free(preply);
308 |
309 | /* Make this quite a bit slower */
310 | usleep(50);
311 |
312 | struct timeval now;
313 | if (gettimeofday(&now, NULL) == -1) {
314 | err(EXIT_FAILURE, "gettimeofday");
315 | }
316 |
317 | struct timeval elapsed;
318 | timersub(&now, &start, &elapsed);
319 |
320 | if (!redrawn &&
321 | (tries % 100) == 0 &&
322 | elapsed.tv_usec >= screen_redraw_timeout) {
323 | redraw_screen();
324 | redrawn = true;
325 | }
326 | }
327 |
328 | while (tries-- > 0) {
329 | kcookie = xcb_grab_keyboard(
330 | conn,
331 | true, /* report events */
332 | screen->root, /* grab the root window */
333 | XCB_CURRENT_TIME,
334 | XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require sync */
335 | XCB_GRAB_MODE_ASYNC);
336 |
337 | if ((kreply = xcb_grab_keyboard_reply(conn, kcookie, NULL)) &&
338 | kreply->status == XCB_GRAB_STATUS_SUCCESS) {
339 | free(kreply);
340 | break;
341 | }
342 |
343 | /* In case the grab failed, we still need to free the reply */
344 | free(kreply);
345 |
346 | /* Make this quite a bit slower */
347 | usleep(50);
348 |
349 | struct timeval now;
350 | if (gettimeofday(&now, NULL) == -1) {
351 | err(EXIT_FAILURE, "gettimeofday");
352 | }
353 |
354 | struct timeval elapsed;
355 | timersub(&now, &start, &elapsed);
356 |
357 | /* Trigger a screen redraw if 100ms elapsed */
358 | if (!redrawn &&
359 | (tries % 100) == 0 &&
360 | elapsed.tv_usec >= screen_redraw_timeout) {
361 | redraw_screen();
362 | redrawn = true;
363 | }
364 | }
365 |
366 | return (tries > 0);
367 | }
368 |
369 | xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice) {
370 | xcb_pixmap_t bitmap;
371 | xcb_pixmap_t mask;
372 | xcb_cursor_t cursor;
373 |
374 | unsigned char *curs_bits;
375 | unsigned char *mask_bits;
376 | int curs_w, curs_h;
377 |
378 | switch (choice) {
379 | case CURS_NONE:
380 | curs_bits = curs_invisible_bits;
381 | mask_bits = curs_invisible_bits;
382 | curs_w = curs_invisible_width;
383 | curs_h = curs_invisible_height;
384 | break;
385 | case CURS_WIN:
386 | curs_bits = curs_windows_bits;
387 | mask_bits = mask_windows_bits;
388 | curs_w = curs_windows_width;
389 | curs_h = curs_windows_height;
390 | break;
391 | case CURS_DEFAULT:
392 | default:
393 | return XCB_NONE; /* XCB_NONE is xcb's way of saying "don't change the cursor" */
394 | }
395 |
396 | bitmap = xcb_create_pixmap_from_bitmap_data(conn,
397 | win,
398 | curs_bits,
399 | curs_w,
400 | curs_h,
401 | 1,
402 | screen->white_pixel,
403 | screen->black_pixel,
404 | NULL);
405 |
406 | mask = xcb_create_pixmap_from_bitmap_data(conn,
407 | win,
408 | mask_bits,
409 | curs_w,
410 | curs_h,
411 | 1,
412 | screen->white_pixel,
413 | screen->black_pixel,
414 | NULL);
415 |
416 | cursor = xcb_generate_id(conn);
417 |
418 | xcb_create_cursor(conn,
419 | cursor,
420 | bitmap,
421 | mask,
422 | 65535, 65535, 65535,
423 | 0, 0, 0,
424 | 0, 0);
425 |
426 | xcb_free_pixmap(conn, bitmap);
427 | xcb_free_pixmap(conn, mask);
428 |
429 | return cursor;
430 | }
431 |
432 | static xcb_atom_t _NET_ACTIVE_WINDOW = XCB_NONE;
433 | void _init_net_active_window(xcb_connection_t *conn) {
434 | if (_NET_ACTIVE_WINDOW != XCB_NONE) {
435 | /* already initialized */
436 | return;
437 | }
438 | xcb_generic_error_t *err;
439 | xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(
440 | conn,
441 | xcb_intern_atom(conn, 0, strlen("_NET_ACTIVE_WINDOW"), "_NET_ACTIVE_WINDOW"),
442 | &err);
443 | if (atom_reply == NULL) {
444 | fprintf(stderr, "X11 Error %d\n", err->error_code);
445 | free(err);
446 | return;
447 | }
448 | _NET_ACTIVE_WINDOW = atom_reply->atom;
449 | free(atom_reply);
450 | }
451 |
452 | xcb_window_t find_focused_window(xcb_connection_t *conn, const xcb_window_t root) {
453 | xcb_window_t result = XCB_NONE;
454 |
455 | _init_net_active_window(conn);
456 |
457 | xcb_get_property_reply_t *prop_reply = xcb_get_property_reply(
458 | conn,
459 | xcb_get_property_unchecked(
460 | conn, false, root, _NET_ACTIVE_WINDOW, XCB_GET_PROPERTY_TYPE_ANY, 0, 1 /* word */),
461 | NULL);
462 | if (prop_reply == NULL) {
463 | goto out;
464 | }
465 | if (xcb_get_property_value_length(prop_reply) == 0) {
466 | goto out_prop;
467 | }
468 | if (prop_reply->type != XCB_ATOM_WINDOW) {
469 | goto out_prop;
470 | }
471 |
472 | result = *((xcb_window_t *)xcb_get_property_value(prop_reply));
473 |
474 | out_prop:
475 | free(prop_reply);
476 | out:
477 | return result;
478 | }
479 |
480 | void set_focused_window(xcb_connection_t *conn, const xcb_window_t root, const xcb_window_t window) {
481 | xcb_client_message_event_t ev;
482 | memset(&ev, '\0', sizeof(xcb_client_message_event_t));
483 |
484 | _init_net_active_window(conn);
485 |
486 | ev.response_type = XCB_CLIENT_MESSAGE;
487 | ev.window = window;
488 | ev.type = _NET_ACTIVE_WINDOW;
489 | ev.format = 32;
490 | ev.data.data32[0] = 2; /* 2 = pager */
491 |
492 | xcb_send_event(conn, false, root, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)&ev);
493 | xcb_flush(conn);
494 | }
495 |
496 | xcb_pixmap_t capture_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t * resolution) {
497 | xcb_pixmap_t bg_pixmap = xcb_generate_id(conn);
498 | xcb_create_pixmap(conn, scr->root_depth, bg_pixmap, scr->root, resolution[0], resolution[1]);
499 | xcb_gcontext_t gc = xcb_generate_id(conn);
500 | uint32_t values[] = { scr->black_pixel, 1};
501 | xcb_create_gc(conn, gc, bg_pixmap, XCB_GC_FOREGROUND | XCB_GC_SUBWINDOW_MODE, values);
502 | xcb_rectangle_t rect = { 0, 0, resolution[0], resolution[1] };
503 | xcb_poly_fill_rectangle(conn, bg_pixmap, gc, 1, &rect);
504 | xcb_copy_area(conn, scr->root, bg_pixmap, gc, 0, 0, 0, 0, resolution[0], resolution[1]);
505 | xcb_flush(conn);
506 | xcb_free_gc(conn, gc);
507 | return bg_pixmap;
508 | }
509 |
510 | static char * get_atom_name(xcb_connection_t* conn, xcb_atom_t atom) {
511 | xcb_get_atom_name_reply_t *reply = NULL;
512 | char *name;
513 | int length;
514 | char* answer = NULL;
515 |
516 | if (atom == 0)
517 | return "";
518 |
519 | xcb_get_atom_name_cookie_t cookie;
520 | xcb_generic_error_t *error = NULL;
521 |
522 | cookie = xcb_get_atom_name(conn, atom);
523 |
524 | reply = xcb_get_atom_name_reply(conn, cookie, &error);
525 | if (!reply || error)
526 | return "";
527 |
528 | length = xcb_get_atom_name_name_length(reply);
529 | name = xcb_get_atom_name_name(reply);
530 |
531 | answer = malloc(sizeof(char) * (length + 1));
532 | strncpy(answer, name, length);
533 | answer[length] = '\0';
534 | free(error);
535 | free(reply);
536 | return answer;
537 | }
538 |
539 |
540 | uint8_t xcb_get_key_group_index(xcb_connection_t *conn) {
541 | xcb_xkb_get_state_cookie_t cookie;
542 | xcb_xkb_get_state_reply_t* reply = NULL;
543 | cookie = xcb_xkb_get_state(conn, XCB_XKB_ID_USE_CORE_KBD);
544 | reply = xcb_xkb_get_state_reply(conn, cookie, NULL);
545 | uint8_t ans = reply->group;
546 | free(reply);
547 | return ans;
548 | }
549 |
550 |
551 | char* xcb_get_key_group_names(xcb_connection_t *conn) {
552 | uint8_t xkb_base_event;
553 | uint8_t xkb_base_error;
554 | if (xkb_x11_setup_xkb_extension(conn,
555 | XKB_X11_MIN_MAJOR_XKB_VERSION,
556 | XKB_X11_MIN_MINOR_XKB_VERSION,
557 | 0,
558 | NULL,
559 | NULL,
560 | &xkb_base_event,
561 | &xkb_base_error) != 1)
562 | errx(EXIT_FAILURE, "Could not setup XKB extension.");
563 |
564 |
565 | xcb_xkb_get_names_reply_t *reply = NULL;
566 |
567 |
568 | xcb_generic_error_t *error = NULL;
569 | xcb_xkb_get_names_cookie_t cookie;
570 |
571 | cookie = xcb_xkb_get_names(conn,
572 | XCB_XKB_ID_USE_CORE_KBD,
573 | all_name_details);
574 |
575 | reply = xcb_xkb_get_names_reply(conn, cookie, &error);
576 | if (!reply || error)
577 | errx(1, "couldn't get reply for get_names");
578 |
579 | xcb_xkb_get_names_value_list_t list;
580 |
581 | void *buffer;
582 |
583 | buffer = xcb_xkb_get_names_value_list(reply);
584 | xcb_xkb_get_names_value_list_unpack(buffer,
585 | reply->nTypes,
586 | reply->indicators,
587 | reply->virtualMods,
588 | reply->groupNames,
589 | reply->nKeys,
590 | reply->nKeyAliases,
591 | reply->nRadioGroups,
592 | reply->which,
593 | &list);
594 |
595 | /* dump group names. */
596 |
597 | int length;
598 | xcb_atom_t *iter;
599 | uint8_t index;
600 | char* answer = NULL;
601 | length = xcb_xkb_get_names_value_list_groups_length(reply, &list);
602 | iter = xcb_xkb_get_names_value_list_groups(&list);
603 | index = xcb_get_key_group_index(conn);
604 |
605 | for (int i = 0; i < length; i++) {
606 | xcb_atom_t group_name = *iter;
607 | char* name = get_atom_name(conn, group_name);
608 | DEBUG("group_name %d: %s\n", i, name);
609 | if (i == index) {
610 | answer = name;
611 | } else {
612 | free(name);
613 | }
614 | iter++;
615 | }
616 | free(reply);
617 | free(error);
618 | return answer;
619 | }
620 |
--------------------------------------------------------------------------------
/xcb.h:
--------------------------------------------------------------------------------
1 | #ifndef _XCB_H
2 | #define _XCB_H
3 |
4 | #include
5 |
6 | #define all_name_details \
7 | (XCB_XKB_NAME_DETAIL_KEYCODES | \
8 | XCB_XKB_NAME_DETAIL_GEOMETRY | \
9 | XCB_XKB_NAME_DETAIL_SYMBOLS | \
10 | XCB_XKB_NAME_DETAIL_PHYS_SYMBOLS | \
11 | XCB_XKB_NAME_DETAIL_TYPES | \
12 | XCB_XKB_NAME_DETAIL_COMPAT | \
13 | XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES | \
14 | XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES | \
15 | XCB_XKB_NAME_DETAIL_INDICATOR_NAMES | \
16 | XCB_XKB_NAME_DETAIL_KEY_NAMES | \
17 | XCB_XKB_NAME_DETAIL_KEY_ALIASES | \
18 | XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES | \
19 | XCB_XKB_NAME_DETAIL_GROUP_NAMES | \
20 | XCB_XKB_NAME_DETAIL_RG_NAMES)
21 |
22 |
23 | extern xcb_connection_t *conn;
24 | extern xcb_screen_t *screen;
25 |
26 | xcb_visualtype_t *get_root_visual_type(xcb_screen_t *s);
27 | xcb_visualtype_t* get_visualtype_by_depth(uint16_t depth, xcb_screen_t* root_screen);
28 | xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_drawable_t drawable, u_int32_t *resolution, char *color);
29 | xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color);
30 | bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor, int tries);
31 | xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice);
32 | xcb_window_t find_focused_window(xcb_connection_t *conn, const xcb_window_t root);
33 | void set_focused_window(xcb_connection_t *conn, const xcb_window_t root, const xcb_window_t window);
34 | xcb_pixmap_t capture_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t* resolution);
35 | char* xcb_get_key_group_names(xcb_connection_t *conn);
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------