#include #include #include #include #include #include #include "xte.h" #include "builtins.h" #include "blocktype.h" typedef struct priv PRIV; typedef struct sb SB; struct priv { double f; } ; struct sb { void (*cont)(void *, void *); void *contarg; PRIV p; } ; static int my_w = -1; static int my_h; static int amp_x; static int factor_x; static int factor_w; static int out_x; static BLOCKDIMS size(void) { XCharStruct cs; XCharStruct cs_factor; XCharStruct cs_in; XCharStruct cs_out; XCharStruct cs_amp; if (my_w < 0) { XTextExtents(font,"-0.0000",7,XTE_JUNK,&cs_factor); XTextExtents(font,"-0.0e-00",8,XTE_JUNK,&cs); if (cs.width > cs_factor.width) cs_factor.width = cs.width; XTextExtents(font,"Amp",3,XTE_JUNK,&cs_amp); XTextExtents(font,"In",2,XTE_JUNK,&cs_in); XTextExtents(font,"Out",3,XTE_JUNK,&cs_out); my_w = cs_in.width + ((cs_factor.width > cs_amp.width) ? cs_factor.width : cs_amp.width) + cs_out.width + (4 * font_space); out_x = my_w - cs_out.width - font_space; amp_x = ((my_w - cs_in.width - cs_out.width - cs_amp.width) / 2) + cs_in.width; factor_x = ((my_w - cs_in.width - cs_out.width - cs_factor.width) / 2) + cs_in.width; factor_w = cs_factor.width; my_h = 3 * font_baselineskip; } return((BLOCKDIMS){.w=my_w,.h=my_h}); } static void setup_cont(int ok, void *sbv) { SB sb; PRIV *p; sb = *(SB *)sbv; free(sbv); if (ok) { p = malloc(sizeof(PRIV)); p->f = sb.p.f; } else { p = 0; } (*sb.cont)(p,sb.contarg); } static void setup(void (*cont)(void *, void *), void *arg) { SB *sb; sb = malloc(sizeof(SB)); sb->cont = cont; sb->contarg = arg; setup_getarg("Amplification",&setup_cont,sb,&sb->p.f,PAR_AMP); } static void destroy(void *pv) { free(pv); } static void render(void *pv, Drawable d, GC gc_bg, GC gc_fg) { PRIV *p; int y; char s[16]; int l; double af; XCharStruct cs; int i; int n; p = pv; XFillRectangle(disp,d,gc_bg,0,0,my_w,my_h); XDrawLine(disp,d,gc_fg,0,0,my_w-2,0); XDrawLine(disp,d,gc_fg,my_w-1,0,my_w-1,my_h-2); XDrawLine(disp,d,gc_fg,my_w-1,my_h-1,1,my_h-1); XDrawLine(disp,d,gc_fg,0,my_h-1,0,1); y = font_baseline + (font_baselineskip / 2); XDrawString(disp,d,gc_fg,amp_x,y,"Amp",3); y += font_baselineskip; af = fabs(p->f); if ((af < .01) || (af >= 10000)) { if ((af >= 1e10) || (af <= 1e-10)) { l = sprintf(&s[0],"%8.1e",p->f); } else { l = sprintf(&s[0],"%9.2e",p->f); if (s[l-2] == '0') { s[l-2] = s[l-1]; l --; } else { l = sprintf(&s[0],"%8.1e",p->f); } } for (i=l-1;s[i]!='e';i--) ; n = 0; while (s[i-n-1] == '0') n ++; if (s[i-n-1] == '.') n ++; if (n > 0) { bcopy(&s[i],&s[i-n],l-i); l -= n; } } else { if (af >= 1000) { l = sprintf(&s[0],"%5.0f",p->f); s[l++] = '.'; } else if (af >= 100) { l = sprintf(&s[0],"%5.1f",p->f); } else if (af >= 10) { l = sprintf(&s[0],"%5.2f",p->f); } else { l = sprintf(&s[0],"%5.3f",p->f); } while (s[l-1] == '0') l --; if (s[l-1] == '.') l --; if (l == 1) s[l++] = '0'; } XTextExtents(font,&s[0],l,XTE_JUNK,&cs); XDrawString(disp,d,gc_fg,factor_x+((factor_w-cs.width)/2),y,&s[0],l); y = font_baselineskip + font_baseline; XDrawString(disp,d,gc_fg,font_space,y,"In",2); XDrawString(disp,d,gc_fg,out_x,y,"Out",3); } static const char *ins[] = { "In" }; static const char *outs[] = { "Out" }; static BLOCKPARAM params[] = { { .name = "Factor", .type = PAR_AMP } }; BLOCKTYPE block_amp = { .name = "Amp", .n_in = 1, .ins = &ins[0], .n_out = 1, .outs = &outs[0], .n_param = 1, .params = ¶ms[0], .compute_size = &size, .setup = &setup, .destroy = &destroy, .render = &render };