/* tanimate.c: animate several strings using threads, curses, usleep() * * bigidea one thread for each animated string * one thread for keyboard control * shared variables for communication * compile cc tanimate.c -lcurses -lpthread -o tanimate * to do needs locks for shared variables * nice to put screen handling in its own thread */ #include #include #include #include #include #define MAXMSG 10 /* limit to number of strings */ #define TUNIT 20000 /* timeunits in microseconds */ struct propset { char *str; /* the message */ int row; /* the row */ int delay; /* delay in time units */ int dir; /* +1 or -1 */ }; pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; int main(int ac, char *av[]) { int c; /* user input */ pthread_t thrds[MAXMSG]; /* the threads */ struct propset props[MAXMSG]; /* properties of string */ void *animate(); /* the function */ int num_msg ; /* number of strings */ int i; if ( ac == 1 ){ printf("usage: tanimate string ..\n"); exit(1); } num_msg = setup(ac-1,av+1,props); /* create all the threads */ for(i=0 ; i= '0' && c <= '9' ){ i = c - '0'; if ( i < num_msg ) props[i].dir = -props[i].dir; } } /* cancel all the threads */ pthread_mutex_lock(&mx); for (i=0; i MAXMSG ? MAXMSG : nstrings ); int i; /* assign rows and velocities to each string */ srand(getpid()); for(i=0 ; istr)+2; /* +2 for padding */ int col = rand()%(COLS-len-3); /* space for padding */ while( 1 ) { usleep(info->delay*TUNIT); pthread_mutex_lock(&mx); /* only one thread */ move( info->row, col ); /* can call curses */ addch(' '); /* at a the same time */ addstr( info->str ); /* Since I doubt it is */ addch(' '); /* reentrant */ move(LINES-1,COLS-1); /* park cursor */ refresh(); /* and show it */ pthread_mutex_unlock(&mx); /* done with curses */ /* move item to next column and check for bouncing */ col += info->dir; if ( col <= 0 && info->dir == -1 ) info->dir = 1; else if ( col+len >= COLS && info->dir == 1 ) info->dir = -1; } }