71 Commits

Author SHA1 Message Date
3ad16d3a3c fix: Makefile 2025-07-05 20:16:40 +02:00
df6a565874 release: v1.2.1 2025-07-05 19:01:55 +02:00
310b0a87dc Merge pull request #55 from javalsai/fix_makefile_rsync
fix: makefile rsync dependency, runit installation
2025-07-05 18:45:02 +02:00
6384a94f61 pkg(Makefile): make services packaging easier 2025-07-05 18:27:29 +02:00
56e8897565 fix(Makefile): wrong path 2025-07-05 18:23:05 +02:00
f67e30991a fix(Makedile): proper service install recipes
update docs too
2025-07-05 17:53:53 +02:00
grialion
e8a9e57af9 fix(Makefile): comprehensive runit installation 2025-07-05 15:19:39 +02:00
31c3ad6d42 fix(Makefile): duplicated s6 install 2025-07-05 14:52:13 +02:00
a00a73756c fix: support /etc/sv/ and /etc/<init>/sv 2025-07-05 14:50:43 +02:00
grialion
51c12eefdc fix: makefile rsync dependency, runit installation 2025-07-05 11:16:02 +02:00
f678056c5b Merge pull request #54 from javalsai/actions/update-aur-
[AUR update]: Bump to v1.2.0
2025-07-04 22:53:04 +02:00
3a7bd6f9f5 fix(ci,aur): empty version strings 2025-07-04 22:50:45 +02:00
5207e1e94b Merge branch 'master' into actions/update-aur- 2025-07-04 22:49:01 +02:00
GitHub Actions
69d48d32d6 Update AUR pkgs to v 2025-07-04 20:47:25 +00:00
7f75b8edce fix: allow building without a git repo 2025-07-04 22:40:23 +02:00
75fc3c139b ci: rename release workflow 2025-07-04 22:09:32 +02:00
ec41c6f70e Merge pull request #53 from javalsai/update_rate
feat: add refresh_rate option for clock
2025-07-04 20:58:49 +02:00
65bbb7d1b4 Merge branch 'master' into update_rate 2025-07-04 19:33:43 +02:00
9fe938b96a Merge pull request #52 from grialion/feat-help-version-menu
feat: help, version menu
2025-07-04 19:28:25 +02:00
5f7e412408 Merge branch 'master' into feat-help-version-menu 2025-07-04 19:25:59 +02:00
335459e127 ci: rename push workflow 2025-07-04 19:22:59 +02:00
c05218d30a ci: split check & build 2025-07-04 19:19:44 +02:00
3d6efa448b ci: update make release action 2025-07-04 19:12:45 +02:00
f3ae85bb94 feat|fix: improve all ci behavior 2025-07-04 18:36:47 +02:00
521a7c295e rm: unused Makefile flags 2025-07-04 16:39:29 +02:00
d1b993c32a ci: fix bear 2025-07-04 16:05:14 +02:00
7cd976f916 ci: fix clang-tidy 2025-07-04 16:03:42 +02:00
240bdbede6 ci(9245d38): set-status first of all
and no need to cache libpam for vm build architectures
2025-07-04 15:56:31 +02:00
e4b11f9a30 ci: add clang-tidy to CI 2025-07-04 15:50:37 +02:00
736e816509 style: satisfy clang-tidy 2025-07-04 15:50:18 +02:00
3fb74ece44 style: indent preprocessor directives 2025-07-04 15:23:22 +02:00
19a1355b06 dev: automatic version.h generation
also added compiler information as a feature
2025-07-04 15:22:22 +02:00
9c022c5813 feat(cfg): add ellipsis to config 2025-07-04 04:48:20 +02:00
a316afecb2 fix: possible memory issues 2025-07-04 04:47:32 +02:00
5a6471dd00 feat: utf8 hostname and ellipsis 2025-07-04 04:40:10 +02:00
9084dfdcda fix: wrong default.ini value 2025-07-04 04:12:22 +02:00
5b5adf76b7 feat: support long hostnames
close #49
2025-07-04 03:56:51 +02:00
ba836e5cd4 feat: add refresh_rate option for clock 2025-07-04 03:30:29 +02:00
981aa4efc7 Merge pull request #48 from rmntgx/ui-improvements
Interface resize
2025-07-04 01:45:16 +02:00
9f905622a2 chore: dry and modularize a bit 2025-07-04 01:43:32 +02:00
grialion
3ec1eec56f fix: git describe always (even in CI build)
use --always to make it work on shallow cloned repos (ie. CI build job)
2025-07-04 00:40:10 +02:00
grialion
9245d38ecf ci: fix: install git before checkout action 2025-07-04 00:35:51 +02:00
grialion
afd23657c0 feat: help, version menu 2025-07-04 00:15:14 +02:00
92d3351292 Merge pull request #50 from rmntgx/master
fix: do not overwrite theme
2025-07-03 20:36:51 +02:00
rmntgx
f5445248d3 Merge branch 'master' into ui-improvements 2025-07-02 14:02:40 +05:00
rmntgx
68ed11fb2d feat: cool resize implementation 2025-07-02 13:50:17 +05:00
bae810eb99 Merge pull request #47 from javalsai/actions/update-aur-1.1.1
[AUR update]: Bump to 1.1.1
2025-07-01 01:56:05 +02:00
GitHub Actions
4c955053e8 Update AUR pkgs to v1.1.1 2025-06-30 23:55:37 +00:00
3bfc2f52f3 Merge pull request #46 from javalsai/fix-45
fix #45
2025-07-01 01:53:22 +02:00
59acddf652 dev: add debug utils folder 2025-07-01 01:26:35 +02:00
6c6769b2b3 chore: clean some auth logic 2025-07-01 01:16:08 +02:00
99e27dd0c0 fix(likely): #45 2025-07-01 01:09:49 +02:00
rmntgx
b653fdcc57 feat: buggy resize implementation 2025-06-29 23:32:04 +05:00
rmntgx
d7b5f4f090 Merge branch 'javalsai:master' into master 2025-06-29 23:10:52 +05:00
4b6d113bdb Merge pull request #44 from javalsai/actions/update-aur-1.1.0
[AUR update]: Bump to 1.1.0
2025-06-29 19:05:26 +02:00
GitHub Actions
4fa400eb06 Update AUR pkgs to v1.1.0 2025-06-29 17:01:11 +00:00
11e9257c4a Merge pull request #43 from javalsai/improvements
fix: broken cfg parser (blame 8403bfc2)
2025-06-29 18:57:49 +02:00
7d7cf10600 Merge pull request #42 from rmntgx/save-last-selection
Save last selection
2025-06-29 18:55:44 +02:00
64e088884d fix: broken cfg parser (blame 8403bfc2) 2025-06-29 18:51:53 +02:00
bceb13b844 feat: save user and session as strings 2025-06-29 18:50:35 +02:00
rmntgx
d5a708ec4a Merge pull request #6 from rmntgx/save-last-selection
Save last selection
2025-06-29 15:21:41 +05:00
rmntgx
f0e962ad50 fix: create directory 2025-06-29 11:51:42 +05:00
rmntgx
16d1325f96 style: formatting and linter satisfaction 2025-06-29 10:56:31 +05:00
rmntgx
8b8784a210 Merge pull request #5 from rmntgx/save-last-selection
Save last selection
2025-06-29 10:26:33 +05:00
rmntgx
1714b477ad fix: compilation error after rebase 2025-06-29 10:24:58 +05:00
rmntgx
a08ffa5a75 fix: simplified code 2025-06-29 10:20:01 +05:00
rmntgx
4a83e5d825 feature: saving previous selection 2025-06-29 10:20:00 +05:00
rmntgx
d9a1bb1e68 fix: made it simplier 2025-06-25 18:05:50 +05:00
rmntgx
8d24924e59 fix: do not overwrite theme 2025-07-02 14:18:46 +05:00
4361e1d9a2 Merge pull request #40 from javalsai/actions/update-aur-1.0.0
[AUR update]: Bump to 1.0.0
2025-06-22 21:32:19 +02:00
GitHub Actions
3d2e5c1a18 Update AUR pkgs to v1.0.0 2025-06-22 19:14:16 +00:00
42 changed files with 895 additions and 496 deletions

View File

@@ -6,3 +6,6 @@ AllowShortIfStatementsOnASingleLine: WithoutElse
AlignAfterOpenBracket: Align
BinPackParameters: true
AllowAllParametersOfDeclarationOnNextLine: true
IndentPPDirectives: BeforeHash
IndentGotoLabels: true

130
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,130 @@
name: Build
on:
workflow_call:
jobs:
build-linux-amd64:
name: amd64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git libpam0g-dev"
version: 1.0
- uses: actions/checkout@v4
- id: build
run: ARCH=amd64 assets/github_scripts/build.sh
- uses: actions/upload-artifact@v4
with:
name: build-amd64
path: lidm-amd64
retention-days: 1
build-linux-i386:
name: i386
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git libpam0g-dev gcc-multilib"
version: 1.0
- uses: actions/checkout@v4
- run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y libpam0g-dev:i386
- id: build
run: ARCH=i386 assets/github_scripts/build.sh CFLAGS="-O3 -Wall -m32"
- uses: actions/upload-artifact@v4
with:
name: build-i386
path: lidm-i386
retention-days: 1
build-linux-aarch64:
name: aarch64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=aarch64 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-aarch64
path: lidm-aarch64
retention-days: 1
build-linux-armv7:
name: armv7
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: armv7
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=armv7 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-armv7
path: lidm-armv7
retention-days: 1
build-linux-riscv64:
name: riscv64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: riscv64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=riscv64 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-riscv64
path: lidm-riscv64
retention-days: 1

View File

@@ -1,291 +0,0 @@
name: Check and Build
on:
workflow_call:
inputs:
set-statuses:
required: false
default: true
type: boolean
jobs:
spellcheck:
name: Check Grammar
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "codespell"
version: 1.0
- run: codespell
shellcheck:
name: Shell Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "shellcheck"
version: 1.0
- run: find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clangcheck:
name: Clang Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "clang-format clang-tidy"
version: 1.0
- run: clang-format -ni src/*.c include/*.h
# TODO: include when the errors/warnings are bearable
#- run: clang-tidy src/*.c include/*.h
build-linux-amd64:
name: Build for amd64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.build.outputs.DESCR }}
context: Build for amd64
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "libpam0g-dev"
version: 1.0
- id: build
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
HSIZE="$(stat --printf="%s" lidm | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
mv lidm lidm-amd64
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.build.outputs.DESCR }}
context: Build for amd64
- uses: actions/upload-artifact@v4
with:
name: build-amd64
path: lidm-amd64
retention-days: 1
build-linux-i386:
name: Build for i386
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.build.outputs.DESCR }}
context: Build for i386
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "libpam0g-dev gcc-multilib"
version: 1.0
- run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y libpam0g-dev:i386
- id: build
run: |
make -j$(nproc) CFLAGS="-O3 -Wall -m32" 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
HSIZE="$(stat --printf="%s" lidm | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
mv lidm lidm-i386
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.build.outputs.DESCR }}
context: Build for i386
- uses: actions/upload-artifact@v4
with:
name: build-i386
path: lidm-i386
retention-days: 1
build-linux-aarch64:
name: Build for aarch64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for aarch64
- uses: uraimo/run-on-arch-action@v2
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-aarch64
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-aarch64 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for aarch64
- uses: actions/upload-artifact@v4
with:
name: build-aarch64
path: lidm-aarch64
retention-days: 1
build-linux-armv7:
name: Build for armv7
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for armv7
- uses: uraimo/run-on-arch-action@v2
with:
arch: armv7
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-armv7
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-armv7 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for armv7
- uses: actions/upload-artifact@v4
with:
name: build-armv7
path: lidm-armv7
retention-days: 1
build-linux-riscv64:
name: Build for riscv64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for riscv64
- uses: uraimo/run-on-arch-action@v2
with:
arch: riscv64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-riscv64
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-riscv64 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for riscv64
- uses: actions/upload-artifact@v4
with:
name: build-riscv64
path: lidm-riscv64
retention-days: 1

43
.github/workflows/check.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Check
on:
workflow_call:
jobs:
spellcheck:
name: Grammar
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "codespell"
version: 1.0
- run: codespell
shellcheck:
name: Shellcheck
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "shellcheck"
version: 1.0
- run: find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clangcheck:
name: Clang
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "clang-format clang-tidy bear libpam0g-dev"
version: 1.0
- run: bear -- make
- run: clang-format -ni src/*.c include/*.h
- run: clang-tidy -p . src/*.c include/*.h

View File

@@ -1,26 +1,52 @@
name: Check and Build Release
name: Make Release
on:
workflow_dispatch:
inputs:
version:
required: true
default: ''
type: string
jobs:
build:
name: Check and Build
uses: ./.github/workflows/check-and-build.yml
permissions: write-all
with:
set-statuses: false
release:
name: Make Release v${{ inputs.version }}
release-checks:
name: Release Checks
runs-on: ubuntu-24.04
permissions: write-all
needs: build
outputs:
VERSION: ${{ steps.check-ver-changed.outputs.VERSION }}
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- name: Check Version Changed
id: check-ver-changed
run: |
GIT_TAG=$(git describe --no-long --abbrev=0 --tags --always)
MAKE_TAG=$(make print-version)
if [[ "$GIT_TAG" == "v$MAKE_TAG" ]]; then
echo "ERR: Git tag matches makefile, did you bump Makefile up?" >&2
exit 1
fi
echo "VERSION=$MAKE_TAG" >> "$GITHUB_OUTPUT"
check:
name: Check
needs: release-checks
uses: ./.github/workflows/check.yml
permissions: write-all
build:
name: Build
needs: release-checks
uses: ./.github/workflows/build.yml
permissions: write-all
release:
name: Make Release v${{ needs.release-checks.outputs.VERSION }}
runs-on: ubuntu-24.04
permissions: write-all
needs: [ release-checks, check, build ]
steps:
- uses: actions/download-artifact@v4
with:
@@ -30,7 +56,7 @@ jobs:
- uses: ncipollo/release-action@v1
with:
tag: v${{ inputs.version }}
tag: v${{ needs.release-checks.outputs.VERSION }}
commit: ${{ github.sha }}
artifacts: builds/lidm-*
artifactErrorsFailBuild: true
@@ -41,7 +67,7 @@ jobs:
runs-on: ubuntu-24.04
container: archlinux:latest
permissions: write-all
needs: release
needs: [ release-checks, release ]
steps:
- run: pacman -Sy --noconfirm git github-cli base-devel pacman-contrib
@@ -53,20 +79,20 @@ jobs:
cd "assets/pkg/aur"
chown nobody:nobody . -R
su - -s /bin/bash nobody -c "$PWD/update-pkgs.sh ${{ inputs.version }}"
su - -s /bin/bash nobody -c "$PWD/update-pkgs.sh ${{ needs.release-checks.outputs.VERSION }}"
su - -s /bin/bash nobody -c "$PWD/test-makepkg.sh" # This will also update -git pkgver
chown $UID:$(id -g) . -R
- run: |
BRANCH=actions/update-aur-${{ inputs.version }}
BRANCH=actions/update-aur-${{ needs.release-checks.outputs.VERSION }}
git config --global --add safe.directory $GITHUB_WORKSPACE
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git checkout -b $BRANCH
git commit -am "Update AUR pkgs to v${{ inputs.version }}"
git commit -am "Update AUR pkgs to v${{ needs.release-checks.outputs.VERSION }}"
git push -u origin $BRANCH
gh pr create --head $BRANCH \
--title "[AUR update]: Bump to ${{ inputs.version }}" \
--title "[AUR update]: Bump to ${{ needs.release-checks.outputs.VERSION }}" \
--body "*This PR was created automatically*"
env:
GH_TOKEN: ${{ github.token }}

View File

@@ -1,5 +1,4 @@
# Kinda based by https://github.com/myrotvorets/set-commit-status-action/actions/runs/12344741285/workflow
name: Push Checks
name: _
on:
push:
@@ -9,7 +8,11 @@ on:
workflow_dispatch:
jobs:
check-and-build:
name: Check and Build
uses: ./.github/workflows/check-and-build.yml
check:
name: Check
uses: ./.github/workflows/check.yml
permissions: write-all
build:
name: Build
uses: ./.github/workflows/build.yml
permissions: write-all

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ valgrind-out.txt
# nix build result
result
include/version.h

View File

@@ -39,9 +39,15 @@ make install-service
# or if you don't like autodetection
make install-service-systemd # systemd
make install-service-dinit # dinit
make install-service-runit # runit
make install-service-runit # runit (/etc/sv)
make install-service-runit-etc # runit (/etc/runit/sv)
make install-service-openrc # openrc
make install-service-s6 # s6
make install-service-s6 # s6 (/etc/sv)
make install-service-s6-etc # s6 (/etc/s6/sv)
# For runit and s6, some distros (e.g. Artix) like to put it in /etc/<init>/sv
# to better isolate their packages while other distros (e.g. Void) just put it
# in /etc/sv
```
# AUR

106
Makefile
View File

@@ -1,3 +1,6 @@
VERSION = 1.2.1
.DEFAULT_GOAL := lidm
CDIR=src
LDIR=lib
IDIR=include
@@ -7,17 +10,29 @@ PREFIX=/usr
CC?=gcc
CFLAGS?=-O3 -Wall
_CFLAGS=-I$(DIR)
ALLFLAGS=$(CFLAGS) -I$(IDIR)
LIBS=-lpam
_DEPS = log.h util.h ui.h ui_state.h config.h desktop.h auth.h ofield.h efield.h keys.h users.h sessions.h chvt.h macros.h
_DEPS = version.h log.h util.h ui.h ui_state.h config.h desktop.h auth.h ofield.h efield.h keys.h users.h sessions.h chvt.h macros.h launch_state.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o log.o util.o ui.o ui_state.o config.o desktop.o auth.o ofield.o efield.o users.o sessions.o chvt.o
_OBJ = main.o log.o util.o ui.o ui_state.o config.o desktop.o auth.o ofield.o efield.o users.o sessions.o chvt.o launch_state.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
.git/HEAD:
$(IDIR)/version.h: Makefile .git/HEAD
@tmp=$$(mktemp); \
printf '' > $$tmp; \
echo '#define LIDM_VERSION "'$(VERSION)'"' >> $$tmp; \
echo '#define LIDM_GIT_REV "'$$(git describe --long --tags --always || echo '?')'"' >> $$tmp; \
echo '#define LIDM_BUILD_TS '$$(date +%s) >> $$tmp; \
if ! cmp -s $$tmp $@; then \
mv $$tmp $@; \
fi; \
rm -f $$tmp;
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
@mkdir -p $(ODIR)
$(CC) -c -o $@ $< $(ALLFLAGS)
@@ -25,7 +40,6 @@ $(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
lidm: $(OBJ)
$(CC) -o $@ $^ $(ALLFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o lidm
@@ -33,14 +47,14 @@ clean:
install: lidm
mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${PREFIX}/share/man/man{1,5}
install -Dm755 ./lidm ${DESTDIR}${PREFIX}/bin/
install -Dm644 ./themes/default.ini ${DESTDIR}/etc/lidm.ini
[ -f ${DESTDIR}/etc/lidm.ini ] || install -Dm644 ./themes/default.ini ${DESTDIR}/etc/lidm.ini
install -Dm644 ./assets/man/lidm.1 ${DESTDIR}${PREFIX}/share/man/man1/
install -Dm644 ./assets/man/lidm-config.5 ${DESTDIR}${PREFIX}/share/man/man5/
uninstall:
rm -rf ${DESTDIR}${PREFIX}/bin/lidm ${DESTDIR}/etc/lidm.ini
rm -rf ${DESTDIR}/usr/share/man/man{1/lidm.1,5/lidm-config.5}.gz
rm -rf /etc/systemd/system/lidm.service /etc/dinit.d/lidm /etc/runit/sv/lidm
rm -rf ${DESTDIR}/etc/systemd/system/lidm.service ${DESTDIR}/etc/dinit.d/lidm ${DESTDIR}/etc/runit/sv/lidm
install-service:
@if command -v systemctl &> /dev/null; then \
@@ -48,33 +62,91 @@ install-service:
elif command -v dinitctl &> /dev/null; then \
make install-service-dinit; \
elif command -v sv &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-runit; \
elif [ -d /etc/runit/sv ]; then \
make install-service-runit-etc; \
else \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
elif command -v rc-update &> /dev/null; then \
make install-service-openrc; \
elif command -v s6-service &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-s6; \
elif [ -d /etc/r6nit/sv ]; then \
make install-service-s6-etc; \
else \
printf '\x1b[1;31m%s\x1b[0m\n' "Unknown init system, skipping service install..."; \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
else \
printf '\033[1;31m%s\033[0m\n' "Unknown init system, skipping service install..." >&2; \
fi
install-service-systemd:
install -m644 ./assets/services/systemd.service /etc/systemd/system/lidm.service
@printf '\x1b[1m%s\x1b[0m\n\n' " don't forget to run 'systemctl enable lidm'"
install -m644 ./assets/services/systemd.service ${DESTDIR}/etc/systemd/system/lidm.service
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'systemctl enable lidm'"
install-service-dinit:
install -m644 ./assets/services/dinit /etc/dinit.d/lidm
@printf '\x1b[1m%s\x1b[0m\n\n' " don't forget to run 'dinitctl enable lidm'"
install -m644 ./assets/services/dinit ${DESTDIR}/etc/dinit.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'dinitctl enable lidm'"
install-service-runit:
rsync -a --no-owner --no-group ./assets/services/runit/. /etc/runit/sv/lidm
@printf '\x1b[1m%s\x1b[0m\n\n' " don't forget to run 'ln -s /etc/runit/sv/lidm /run/runit/service' and 'sv enable lidm'"
@if [ ! -e /etc/sv ] && [ -d /etc/runit/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/runit/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/sv/lidm /var/service' or your distro equivalent"
install-service-runit-etc:
@if [ ! -e /etc/runit/sv ] && [ -d /etc/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/runit/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/runit/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/runit/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/runit/sv/lidm /run/runit/service' or your distro equivalent"
install-service-openrc:
install -m755 ./assets/services/openrc /etc/init.d/lidm
@printf '\x1b[1m%s\x1b[0m\n\n' " don't forget to run 'rc-update add lidm'"
install -m755 ./assets/services/openrc ${DESTDIR}/etc/init.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'rc-update add lidm'"
install-service-s6:
rsync -a --no-owner --no-group ./assets/services/s6/. /etc/s6/sv/lidm
@printf '\x1b[1m%s\x1b[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
@if [ ! -e /etc/sv ] && [ -d /etc/s6/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/s6/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
install-service-s6-etc:
@if [ ! -e /etc/s6/sv ] && [ -d /etc/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/s6/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/s6/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/s6/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
pre-commit:
codespell
find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clang-format -i $$(git ls-files "*.c" "*.h")
clang-tidy -p . $$(git ls-files "*.c" "*.h")
print-version:
@echo $(VERSION)
.PHONY: clean \
install uninstall \
install-service \
install-service-s6 \
install-service-s6-etc \
install-service-dinit \
install-service-runit \
install-service-runit-etc \
install-service-openrc \
install-service-systemd \
pre-commit \
print-version

5
aaaa/etc/sv/lidm/conf Executable file
View File

@@ -0,0 +1,5 @@
BAUD_RATE=38400
TERM_NAME=linux
TTY=tty7
EXEC_PATH=/bin/lidm

5
aaaa/etc/sv/lidm/finish Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
[ -r conf ] && . ./conf
exec utmpset -w $TTY

15
aaaa/etc/sv/lidm/run Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
[ -r conf ] && . ./conf
if [ -x /sbin/getty -o -x /bin/getty ]; then
# busybox
GETTY=getty
elif [ -x /sbin/agetty -o -x /bin/agetty ]; then
# util-linux
GETTY=agetty
fi
exec setsid ${GETTY} ${GETTY_ARGS} \
"${TTY}" "${TERM_NAME}" \
-n -l "${EXEC_PATH}" -o 7

47
assets/github_scripts/build.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail
if [ -z "$ARCH" ]; then
echo "\$ARCH not present" >&2
exit 1
fi
ERR=0
# shellcheck disable=SC2034
make -j"$(nproc)" "$@" 2> /tmp/stderr || ERR=$?
BSIZE=$(stat --printf="%s" lidm)
HSIZE=$(numfmt --to=iec-i<<<"$BSIZE")B
WARNS=$(
{ grep -E '^[^ ]+\.[ch]:[0-9]+:[0-9]+: [a-z]+:' /tmp/stderr || :; } \
| sed -E 's/^([^ ]+\.[ch]):([0-9]+):([0-9]+): ([a-z]+): (.*)$/::\4 file=\1,line=\2,col=\3::\5/'
)
WARNS_NUM=$({ [[ "$WARNS" == "" ]] && echo 0; } || wc -l <<<"$WARNS")
echo "$WARNS"
{
echo "# Build for $ARCH"
echo ""
if [ -s "/tmp/stderr" ]; then
echo "<details><summary><code>stderr</code></summary>"
echo ""
echo "\`\`\`"
cat "/tmp/stderr"
echo "\`\`\`"
echo ""
echo "</details>"
else
echo "*no \`stderr\` to show*"
fi
echo ""
echo "## Stats"
echo "* **Filesize:** $HSIZE ($BSIZE B)"
echo "* **Warnings & Errors:** $WARNS_NUM"
} >> "$GITHUB_STEP_SUMMARY"
if [ "$ERR" -ne 0 ]; then exit "$ERR"; fi
mv lidm lidm-"$ARCH"
echo "DESCR='$HSIZE, $WARNS_NUM warnings'" >> "$GITHUB_OUTPUT"

View File

@@ -86,6 +86,9 @@ Text to display as the header for such sessions.
.TP
\fBopts_pre, opts_post\fP
To be used for items with multiple options on the left and right sides \fB"< "\fP and \fB" >"\fP.
.TP
\fBellipsis\fP
Ellipsis to be used in multiple parts such as overflowing hostnames.
.SS behavior
Other miscellaneous behavior strings, of mixed types
@@ -98,6 +101,9 @@ Types \fBSTRING_ARRAY\fP. Specify paths to source on login if they exist, simple
.TP
\fBtimefmt\fP
Specify the time format string to be displayed. Check \fBstrftime (3)\fP to know the possible formatting variables.
.TP
\fBrefresh_rate\fP
Rate (in milliseconds) at which the UI should refresh, affects clock and resize behavior.
.SH "SEE ALSO"

View File

@@ -1,6 +1,6 @@
pkgbase = lidm-bin
pkgdesc = A fully colorful customizable TUI display manager made in C. (release binary)
pkgver = 0.2.2
pkgver = 1.2.0
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = x86_64
@@ -8,13 +8,13 @@ pkgbase = lidm-bin
depends = pam
provides = lidm
conflicts = lidm
source = lidm::https://github.com/javalsai/lidm/releases/download/v0.2.2/lidm-amd64
source = default-theme.ini::https://raw.githubusercontent.com/javalsai/lidm/v0.2.2/themes/default.ini
source = lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v0.2.2/assets/man/lidm.1
source = lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v0.2.2/assets/man/lidm-config.5
sha256sums = be2307be9bef7b3ef294fb0e8178040e2d8ccff6b8efb7546514da8b0f69c179
sha256sums = 68662430a6d262b35cc54d9f0e164ed935b7f7f4497a87cc94946c558bbe8a91
sha256sums = a6807a55ff72ec5a5678583156b3efd0d367f0bcb79854094132771f0cb86bce
sha256sums = 3adaae60f79dff1cef2b2aba7dcea04196cd49816759ad36afb9f7331ac9c3e4
source = lidm::https://github.com/javalsai/lidm/releases/download/v1.2.0/lidm-amd64
source = default-theme.ini::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/themes/default.ini
source = lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/assets/man/lidm.1
source = lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/assets/man/lidm-config.5
sha256sums = 6bf4403c21bd26607302d99d7bd1a129822e7d2506e949fb483ea445e022eb6d
sha256sums = ffaa5fe2cf5011bf53c90f81bfec8585158d35f72c0666db0bd4d3866ae041ca
sha256sums = 7f2fb91f55088be1a9b1c93ecf5d6c1e437f369b56df2eacc9d10b00c93c39f8
sha256sums = 0aa5755bdcc60ea80cd9ee0f89233ffaf22c6cee9db9da277274a62c6ed477d9
pkgname = lidm-bin

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-bin
pkgver=0.2.2
pkgver=1.2.0
pkgrel=1
depends=('pam')
pkgdesc="A fully colorful customizable TUI display manager made in C. (release binary)"
@@ -16,10 +16,10 @@ source=(
"lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v$pkgver/assets/man/lidm.1"
"lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v$pkgver/assets/man/lidm-config.5"
)
sha256sums=('be2307be9bef7b3ef294fb0e8178040e2d8ccff6b8efb7546514da8b0f69c179'
'68662430a6d262b35cc54d9f0e164ed935b7f7f4497a87cc94946c558bbe8a91'
'a6807a55ff72ec5a5678583156b3efd0d367f0bcb79854094132771f0cb86bce'
'3adaae60f79dff1cef2b2aba7dcea04196cd49816759ad36afb9f7331ac9c3e4')
sha256sums=('6bf4403c21bd26607302d99d7bd1a129822e7d2506e949fb483ea445e022eb6d'
'ffaa5fe2cf5011bf53c90f81bfec8585158d35f72c0666db0bd4d3866ae041ca'
'7f2fb91f55088be1a9b1c93ecf5d6c1e437f369b56df2eacc9d10b00c93c39f8'
'0aa5755bdcc60ea80cd9ee0f89233ffaf22c6cee9db9da277274a62c6ed477d9')
package() {
install -Dm755 lidm "${pkgdir}/usr/bin/lidm"

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-git
pkgver=0.2.2.r0.gb22ae6b
pkgver=1.2.0.r0.g7f75b8e
pkgrel=1
depends=('pam')
makedepends=('git' 'make' 'gcc')

View File

@@ -1,6 +1,6 @@
pkgbase = lidm
pkgdesc = A fully colorful customizable TUI display manager made in C. (build latest tag)
pkgver = 0.2.2
pkgver = 1.2.0
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = any
@@ -8,7 +8,7 @@ pkgbase = lidm
makedepends = git
makedepends = gcc
depends = pam
source = tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v0.2.2.tar.gz
sha256sums = 25523abc3ce6f2f261bff0cc52663607fe114692d6d3736f27fd843cae3f3a27
source = tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v1.2.0.tar.gz
sha256sums = 0dffded5fcef45cb45fe88358b0cba8de04f614e323a9c6e4162f84b6e3a50b6
pkgname = lidm

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm
pkgver=0.2.2
pkgver=1.2.0
pkgrel=1
depends=('pam')
makedepends=('git' 'gcc')
@@ -10,7 +10,7 @@ arch=('any')
url="https://github.com/javalsai/lidm"
license=('GPL')
source=("tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v$pkgver.tar.gz")
sha256sums=('25523abc3ce6f2f261bff0cc52663607fe114692d6d3736f27fd843cae3f3a27')
sha256sums=('0dffded5fcef45cb45fe88358b0cba8de04f614e323a9c6e4162f84b6e3a50b6')
build() {
tar -xzf "tarball.tar.gz"

View File

@@ -4,7 +4,7 @@ This folder contains the files necessary to set up lidm on start up for the supp
If you don't know what a init system is, you're certainly using `systemd`.
There's make scripts to automatically copy the service files to the proper locations, you just have to run `make install-service-$INIT`. `make install-service` will attempt to detect the init system in use and install for it.
There's make scripts to automatically copy the service files to the proper locations, you just have to run `make install-service-$INIT` (or `make install-service-$INIT-etc`). `make install-service` will attempt to detect the init system in use and install for it.
The manual steps for installation are:

3
debug/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Debug
This folder contains debug utils like gdb scripts. They are not guaranteed to work but can ease some tasks when debugging.

59
debug/debug.gdb Normal file
View File

@@ -0,0 +1,59 @@
# this just meant to run in another term, is probably better to attach to another already running window
set inferior-tty /dev/pts/7
set pagination off
break *(read_press + 62)
define fake_read
set *((char*) $rsi) = $al
set $rax = 1
jump *(read_press + 67)
end
break *(read_press + 108)
define fake_magic_cont
set $eax = 1
jump *(read_press + 113)
end
define fake_magic_end
set $eax = 0
jump *(read_press + 113)
end
run
set $al = 0x1b
fake_read
fake_magic_cont
set $al = '['
fake_read
fake_magic_cont
set $al = 'D'
fake_read
fake_magic_end
set $al = 'p'
fake_read
fake_magic_end
set $al = 'a'
fake_read
fake_magic_end
set $al = 's'
fake_read
fake_magic_end
set $al = 's'
fake_read
fake_magic_end
set $al = 'w'
fake_read
fake_magic_end
set $al = 'd'
fake_read
fake_magic_end
set $al = '\n'
fake_read
fake_magic_end

View File

@@ -11,12 +11,14 @@
enum introspection_type {
STRING,
BOOL,
NUMBER,
KEY,
STRING_ARRAY,
};
static const char* NNULLABLE const INTROS_TYS_NAMES[] = {
[STRING] = "STRING",
[BOOL] = "BOOL",
[NUMBER] = "NUMBER",
[KEY] = "KEY",
[STRING_ARRAY] = "STRING_ARRAY",
};
@@ -104,7 +106,8 @@ BUILD(functions, FUNCTIONS, TABLE_FUNCTIONS);
F(char* NNULLABLE, s_xorg, STRING, "xorg", name) \
F(char* NNULLABLE, s_shell, STRING, "shell", name) \
F(char* NNULLABLE, opts_pre, STRING, "< ", name) \
F(char* NNULLABLE, opts_post, STRING, " >", name)
F(char* NNULLABLE, opts_post, STRING, " >", name) \
F(char* NNULLABLE, ellipsis, STRING, "…", name)
BUILD(strings, STRINGS, TABLE_STRINGS);
@@ -116,7 +119,8 @@ BUILD(strings, STRINGS, TABLE_STRINGS);
F(bool, include_defshell, BOOL, true, name) \
F(struct Vector, source, STRING_ARRAY, NULL_VEC, name) \
F(struct Vector, user_source, STRING_ARRAY, NULL_VEC, name) \
F(char* NNULLABLE, timefmt, STRING, "%X %x", name)
F(char* NNULLABLE, timefmt, STRING, "%X %x", name) \
F(long long, refresh_rate, NUMBER, 100, name)
BUILD(behavior, BEHAVIOR, TABLE_BEHAVIOR);

17
include/launch_state.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef LAUNCHSTATEH_
#define LAUNCHSTATEH_
#include <stdbool.h>
#include <sys/stat.h>
#include "macros.h"
struct LaunchState {
char* NNULLABLE username;
char* NNULLABLE session_opt;
};
int read_launch_state(struct LaunchState* NNULLABLE state);
bool write_launch_state(struct LaunchState state);
#endif

View File

@@ -20,6 +20,16 @@
#define UNULLABLE
#endif
#if defined(__clang__)
#define COMPILER_VERSION __VERSION__
#elif defined(__GNUC__)
#define xstr(s) str(s)
#define str(s) #s
#define COMPILER_VERSION \
"GCC " xstr(__GNUC__) "." xstr(__GNUC_MINOR__) "." xstr(__GNUC_PATCHLEVEL__)
#endif
#define LEN(X) (sizeof(X) / sizeof((X)[0]))
#endif

View File

@@ -1,6 +1,7 @@
#ifndef UTILH_
#define UTILH_
#include <bits/types/struct_timeval.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -12,6 +13,8 @@
int find_keyname(enum keys* at, const char* name);
enum keys find_ansi(const char* seq);
void read_press(u_char* length, char* out);
// non blocking, waits up to tv or interrupt, returns true if actually read
bool read_press_nb(u_char* length, char* out, struct timeval* tv);
bool utf8_iscont(char byte);
size_t utf8len(const char* str);

View File

@@ -121,19 +121,26 @@ void moarEnv(char* user, struct session session, struct passwd* pw,
sourceFileTry((char*)vec_get(&config->behavior.source, i));
}
/* printf("\n"); */
if (pw->pw_dir) {
uint home_len = strlen(pw->pw_dir);
for (size_t i = 0; i < config->behavior.user_source.length; i++) {
char* file2sourcepath = (char*)vec_get(&config->behavior.user_source, i);
size_t newbuf_len = home_len + strlen(file2sourcepath) + 2;
char* newbuf = malloc(newbuf_len); // nullbyte and slash
if (newbuf == NULL) continue; // can't bother
memcpy(newbuf, pw->pw_dir, newbuf_len);
newbuf[home_len] = '/'; // assume pw_dir doesn't start with '/' :P
memcpy(&newbuf[home_len + 1], file2sourcepath, newbuf_len - home_len);
sourceFileTry(newbuf);
free(newbuf);
if (pw->pw_dir) {
const char* home = pw->pw_dir;
size_t home_len = strlen(home);
for (size_t i = 0; i < config->behavior.user_source.length; i++) {
const char* filename = (char*)vec_get(&config->behavior.user_source, i);
size_t filename_len = strlen(filename);
size_t path_len = home_len + 1 + filename_len + 1; // nullbyte and slash
char* path = malloc(path_len);
if (!path) continue; // can't bother
memcpy(path, home, home_len);
path[home_len] = '/'; // assume pw_dir doesn't start with '/' :P
memcpy(&path[home_len + 1], filename, filename_len);
path[path_len - 1] = '\0';
sourceFileTry(path);
free(path);
}
}

View File

@@ -1,10 +1,13 @@
#include <errno.h>
#include <linux/fs.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "config.h"
#include "desktop.h"
@@ -111,6 +114,7 @@ unfinished:
#define NOFAIL return (struct parser_error){NULL, 0}
union typ_ptr {
char** string;
long long* number;
bool* boolean;
enum keys* key;
struct Vector* vec;
@@ -126,7 +130,7 @@ struct parser_error parse_key(enum introspection_type typ, union typ_ptr at,
aux_str = strdup(key);
if (!aux_str) FAIL("allocation failure");
aux_err = parse_str_inplace(aux_str);
if (!aux_err.msg) {
if (aux_err.msg) {
free(aux_str);
return aux_err;
}
@@ -147,6 +151,13 @@ struct parser_error parse_key(enum introspection_type typ, union typ_ptr at,
FAIL("Invalid key value, wasn't 'true' nor 'false'");
}
break;
case NUMBER:
errno = 0;
*at.number = strtol(key, NULL, 10);
if (errno) {
FAIL("strtol failed");
}
break;
case KEY:
// NOLINTNEXTLINE(performance-no-int-to-ptr)
if (find_keyname(at.key, key) != 0) {
@@ -157,7 +168,7 @@ struct parser_error parse_key(enum introspection_type typ, union typ_ptr at,
aux_str = strdup(key);
if (!aux_str) FAIL("allocation failure");
aux_err = parse_str_inplace(aux_str);
if (!aux_err.msg) {
if (aux_err.msg) {
free(aux_str);
return aux_err;
}
@@ -170,7 +181,7 @@ struct parser_error parse_key(enum introspection_type typ, union typ_ptr at,
#undef FAIL
#undef NOFAIL
// NOLINTBEGIN(readability-identifier-length,readability-function-cognitive-complexity,readability-identifier-length)
// NOLINTBEGIN(readability-identifier-length,readability-function-cognitive-complexity)
struct status config_line_handler(void* _config, char* table, char* k,
char* v) {
struct config* config = (struct config*)_config;
@@ -205,6 +216,8 @@ struct status config_line_handler(void* _config, char* table, char* k,
size_t offset = this_intros_table->offset + this_intros_key->offset;
union typ_ptr k_addr = {.ptr = (uintptr_t)config + offset};
log_printf("[I] parsing [%s.%s] as %s\n", table, k,
INTROS_TYS_NAMES[this_intros_key->typ]);
struct parser_error err = parse_key(this_intros_key->typ, k_addr, v, offset);
if (err.msg != NULL) {
log_printf("[E] cfg parser, failed to parse [%s.%s] (%s): %s\n", table, k,
@@ -213,11 +226,16 @@ struct status config_line_handler(void* _config, char* table, char* k,
return ret;
}
if (this_intros_key->typ == NUMBER)
log_printf("[I] cfg parsed [%s.%s] (%lld)\n", table, k, *k_addr.number);
else if (this_intros_key->typ == STRING)
log_printf("[I] cfg parsed [%s.%s] (%s)\n", table, k, *k_addr.string);
else
log_printf("[I] cfg parsed [%s.%s]\n", table, k);
return ret;
}
// NOLINTEND(readability-identifier-length,readability-function-cognitive-complexity,readability-identifier-length)
// NOLINTEND(readability-identifier-length,readability-function-cognitive-complexity)
int parse_config(struct config* NNULLABLE config, char* NNULLABLE path) {
FILE* fd = fopen(path, "r");
@@ -232,9 +250,7 @@ int parse_config(struct config* NNULLABLE config, char* NNULLABLE path) {
bool ret = read_desktop(fd, config, config_line_handler);
(void)fclose(fd);
if (!ret) {
return -1;
}
if (!ret) return -1;
return 0;
}

52
src/launch_state.c Normal file
View File

@@ -0,0 +1,52 @@
// Small file for saving last selection
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "launch_state.h"
#define STATE_DIR "/var/lib/lidm"
#define STATE_FILE "/var/lib/lidm/state"
#define RWXR_X___ 0750
int read_launch_state(struct LaunchState* NNULLABLE state) {
FILE* state_fd = fopen(STATE_FILE, "r");
if (state_fd == NULL) return -1;
*state = (struct LaunchState){
.username = NULL,
.session_opt = NULL,
};
size_t num = 0;
if (getline(&state->username, &num, state_fd) < 0) goto fail;
state->username[strcspn(state->username, "\n")] = 0;
num = 0;
if (getline(&state->session_opt, &num, state_fd) < 0) {
free(state->session_opt);
goto fail;
}
state->session_opt[strcspn(state->session_opt, "\n")] = 0;
(void)fclose(state_fd);
return 0;
fail:
(void)fclose(state_fd);
return -1;
}
bool write_launch_state(struct LaunchState state) {
FILE* state_fd = fopen(STATE_FILE, "w");
if (state_fd == NULL) {
if (mkdir(STATE_DIR, RWXR_X___) == -1) return false;
state_fd = fopen(STATE_FILE, "w");
if (state_fd == NULL) return false;
}
(void)fprintf(state_fd, "%s\n%s\n", state.username, state.session_opt);
(void)fclose(state_fd);
return true;
}

View File

@@ -1,18 +1,23 @@
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "chvt.h"
#include "config.h"
#include "log.h"
#include "macros.h"
#include "sessions.h"
#include "ui.h"
#include "users.h"
#include "util.h"
#include "version.h"
#define DATESTR_MAXBUFSIZE 0x20
int main(int argc, char* argv[]) {
// Logger
char* log_output = getenv("LIDM_LOG");
@@ -27,8 +32,45 @@ int main(int argc, char* argv[]) {
log_init(log_fd);
}
if (argc == 2) {
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
// NOLINTBEGIN(clang-analyzer-deadcode.DeadStores)
char* version = "?";
char* revision = "?";
char* builddate = "?";
char* compilever = "?";
// NOLINTEND(clang-analyzer-deadcode.DeadStores)
#ifdef LIDM_VERSION
version = LIDM_VERSION;
#endif
#ifdef LIDM_GIT_REV
revision = LIDM_GIT_REV;
#endif
#ifdef LIDM_BUILD_TS
time_t ts = LIDM_BUILD_TS;
char date_buf[DATESTR_MAXBUFSIZE];
builddate = date_buf;
if (strftime(date_buf, 0xff, "%Y-%m-%dT%H:%M:%SZ", localtime(&ts)) > 0)
builddate = date_buf;
#endif
#ifdef COMPILER_VERSION
compilever = COMPILER_VERSION;
#endif
printf("lidm version %s (git %s, build date %s, compiler %s)\n", version,
revision, builddate, compilever);
return 0;
}
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
printf(
"Usage: lidm [vt number]\n"
"Options:\n"
" -h, --help Display help menu\n"
" -v, --version Display version information\n");
return 0;
}
// Chvt
if (argc == 2) chvt_str(argv[1]);
chvt_str(argv[1]);
}
struct config config = DEFAULT_CONFIG;
char* conf_override = getenv("LIDM_CONF");

290
src/ui.c
View File

@@ -1,11 +1,13 @@
// i'm sorry
// really sorry
#include <asm-generic/errno.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -20,6 +22,8 @@
#include "auth.h"
#include "efield.h"
#include "keys.h"
#include "launch_state.h"
#include "log.h"
#include "ofield.h"
#include "sessions.h"
#include "ui.h"
@@ -29,21 +33,21 @@
const u_char INPUTS_N = 3;
static void print_box();
static void print_footer();
static void restore_all();
static void signal_handler(int code);
struct uint_point {
uint x;
uint y;
};
static void print_session(struct uint_point origin, struct session session,
bool multiple);
static void print_user(struct uint_point origin, struct user user,
bool multiple);
static void print_passwd(struct uint_point origin, uint length, bool err);
static void print_box();
static void print_head();
static void print_footer();
static void restore_all();
static void signal_handler(int code);
static void print_session(struct session session, bool multiple);
static void print_user(struct user user, bool multiple);
static void print_passwd(uint length, bool err);
static void scratch_print_ui();
// ansi resource: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
static struct termios orig_term;
@@ -52,18 +56,15 @@ static struct winsize window;
#define INNER_BOX_OUT_MARGIN 2
struct config* g_config = NULL;
static volatile sig_atomic_t need_resize = 0;
static void process_sigwinch(int signal) {
need_resize = 1;
}
void setup(struct config* config) {
g_config = config;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
// at least
// 2 padding top and bottom for footer and vertical compensation
// 2 padding left & right to not overflow footer width
if (window.ws_row < BOX_HEIGHT + INNER_BOX_OUT_MARGIN * 2 ||
window.ws_col < BOX_WIDTH + INNER_BOX_OUT_MARGIN * 2) {
(void)fprintf(stderr, "\x1b[1;31mScreen too small\x1b[0m\n");
exit(1);
}
tcgetattr(STDOUT_FILENO, &orig_term);
term = orig_term; // save term
@@ -76,17 +77,13 @@ void setup(struct config* config) {
printf("\x1b[s\x1b[?47h\x1b[%s;%sm\x1b[2J", g_config->colors.bg,
g_config->colors.fg);
print_footer();
(void)atexit(restore_all);
(void)signal(SIGINT, signal_handler);
(void)signal(SIGWINCH, process_sigwinch);
(void)fflush(stdout);
}
static struct uint_point box_start() {
return (struct uint_point){
.x = ((window.ws_col - BOX_WIDTH) / 2) + 1, // looks better
.y = ((window.ws_row - BOX_HEIGHT) / 2), // leave more space under
};
}
static struct uint_point box_start = {.x = 0, .y = 0};
#define STRFTIME_PREALLOC 64
#define TM_YEAR_EPOCH 1900
@@ -98,7 +95,8 @@ static char* fmt_time(const char* fmt) {
char* buf = malloc(alloc_size);
if (!buf) return NULL;
while (true) {
if (strftime(buf, alloc_size, fmt, &tm) != 0) return buf;
if (strftime(buf, alloc_size, fmt, &tm) != 0 && strlen(fmt) != 0)
return buf;
alloc_size *= 2;
char* nbuf = realloc(buf, alloc_size);
@@ -110,10 +108,35 @@ static char* fmt_time(const char* fmt) {
}
}
char* trunc_gethostname(const size_t MAXSIZE, const char* const ELLIPSIS) {
if (utf8len(ELLIPSIS) > MAXSIZE) return NULL;
size_t alloc_size = MAXSIZE + 1;
char* buf = malloc(alloc_size);
if (!buf) return NULL;
while (true) {
if (gethostname(buf, alloc_size) == 0) return buf;
if (errno == ENAMETOOLONG) {
buf[alloc_size] = '\0';
if (utf8len(buf) > MAXSIZE - utf8len(ELLIPSIS)) {
strcpy(&buf[MAXSIZE - utf8len(ELLIPSIS)], ELLIPSIS);
return buf;
}
alloc_size *= 2;
char* nbuf = realloc(buf, alloc_size);
if (!nbuf) goto fail;
buf = nbuf;
} else
goto fail;
}
fail:
free(buf);
return NULL;
}
void ui_update_cursor_focus() {
struct uint_point bstart = box_start();
u_char line = bstart.y;
u_char col = bstart.x + VALUES_COL;
u_char line = box_start.y;
u_char col = box_start.x + VALUES_COL;
struct opts_field* ofield = get_opts_ffield();
u_char maxlen = VALUE_MAXLEN;
@@ -133,19 +156,16 @@ void ui_update_cursor_focus() {
line += PASSWD_ROW;
(void)printf("\x1b[%d;%dH", line, col);
(void)fflush(stdout);
}
void ui_update_field(enum input focused_input) {
struct uint_point origin = box_start();
if (focused_input == PASSWD) {
print_passwd(origin, utf8len(of_passwd.efield.content), false);
print_passwd(utf8len(of_passwd.efield.content), false);
} else if (focused_input == SESSION) {
print_session(origin, st_session(g_config->behavior.include_defshell),
print_session(st_session(g_config->behavior.include_defshell),
of_session.opts > 1);
} else if (focused_input == USER) {
print_user(origin, st_user(), of_user.opts > 1);
print_user(st_user(), of_user.opts > 1);
ui_update_field(SESSION);
}
@@ -170,63 +190,102 @@ void ui_update_ofield(struct opts_field* NNULLABLE self) {
ui_update_field(input);
}
static char* unknown_str = "unknown";
void scratch_print_ui() {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
box_start = (struct uint_point){
.x = ((window.ws_col - BOX_WIDTH) / 2) + 1, // looks better
.y = ((window.ws_row - BOX_HEIGHT) / 2), // leave more space under
};
if (window.ws_row < BOX_HEIGHT + INNER_BOX_OUT_MARGIN * 2 ||
window.ws_col < BOX_WIDTH + INNER_BOX_OUT_MARGIN * 2) {
printf("\033[2J\033[H"); // Clear screen
printf("\x1b[1;31mScreen too small\x1b[0m\n");
printf("\x1b[%s;%sm\x1b[2J", g_config->colors.bg, g_config->colors.fg);
return;
}
printf("\033[2J\033[H"); // Clear screen
/// PRINTING
// printf box
print_box();
print_head();
print_footer();
ui_update_field(SESSION);
ui_update_field(USER);
ui_update_field(PASSWD);
ui_update_cursor_focus();
}
#define MS_PER_S 1000
#define US_PER_MS 1000
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
int load(struct Vector* users, struct Vector* sessions) {
long long ms_time = g_config->behavior.refresh_rate;
ms_time = ms_time < 0 ? 0 : ms_time;
/// SETUP
gusers = users;
gsessions = sessions;
// hostnames larger won't render properly
const u_char HOSTNAME_SIZE = VALUES_COL - VALUES_SEPR - BOX_HMARGIN;
char hostname_buf[HOSTNAME_SIZE];
char* hostname = hostname_buf;
if (gethostname(hostname_buf, HOSTNAME_SIZE) != 0) {
hostname = unknown_str;
} else {
// Ig "successful completion" doesn't contemplate truncation case, so need
// to append the unspecified nullbyte
// char* hidx =
// (char*)utf8back(&hostname[VALUES_COL - VALUES_SEPR - BOX_HMARGIN -
// 1]);
// *hidx = '\0';
}
of_session =
ofield_new(sessions->length + g_config->behavior.include_defshell);
of_user = ofield_new(users->length);
of_passwd = ofield_new(0);
/// PRINTING
const struct uint_point BOXSTART = box_start();
of_user.current_opt = users->length > 0;
of_session.current_opt = sessions->length > 0;
struct LaunchState initial_state;
if (read_launch_state(&initial_state) == 0) {
for (size_t i = 0; i < users->length; i++) {
struct user* user_i = (struct user*)vec_get(users, i);
if (strcmp(user_i->username, initial_state.username) == 0) {
of_user.current_opt = i + 1;
break;
}
}
// printf box
print_box();
for (size_t i = 0; i < sessions->length; i++) {
struct session* session_i = (struct session*)vec_get(sessions, i);
if (strcmp(session_i->name, initial_state.session_opt) == 0) {
of_session.current_opt = i + 1;
break;
}
}
if (g_config->behavior.include_defshell) {
if (strcmp(st_user().shell, initial_state.session_opt) == 0)
of_session.current_opt = sessions->length + 1;
}
// put hostname
printf("\x1b[%d;%dH\x1b[%sm%s\x1b[%sm", BOXSTART.y + HEAD_ROW,
BOXSTART.x + VALUES_COL - VALUES_SEPR - (uint)utf8len(hostname),
g_config->colors.e_hostname, hostname, g_config->colors.fg);
free(initial_state.username);
free(initial_state.session_opt);
}
// put date
char* fmtd_time = fmt_time(g_config->behavior.timefmt);
printf("\x1b[%d;%dH\x1b[%sm%s\x1b[%sm", BOXSTART.y + HEAD_ROW,
BOXSTART.x + BOX_WIDTH - 1 - BOX_HMARGIN - (uint)utf8len(fmtd_time),
g_config->colors.e_date, fmtd_time, g_config->colors.fg);
free(fmtd_time);
ui_update_field(SESSION);
ui_update_field(USER);
ui_update_field(PASSWD);
ui_update_cursor_focus();
scratch_print_ui();
/// INTERACTIVE
u_char len;
char seq[0xff];
uint esc = 0;
while (true) {
read_press(&len, seq);
if (need_resize) {
need_resize = 0;
scratch_print_ui();
} else {
// partial refresh
print_head();
ui_update_cursor_focus();
}
struct timeval tv;
tv.tv_usec = (ms_time % MS_PER_S) * US_PER_MS;
tv.tv_sec = ms_time / MS_PER_S;
(void)fflush(stdout);
if (!read_press_nb(&len, seq, &tv)) continue;
if (*seq == '\x1b') {
enum keys ansi_code = find_ansi(seq);
if (ansi_code != -1) {
@@ -254,10 +313,16 @@ int load(struct Vector* users, struct Vector* sessions) {
}
} else {
if (len == 1 && *seq == '\n') {
bool successful_write = write_launch_state((struct LaunchState){
.username = st_user().username,
.session_opt = st_session(g_config->behavior.include_defshell).name,
});
if (!successful_write) log_puts("[E] failed to write launch state");
if (!launch(st_user().username, of_passwd.efield.content,
st_session(g_config->behavior.include_defshell),
&restore_all, g_config)) {
print_passwd(box_start(), utf8len(of_passwd.efield.content), true);
print_passwd(utf8len(of_passwd.efield.content), true);
ui_update_cursor_focus();
}
} else
@@ -283,9 +348,30 @@ u_char get_render_pos_offset(struct opts_field* self, u_char maxlen) {
return pos - ofield_display_cursor_col(self, maxlen);
}
void print_session(struct uint_point origin, struct session session,
bool multiple) {
clean_line(origin, SESSION_ROW);
#define HOSTNAME_SIZE (VALUES_COL - VALUES_SEPR - BOX_HMARGIN - 1)
void print_head() {
// hostname doesn't just change on runtime
static char* hostname = NULL;
if (!hostname)
hostname = trunc_gethostname(HOSTNAME_SIZE, g_config->strings.ellipsis);
if (!hostname) hostname = "unknown";
clean_line(box_start, HEAD_ROW);
// put hostname
printf("\x1b[%dG\x1b[%sm%s\x1b[%sm",
box_start.x + VALUES_COL - VALUES_SEPR - (uint)utf8len(hostname),
g_config->colors.e_hostname, hostname, g_config->colors.fg);
// put date
char* fmtd_time = fmt_time(g_config->behavior.timefmt);
printf("\x1b[%dG\x1b[%sm%s\x1b[%sm",
box_start.x + BOX_WIDTH - 1 - BOX_HMARGIN - (uint)utf8len(fmtd_time),
g_config->colors.e_date, fmtd_time, g_config->colors.fg);
free(fmtd_time);
}
void print_session(struct session session, bool multiple) {
clean_line(box_start, SESSION_ROW);
const char* NNULLABLE session_type;
if (session.type == XORG) {
@@ -300,9 +386,9 @@ void print_session(struct uint_point origin, struct session session,
// already in the box, - 1 bcs no need to step over margin, same reasoning in
// other places
printf(
"\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR - utf8len(session_type) - 1),
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(session_type) - 1),
g_config->colors.e_header, session_type, g_config->colors.fg);
char* session_color;
@@ -321,21 +407,21 @@ void print_session(struct uint_point origin, struct session session,
toprint += get_render_pos_offset(&of_session, maxlen);
size_t printlen = utf8seekn(toprint, maxlen) - toprint;
printf("\r\x1b[%dC%s\x1b[%sm%.*s\x1b[%sm%s", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC%s\x1b[%sm%.*s\x1b[%sm%s", box_start.x + VALUES_COL - 1,
g_config->strings.opts_pre, session_color, (int)printlen, toprint,
g_config->colors.fg, g_config->strings.opts_post);
} else {
toprint += get_render_pos_offset(&of_session, VALUE_MAXLEN);
size_t printlen = utf8seekn(toprint, VALUE_MAXLEN) - toprint;
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", box_start.x + VALUES_COL - 1,
session_color, (int)printlen, toprint, g_config->colors.fg);
}
}
void print_user(struct uint_point origin, struct user user, bool multiple) {
clean_line(origin, USER_ROW);
void print_user(struct user user, bool multiple) {
clean_line(box_start, USER_ROW);
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR -
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(g_config->strings.e_user) - 1),
g_config->colors.e_header, g_config->strings.e_user,
g_config->colors.fg);
@@ -349,21 +435,21 @@ void print_user(struct uint_point origin, struct user user, bool multiple) {
toprint += get_render_pos_offset(&of_session, maxlen);
size_t printlen = utf8seekn(toprint, maxlen) - toprint;
printf("\r\x1b[%dC< \x1b[%sm%.*s\x1b[%sm >", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC< \x1b[%sm%.*s\x1b[%sm >", box_start.x + VALUES_COL - 1,
user_color, (int)printlen, toprint, g_config->colors.fg);
} else {
toprint += get_render_pos_offset(&of_user, VALUE_MAXLEN);
size_t printlen = utf8seekn(toprint, VALUE_MAXLEN) - toprint;
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", box_start.x + VALUES_COL - 1,
user_color, (int)printlen, toprint, g_config->colors.fg);
}
}
void print_passwd(struct uint_point origin, uint length, bool err) {
void print_passwd(uint length, bool err) {
char passwd_prompt[VALUE_MAXLEN + 1];
clean_line(origin, PASSWD_ROW);
clean_line(box_start, PASSWD_ROW);
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR -
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(g_config->strings.e_passwd) - 1),
g_config->colors.e_header, g_config->strings.e_passwd,
g_config->colors.fg);
@@ -379,7 +465,7 @@ void print_passwd(struct uint_point origin, uint length, bool err) {
memset(passwd_prompt, '*', actual_len);
passwd_prompt[VALUE_MAXLEN] = '\0';
printf("\r\x1b[%dC\x1b[%sm", origin.x + VALUES_COL - 1, pass_color);
printf("\r\x1b[%dC\x1b[%sm", box_start.x + VALUES_COL - 1, pass_color);
printf("%s", passwd_prompt);
printf("\x1b[%sm", g_config->colors.fg);
@@ -403,9 +489,8 @@ static void print_row(uint wid, uint n, char* edge1, char* edge2,
}
static void print_box() {
const struct uint_point BSTART = box_start();
printf("\x1b[%d;%dH\x1b[%sm", BSTART.y, BSTART.x, g_config->colors.e_box);
printf("\x1b[%d;%dH\x1b[%sm", box_start.y, box_start.x,
g_config->colors.e_box);
print_row(BOX_WIDTH - 2, 1, g_config->chars.ctl, g_config->chars.ctr,
g_config->chars.hb);
print_empty_row(BOX_WIDTH - 2, BOX_HEIGHT - 2, g_config->chars.vb,
@@ -413,7 +498,6 @@ static void print_box() {
print_row(BOX_WIDTH - 2, 1, g_config->chars.cbl, g_config->chars.cbr,
g_config->chars.hb);
printf("\x1b[%sm", g_config->colors.fg);
(void)fflush(stdout);
}
static void print_footer() {
@@ -437,24 +521,21 @@ static void print_footer() {
KEY_NAMES[g_config->functions.reboot],
KEY_NAMES[g_config->functions.refresh], g_config->strings.f_poweroff,
g_config->strings.f_reboot, g_config->strings.f_refresh);
(void)fflush(stdout);
}
void print_err(const char* msg) {
struct uint_point origin = box_start();
(void)fprintf(stderr, "\x1b[%d;%dH%s(%d): %s", origin.y - 1, origin.x, msg,
errno, strerror(errno));
(void)fprintf(stderr, "\x1b[%d;%dH%s(%d): %s", box_start.y - 1, box_start.x,
msg, errno, strerror(errno));
}
void print_errno(const char* descr) {
struct uint_point origin = box_start();
if (descr == NULL)
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%smunknown error(%d): %s",
origin.y - 1, origin.x, g_config->colors.err, errno,
box_start.y - 1, box_start.x, g_config->colors.err, errno,
strerror(errno));
else {
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%sm%s(%d): %s", origin.y - 1,
origin.x, g_config->colors.err, descr, errno,
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%sm%s(%d): %s", box_start.y - 1,
box_start.x, g_config->colors.err, descr, errno,
strerror(errno));
}
}
@@ -462,7 +543,6 @@ void print_errno(const char* descr) {
void restore_all() {
// restore cursor pos, restore screen and show cursor
(void)printf("\x1b[u\x1b[?47l\x1b[?25h");
(void)fflush(stdout);
tcsetattr(STDOUT_FILENO, TCSANOW, &orig_term);
}

View File

@@ -1,3 +1,5 @@
#include <asm-generic/errno-base.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -53,6 +55,18 @@ void read_press(u_char* length, char* out) {
}
}
bool read_press_nb(u_char* length, char* out, struct timeval* tv) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
errno = 0;
int ret = select(STDIN_FILENO + 1, &fds, NULL, NULL, tv);
if (errno || ret <= 0) return false;
read_press(length, out);
return true;
}
// https://stackoverflow.com/a/48040042
static int selret_magic() {
fd_set set;

View File

@@ -38,10 +38,12 @@ e_key = "1;23;38;5;197"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
# timefmt = "%X %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
# timefmt = "%X %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_user = "38;2;148;89;84"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_user = "38;2;211;137;88"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -39,10 +39,12 @@ s_xorg = "X"
s_shell = "$"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "\xef\x80\x97 %X \xef\x84\xb3 %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_key = "32"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_key = "34"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -40,10 +40,12 @@ s_xorg = ""
s_shell = ""
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = " "
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ s_xorg = "xworg"
s_shell = "swell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -39,10 +39,12 @@ s_xorg = "xorg"
s_shell = "sh"
opts_pre = "· "
opts_post = " "
ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"