enum { Qdir, Qacme, Qcons, Qconsctl, Qdraw, Qeditout, Qindex, Qlabel, Qlog, Qnew, QWaddr, QWbody, QWctl, QWdata, QWeditout, QWerrors, QWevent, QWrdsel, QWwrsel, QWtag, QWxdata, QMAX }; enum { Blockincr = 256, Maxblock = 8*1024, NRange = 10, Infinity = 0x7FFFFFFF /* huge value for regexp address */ }; #define Buffer AcmeBuffer typedef struct Block Block; typedef struct Buffer Buffer; typedef struct Command Command; typedef struct Column Column; typedef struct Dirlist Dirlist; typedef struct Dirtab Dirtab; typedef struct Disk Disk; typedef struct Expand Expand; typedef struct Fid Fid; typedef struct File File; typedef struct Elog Elog; typedef struct Mntdir Mntdir; typedef struct Range Range; typedef struct Rangeset Rangeset; typedef struct Reffont Reffont; typedef struct Row Row; typedef struct Runestr Runestr; typedef struct Text Text; typedef struct Timer Timer; typedef struct Window Window; typedef struct Xfid Xfid; struct Runestr { Rune *r; int nr; }; struct Range { int q0; int q1; }; struct Block { vlong addr; /* disk address in bytes */ union { uint n; /* number of used runes in block */ Block *next; /* pointer to next in free list */ } u; }; struct Disk { int fd; vlong addr; /* length of temp file */ Block *free[Maxblock/Blockincr+1]; }; Disk* diskinit(void); Block* disknewblock(Disk*, uint); void diskrelease(Disk*, Block*); void diskread(Disk*, Block*, Rune*, uint); void diskwrite(Disk*, Block**, Rune*, uint); struct Buffer { uint nc; Rune *c; /* cache */ uint cnc; /* bytes in cache */ uint cmax; /* size of allocated cache */ uint cq; /* position of cache */ int cdirty; /* cache needs to be written */ uint cbi; /* index of cache Block */ Block **bl; /* array of blocks */ uint nbl; /* number of blocks */ }; void bufinsert(Buffer*, uint, Rune*, uint); void bufdelete(Buffer*, uint, uint); uint bufload(Buffer*, uint, int, int*, DigestState*); void bufread(Buffer*, uint, Rune*, uint); void bufclose(Buffer*); void bufreset(Buffer*); struct Elog { short type; /* Delete, Insert, Filename */ uint q0; /* location of change (unused in f) */ uint nd; /* number of deleted characters */ uint nr; /* # runes in string or file name */ Rune *r; }; void elogterm(File*); void elogclose(File*); void eloginsert(File*, int, Rune*, int); void elogdelete(File*, int, int); void elogreplace(File*, int, int, Rune*, int); void elogapply(File*); struct File { Buffer b; /* the data */ Buffer delta; /* transcript of changes */ Buffer epsilon; /* inversion of delta for redo */ Buffer *elogbuf; /* log of pending editor changes */ Elog elog; /* current pending change */ Rune *name; /* name of associated file */ int nname; /* size of name */ uvlong qidpath; /* of file when read */ ulong mtime; /* of file when read */ int dev; /* of file when read */ uchar sha1[20]; /* of file when read */ int unread; /* file has not been read from disk */ int editclean; /* mark clean after edit command */ int seq; /* if seq==0, File acts like Buffer */ int mod; Text *curtext; /* most recently used associated text */ Text **text; /* list of associated texts */ int ntext; int dumpid; /* used in dumping zeroxed windows */ }; File* fileaddtext(File*, Text*); void fileclose(File*); void filedelete(File*, uint, uint); void filedeltext(File*, Text*); void fileinsert(File*, uint, Rune*, uint); uint fileload(File*, uint, int, int*, DigestState*); void filemark(File*); void filereset(File*); void filesetname(File*, Rune*, int); void fileundelete(File*, Buffer*, uint, uint); void fileuninsert(File*, Buffer*, uint, uint); void fileunsetname(File*, Buffer*); void fileundo(File*, int, uint*, uint*); uint fileredoseq(File*); enum /* Text.what */ { Columntag, Rowtag, Tag, Body }; struct Text { File *file; Frame fr; Reffont *reffont; uint org; uint q0; uint q1; int what; int tabstop; Window *w; Rectangle scrollr; Rectangle lastsr; Rectangle all; Row *row; Column *col; uint iq1; /* last input position */ uint eq0; /* start of typing for ESC */ uint cq0; /* cache position */ int ncache; /* storage for insert */ int ncachealloc; Rune *cache; int nofill; int needundo; }; uint textbacknl(Text*, uint, uint); uint textbsinsert(Text*, uint, Rune*, uint, int, int*); int textbswidth(Text*, Rune); int textclickhtmlmatch(Text*, uint*, uint*); int textclickmatch(Text*, int, int, int, uint*); void textclose(Text*); void textcolumnate(Text*, Dirlist**, int); void textcommit(Text*, int); void textconstrain(Text*, uint, uint, uint*, uint*); void textdelete(Text*, uint, uint, int); void textdoubleclick(Text*, uint*, uint*); void textfill(Text*); void textframescroll(Text*, int); void textinit(Text*, File*, Rectangle, Reffont*, Image**); void textinsert(Text*, uint, Rune*, uint, int); int textload(Text*, uint, char*, int); Rune textreadc(Text*, uint); void textredraw(Text*, Rectangle, Font*, Image*, int); void textreset(Text*); int textresize(Text*, Rectangle, int); void textscrdraw(Text*); void textscroll(Text*, int); void textselect(Text*); int textselect2(Text*, uint*, uint*, Text**); int textselect23(Text*, uint*, uint*, Image*, int); int textselect3(Text*, uint*, uint*); void textsetorigin(Text*, uint, int); void textsetselect(Text*, uint, uint); void textshow(Text*, uint, uint, int); void texttype(Text*, Rune); struct Window { QLock lk; Ref ref; Text tag; Text body; Rectangle r; uchar isdir; uchar isscratch; uchar filemenu; uchar dirty; uchar autoindent; uchar showdel; int id; Range addr; Range limit; uchar nopen[QMAX]; uchar nomark; Range wrselrange; int rdselfd; Column *col; Xfid *eventx; char *events; int nevents; int owner; int maxlines; Dirlist **dlp; int ndl; int putseq; int nincl; Rune **incl; Reffont *reffont; QLock ctllock; uint ctlfid; char *dumpstr; char *dumpdir; int dumpid; int utflastqid; int utflastboff; int utflastq; int tagsafe; /* taglines is correct */ int tagexpand; int taglines; Rectangle tagtop; QLock editoutlk; }; void wininit(Window*, Window*, Rectangle); void winlock(Window*, int); void winlock1(Window*, int); void winunlock(Window*); void wintype(Window*, Text*, Rune); void winundo(Window*, int); void winsetname(Window*, Rune*, int); void winsettag(Window*); void winsettag1(Window*); void wincommit(Window*, Text*); int winresize(Window*, Rectangle, int, int); void winclose(Window*); void windelete(Window*); int winclean(Window*, int); void windirfree(Window*); void winevent(Window*, char*, ...); void winmousebut(Window*); void winaddincl(Window*, Rune*, int); void wincleartag(Window*); char *winctlprint(Window*, char*, int); struct Column { Rectangle r; Text tag; Row *row; Window **w; int nw; int safe; }; void colinit(Column*, Rectangle); Window* coladd(Column*, Window*, Window*, int); void colclose(Column*, Window*, int); void colcloseall(Column*); void colresize(Column*, Rectangle); Text* colwhich(Column*, Point); void coldragwin(Column*, Window*, int); void colgrow(Column*, Window*, int); int colclean(Column*); void colsort(Column*); void colmousebut(Column*); struct Row { QLock lk; Rectangle r; Text tag; Column **col; int ncol; }; void rowinit(Row*, Rectangle); Column* rowadd(Row*, Column *c, int); void rowclose(Row*, Column*, int); Text* rowwhich(Row*, Point); Column* rowwhichcol(Row*, Point); void rowresize(Row*, Rectangle); Text* rowtype(Row*, Rune, Point); void rowdragcol(Row*, Column*, int but); int rowclean(Row*); void rowdump(Row*, char*); int rowload(Row*, char*, int); void rowloadfonts(char*); struct Timer { int dt; int cancel; Channel *c; /* chan(int) */ Timer *next; }; struct Command { int pid; Rune *name; int nname; char *text; char **av; int iseditcmd; Mntdir *md; Command *next; }; struct Dirtab { char *name; uchar type; uint qid; uint perm; }; struct Mntdir { int id; int ref; Rune *dir; int ndir; Mntdir *next; int nincl; Rune **incl; }; struct Fid { int fid; int busy; int open; Qid qid; Window *w; Dirtab *dir; Fid *next; Mntdir *mntdir; int nrpart; uchar rpart[UTFmax]; vlong logoff; // for putlog }; struct Xfid { void *arg; /* args to xfidinit */ Fcall fcall; Xfid *next; Channel *c; /* chan(void(*)(Xfid*)) */ Fid *f; uchar *buf; int flushed; }; void xfidctl(void *); void xfidflush(Xfid*); void xfidopen(Xfid*); void xfidclose(Xfid*); void xfidread(Xfid*); void xfidwrite(Xfid*); void xfidctlwrite(Xfid*, Window*); void xfideventread(Xfid*, Window*); void xfideventwrite(Xfid*, Window*); void xfidindexread(Xfid*); void xfidutfread(Xfid*, Text*, uint, int); int xfidruneread(Xfid*, Text*, uint, uint); void xfidlogopen(Xfid*); void xfidlogread(Xfid*); void xfidlogflush(Xfid*); void xfidlog(Window*, char*); struct Reffont { Ref ref; Font *f; }; Reffont *rfget(int, int, int, char*); void rfclose(Reffont*); struct Rangeset { Range r[NRange]; }; struct Dirlist { Rune *r; int nr; int wid; }; struct Expand { uint q0; uint q1; Rune *name; int nname; char *bname; int jump; union{ Text *at; Rune *ar; } u; int (*agetc)(void*, uint); int a0; int a1; }; enum { /* fbufalloc() guarantees room off end of BUFSIZE */ BUFSIZE = Maxblock+IOHDRSZ, /* size from fbufalloc() */ RBUFSIZE = BUFSIZE/sizeof(Rune), EVENTSIZE = 256, }; #define Scrollwid scalesize(display, 12) #define Scrollgap scalesize(display, 4) #define Margin scalesize(display, 4) #define Border scalesize(display, 2) #define ButtonBorder scalesize(display, 2) #define QID(w,q) ((w<<8)|(q)) #define WIN(q) ((((ulong)(q).path)>>8) & 0xFFFFFF) #define FILE(q) ((q).path & 0xFF) #undef FALSE #undef TRUE enum { FALSE, TRUE, XXX }; enum { Empty = 0, Null = '-', Delete = 'd', Insert = 'i', Replace = 'r', Filename = 'f' }; enum /* editing */ { Inactive = 0, Inserting, Collecting }; uint globalincref; uint seq; uint maxtab; /* size of a tab, in units of the '0' character */ Display *display; Image *screen; Font *font; Mouse *mouse; Mousectl *mousectl; Keyboardctl *keyboardctl; Reffont reffont; Image *modbutton; Image *colbutton; Image *button; Image *but2col; Image *but3col; Cursor boxcursor; Cursor2 boxcursor2; Row row; int timerpid; Disk *disk; Text *seltext; Text *argtext; Text *mousetext; /* global because Text.close needs to clear it */ Text *typetext; /* global because Text.close needs to clear it */ Text *barttext; /* shared between mousetask and keyboardthread */ int bartflag; int swapscrollbuttons; Window *activewin; Column *activecol; Buffer snarfbuf; Rectangle nullrect; int fsyspid; char *cputype; char *objtype; char *home; char *acmeshell; char *fontnames[2]; Image *tagcols[NCOL]; Image *textcols[NCOL]; extern char wdir[]; /* must use extern because no dimension given */ int editing; int erroutfd; int messagesize; /* negotiated in 9P version setup */ int globalautoindent; int dodollarsigns; char* mtpt; enum { Kscrolloneup = KF|0x20, Kscrollonedown = KF|0x21 }; Channel *cplumb; /* chan(Plumbmsg*) */ Channel *cwait; /* chan(Waitmsg) */ Channel *ccommand; /* chan(Command*) */ Channel *ckill; /* chan(Rune*) */ Channel *cxfidalloc; /* chan(Xfid*) */ Channel *cxfidfree; /* chan(Xfid*) */ Channel *cnewwindow; /* chan(Channel*) */ Channel *mouseexit0; /* chan(int) */ Channel *mouseexit1; /* chan(int) */ Channel *cexit; /* chan(int) */ Channel *cerr; /* chan(char*) */ Channel *cedit; /* chan(int) */ Channel *cwarn; /* chan(void*)[1] (really chan(unit)[1]) */ QLock editoutlk; #define STACK 65536