ref: 0e8796746fad950ab61be075de5638fdcbd6fc32
dir: /layer.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <memdraw.h> #include <event.h> #include <bio.h> #include "blie.h" char Ebadfmt[] = "bad file format: "; typedef struct List List; struct List { Layer *layer; List *next; }; List *firstlayer = nil; static Drawop str2op(char *s) { #define OP(n) if (!strcmp(s, "n")) { return n; } OP(Clear); OP(SinD); OP(DinS); OP(SoutD); OP(DoutS); OP(S); OP(SoverD); OP(SatopD); OP(SxorD); OP(D); OP(DoverS); OP(DatopS); OP(DxorS); #undef OP return SoverD; } static char* op2str(Drawop op) { #define OP(n) if (op == n) { return "n"; } OP(Clear); OP(SinD); OP(DinS); OP(SoutD); OP(DoutS); OP(S); OP(SoverD); OP(SatopD); OP(SxorD); OP(D); OP(DoverS); OP(DatopS); OP(DxorS); #undef OP return "SoverD"; } static void addlayerl(Layer *l) { List *f; if (!firstlayer) { firstlayer = mallocz(sizeof(List), 1); firstlayer->layer = l; return; } for (f = firstlayer; f->next; f = f->next) continue; f->next = mallocz(sizeof(List), 1); f->next->layer = l; } void addlayer(char *name) { Biobuf *b; char *file; char *ed, *lbl, *op; Layer *l; if (!name || !name[0]) return; file = smprint("%s/meta", name); b = Bopen(file, OREAD); free(file); if (!b) sysfatal("error opening file %s/meta: %r", name); ed = Brdstr(b, '\n', 1); if (!ed) sysfatal("%s%s/meta: missing editor", Ebadfmt, name); lbl = Brdstr(b, '\n', 1); if (!lbl) sysfatal("%s%s/meta: missing label", Ebadfmt, name); op = Brdstr(b, '\n', 1); if (!op) sysfatal("%s%s/meta: missing drawop", Ebadfmt, name); l = mallocz(sizeof(Layer), 1); l->name = strdup(name); l->label = strdup(lbl); l->editor = geteditor(ed); l->op = str2op(op); if (!l->editor) sysfatal("editor %s not found for %s", ed, name); addlayerl(l); free(lbl); free(ed); free(op); Bterm(b); } void movelayer(Layer *layer, int dir) { List *parent; List *l; if (firstlayer->layer == layer) { if (dir == DOWN) { l = firstlayer->next; firstlayer->next = l ? l->next : nil; l->next = firstlayer; firstlayer = l; return; } if (dir == UP) return; /* NOP */ } /* find parent */ for (l = firstlayer; l && l->next->layer != layer; l = l->next) continue; if (!l) return; /* not found */ parent = l; if (dir == DOWN) goto Movedown; if (dir != UP) sysfatal("code error: direction != UP|DOWN"); /* movelayer(layer, UP) == movelayer(parent, DOWN) */ movelayer(parent->layer, DOWN); return; Movedown: l = parent->next; if (!l) return; /* NOP: last element */ parent->next = l->next; l->next = l->next ? l->next->next : nil; parent->next->next = l; } void savelayermeta(Layer *layer) { Biobuf *b; char *file; file = smprint("%s.meta", layer->name); b = Bopen(file, OWRITE|OTRUNC); free(file); if (!b) sysfatal("error opening file %s.meta for write: %r", layer->name); Bprint(b, "%s\n%s\n", layer->editor->name, layer->label); Bterm(b); } int foreachlayer(void (*f)(Layer*, int, void*), void* aux) { List *l; int i; i = 0; for (l = firstlayer; l; l = l->next, i++) { f(l->layer, i, aux); } return i; }