typedef struct Panel Panel;
typedef struct Pops Pops;
typedef struct Plabel Plabel;
typedef struct Pimage Pimage;
typedef struct Pgauge Pgauge;
typedef struct Pframe Pframe;
typedef struct Pdraw Pdraw;
typedef struct Con Con;
typedef struct Edit Edit;
typedef struct Pcolrow Pcolrow;
typedef struct Tblock Tblock;
typedef struct Cmouse Cmouse;
typedef struct Icache Icache;
/*
* Locking and misc conventions:
*
* - A File holds its Panel in f->aux, which may be nil
* while the panel is being created.
* - p->dfile/cfile/file may be nil while being deleted.
* - All of dir/ctl/data hold refs to the panel, and
* the panel is removed once the last ref is gone.
* - No locking is done while creating the panel.
* - Rlocks on data file protect readers of the panel.
* - Wlocks on data file protect writers of the panel.
* - Only lib9p locks multiple files at the same time.
*/
enum {
// Grouping panel types;
Qnone, // no panel, used to catch up bugs
Qrow, // Lay out in columns
Qcol, // Lay out in rows
// Sizes
Inset = 3, // empty space for inner elements
Tagwid = 10, // size of the window tag box
Taght = 10,
// Window events through Panel.wevc
// when processed, send anything through Panel.wevr
Winit = 0,
Wexit = 0,
// Panel flags
Phide = 0x001, // panel is not shown
Ptop = 0x002, // A top-level layout container
Playout = 0x004, // A layout container, should always reclaim space.
Pedit = 0x008, // text can be edited with mouse/keyboard
Ptag = 0x010, // must show the tag, no matter the default rule.
Pmore = 0x020, // has more inner ones that are Phide
Pline = 0x040, // (text panel) use at most one line.
Pdirty = 0x080, // has unsaved changes, for tag.
Phold = 0x100, // hold layout change requests due to its tree.
Predraw = 0x200, // A redraw is needed.
Pdead = 0x400, // Its file(s) are being removed.
// Fonts
FR = 0, // regular (Vera 12pt)
FB, // bold (Vera bold 12pt)
FT, // teletype (Vera mono 12pt)
FL, // large (Vera mono 20pt)
FS, // small (Vera mono 10pt)
NFONT,
// Extra colors besides NCOL...
HBORD = NCOL,
BORD2,
WS1,
WS2,
WS3,
MAXCOL,
// Colors
CBack = 0xFAFAFFFF, // VERY light grey
CHigh = 0xFFAA00FF,
CSet = 0x5555AAFF, // blue
CClear = 0xADADADFF, // grey
// Images for borders and tags
Bback = 0, // background (no border)
Btag = 1, // tag image
Bdtag = 2, // dirty tag
Bmtag = 3, // maximized tag
Bdmtag = 4, // maximized dirty tag
Bn = 5, // north border
Bs = 6, // south border
Be = 7, // east border
Bw = 8, // west border
Bws1 = 9, // workspace tag #1 (#0 has no tag)
Bws2 = 10, // workspace tag #2
Bws3 = 11,
Bnw,
Bne,
Bse,
Bsw,
NBORD,
// addedit op's
Ins = 0,
Del,
};
struct Plabel {
char* text;
};
struct Pimage {
Icache* ic;
Rectangle irect;
int voff; // vertical offset for page
int hoff; // horizontal offset for page
};
struct Pdraw {
Rectangle drect;// image rectangle
Image* canvas; // where draws work
char* dcmds; // image drawing commands.
int dsize;
int dloaded;// true if has a draw to show.
};
struct Pgauge {
int pcent;
Rectangle grect;
};
struct Edit {
short op; // true for insert
short end; // true if it completes an edit.
Rune* r; // runes inserted; nil for deletion
int pos; // position where inserted/deleted
int nr; // number of runes
};
struct Pframe {
Tblock* blks;
char partial[UTFmax]; // partial rune sent from user
int npartial;
int partialoff;
Frame f;
int froff; // offset in text for rune #0 in frame
int loaded; // true if frame has been initialized
int ss, se; // start/end selection offsets in text
int s0; // offset in text for 1st selection point
int sdir; // direction of selection: >0 right; < 0 left
int mpos; // last position set by mouse
Rune* snarf;
int nsnarf;
Edit* undos; // edit operations that can be undone
int nundos; // # such ops
Edit* undo; // where to place next edit op in the list.
int cundo; // index in undos for a clean frame.
int nlines; // # lines in text (to compute maxsz)
int ncols; // used to report size
int nrows; // idem
int mark; // floating mark kept for users
int scroll; // do scroll for this
};
struct Pcolrow {
uint nwins; // # of inner winsows shown || 0 for all
};
struct Con {
Ref;
char* addr; // netaddr of event receiver
int fd; // connection to it.
};
struct Pops {
char* pref;
void (*init)(Panel*);
void (*term)(Panel*);
int (*ctl)(Panel*, char*);
long (*attrs)(Panel*,char*,long);
long (*read)(Panel*,void*,long,vlong);
long (*write)(Panel*,void*,long,vlong);
void (*draw)(Panel*, int);
void (*mouse)(Panel*, Cmouse* m, Channel* mc);
void (*keyboard)(Panel*, Rune);
long (*writeall)(Panel*, void*, long);
void (*truncate)(Panel*);
};
struct Panel {
Ref; // one per file holding it in its aux field.
Panel* link; // to next allocated panel
int type; // assigned automatically
char* name; // suffix of the file name; don't touch.
char* path; // cached full path for its file
File* file; // its correspondant directory.
File* cfile; // its ctl file
File* dfile; // its data file
Con* con; // where to send its events
long atime; // time() as of last kbd/mouse event
int flags;
int space; // id of workspace; 0 for boot ws.
int holdfid;// fid that sets Phold (to clear on clunk)
Point wants; // willing to get more x room
Point minsz; // Dx/Dy that we'd like as a minimum.
Point maxsz; // Dx/Dy that we would use at most, or ZP.
Font* font;
Rectangle rect; // where shown.
Rectangle orect; // where shown before last layout()
int ochild; // old #sons. to force redraw if changed.
Point size; // dx/dy wanted. Can be != Dx/Dy of rect.
char* writebuf;// for atomic writes to all the panel.
long nawrite; // # of bytes allocated in writebuf
long nwrite; // # of bytes used in writebuf
struct {
Pcolrow;
Plabel;
Pimage;
Pdraw;
Pgauge;
Pframe;
};
};
enum {
Nblock= 64, // exercise blocks
//Nblock= 8*1024,
};
struct Tblock {
Tblock* next;
Tblock* block0;
int nr;
int ar;
Rune* r;
};
#pragma varargck type "T" Tblock*
// |sort -bd +1
int Mfmt(Fmt* f);
int Tfmt(Fmt* f);
Edit* addedit(Panel* p, int op, Rune* r, int nr, int pos);
void argcursor(int yes);
char* block2str(Tblock* bl, long* l);
void blockcat(Tblock* b, Tblock* nb);
void blockdel(Tblock* b, int n, int len, Rune* rp);
void blockdump(Tblock* b);
void blockfree(Tblock* b);
void blockget(Tblock* b, int n, int len, Rune* rp);
void blockins(Tblock* b, int off, Rune* r, int len);
long blocklen(Tblock* b);
Tblock* blockseek(Tblock* b, int *np, int off);
long blocksize(Tblock* b);
void borders(File* f);
void cleanedits(Panel* p);
void cleanpolicy(File* f);
void closecon(Con* c);
void closepanel(Panel* p);
int conprint(Con* c, char* fmt, ...);
int cookclick(Cmouse* m, Channel* mc);
Channel* cookmouse(Channel* mc);
int cookslide(Cmouse* m, Channel* mc);
void detachfile(File* f);
void drawsel(Panel* p);
void drawtag(Panel* p, int setdirty);
void endfilewalk(File** sons);
void event(Panel* p, char* fmt, ...);
int fileclass(File* f);
char* filepath(File* f);
void filltext(Panel* p);
int findln(Tblock* b, int* pp);
int findrln(Tblock* b, int* pp);
int flagothersons(File* f, int set, int clr, File* excl);
int flagsons(File* f, int set, int clr, int first, int last);
int fontheight(Font* f);
int framedel(Panel* p, Rune* r, int nr, int pos);
int frameins(Panel* p, Rune* r, int nr, int pos);
void fullwin(File* f);
long genattrs(Panel* p, char* str, long l);
int genctl(Panel* p, char* op);
void genkeyboard(Panel* p, Rune r);
int genmouse(Panel* p, Cmouse* m, Channel* mc);
long genreadbuf(void* data, long count, vlong off, void *s, long n);
int gettextht(Panel* p);
int gettextwid(Panel* p);
Rune* gettextword(Panel* p, int pos, int* ss, int* se);
int hasedits(Panel* p);
int hassons(File* f, int flag);
int hastag(File*f);
int hidden(File* f);
void hidesel(Panel* p);
void incwin(File* f);
void initui(void);
void insertfile(File* from, File* dir, File* after);
int intag(Panel* p, Point xy);
double jumpscale(Panel* p, Point xy);
void layout(File* f);
void maxwin(File* f);
void minwin(File* f);
int mousecmdarg(File* f, Cmouse* m, Channel* mc);
Tblock* newblock(Rune* r, int nr);
Con* newcon(char* addr);
void newedit(Panel* p);
File** newfilewalk(File* f);
File* newfspanel(File* d, char* name, char* uid);
Panel* newpanel(char* name, Panel* parent);
long off2pos(Tblock* b, long off);
void othreadlistensrv(Srv *os, char *addr);
void packblock(Tblock* b);
void panelok(Panel* p);
File* paneltop(File* f);
File* pointinpanel(Point xy, int atomok);
long pos2off(Tblock* b, long pos);
void pstring(Point pt, Image* color, Font* font, char* s, Rectangle clipr);
int redo(Panel* p, int* ppos);
void resize(void);
void rmhuppanels(File* f, Con* c);
void rmpanel(File* f);
int runeslen(Rune* r);
void runoxloop(char* p);
int scrollframe(Panel* p, int nscroll);
void setctlfilelen(Panel* p);
void setfileclass(File* f, int id);
void setnoedits(Panel* p);
void setsel(Panel* p, int ss, int se);
void setterm(char* term);
int settextsize(Panel* p);
void shiftsonsleft(File* f);
void shiftsonsright(File* f);
void showtree(File* f, int force);
long sprintattrs(Panel* p, char* str, long l, char* attr);
void startproc(void*a);
Tblock* str2block(char* s);
void tagmousecmd(File *f, Cmouse* m, Channel* mc);
void textdel(Panel* p, Rune* r, int nr, int pos);
int textins(Panel* p, Rune* r, int nr, int pos);
void threadmain(int argc, char **argv);
int undo(Panel* p, int* ppos);
void usage(void);
Rune* utf2runes(char* s, int* lp, int* nlines);
int wcommand(char* c);
int within(File* d, File* f);
#define ispanel(f) ((f) && ((f)->qid.type&QTDIR) && (f)->aux)
#define Ox "/bin/ox"
extern File* slash;
extern Image* cols[MAXCOL];
extern Image* bord[NBORD];
extern Font* fonts[NFONT];
extern Channel* panelhupc;
extern char* sname;
extern char* saddr;
extern Channel* startc;
extern Channel* destroyc;
#define dprint if(eventdebug)print
#define ldprint if(layoutdebug)print
#define fdprint if(framedebug)print
#define edprint if(eventdebug)print
#define Edprint if(eventdebug>1)print
#define tdprint if(textdebug)print
#define cdprint if(condebug)print
#define bdprint if(blockdebug)print
extern int blockdebug;
extern int layoutdebug;
extern int framedebug;
extern int eventdebug;
extern int textdebug;
extern int condebug;
extern int smallomero;
extern Pops* panels[];
extern Point lastxy;
|