Merge pull request #19 from cgie/master

Several features
reverse-branch
Martin Duquesnoy 13 years ago
commit 4e6b4cae8a
  1. 41
      Makefile
  2. 10
      README
  3. 131
      tty-clock.1
  4. 208
      ttyclock.c
  5. 14
      ttyclock.h

@ -5,35 +5,50 @@
SRC = ttyclock.c
CC ?= gcc
BIN = tty-clock
INSTALLPATH = /usr/local/bin/
CFLAGS ?= -O2 -g
CFLAGS += -Wall $(shell pkg-config --cflags ncurses 2>/dev/null)
LIBS = $(shell pkg-config --libs ncurses 2>/dev/null | echo -lncurses)
PREFIX ?= /usr/local
INSTALLPATH = ${DESTDIR}${PREFIX}/bin
MANPATH = ${DESTDIR}${PREFIX}/share/man/man1
ifeq ($(shell sh -c 'which ncurses5-config>/dev/null 2>/dev/null && echo y'), y)
CFLAGS = -Wall -g -I $$(ncurses5-config --includedir)
LDFLAGS = -L $$(ncurses5-config --libdir) $$(ncursesw5-config --libs)
else ifeq ($(shell sh -c 'which ncursesw5-config>/dev/null 2>/dev/null && echo y'), y)
CFLAGS = -Wall -g -I $$(ncursesw5-config --includedir)
LDFLAGS = -L $$(ncursesw5-config --libdir) $$(ncursesw5-config --libs)
endif
tty-clock : ${SRC}
@echo "build ${SRC}"
${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} ${SRC} -o ${BIN} ${LIBS}
@echo "CC ${CFLAGS} ${LDFLAGS} ${SRC}"
@${CC} ${CFLAGS} ${SRC} -o ${BIN} ${LDFLAGS}
install : ${BIN}
@echo "creating target folder in ${DESTDIR}${INSTALLPATH}"
@mkdir -p "${DESTDIR}${INSTALLPATH}"
@echo "installing binary file to ${DESTDIR}${INSTALLPATH}${BIN}"
@cp ${BIN} "${DESTDIR}${INSTALLPATH}"
@chmod 755 "${DESTDIR}${INSTALLPATH}${BIN}"
@echo "installing binary file to ${INSTALLPATH}/${BIN}"
@mkdir -p ${INSTALLPATH}
@cp ${BIN} ${INSTALLPATH}
@chmod 0755 ${INSTALLPATH}/${BIN}
@echo "installing manpage to ${MANPATH}/${BIN}.1"
@mkdir -p ${MANPATH}
@cp ${BIN}.1 ${MANPATH}
@chmod 0644 ${MANPATH}/${BIN}.1
@echo "installed"
uninstall :
@echo "uninstalling binary file (${DESTDIR}${INSTALLPATH}${BIN})"
@rm -f "${DESTDIR}${INSTALLPATH}${BIN}"
@echo "uninstalling binary file (${INSTALLPATH})"
@rm -f ${INSTALLPATH}/${BIN}
@echo "uninstalling manpage (${MANPATH})"
@rm -f ${MANPATH}/${BIN}.1
@echo "${BIN} uninstalled"
clean :
@echo "cleaning ${BIN}"
@rm ${BIN}
@rm -f ${BIN}
@echo "${BIN} cleaned"

@ -1,14 +1,20 @@
usage : tty-clock [-sctrvihDB] [-C [0-7]] [-f format]
usage : tty-clock [-iuvsScbtrahDBxn] [-C [0-7]] [-f format] [-d delay] [-a nsdelay] [-T tty]
-s Show seconds
-S Screensaver mode
-x Show box
-c Set the clock at the center of the terminal
-C [0-7] Set the clock color
-b Use bold colors
-t Set the hour in 12h format
-u Use UTC time
-T tty Display the clock on the specified terminal
-r Do rebound the clock
-f format Set the date format
-n Don't quit on keypress
-v Show tty-clock version
-i Show some info about tty-clock
-h Show this page
-d delay Set the delay between two redraws of the clock
-D Hide date
-B Enable blinking colon
-d delay Set the delay between two redraws of the clock. Default 1s.
-a nsdelay Additional delay between two redraws in nanoseconds. Default 0ns.

@ -0,0 +1,131 @@
.\" This manpage was written by Carla Valenti <valenti.karla@gmail.com>
.\" and Christian Giessen <cgie@informatik.uni-kiel.de> for tty-clock.
.\" In details the command line options displayed by tty-clock -h as
.\" well as the keyboard commands.
.TH "TTY-CLOCK" "1" "October 2013" "" "User Commands"
.SH "NAME"
.LP
tty\-clock \- a terminal digital clock
.SH "SYNOPSIS"
.LP
\fBtty\-clock [\-iuvsScbtrahDBxn] [\-C [\fI0\-7\fB]] [\-f \fIformat\fB] [\-d \fIdelay\fB] [\-a \fInsdelay\fB] \fB[\-T \fItty\fB]\fR
.SH "DESCRIPTION"
.LP
\fItty\-clock\fR displays a simple digital clock on the terminal. Invoked without options
it will display the clock on the upper left corner of the screen on the terminal it was
executed from.
.SH "COMMANDS"
.LP
\fItty\-clock\fR accepts a number of runtime keyboard commands, upper and lower case characters are
treated identically.
.TP
K,J,H,L
vi\-style movement commands to set the position of the displayed clock.
These commands have no effect when the \fBcentered\fR option is set.
.TP
[0\-7]
Select a different color for displaying the clock.
.TP
B
Toggles bewteen bold and normal colors.
.TP
X
Toggles displaying a box around the clock. This option is disabled by default.
.TP
C
Toggle the clock's position to \fBcentered\fR.
When set the movement commands are disabled.
.TP
R
Set the clock to \fBrebound\fR along the edges of the terminal.
.TP
S
Display seconds.
.TP
T
Switch time output to the 12\-hour format.
.TP
Q
Quit.
.SH "OPTIONS"
.LP
.TP
\fB\-s\fR
Show seconds.
.TP
\fB\-S\fR
Screensaver mode. tty\-clock terminates when any key is pressed.
.TP
\fB\-x\fR
Show box.
.TP
\fB\-c\fR
Set the clock at the center of the terminal.
.TP
\fB\-C\fR \fI[0\-7]\fR
Set the clock color.
.TP
\fB\-b\fR
Use bold colors.
.TP
\fB\-t\fR
Set the hour in 12h format.
.TP
\fB\-u\fR
Use UTC time.
.TP
\fB\-T\fR \fItty\fR
Display the clock on the given \fItty\fR. \fItty\fR must be
a valid character device to which the user has rw access permissions.
(See \fBEXAMPLES\fR)
.TP
\fB\-r\fR
Do rebound the clock.
.TP
\fB\-f\fR \fIformat\fR
Set the date format as described in \fBstrftime(3)\fR.
.TP
\fB\-n\fR
Do not quit the program when the Q key is pressed (or when any
key is pressed while in \fBScreensaver\fR mode). A signal must
be sent to \fItty\-clock\fR in order to terminate its execution. (See \fBEXAMPLES\fR)
.TP
\fB\-v\fR
Show tty\-clock version.
.TP
\fB\-i\fR
Show some info about tty\-clock.
.TP
\fB\-h\fR
Show usage information.
.TP
\fB\-D\fR
Hide the date.
.TP
\fB\-B\fR
Enable blinking colon.
.TP
\fB\-d\fR \fIdelay\fR
Set the delay (in seconds) between two redraws of the clock. Default 1s.
.TP
\fB\-a\fR \fInsdelay\fR
Additional delay (in nanoseconds) between two redraws of the clock. Default 0ns.
.SH "EXAMPLES"
.LP
To invoke
.I tty\-clock
in screensaver mode with the clock display set to rebound and the update
delay set to 1/10th of a second (10 FPS):
.IP
$ tty\-clock \-Sra 100000000 \-d 0
.LP
The following example arranges for \fItty\-clock\fR to be displayed
indefinitely on one of the Virtual Terminals on a Linux system
at boot time using an
.B inittab(5)
entry:
.IP
# /etc/inittab:
.br
9:2345:respawn:/usr/bin/tty\-clock \-c \-n \-T /dev/tty9
.LP

@ -39,7 +39,19 @@ init(void)
ttyclock->bg = COLOR_BLACK;
/* Init ncurses */
initscr();
if (ttyclock->tty) {
FILE *ftty = fopen(ttyclock->tty, "r+");
if (!ftty) {
fprintf(stderr, "tty-clock: error: '%s' couldn't be opened: %s.\n",
ttyclock->tty, strerror(errno));
exit(EXIT_FAILURE);
}
ttyclock->ttyscr = newterm(NULL, ftty, ftty);
assert(ttyclock->ttyscr != NULL);
set_term(ttyclock->ttyscr);
} else
initscr();
cbreak();
noecho();
keypad(stdscr, True);
@ -55,6 +67,9 @@ init(void)
init_pair(0, ttyclock->bg, ttyclock->bg);
init_pair(1, ttyclock->bg, ttyclock->option.color);
init_pair(2, ttyclock->option.color, ttyclock->bg);
// init_pair(0, ttyclock->bg, ttyclock->bg);
// init_pair(1, ttyclock->bg, ttyclock->option.color);
// init_pair(2, ttyclock->option.color, ttyclock->bg);
refresh();
/* Init signal handler */
@ -89,18 +104,24 @@ init(void)
ttyclock->geo.w,
ttyclock->geo.x,
ttyclock->geo.y);
box(ttyclock->framewin, 0, 0);
if(ttyclock->option.box) {
box(ttyclock->framewin, 0, 0);
}
/* Create the date win */
if (ttyclock->option.date)
if (ttyclock->option.bold)
{
ttyclock->datewin = newwin(DATEWINH, strlen(ttyclock->date.datestr) + 2,
ttyclock->geo.x + ttyclock->geo.h - 1,
ttyclock->geo.y + (ttyclock->geo.w / 2) -
(strlen(ttyclock->date.datestr) / 2) - 1);
wattron(ttyclock->framewin, A_BLINK);
}
/* Create the date win */
ttyclock->datewin = newwin(DATEWINH, strlen(ttyclock->date.datestr) + 2,
ttyclock->geo.x + ttyclock->geo.h - 1,
ttyclock->geo.y + (ttyclock->geo.w / 2) -
(strlen(ttyclock->date.datestr) / 2) - 1);
if(ttyclock->option.box) {
box(ttyclock->datewin, 0, 0);
clearok(ttyclock->datewin, True);
}
clearok(ttyclock->datewin, True);
set_center(ttyclock->option.center);
@ -141,6 +162,20 @@ signal_handler(int signal)
return;
}
void
cleanup(void)
{
if (ttyclock->ttyscr)
delscreen(ttyclock->ttyscr);
if (ttyclock && ttyclock->tty)
free(ttyclock->tty);
if (ttyclock && ttyclock->option.format)
free(ttyclock->option.format);
if (ttyclock)
free(ttyclock);
}
void
update_hour(void)
{
@ -198,6 +233,12 @@ draw_number(int n, int x, int y)
sy = y;
++x;
}
if (ttyclock->option.bold)
wattron(ttyclock->framewin, A_BLINK);
else
wattroff(ttyclock->framewin, A_BLINK);
wbkgdset(ttyclock->framewin, COLOR_PAIR(number[n][i/2]));
mvwaddch(ttyclock->framewin, x, sy, ' ');
}
@ -242,6 +283,11 @@ draw_clock(void)
draw_number(ttyclock->date.minute[1], 1, 27);
/* Draw the date */
if (ttyclock->option.bold)
wattron(ttyclock->datewin, A_BOLD);
else
wattroff(ttyclock->datewin, A_BOLD);
if (ttyclock->option.date)
{
wbkgdset(ttyclock->datewin, (COLOR_PAIR(2)));
@ -294,13 +340,19 @@ clock_move(int x, int y, int w, int h)
ttyclock->geo.x + ttyclock->geo.h - 1,
ttyclock->geo.y + (ttyclock->geo.w / 2) - (strlen(ttyclock->date.datestr) / 2) - 1);
wresize(ttyclock->datewin, DATEWINH, strlen(ttyclock->date.datestr) + 2);
box(ttyclock->datewin, 0, 0);
wrefresh(ttyclock->datewin);
if (ttyclock->option.box) {
box(ttyclock->datewin, 0, 0);
}
}
box(ttyclock->framewin, 0, 0);
wrefresh(ttyclock->framewin);
if (ttyclock->option.box)
{
box(ttyclock->framewin, 0, 0);
}
wrefresh(ttyclock->framewin);
wrefresh(ttyclock->datewin);
return;
}
@ -359,12 +411,57 @@ set_center(Bool b)
return;
}
void
set_box(Bool b)
{
ttyclock->option.box = b;
wbkgdset(ttyclock->framewin, COLOR_PAIR(0));
wbkgdset(ttyclock->datewin, COLOR_PAIR(0));
if(ttyclock->option.box) {
wbkgdset(ttyclock->framewin, COLOR_PAIR(0));
wbkgdset(ttyclock->datewin, COLOR_PAIR(0));
box(ttyclock->framewin, 0, 0);
box(ttyclock->datewin, 0, 0);
}
else {
wborder(ttyclock->framewin, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
wborder(ttyclock->datewin, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
}
wrefresh(ttyclock->datewin);
wrefresh(ttyclock->framewin);
}
void
key_event(void)
{
int i, c;
struct timespec length = { 0, ttyclock->option.delay };
struct timespec length = { ttyclock->option.delay, ttyclock->option.nsdelay };
if (ttyclock->option.screensaver)
{
c = wgetch(stdscr);
if(c != ERR && ttyclock->option.noquit == False)
{
ttyclock->running = False;
}
else
{
nanosleep(&length, NULL);
for(i = 0; i < 8; ++i)
if(c == (i + '0'))
{
ttyclock->option.color = i;
init_pair(1, ttyclock->bg, i);
init_pair(2, i, ttyclock->bg);
}
}
return;
}
switch(c = wgetch(stdscr))
{
@ -402,7 +499,8 @@ key_event(void)
case 'q':
case 'Q':
ttyclock->running = False;
if (ttyclock->option.noquit == False)
ttyclock->running = False;
break;
case 's':
@ -423,12 +521,23 @@ key_event(void)
set_center(!ttyclock->option.center);
break;
case 'b':
case 'B':
ttyclock->option.bold = !ttyclock->option.bold;
break;
case 'r':
case 'R':
ttyclock->option.rebound = !ttyclock->option.rebound;
if(ttyclock->option.rebound && ttyclock->option.center)
ttyclock->option.center = False;
break;
case 'x':
case 'X':
set_box(!ttyclock->option.box);
break;
default:
nanosleep(&length, NULL);
for(i = 0; i < 8; ++i)
@ -451,47 +560,54 @@ main(int argc, char **argv)
/* Alloc ttyclock */
ttyclock = malloc(sizeof(ttyclock_t));
assert(ttyclock != NULL);
memset(ttyclock, 0, sizeof(ttyclock_t));
ttyclock->option.date = True;
/* Date format */
ttyclock->option.format = malloc(sizeof(char) * 100);
/* Default date format */
strncpy(ttyclock->option.format, "%d/%m/%Y", 100);
strncpy(ttyclock->option.format, "%F", 100);
/* Default color */
ttyclock->option.color = COLOR_GREEN; /* COLOR_GREEN = 2 */
/* Default delay */
ttyclock->option.delay = 40000000; /* 25FPS */
/* Default blink */
ttyclock->option.delay = 1; /* 1FPS */
ttyclock->option.nsdelay = 0; /* -0FPS */
ttyclock->option.blink = False;
while ((c = getopt(argc, argv, "utvsrcihf:DBd:C:")) != -1)
atexit(cleanup);
while ((c = getopt(argc, argv, "iuvsScbtrhBxnDC:f:d:T:a:")) != -1)
{
switch(c)
{
case 'h':
default:
printf("usage : tty-clock [-sctrvihDB] [-C [0-7]] [-f format] \n"
printf("usage : tty-clock [-iuvsScbtrahDBxn] [-C [0-7]] [-f format] [-d delay] [-a nsdelay] [-T tty] \n"
" -s Show seconds \n"
" -S Screensaver mode \n"
" -x Show box \n"
" -c Set the clock at the center of the terminal \n"
" -C [0-7] Set the clock color \n"
" -b Use bold colors \n"
" -t Set the hour in 12h format \n"
" -u Use UTC time \n"
" -T tty Display the clock on the specified terminal \n"
" -r Do rebound the clock \n"
" -f format Set the date format \n"
" -n Don't quit on keypress \n"
" -v Show tty-clock version \n"
" -i Show some info about tty-clock \n"
" -h Show this page \n"
" -d delay Set the delay between two redraws of the clock \n"
" -D Hide date \n"
" -B Enable blinking colon \n");
free(ttyclock);
" -B Enable blinking colon \n"
" -d delay Set the delay between two redraws of the clock. Default 1s. \n"
" -a nsdelay Additional delay between two redraws in nanoseconds. Default 0ns.\n");
exit(EXIT_SUCCESS);
break;
case 'i':
puts("TTY-Clock 2 © by Martin Duquesnoy (xorg62@gmail.com)");
free(ttyclock);
free(ttyclock->option.format);
puts("TTY-Clock 2 © by Martin Duquesnoy (xorg62@gmail.com), Grey (grey@greytheory.net)");
exit(EXIT_SUCCESS);
break;
case 'u':
@ -499,16 +615,20 @@ main(int argc, char **argv)
break;
case 'v':
puts("TTY-Clock 2 © devel version");
free(ttyclock);
free(ttyclock->option.format);
exit(EXIT_SUCCESS);
break;
case 's':
ttyclock->option.second = True;
break;
case 'S':
ttyclock->option.screensaver = True;
break;
case 'c':
ttyclock->option.center = True;
break;
case 'b':
ttyclock->option.bold = True;
break;
case 'C':
if(atoi(optarg) >= 0 && atoi(optarg) < 8)
ttyclock->option.color = atoi(optarg);
@ -523,7 +643,7 @@ main(int argc, char **argv)
strncpy(ttyclock->option.format, optarg, 100);
break;
case 'd':
if(atol(optarg) >= 0 && atol(optarg) < 1000000000)
if(atol(optarg) >= 0 && atol(optarg) < 100)
ttyclock->option.delay = atol(optarg);
break;
case 'D':
@ -532,11 +652,37 @@ main(int argc, char **argv)
case 'B':
ttyclock->option.blink = True;
break;
case 'a':
if(atol(optarg) >= 0 && atol(optarg) < 1000000000)
ttyclock->option.nsdelay = atol(optarg);
break;
case 'x':
ttyclock->option.box = True;
break;
case 'T': {
struct stat sbuf;
if (stat(optarg, &sbuf) == -1) {
fprintf(stderr, "tty-clock: error: couldn't stat '%s': %s.\n",
optarg, strerror(errno));
exit(EXIT_FAILURE);
} else if (!S_ISCHR(sbuf.st_mode)) {
fprintf(stderr, "tty-clock: error: '%s' doesn't appear to be a character device.\n",
optarg);
exit(EXIT_FAILURE);
} else {
if (ttyclock->tty)
free(ttyclock->tty);
ttyclock->tty = strdup(optarg);
}}
break;
case 'n':
ttyclock->option.noquit = True;
break;
}
}
init();
attron(A_BLINK);
while(ttyclock->running)
{
clock_rebound();
@ -545,8 +691,6 @@ main(int argc, char **argv)
key_event();
}
free(ttyclock);
free(ttyclock->option.format);
endwin();
return 0;

@ -33,8 +33,12 @@
#ifndef TTYCLOCK_H_INCLUDED
#define TTYCLOCK_H_INCLUDED
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <ncurses.h>
@ -55,21 +59,30 @@ typedef struct
{
/* while() boolean */
Bool running;
/* terminal variables */
SCREEN *ttyscr;
char *tty;
int bg;
/* Running option */
struct
{
Bool second;
Bool screensaver;
Bool twelve;
Bool center;
Bool rebound;
Bool date;
Bool utc;
Bool box;
Bool noquit;
char *format;
int color;
Bool bold;
long delay;
Bool blink;
long nsdelay;
} option;
/* Clock geometry */
@ -109,6 +122,7 @@ void draw_clock(void);
void clock_move(int x, int y, int w, int h);
void set_second(void);
void set_center(Bool b);
void set_box(Bool b);
void key_event(void);
/* Global variable */

Loading…
Cancel
Save