/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ enum { Qdir, Qacme, Qcons, Qconsctl, Qdraw, Qeditout, Qindex, Qlabel, 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 */ }; 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 { uint32_t addr; /* disk address in bytes */ union { uint32_t n; /* number of used runes in block */ Block *next; /* pointer to next in free list */ }; }; struct Disk { int fd; uint32_t addr; /* length of temp file */ Block *free[Maxblock/Blockincr+1]; }; Disk* diskinit(void); Block* disknewblock(Disk*, uint32_t); void diskrelease(Disk*, Block*); void diskread(Disk*, Block*, Rune*, uint32_t); void diskwrite(Disk*, Block**, Rune*, uint32_t); struct Buffer { uint32_t nc; Rune *c; /* cache */ uint32_t cnc; /* bytes in cache */ uint32_t cmax; /* size of allocated cache */ uint32_t cq; /* position of cache */ int cdirty; /* cache needs to be written */ uint32_t cbi; /* index of cache Block */ Block **bl; /* array of blocks */ uint32_t nbl; /* number of blocks */ }; void bufinsert(Buffer*, uint32_t, Rune*, uint32_t); void bufdelete(Buffer*, uint32_t, uint32_t); uint32_t bufload(Buffer*, uint32_t, int, int*); void bufread(Buffer*, uint32_t, Rune*, uint32_t); void bufclose(Buffer*); void bufreset(Buffer*); struct Elog { short type; /* Delete, Insert, Filename */ uint32_t q0; /* location of change (unused in f) */ uint32_t nd; /* number of deleted characters */ uint32_t 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; /* 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 */ uint64_t qidpath; /* of file when read */ uint32_t mtime; /* of file when read */ int dev; /* 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*, uint32_t, uint32_t); void filedeltext(File*, Text*); void fileinsert(File*, uint32_t, Rune*, uint32_t); uint32_t fileload(File*, uint32_t, int, int*); void filemark(File*); void filereset(File*); void filesetname(File*, Rune*, int); void fileundelete(File*, Buffer*, uint32_t, uint32_t); void fileuninsert(File*, Buffer*, uint32_t, uint32_t); void fileunsetname(File*, Buffer*); void fileundo(File*, int, uint32_t*, uint32_t*); uint32_t fileredoseq(File*); enum /* Text.what */ { Columntag, Rowtag, Tag, Body, }; struct Text { File *file; Frame; Reffont *reffont; uint32_t org; uint32_t q0; uint32_t q1; int what; int tabstop; Window *w; Rectangle scrollr; Rectangle lastsr; Rectangle all; Row *row; Column *col; uint32_t eq0; /* start of typing for ESC */ uint32_t cq0; /* cache position */ int ncache; /* storage for insert */ int ncachealloc; Rune *cache; int nofill; }; uint32_t textbacknl(Text*, uint32_t, uint32_t); uint32_t textbsinsert(Text*, uint32_t, Rune*, uint32_t, int, int*); int textbswidth(Text*, Rune); int textclickmatch(Text*, int, int, int, uint32_t*); void textclose(Text*); void textcolumnate(Text*, Dirlist**, int); void textcommit(Text*, int); void textconstrain(Text*, uint32_t, uint32_t, uint32_t*, uint32_t*); void textdelete(Text*, uint32_t, uint32_t, int); void textdoubleclick(Text*, uint32_t*, uint32_t*); void textfill(Text*); void textframescroll(Text*, int); void textinit(Text*, File*, Rectangle, Reffont*, Image**); void textinsert(Text*, uint32_t, Rune*, uint32_t, int); uint32_t textload(Text*, uint32_t, char*, int); Rune textreadc(Text*, uint32_t); void textredraw(Text*, Rectangle, Font*, Image*, int); void textreset(Text*); int textresize(Text*, Rectangle); void textscrdraw(Text*); void textscroll(Text*, int); void textselect(Text*); int textselect2(Text*, uint32_t*, uint32_t*, Text**); int textselect23(Text*, uint32_t*, uint32_t*, Image*, int); int textselect3(Text*, uint32_t*, uint32_t*); void textsetorigin(Text*, uint32_t, int); void textsetselect(Text*, uint32_t, uint32_t); void textshow(Text*, uint32_t, uint32_t, int); void texttype(Text*, Rune); struct Window { QLock; Ref; Text tag; Text body; Rectangle r; uint8_t isdir; uint8_t isscratch; uint8_t filemenu; uint8_t dirty; uint8_t autoindent; uint8_t showdel; uint32_t noredraw; int id; Range addr; Range limit; uint8_t nopen[QMAX]; uint8_t nomark; uint8_t noscroll; 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; uint32_t ctlfid; char *dumpstr; char *dumpdir; int dumpid; int utflastqid; int utflastboff; int utflastq; int tagsafe; /* taglines is correct */ int tagexpand; int taglines; Rectangle tagtop; }; 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); 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; 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; uint8_t type; uint32_t qid; uint32_t 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; uint8_t rpart[UTFmax]; }; struct Xfid { void *arg; /* args to xfidinit */ Fcall; Xfid *next; Channel *c; /* chan(void(*)(Xfid*)) */ Fid *f; uint8_t *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*, uint32_t, int); int xfidruneread(Xfid*, Text*, uint32_t, uint32_t); struct Reffont { 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 { uint32_t q0; uint32_t q1; Rune *name; int nname; char *bname; int jump; union{ Text *at; Rune *ar; }; int (*agetc)(void*, uint32_t); int a0; int a1; }; enum { /* fbufalloc() guarantees room off end of BUFSIZE */ BUFSIZE = Maxblock+IOHDRSZ, /* size from fbufalloc() */ RBUFSIZE = BUFSIZE/sizeof(Rune), EVENTSIZE = 256, Scrollwid = 12, /* width of scroll bar */ Scrollgap = 4, /* gap right of scroll bar */ Margin = 4, /* margin around text */ Border = 2, /* line between rows, cols, windows */ }; #define QID(w,q) ((w<<8)|(q)) #define WIN(q) ((((uint32_t)(q).path)>>8) & 0xFFFFFF) #define FILE(q) ((q).path & 0xFF) enum { FALSE, TRUE, XXX, }; enum { Empty = 0, Null = '-', Delete = 'd', Insert = 'i', Replace = 'r', Filename = 'f', }; enum /* editing */ { Inactive = 0, Inserting, Collecting, }; uint32_t globalincref; uint32_t seq; uint32_t 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; 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; Window *activewin; Column *activecol; Buffer snarfbuf; Rectangle nullrect; int fsyspid; char *cputype; char *objtype; char *home; char *fontnames[2]; char acmeerrorfile[128]; Image *tagcols[NCOL]; Image *textcols[NCOL]; int plumbsendfd; int plumbeditfd; char wdir[512]; int editing; int messagesize; /* negotiated in 9P version setup */ int globalautoindent; 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]) */ #define STACK 8192