void display_update (void) { char statS[20], *str; char _tabs[4][20]={"[q]________", "BATTERY", "TEMPERATURE", "LIGHT"}; int i, imx=(MACHINE_NUM+1), j, jmx=(SENSOR_NUM+1); for (i=0; i<imx; i++) { for (j=0; j<jmx; j++) { //point to the proper string if (i==0) { //Top row. str=_tabs[j]; } else if (j==0) { //Left collumn (except for the first cell). snprintf(statS, 19, "Lunix_%02d", i); str=statS; } else { //Normal cell. str=MyRA[i-1][j-1].value; } //clear previously occupying text XClearArea(_D, _W, col(j, jmx), row(i, imx), (W_Width/jmx), (W_Height/imx), 0); //set the correct color for current text if (i==0 || j==0) XSetForeground(_D, _gc, black_pixel); else if (MyRA[i-1][j-1].status==error) XSetForeground(_D, _gc, red.pixel); else if (MyRA[i-1][j-1].status==online) XSetForeground(_D, _gc, blue.pixel); else XSetForeground(_D, _gc, black_pixel); XDrawString(_D, _W, /*DefaultGC(_D, _S)*/_gc, col(j, jmx), row(i, imx), str, strlen(str)); XFlush(_D); DEBUG_(fprintf(stderr, "S: %s @ (%d', %d') <= (%d, %d) : %p\n", str, col(j, jmx), row(i, imx), i, j, str)); } } DEBUG_(fprintf(stderr, "DISPLAY was just updated.\n")); DEBUG_(usleep(100000)); usleep(10000); }
static void convert_mouseloc(char * buf, int *x, int *y) { int retval; errno = 0; if ( (retval = sscanf(buf,"x:%d y:%d screen:%*d window:%*u",x,y)) != 2){ DEBUG_(printf("sscanf returned %d\n", retval)); perror("xdotool conversion"); *x=-1; *y=-1; return; } DEBUG_(printf("xdotool conversion complete, got %d,%d\n", *x,*y)); }
void statistics_print(void) { int i; DEBUG_("Statistics:"); for (i = 0; i < STAT_MAX; i += 3) { DEBUG_("\t%s: %d, %s: %d, %s: %d", statistics[i].name, statistics[i].count, statistics[i+1].name, statistics[i+1].count, statistics[i+2].name, statistics[i+2].count); } }
static void mouseloc(int *x, int *y) { char buf[SMALL_BUF]; int fds[2]; int n_bytes; pid_t childpid; pipe(fds); DEBUG_(printf("spawning mouse location reading command\n")); if ((childpid = fork()) == -1) { perror("fork"); *x=-1; *y=-1; return; } if (childpid == 0){ if (close(fds[0]) < 0){ perror("close"); } if (dup2(fds[1],STDOUT_FILENO) < 0){ perror("dup2"); } execlp("xdotool","xdotool","getmouselocation",NULL); exit(0); } else { if (close(fds[1]) < 0){ perror("parent close"); } DEBUG_(printf("parent, waiting for xdotool %d to exit\n", childpid)); if (waitpid(childpid, NULL, 0) < 0){ perror("wait"); } DEBUG_(printf("parent, done waiting on xdotool %d, reading output\n", childpid)); if ((n_bytes = read(fds[0],buf,SMALL_BUF)) < 0){ perror("mouse read"); *x=-1; *y=-1; return; } DEBUG_(printf("read: %s\n", buf)); convert_mouseloc(buf,x,y); } }
static void process_click(int fd) { char buf[SMALL_BUF]; char *args[MAX_CLICK_ARGS]; int x,y; ssize_t n_bytes; pid_t childpid; n_bytes = read(fd, buf, SMALL_BUF); if (n_bytes < 0){ perror("lemonbar click read"); } if (buf[n_bytes-1] == '\n'){ buf[n_bytes-1] = '\0'; //ends in newline, overwrite \n with termination } else { buf[n_bytes] = 0; } if ((childpid = fork()) == -1) { perror("fork"); return; } if (childpid == 0) { DEBUG_(printf("got command string: %s\n",buf)); process_args(buf, args); mouseloc(&x,&y); if (x != -1 && y != -1){ set_env_coords(x,y); } else { fprintf(stderr, "mouse location determination failed\n"); } set_environment(); execvp(args[0],args); } else { return; } DEBUG_(printf("got lemonbar output: %s\n", buf)); }
enum {loop_end,still_going} service_select_request (int x_fd) { size_t i, j; size_t selects_num=-1; //Create the descriptor set (creation can't be static due to inclusion condition). int select_max_arg=0; //Minimum legal fd value. FD_ZERO(&backup_set); for (i=0; i<MACHINE_NUM; i++) { for (j=0; j<SENSOR_NUM; j++) { //Remote testing: MyRA[i][j].status==online -- Normal operation: MyRA[i][j].status!=error if (MyRA[i][j].status==online) //only non-error streams FD_SET(MyRA[i][j].file_d, &backup_set); select_max_arg=(MyRA[i][j].file_d>select_max_arg) ? MyRA[i][j].file_d : select_max_arg; } } FD_SET(x_fd, &backup_set); select_max_arg=(select_max_arg>x_fd) ? select_max_arg : x_fd; select_max_arg++; check_set=backup_set; //Do the select. DEBUG_(fprintf(log_stream, "Select called with max_fd %d.\n", select_max_arg)); if (select(select_max_arg, &check_set, NULL, NULL, NULL)==-1) goto error_check; //Check the descriptor set. for (i=0; i<MACHINE_NUM; i++) { for (j=0; j<SENSOR_NUM; j++) { //Normal requests serviced here. if (FD_ISSET(MyRA[i][j].file_d, &check_set)) { DEBUG_(fprintf(stderr, "Request: Descriptor [%d, %d].\n", i, j)); read_from(i, j); } } } //X requests serviced here. if (FD_ISSET(x_fd, &check_set)) { DEBUG_(fprintf(stderr, "Request X: ")); char RetV[2]={0}; XNextEvent(_D, &_E); if (_E.type==Expose) { display_update(); } else if (_E.type == KeyPress) { XLookupString(&_E.xkey, RetV, 1, &key, NULL); if (key=='q' || key=='Q') return loop_end; } } else if (MyRA_Updated==1 && selects_num>=updates_every) { //Non-event triggered updates on multiples. display_update(); usleep(10000); selects_num=0; } //Normal exit point. return still_going; //Return 'loop_end' when all sensor fds are non-responsive. error_check: fprintf(log_stream, "Select call returned with %d: ", errno); switch (errno) { case EBADF: fprintf(log_stream, "EBADF: Terminating.\n"); break; case EINTR: fprintf(log_stream, "EINTR: Relooping.\n"); return still_going; break; case EINVAL: fprintf(log_stream, "EINVAL: Terminating.\n"); break; case ENOMEM: fprintf(log_stream, "ENOMEM: Relooping after 5 seconds.\n"); sleep(5); return still_going; break; default: fprintf(log_stream, "Undefined error: Terminating.\n"); } //Default error exit point. return loop_end; }
void SerialPortDataTransport::configure(boost::shared_ptr<SerialPortXml> port, bool retryConfiguring) { EXCEPTION_ASSERT_WITH_LOG(port, LibLogicalAccessException, "No serial port configured !"); EXCEPTION_ASSERT_WITH_LOG(port->getSerialPort()->deviceName() != "", LibLogicalAccessException, "Serial port name is empty ! Auto-detect failed !"); try { unsigned long baudrate = getPortBaudRate(); DEBUG_("Configuring serial port %s - Baudrate {%ul}...", port->getSerialPort()->deviceName().c_str(), baudrate); #ifndef _WINDOWS struct termios options = port->getSerialPort()->configuration(); /* Set speed */ cfsetispeed(&options, static_cast<speed_t>(baudrate)); cfsetospeed(&options, static_cast<speed_t>(baudrate)); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* Set character size and parity check */ /* 8N1 */ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; /* Disable parity check and fancy stuff */ options.c_iflag &= ~ICRNL; options.c_iflag &= ~INPCK; options.c_iflag &= ~ISTRIP; /* Disable software flow control */ options.c_iflag &= ~(IXON | IXOFF | IXANY); /* RAW input */ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* RAW output */ options.c_oflag &= ~OPOST; /* Timeouts */ options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 5; port->getSerialPort()->setConfiguration(options); #else DCB options = port->getSerialPort()->configuration(); options.BaudRate = baudrate; options.fBinary = TRUE; // Binary mode; no EOF check options.fParity = FALSE; // Enable parity checking options.fOutxCtsFlow = FALSE; // No CTS output flow control options.fOutxDsrFlow = FALSE; // No DSR output flow control options.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control type options.fDsrSensitivity = FALSE; // DSR sensitivity options.fTXContinueOnXoff = TRUE; // XOFF continues Tx options.fOutX = FALSE; // No XON/XOFF out flow control options.fInX = FALSE; // No XON/XOFF in flow control options.fErrorChar = FALSE; // Disable error replacement options.fNull = FALSE; // Disable null stripping options.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control options.fAbortOnError = FALSE; // Do not abort reads/writes on // error options.ByteSize = 8; // Number of bits/byte, 4-8 options.Parity = NOPARITY; // 0-4=no,odd,even,mark,space options.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 port->getSerialPort()->setConfiguration(options); #endif } catch(std::exception& e) { if (retryConfiguring) { // Strange stuff is going here... by waiting and reopening the COM port (maybe for system cleanup), it's working ! std::string portn = port->getSerialPort()->deviceName(); WARNING_("Exception received {%s} ! Sleeping {%d} milliseconds -> Reopen serial port {%s} -> Finally retry to configure...", e.what(), Settings::getInstance()->ConfigurationRetryTimeout, portn.c_str()); #ifndef __unix__ Sleep(Settings::getInstance()->ConfigurationRetryTimeout); #else sleep(Settings::getInstance()->ConfigurationRetryTimeout); #endif port->getSerialPort()->reopen(); configure(port, false); } } }
void notified(int sig, pid_t pid, int value) { (void) sig; (void) pid; (void) value; DEBUG_(printf("server woke us up!\n")); }
int main(int argc, char const *argv[]) { shmem *mem; const char *geometry; int lemon_in, lemon_out; int tries=0; struct pollfd fds[1]; fds[0].events = POLLIN; geometry = (argc < 2) ? DEFAULT_GEOM : argv[1]; if (validate_geometry(geometry) < 0){ fprintf(stderr, "please provide a valid window geometry. E.g. 1920x22+0+0 (widthxheight+X+Y)\n"); return -1; } if ((mem = setup_memory(0)) == MEM_FAILED){ printf("Spawning data daemon\n"); if (spawn_daemon() < 0){ fprintf(stderr, "failed to start daemon\n"); exit(-1); } while ((mem = setup_memory(0)) == MEM_FAILED){ if (tries++ > 10){ fprintf(stderr, "failed to connect to daemon\n"); exit(-1); } sleep(1); } printf("connected to new data source\n"); } else { printf("Connected to running data source.\n"); } spawn_bar(&lemon_in, &lemon_out, geometry); fds[0].fd = lemon_out; notify_server(mem->server); catch_signals(); //@todo allow an escape for when server dies while (1) { DEBUG_(printf("waiting for wakeup signal\n")); //block. wait here for lemonbar click output, or update signal from server //we could block with read() or something, but let's plan for multiple //sources for the future. if (poll(fds, 1, -1) < 0){ if (errno != EINTR){ perror("poll"); break; } } if (fds[0].revents & POLLIN) { fds[0].revents = 0; //clear for next round //something was clicked process_click(fds[0].fd); } else { //must have gotten pinged by server //@todo verify SIGUSR1 vs other signals (which generally just exit anyway) update_bar(mem,lemon_in); } } return -1; }
static void spawn_bar(int *lemon_in, int *lemon_out, const char *geometry) { int child_in[2]; //could be done one 2D array, fd[2][2], but harder to read int child_out[2]; pid_t childpid; pipe(child_in); pipe(child_out); if ((childpid = fork()) == -1) { perror("fork"); exit(-1); } if (childpid == 0) { //child if (close(child_in[1]) < 0){ //close input of first pipe perror("closing child input"); } if (close(child_out[0]) < 0){ //close output of second pipe perror("closing child output"); } //send SIGHUP to us when parent dies if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0){ //Linux only perror("setting up deathsig"); } if (dup2(child_in[0],STDIN_FILENO) < 0){ //replace lemon stdin with pipe output perror("setting lemon stdin"); } if (dup2(child_out[1],STDOUT_FILENO) < 0){ //send lemon output through pipe2 input perror("setting lemon stdout"); } signal(SIGUSR1,SIG_IGN); //if pgrep -x compton; then #ee383a3b else #383a3b fi execlp("lemonbar", "lemonbar", "-g",geometry,"-B","#ee383a3b","-F","#ffffff", "-u","3","-a","20", "-f","-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*", "-f","-*-lemon-medium-*-*-*-10-*-75-75-*-*-iso10646-*", "-f","-*-uushi-*-*-*-*-*-*-75-75-*-*-iso10646-*", "-f","-*-siji-*-*-*-*-10-*-75-75-*-*-iso10646-*", NULL); exit(0); //if lemonbar exits, don't continue running C code. DIE! } else { //parent if (close(child_in[0]) < 0){ //close output of child's stdin perror("parent closing output"); } if (close(child_out[1]) <0){ //close input of its stdout perror("parent closing intput"); } *lemon_in = child_in[1]; //child_in[1] is stdin to lemonbar *lemon_out = child_out[0]; //child_out[0] is lemonbar output DEBUG_(printf("waiting for lemonbar to start up\n")); sleep(1); //give time for lemonbar to start, pipes to be swapped DEBUG_(printf("spawned lemonbar\n")); } }
static void notify_server(pid_t server) { kill(server,SIGUSR1); //give server our PID DEBUG_(printf("sent ping to server (we are %d)\n",getpid())); }