rendered paste body/* Sean Bradly - 2009 */#include <stdio.h>#include <stdlib.h> #include <time.h> /* for nanosleep */#include <curses.h> /* for nonblocking getch */#include <sys/io.h> /* for ioperm and outb *//* Check with /proc/ioports to make sure this io-mapping is correct */#define LPT0 0x03bc/* Modify depending on what pins you attached LEDs to */#define RED ( 1 << 0 )#define GREEN ( 1 << 1 )#define BLUE ( 1 << 2 )/* Simple use toggle macros */#define ON(LED) (lpt0_shadow |= LED)#define OFF(LED) (lpt0_shadow &= ~LED)/* One-liner to flush local copy of port to the wire */#define OUTPUT outb(lpt0_shadow,LPT0)/* char to simulate led ' '=off or [.,oO]=on w/ brightness */ #define FAKELED(val,color) (lpt0_shadow & color)?((val>192)?'O':(val>128)?'o':(val>64)?',':'.'):' '/* keep a copy of the port status to prevent clobbering pins unintentionally */static unsigned char lpt0_shadow = 0;/* Ncurses foo */WINDOW *window;int handle_keys(unsigned char *, unsigned char *, unsigned char *, unsigned int *);int main(int argc, char *argv[]){ unsigned int finished = 0; /* Timer values */ struct timespec tm = {0,0}; int freq=1; /* Contains current RGB values (0..255) */ unsigned char r,g,b; unsigned char r_ctr,g_ctr,b_ctr; r=g=b=r_ctr=g_ctr=b_ctr=0; /* Get permission for raw IO */ if(ioperm(LPT0,3,1)) { fprintf(stderr,"Failed to get raw IO permissions (are you root?)\n"); exit(-1); } /* set all output pins to 0 */ OFF(RED); OFF(GREEN); OFF(BLUE); OUTPUT; /* Initialize ncurses for nonblocking key polling w/o echo */ window = initscr(); cbreak(); noecho(); nodelay(window,1); keypad(window,1); /* Loop until done */ while(!finished) { /* configure output bits */ (r_ctr<r) ? ON(RED) : OFF(RED); (g_ctr<g) ? ON(GREEN) : OFF(GREEN); (b_ctr<b) ? ON(BLUE) : OFF(BLUE); /* send bits to the physical pins */ OUTPUT; /* delay (1bil nanosec/sec)/(256 duty cycle steps)/(hZ)*/ tm.tv_nsec = (long)(1000000000/(double)freq/256.0); nanosleep(&tm,NULL); /* update counters */ r_ctr++; g_ctr++; b_ctr++; /* use ncurses to check keypresses */ finished = handle_keys(&r,&g,&b,&freq); } /* set all pins to 0 to clean up */ OFF(RED); OFF(GREEN); OFF(BLUE); OUTPUT; /* release the port (might not be needed) */ ioperm(LPT0,3,0); /* cleanup nurses */ endwin(); return 0;}int handle_keys(unsigned char *r, unsigned char *g, unsigned char *b, unsigned int *freq){ char status[128]; int c; /* Dump some status info */ snprintf(status,128,"RGB:#%02hhx%02hhx%02hhx FREQ:%dHz\n",*r,*g,*b,*freq); mvaddstr(0,0,status); snprintf(status,128,"(%c)(%c)(%c)",FAKELED(*r,RED),FAKELED(*g,GREEN),FAKELED(*b,BLUE)); mvaddstr(1,0,status); /* Handle each key (backspace exits) */ if((c=getch()) != ERR) { switch(c) { case 'q': *r-=1; break; case 'w': *r+=1; break; case 'a': *g-=1; break; case 's': *g+=1; break; case 'z': *b-=1; break; case 'x': *b+=1; break; case KEY_UP: *freq+=1; break; case KEY_DOWN: (*freq>1)?*freq-=1:(void)0; break; case KEY_BACKSPACE: return 1; } } return 0;}