#include #include "builtins.h" #include "blocktype.h" typedef struct kind KIND; struct kind { const char *in[2]; int w; int h; const char *label; int x_label; int x_out; int inlen[2]; int labellen; } ; static const char *outs[] = { "Out" }; #define TYPEDECL(name,lbl,in1,in2)\ static BLOCKDIMS size_##name(BLOCK_SIZE_PROTO); \ static void setup_##name(BLOCK_SETUP_PROTO); \ static KIND kind_##name = { .in = { in1, in2 }, .w = -1, .label = lbl };\ static BLOCKDIMS size_##name(BLOCK_SIZE_ARGS) \ { \ return(size_common(&kind_##name)); \ } \ static void setup_##name(BLOCK_SETUP_ARGS) \ { \ setup_common(&kind_##name,cont,contarg); \ } \ static void resetup_##name(BLOCK_RESETUP_ARGS) \ { \ (*cont)(contarg,1); \ } \ static const char *ins_##name[] = { in1, in2 }; \ BLOCKTYPE block_##name = BLOCKTYPE_I_O(lbl,ins_##name,outs,size_##name,setup_##name,resetup_##name,destroy,render,iny,outy,rinit,rstep,out_##name); static BLOCKDIMS size_common(KIND *k) { int w[2]; int w_label; int w_out; if (k->w < 0) { k->labellen = strlen(k->label); k->inlen[0] = strlen(k->in[0]); k->inlen[1] = strlen(k->in[1]); w[0] = widthof(k->in[0],k->inlen[0]); w[1] = widthof(k->in[1],k->inlen[1]); w_label = widthof(k->label,strlen(k->label)); w_out = widthof("Out",3); k->x_label = ((w[0] > w[1]) ? w[0] : w[1]) + (2 * font_space); k->x_out = k->x_label + w_label + font_space; k->w = k->x_out + w_out + font_space; k->h = 3 * font_baselineskip; } return((BLOCKDIMS){.w=k->w,.h=k->h}); } static void setup_common(KIND *k, BLOCK_SETUP_ARGS) { (*cont)(k,contarg); } static void destroy(BLOCK_DESTROY_ARGS) { } static void render(BLOCK_RENDER_ARGS) { KIND *k; int y; k = priv; XFillRectangle(disp,d,gc_bg,0,0,k->w,k->h); XDrawLine(disp,d,gc_fg,0,0,k->w-2,0); XDrawLine(disp,d,gc_fg,k->w-1,0,k->w-1,k->h-2); XDrawLine(disp,d,gc_fg,k->w-1,k->h-1,1,k->h-1); XDrawLine(disp,d,gc_fg,0,k->h-1,0,1); y = font_baseline + font_baselineskip; XDrawString(disp,d,gc_fg,k->x_label,y,k->label,k->labellen); XDrawString(disp,d,gc_fg,k->x_out,y,"Out",3); y = font_baseline + (font_baselineskip / 2); XDrawString(disp,d,gc_fg,font_space,y,k->in[0],k->inlen[0]); XDrawString(disp,d,gc_fg,font_space,y+font_baselineskip,k->in[1],k->inlen[1]); } static int iny(BLOCK_INPUT_Y_ARGS) { return((pin+1)*font_baselineskip); } static int outy(BLOCK_OUTPUT_Y_ARGS) { return((3*font_baselineskip)/2); } static void rinit(BLOCK_RUN_INIT_ARGS) { } static void rstep(BLOCK_RUN_STEP_ARGS) { } static double out_cmp(BLOCK_RUN_OUT_ARGS) { return((ins[0]>ins[1])?-1:(ins[0]ins[1])?ins[0]:ins[1]); } static double out_sum(BLOCK_RUN_OUT_ARGS) { return(ins[0]+ins[1]); } static double out_prod(BLOCK_RUN_OUT_ARGS) { return(ins[0]*ins[1]); } TYPEDECL(cmp,"Cmp","+","-") TYPEDECL(min,"Min","In","In") TYPEDECL(max,"Max","In","In") TYPEDECL(sum,"Sum","In","In") TYPEDECL(prod,"Prod","In","In")