sxmo_timer.sh: allow suspension while running
To do this, we implement a new sxmo_sleep program that is a sleep but that can wake the device from suspension when the timer expires. Also, stopwatch can perfectly survive a suspension. So we don't have to wakelock on this.
This commit is contained in:
5
Makefile
5
Makefile
@@ -23,6 +23,7 @@ OPENRC:=1
|
||||
CC ?= $(CROSS_COMPILE)gcc
|
||||
PROGRAMS = \
|
||||
programs/sxmo_aligned_sleep \
|
||||
programs/sxmo_sleep \
|
||||
programs/sxmo_vibrate
|
||||
|
||||
DOCS = \
|
||||
@@ -51,7 +52,7 @@ programs/%: programs/%.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f programs/sxmo_aligned_sleep programs/sxmo_vibrate
|
||||
rm -f programs/sxmo_aligned_sleep programs/sxmo_sleep programs/sxmo_vibrate
|
||||
|
||||
install: install-sway install-dwm install-scripts install-docs
|
||||
|
||||
@@ -97,6 +98,8 @@ install-scripts: $(PROGRAMS)
|
||||
|
||||
install -D programs/sxmo_aligned_sleep $(DESTDIR)$(PREFIX)/bin/
|
||||
install -D programs/sxmo_vibrate $(DESTDIR)$(PREFIX)/bin/
|
||||
install -D programs/sxmo_sleep $(DESTDIR)$(PREFIX)/bin/
|
||||
setcap 'cap_wake_alarm=ep' $(DESTDIR)$(PREFIX)/bin/sxmo_sleep
|
||||
|
||||
find $(DESTDIR)$(PREFIX)/share/sxmo/default_hooks/ -type f -exec ./setup_config_version.sh "{}" \;
|
||||
find $(DESTDIR)$(PREFIX)/share/sxmo/appcfg/ -type f -exec ./setup_config_version.sh "{}" \;
|
||||
|
70
programs/sxmo_sleep.c
Normal file
70
programs/sxmo_sleep.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <errno.h> // error handling
|
||||
#include <stdint.h> // uint64_t type
|
||||
#include <stdio.h> // dprintf
|
||||
#include <stdlib.h> // strtol, exit
|
||||
#include <string.h> // strerror, strcmp
|
||||
#include <sys/timerfd.h> // timers
|
||||
#include <unistd.h> // read
|
||||
|
||||
static void error(char *message, int err) {
|
||||
dprintf(2, "%s: %s\n", message, strerror(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(char *cmd, char *msg) {
|
||||
dprintf(2, "Usage: %s [-c <clock-name>] <seconds>\n", cmd);
|
||||
dprintf(2, "%s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint64_t buf;
|
||||
long duration = -1;
|
||||
int time_fd;
|
||||
int clockid = CLOCK_REALTIME;
|
||||
|
||||
struct itimerspec time = {
|
||||
.it_value = { .tv_sec = 0, .tv_nsec = 0 },
|
||||
.it_interval = { .tv_sec = 0, .tv_nsec = 0 }
|
||||
};
|
||||
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
if (0 == strcmp(argv[i], "-c")) {
|
||||
if (argc <= i + 1) {
|
||||
usage(argv[0], "You must pass a clock name.");
|
||||
}
|
||||
if (0 == strcmp(argv[i+1], "realtime")) {
|
||||
clockid = CLOCK_REALTIME;
|
||||
} else if (0 == strcmp(argv[i+1], "monotonic")) {
|
||||
clockid = CLOCK_MONOTONIC;
|
||||
} else if (0 == strcmp(argv[i+1], "boottime")) {
|
||||
clockid = CLOCK_BOOTTIME;
|
||||
} else if (0 == strcmp(argv[i+1], "realtime_alarm")) {
|
||||
clockid = CLOCK_REALTIME_ALARM;
|
||||
} else if (0 == strcmp(argv[i+1], "boottime_alarm")) {
|
||||
clockid = CLOCK_BOOTTIME_ALARM;
|
||||
} else {
|
||||
usage(argv[0], "Unknown clock name.");
|
||||
}
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
duration = strtol(argv[i], NULL, 0);;
|
||||
}
|
||||
|
||||
if (duration <= 0) {
|
||||
usage(argv[0], "You must pass a duration in second.");
|
||||
}
|
||||
|
||||
// Setup timer
|
||||
if ((time_fd = timerfd_create(clockid, TFD_CLOEXEC)) == -1)
|
||||
error("Failed to create timerfd", errno);
|
||||
|
||||
time.it_value.tv_sec = duration;
|
||||
|
||||
if (timerfd_settime(time_fd, 0, &time, NULL) == -1)
|
||||
error("Failed to set timer",errno);
|
||||
|
||||
// Wait for timer
|
||||
read(time_fd, &buf, sizeof(uint64_t));
|
||||
}
|
@@ -6,13 +6,34 @@
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
_finish_timerrun() {
|
||||
_releasealarm
|
||||
exit
|
||||
}
|
||||
|
||||
_setupalarm() {
|
||||
sxmo_sleep -c boottime_alarm "$1" &
|
||||
alarmpid=$!
|
||||
}
|
||||
|
||||
_releasealarm() {
|
||||
if [ -n "$alarmpid" ]; then
|
||||
kill "$alarmpid" 2> /dev/null
|
||||
unset alarmpid
|
||||
fi
|
||||
}
|
||||
|
||||
timerrun() {
|
||||
trap '_finish_timerrun' INT TERM EXIT
|
||||
|
||||
TIME="$(
|
||||
echo "$@" |
|
||||
sed 's/\([^0-9]\)\([0-9]\)/\1+\2/g; s/h/*60m/g; s/m/*60s/g; s/s//g' |
|
||||
bc
|
||||
)"
|
||||
|
||||
_setupalarm "$TIME"
|
||||
|
||||
DATE1="$(($(date +%s) + TIME))";
|
||||
while [ "$DATE1" -ge "$(date +%s)" ]; do
|
||||
printf "%s\r" "$(date -u --date @$((DATE1 - $(date +%s))) +%H:%M:%S)";
|
||||
@@ -20,6 +41,8 @@ timerrun() {
|
||||
done
|
||||
echo "Done with $*"
|
||||
|
||||
_releasealarm
|
||||
|
||||
while : ;
|
||||
do notify-send "Done with $*";
|
||||
sxmo_vibrate 1000 "${SXMO_VIBRATE_STRENGTH:-1}"
|
||||
@@ -27,10 +50,6 @@ timerrun() {
|
||||
done
|
||||
}
|
||||
|
||||
cleanwakelock() {
|
||||
sxmo_wakelock.sh unlock sxmo_"$(basename "$0")"
|
||||
}
|
||||
|
||||
stopwatchrun() {
|
||||
start="$(date +%s)"
|
||||
while : ; do
|
||||
@@ -63,13 +82,9 @@ EOF
|
||||
exit 0
|
||||
;;
|
||||
"Stopwatch")
|
||||
sxmo_wakelock.sh lock sxmo_"$(basename "$0")" infinite
|
||||
trap 'cleanwakelock' INT TERM EXIT
|
||||
sxmo_terminal.sh "$0" stopwatchrun
|
||||
;;
|
||||
*)
|
||||
sxmo_wakelock.sh lock sxmo_"$(basename "$0")" infinite
|
||||
trap 'cleanwakelock' INT TERM EXIT
|
||||
sxmo_terminal.sh "$0" timerrun "$TIMEINPUT"
|
||||
;;
|
||||
esac
|
||||
|
Reference in New Issue
Block a user