/* dmxin.c by Michael Thorpe 2019-02-07 */ #include #include #include #include #include #include "runner.h" struct dmx dmxin={len:0,fd:-1,sawFE:0,pos:-1}; static void dmxin_redraw() { dmx_redraw(&dmxinframe,&dmxin); } enum chancmp_t {GOOD,LOW,HIGH,UNKNOWN}; static enum chancmp_t chancmp[1+DMX_MAXCHAN]; static int dmxin_offset=0; static char titlebar[13]; void dmxin_setoffset(int new) { int i; if(-1==new) new=dmxin_offset; if(0==new) { dmxinframe.title="DMX IN"; } else { snprintf(titlebar,sizeof(titlebar),"DMX IN (%d)",new); dmxinframe.title=titlebar; } if(dmxinframe.h && dmxinframe.w) draw_titlebar(&dmxinframe); /* Update the actual variable and pin the channels */ dmxin_offset=new; for(i=1;i<=DMX_MAXCHAN;i++) chancmp[i]=UNKNOWN; } void dmxin_unlinkchan(int chan) { chancmp[chan]=UNKNOWN; } static void gotchan(struct dmx *dmx,unsigned char val) { unsigned char curval; if(0==dmx->pos) { if(val) dmx->pos=-1; /* throw out packets with non-NULL START codes */ else dmx->pos++; return; } if(-1==dmx->pos) return; if(DMX_MAXCHANpos) return; if(&dmxin==dmx) show_new_chan(&dmxinframe,dmx->pos,val); if(dmx->lenpos) dmx->len=dmx->pos; dmx->data[dmx->pos]=val; /* FIXME: We should update the looks frame here if applicable. */ if(&dmxin==dmx && editlook) { if(DMX_MAXCHANpos) goto done; if(GOOD != chancmp[dmx->pos]) { curval=editlook->func(editlook,dmxin_offset+dmx->pos); switch(chancmp[dmx->pos]) { case GOOD: /* Useless case, but it shuts up the compiler. */ break; case LOW: if(valpos]=GOOD; break; case HIGH: if(curvalpos]=GOOD; break; case UNKNOWN: if(valpos]=LOW; goto done; } if(curvalpos]=HIGH; goto done; } chancmp[dmx->pos]=GOOD; break; } } while(editlook->dmx->lenpos) editlook->dmx->data[++editlook->dmx->len]=0; editlook->dmx->data[dmxin_offset+dmx->pos]=val; } done: dmx->pos++; } void dmx_readable(struct dmx *dmx) { unsigned char buf[1028]; int i,l; l=read(dmx->fd,buf,sizeof(buf)); if(-1==l) { perror("read"); exit(-1); } if(0==l) { errmsg("short read from proc"); dmx->len=0; dmx->fd=-1; if(&dmxin==dmx) /* somebody probably unplugged the Teensy */ dmxin_redraw(); return; } for(i=0;isawFE=1; continue; } if(dmx->sawFE) { switch(buf[i]) { case 0: /* BREAK */ if(-1 != dmx->pos) dmx->len=dmx->pos; dmx->pos=0; break; case 1: /* literal FE */ gotchan(dmx,0xFE); break; case 2: dmx->pos=-1; break; default: fprintf(stderr,"Got %2.2X from DMX %p fd %d\n",buf[i],dmx,dmx->fd); exit(-1); } dmx->sawFE=0; continue; } gotchan(dmx,buf[i]); } } struct frame dmxinframe={draw:dmxin_redraw};