#include #include #include #include #include #include #include #include #include void resized(int new) { if (new && getwindow(display, Refnone) < 0 ) exits("getwindow failed"); redraw(); } static Point calcmove(Point p) { Point pos; pos=Pt((Δx/2+p.x)/Δx,(Δy/2+p.y)/Δy); if(pos.x > Bansz) pos.x=-1; if(pos.y > Bansz) pos.y=-1; if(pos.x < 1) pos.x=-1; if(pos.y<1) pos.y=-1; return pos; } static int mouseevrd (Mouse *mev) { int button; button=mev->buttons; if (button==1){ return Click1; } if (button==2){ return Click2; } if (button==4){ return Click3; } return 0; } void opsend(Move *m, char) { Move *mdead; if(!m){ dprint("nil\n"); return; } m->next = nil; sendp(ifcchan,m); mdead=recvp(ifcchan); freegrp(mdead); } void inthread(void *) { int desvx, desvy; int pressed, nw, nb, ndead; int altval; Point pos; Rune r; Mouse m; Move *mv, *mdead; Move *mread; Filectl *fc=filectl; static Alt alts[NALT+1]; threadsetname("inthread"); initifc(); alts[Akeyboard].c = keyboardctl->c; alts[Akeyboard].v = &r; alts[Akeyboard].op = CHANRCV; alts[Areshape].c = mousectl->resizec; alts[Areshape].v = nil; alts[Areshape].op = CHANRCV; alts[Amouse].c = mousectl->c; alts[Amouse].v = &m; alts[Amouse].op = CHANRCV; alts[Afile].c = filectl->c; alts[Afile].v = &mread; alts[Afile].op = CHANRCV; alts[NALT].op = CHANEND; while((altval=alt(alts)) != NALT){ visible = 1; switch(altval){ case Akeyboard: if(r==DELETEKEY) threadexitsall(nil); else if(r=='q') threadexitsall(nil); else if(r=='c'){ trycount(&nw, &nb); bdead += nb; wdead += nw; drwlabel(bdead,wdead,clk); drawgoban(); flushimage(display,1); } else if(r=='u' && moves){ visible = 0; mv = moves; mv = freelast(mv); moves = nil; bdead = 0; wdead = 0; cleangoban(); if(mv) opgrp(mv, '\0', opsend); visible = 1; drwlabel(bdead,wdead,clk); drawgoban(); flushimage(display,1); } break; case Areshape: resized(1); break; case Amouse: desvx=(m.xy.x)-screen->r.min.x; desvy=(m.xy.y)-screen->r.min.y; pos=calcmove(Pt(desvx,desvy)); pressed=mouseevrd(&m); if(pressed && isvalidpos(pos)){ mv=getmove(pos); if(pressed==Click1 || pressed==Click2){ if(fc->p!=fc->r || fc->ro) break; mv->ev.m = pressed; filectl->ev = pressed; } if(pressed==Click1 && fc->r=='W'){ mv->type='W'; mv->ev.fd = filectl->W; sendp(ifcchan,mv); mdead=recvp(ifcchan); } else if(pressed==Click2 && fc->r=='B'){ mv->type='B'; mv->ev.fd = filectl->B; sendp(ifcchan,mv); mdead=recvp(ifcchan); } else if(pressed==Click3){ if(strchr(emptytype, mv->type)!=nil) break; ndead = markdead(mv, &mdead); if(mdead->type=='B') wdead+=ndead; else if(mdead->type=='W') bdead+=ndead; drwlabel(bdead,wdead,clk); drawgoban(); } else break; flushimage(display,1); opgrp(mdead,0,opprint); freegrp(mdead); freegrp(mv); } break; case Afile: pos=mread->Point; if(!isvalidpos(pos)) break; mv=getmove(pos); mv->ev.m = 0; mv->type = mread->type; sendp(ifcchan,mv); mdead=recvp(ifcchan); flushimage(display,1); opgrp(mdead,0,opprint); freegrp(mdead); freegrp(mv); free(mread); break; } } }