void setbacktick(int num, int lifespan, int tick, char **cmdv) { struct backtick **btp, *bt; char **v; for (btp = &backticks; (bt = *btp) != 0; btp = &bt->next) if (bt->num == num) break; if (!bt && !cmdv) return; if (bt) { for (v = bt->cmdv; *v; v++) free(*v); free(bt->cmdv); if (bt->buf) free(bt->buf); if (bt->ev.fd >= 0) close(bt->ev.fd); evdeq(&bt->ev); } if (bt && !cmdv) { *btp = bt->next; free(bt); return; } if (!bt) { bt = malloc(sizeof *bt); if (!bt) { Msg(0, "%s", strnomem); return; } memset(bt, 0, sizeof(*bt)); bt->next = 0; *btp = bt; } bt->num = num; bt->tick = tick; bt->lifespan = lifespan; bt->bestbefore = 0; bt->result[0] = 0; bt->buf = 0; bt->bufi = 0; bt->cmdv = cmdv; bt->ev.fd = -1; if (bt->tick == 0 && bt->lifespan == 0) { bt->buf = malloc(MAXSTR); if (bt->buf == 0) { Msg(0, "%s", strnomem); setbacktick(num, 0, 0, (char **)0); return; } bt->ev.type = EV_READ; bt->ev.fd = readpipe(bt->cmdv); bt->ev.handler = backtick_fn; bt->ev.data = (char *)bt; if (bt->ev.fd >= 0) evenq(&bt->ev); } }
void SetCanvasWindow(struct canvas *cv, struct win *win) { struct win *p = 0, **pp; struct layer *l; struct canvas *cvp, **cvpp; l = cv->c_layer; display = cv->c_display; if (l) { /* remove old layer */ for (cvpp = &l->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext) if (cvp == cv) break; ASSERT(cvp); *cvpp = cvp->c_lnext; p = Layer2Window(l); l = cv->c_layer; cv->c_layer = 0; if (p && cv == D_forecv) { if (p->w_silence) { SetTimeout(&p->w_silenceev, p->w_silencewait * 1000); evenq(&p->w_silenceev); } D_other = fore; D_fore = 0; } if (l->l_cvlist == 0 && (p == 0 || l != p->w_savelayer)) KillLayerChain(l); } /* find right layer to display on canvas */ if (win && win->w_type != W_TYPE_GROUP) { l = &win->w_layer; if (win->w_savelayer && (win->w_blocked || win->w_savelayer->l_cvlist == 0)) l = win->w_savelayer; } else { l = &cv->c_blank; if (win) l->l_data = (char *)win; else l->l_data = 0; } /* add our canvas to the layer's canvaslist */ ASSERT(l->l_cvlist != cv); cv->c_lnext = l->l_cvlist; l->l_cvlist = cv; cv->c_layer = l; cv->c_xoff = cv->c_xs; cv->c_yoff = cv->c_ys; RethinkViewportOffsets(cv); if (flayer == 0) flayer = l; if (win && win->w_type == W_TYPE_GROUP) { /* auto-start windowlist on groups */ struct display *d = display; struct layer *oldflayer = flayer; flayer = l; display_windows(0, 0, win); flayer = oldflayer; display = d; } if (win && D_other == win) D_other = win->w_next; /* Might be 0, but that's OK. */ if (cv == D_forecv) { D_fore = win; fore = D_fore; /* XXX ? */ if (win) { /* * Place the window at the head of the most-recently-used list */ if (windows != win) { for (pp = &windows; (p = *pp); pp = &p->w_next) if (p == win) break; ASSERT(p); *pp = p->w_next; p->w_next = windows; windows = p; WListLinkChanged(); } } } }