/*
* hello.c
* purpose show the minimal calls needed to use curses
* outline initialize, draw stuff, wait for input, quit
*/#include <stdio.h>
#include <curses.h>
main()
{
initscr(); /* turn on curses *//* send requests */clear(); /* clear screen */move(10, 20); /* row 10, col 20 */addstr("Hello, world"); /* add a string */move(LINES-1, 0); /* move to LL */refresh(); /* update the screen */getch(); /* wait for user input */endwin(); /* trun off curses */
}
/* sleep1.c
* purpose show how sleep works
* usage sleep1
* outline sets handler, sets alarm, pause, then returns
*/#include <stdio.h>#include <signal.h>#define SHHHH
main()
{
void wakeup(int);
printf("about to sleep for 4 seconds\n");
signal(SIGALRM, wakeup); /* catch it */
alarm(4); /* set clock */
pause(); /* freeze here */
printf("Morning so soon? \n"); /* back to work */
}
void wakeup(int signum)
{
#ifdef SHHHH
printf("Alarm received from kernel %d\n", signum);
#endif
}
/* set_ticker( number_of_milliseconds )
* arranges for interval timer to issue SIGALRMs at regular intervals
* returns -1 on error, 0 for ok
* arg in milliseconds, converted into whole seconds and microseconds
* note: set_ticker(0) turns off ticker
*/#include <stdio.h>#include <sys/time.h>int set_ticker(int n_msecs)
{
struct itimerval new_timeset;
long n_sec, n_usecs;
n_sec = n_msecs / 1000; /* int part */
n_usecs = (n_msecs % 1000 ) * 1000L; /* remainder */
new_timeset.it_interval.tv_sec = n_sec; /* set reload */
new_timeset.it_interval.tv_usec = n_usecs; /* new ticker value */
new_timeset.it_value.tv_sec = n_sec; /* store this */
new_timeset.it_value.tv_usec = n_usecs; /* and this */return setitimer(ITIMER_REAL, &new_timeset, NULL);
}
/* ticker_demo.c
* demonstrates use of interval timer to generate reqular
* signals, which are in turn caught and used to count down
*/#include <stdio.h>#include <sys/time.h>#include <signal.h>int main()
{
void countdown(int);
signal(SIGALRM, countdown);
if (set_ticker(500) == -1)
perror("set_ticker");
elsewhile(1)
pause();
return0;
}
void countdown(int signum)
{
staticint num = 10;
printf("%d..", num--);
fflush(stdout);
if(num < 0) {
printf("DONE! \n");
exit(0);
}
}
/* sigactdemo.c
* purpose: shows use of sigaction()
* feature: blocks ^\ while handling ^C
* does not reset ^C handler, so two kill
*/#include <stdio.h>#include <signal.h>#define INPUTLEN 100
main()
{
struct sigaction newhandler; /* new settings */
sigset_t blocked; /* set of blocked sigs */void inthandler(); /* the handler */char x[INPUTLEN];
/* load these two members first */
newhandler.sa_handler = inthandler; /* handler function */
newhandler.sa_flags = SA_RESETHAND | SA_RESTART; /* options *//* then build the list of blocked signals */
sigemptyset(&blocked); /* clear all bits */
sigaddset(&blocked, SIGQUIT); /* add SIGQUIT to list */
newhandler.sa_mask = blocked; /* store blockmask */if (sigaction(SIGINT, &newhandler, NULL) == -1)
perror("sigaction");
elsewhile (1) {
fgets(x, INPUTLEN, stdin);
printf("input: %s", x);
}
}
void inthandler(int s)
{
printf("Called with signal %d\n", s);
sleep(s);
printf("done handling signal %d\n", s);
}
/* digdemo3.c
* purpose: show answers to signal questions
* question1: does the handler stay in effect after a signal arrives?
* question2: what if a signalX arrives while handling signalX?
* question3: what if a signalX arrives while handling signalY?
* quesiong4: what happens to read() when a signal arrives?
*/#include <stdio.h>#include <signal.h>#define INPUTLEN 100
main(int ac, char *av[])
{
void inthandler(int);
void quithandler(int);
char input[INPUTLEN];
int nchars;
signal(SIGINT, inthandler); /* set handler */
signal(SIGQUIT, quithandler); /* set handler */do {
printf("\nType a message\n");
nchars = read(0, input, (INPUTLEN - 1));
if (nchars == -1)
perror("read returned an error");
else {
input[nchars] = '\0';
printf("You typed: %s", input);
}
}
while (strncmp(input, "quit", 4) != 0);
}
void inthandler(ints)
{
printf("Received signal %d..waiting\n", s);
sleep(2);
printf("Leaving inthandle\n");
}
void quithandler(ints)
{
printf("Received signal %d..waiting\n", s);
sleep(3);
printf("Leaving quithandler\n");
}
/* bounce.h *//* some settings for the game */#define BLANK ' '#define DFL_SYMBOL 'o'#define TOP_ROW 5#define BOT_ROW 20#define LEFT_EDGE 10#define RIGHT_EDGE 70#define X_INIT 10 /* starting col */#define Y_INIT 10 /* starting row */#define TICKS_PER_SEC 50 /* affects speed */#define X_TTM 5#define Y_TTM 8/** the ping pong ball **/struct ppball {
int y_pos, x_pos,
y_ttm, x_ttm,
y_ttg, x_ttg,
y_dir, x_dir;
char symbol;
};
/* bounce1d.c
* purpose animation with user contolled speed and direction
* not the handler does the animation
* the main program reads keyboard input
* compile cc bounce1d.c set_ticker.c -lcurses -o bounce1d
*/
#include <stdio.h>
#include <curses.h>
#include <signal.h>
/* some global settings main and the handler use */
#define MESSAGE "hello"
#define BLANK " "int row; /* current row */int col; /* current column */intdir; /* where we are going */int main()
{
int delay; /* bigger => slower */int ndelay; /* new delay */int c; /* user input */
void move_msg(int); /* handler for timer */
initscr();
crmode();
noecho();
clear();
row = 10; /* start here */
col = 0;
dir = 1; /* add 1 to row number */
delay = 200; /* 200ms = 0.2 seconds */move(row, col); /* get into position */
addstr(MESSAGE); /* draw message */
signal(SIGALRM, move_msg);
set_ticker(delay);
while (1)
{
ndelay = 0;
c = getch();
if (c == 'Q') break;
if (c == ' ') dir = -dir;
if (c == 'f' && delay > 2) ndelay = delay / 2;
if (c == 's') ndelay = delay * 2;
if (ndelay > 0)
set_ticker(delay = ndelay);
}
endwin();
return0;
}
void move_msg(int signum)
{
signal(SIGALRM, move_msg); /* reset, just in case */move(row, col);
addstr(BLANK);
col += dir; /* move to new colum */move(row, col); /* then set cursor */
addstr(MESSAGE); /* redo message */
refresh(); /* and show it *//*
* now handle borders
*/if (dir == -1 && col <= 0)
dir = 1;
elseif (dir == 1 && col + strlen(MESSAGE) >= COLS)
dir = -1;
}
/* bounce2d 1.0
* bounce a character (default is 'o') around the screen
* defined by some parameters
*
* user input: s slow down x component, S: slow y component
* f speed up x component, F: speed by component
* Q quit
*
* blocks on read, but timer tick sends SIGALRM caught by ball_move
* build: cc bounce2d.c set_ticker.c -lcurses -o bounce2d
*/
#include <curses.h>
#include <signal.h>
#include "bounce.h"
struct ppball the_ball;
/** the main loop **/void set_up();
void wrap_up();
int main()
{
int c;
set_up();
while ((c = getchar()) != 'Q') {
if (c == 'f') the_ball.x_ttm--;
elseif (c == 's') the_ball.x_ttm++;
elseif (c == 'F') the_ball.x_ttm--;
elseif (c == 'S') the_ball.x_ttm++;
}
wrap_up();
}
void set_up()
/*
* init structure and other stuff
*/
{
void ball_move(int);
the_ball.y_pos = Y_INIT;
the_ball.x_pos = X_INIT;
the_ball.y_ttg = the_ball.y_ttm = Y_TTM;
the_ball.x_ttg = the_ball.x_ttm = X_TTM;
the_ball.y_dir = 1;
the_ball.x_dir = 1;
the_ball.symbol = DFL_SYMBOL;
initscr();
noecho();
crmode();
signal(SIGINT, SIG_IGN);
mvaddch(the_ball.y_pos, the_ball.x_pos, the_ball.symbol);
refresh();
signal(SIGALRM, ball_move);
set_ticker(1000 / TICKS_PER_SEC); /* send millisecs per tick */
}
void wrap_up()
{
set_ticker(0);
endwin(); /* put back to normal */
}
void ball_move(int signum)
{
int y_cur, x_cur, moved;
signal(SIGALRM, SIG_IGN); /* dont get caught now */
y_cur = the_ball.y_pos; /* old spot */
x_cur = the_ball.x_pos;
moved = 0;
if (the_ball.y_ttm > 0 && the_ball.y_ttg-- == 1) {
the_ball.y_pos += the_ball.y_dir; /* move */
the_ball.y_ttg = the_ball.y_ttm; /* reset */
moved = 1;
}
if (the_ball.x_ttm > 0 && the_ball.x_ttg-- == 1) {
the_ball.x_pos += the_ball.x_dir; /* move */
the_ball.x_ttg = the_ball.x_ttm; /* reset */
moved = 1;
}
if (moved) {
mvaddch(y_cur, x_cur, BLANK);
mvaddch(y_cur, x_cur, BLANK);
mvaddch(the_ball.y_pos, the_ball.x_pos, the_ball.symbol);
bounce_or_lose(&the_ball);
move(LINES - 1, COLS - 1);
refresh();
}
signal(SIGALRM, ball_move); /* for unreliable systems */
}
int bounce_or_lose(struct ppball *bp)
{
int return_val = 0;
if (bp->y_pos == TOP_ROW) {
bp->y_dir = 1;
return_val = 1;
} elseif (bp->y_pos == BOT_ROW) {
bp->y_dir = -1;
return_val = 1;
}
if (bp->x_pos == LEFT_EDGE) {
bp->x_dir = 1;
return_val = 1;
} elseif (bp->x_pos == RIGHT_EDGE) {
bp->x_dir = -1;
return_val = 1;
}
return return_val;
}
/* set_ticker( number_of_milliseconds )
* arranges for interval timer to issue SIGALRMs at regular intervals
* returns -1 on error, 0 for ok
* arg in milliseconds, converted into whole seconds and microseconds
* note: set_ticker(0) turns off ticker
*/#include <stdio.h>#include <sys/time.h>int set_ticker(int n_msecs)
{
struct itimerval new_timeset;
long n_sec, n_usecs;
n_sec = n_msecs / 1000; /* int part */
n_usecs = (n_msecs % 1000 ) * 1000L; /* remainder */
new_timeset.it_interval.tv_sec = n_sec; /* set reload */
new_timeset.it_interval.tv_usec = n_usecs; /* new ticker value */
new_timeset.it_value.tv_sec = n_sec; /* store this */
new_timeset.it_value.tv_usec = n_usecs; /* and this */return setitimer(ITIMER_REAL, &new_timeset, NULL);
}