📄 w.c
字号:
/* * Window system * Copyright * (C) 1992 Joseph H. Allen * * This file is part of JOE (Joe's Own Editor) */#include "types.h"/* Count no. of main windows */int countmain(Screen *t){ int nmain = 1; W *m = t->curwin->main; W *q; for (q = t->curwin->link.next; q != t->curwin; q = q->link.next) if (q->main != m) { ++nmain; m = q->main; } return nmain;}/* Redraw a window */void wredraw(W *w){ msetI(w->t->t->updtab + w->y, 1, w->h);}/* Find first window in a group */W *findtopw(W *w){ W *x; for (x = w; x->link.prev->main == w->main && x->link.prev != w; x = x->link.prev) ; return x;}/* Determine height of a window. Returns reqh if it is set, otherwise * used fixed or hh scaled to the current screen size */static int geth(W *w){ if (w->reqh) return w->reqh; else if (w->fixed) return w->fixed; else return (((long) w->t->h - w->t->wind) * w->hh) / 1000;}/* Set the height of a window */static void seth(W *w, int h){ long tmp; w->reqh = h; tmp = 1000L * h; w->hh = tmp / (w->t->h - w->t->wind) + (tmp % (w->t->h - w->t->wind) ? 1 : 0);}/* Determine height of a family of windows. Uses 'reqh' if it's set */int getgrouph(W *w){ W *x; int h; /* Find first window in family */ x = findtopw(w); /* Add heights of all windows in family */ for (w = x, h = geth(w); w->link.next != x && w->link.next->main == x->main; w = w->link.next, h += geth(w)) ; return h;}/* Determine minimum height of a family */static int getminh(W *w){ W *x; int h; x = findtopw(w); for (w = x, h = (w->fixed ? w->fixed : 2); w->link.next != x && w->link.next->main == x->main; w = w->link.next, h += (w->fixed ? w->fixed : 2)) ; return h;}/* Find last window in a group */W *findbotw(W *w){ W *x; for (x = w; x->link.next->main == w->main && x->link.next != w; x = x->link.next) ; return x;}/* Demote group of window to end of window list. Returns true if top window was demoted */int demotegroup(W *w){ W *top = findtopw(w); W *bot = findbotw(w); W *next; int flg = 0; for (w = top; w != bot; w = next) { next = w->link.next; if (w == w->t->topwin) { flg = 1; w->t->topwin = next; } else demote(W, link, w->t->topwin, w); w->y = -1; } if (w == w->t->topwin) flg = 1; else demote(W, link, w->t->topwin, w); w->y = -1; return flg;}/* Find last window on the screen */W *lastw(Screen *t){ W *x; for (x = t->topwin; x->link.next != t->topwin && x->link.next->y >= 0; x = x->link.next) ; return x;}/* Create a screen object */Screen *scr;Screen *screate(SCRN *scrn){ Screen *t = (Screen *) joe_malloc(sizeof(Screen)); t->t = scrn; t->w = scrn->co; t->h = scrn->li; t->topwin = NULL; t->curwin = NULL; t->wind = skiptop; scr = t; return t;}void sresize(Screen *t){ SCRN *scrn = t->t; W *w; t->w = scrn->co; t->h = scrn->li; if (t->h - t->wind < FITHEIGHT) t->wind = t->h - FITHEIGHT; if (t->wind < 0) t->wind = 0; w = t->topwin; do { w->y = -1; w->w = t->w - 1; w = w->link.next; } while (w != t->topwin); wfit(t); updall();}void updall(void){ int y; for (y = 0; y != scr->h; ++y) { scr->t->updtab[y] = 1; }}void scrins(B *b, long l, long n, int flg){ W *w; if ((w = scr->topwin) != NULL) { do { if (w->y >= 0) { if (w->object && w->watom->ins) w->watom->ins(w->object, b, l, n, flg); } w = w->link.next; } while (w != scr->topwin); }}void scrdel(B *b, long l, long n, int flg){ W *w; if ((w = scr->topwin) != NULL) { do { if (w->y >= 0) { if (w->object && w->watom->del) w->watom->del(w->object, b, l, n, flg); } w = w->link.next; } while (w != scr->topwin); }}W *watpos(Screen *t,int x,int y){ W *w=t->topwin; do if(w->y>=0 && w->y<=y && w->y+w->h>y && w->x<=x && w->x+w->w>x) return w; while(w=w->link.next, w!=t->topwin); return 0;}/* Fit as many windows on the screen as is possible beginning with the window * at topwin. Give any extra space which couldn't be used to fit in another * window to the last text window on the screen. This function guarentees * to fit on the window with the cursor in it (moves topwin to next group * of windows until window with cursor fits on screen). */static int doabort(W *w, int *ret);void wfit(Screen *t){ int y; /* Where next window goes */ int left; /* Lines left on screen */ W *w; /* Current window we're fitting */ W *pw; /* Main window of previous family */ int req; /* Amount this family needs */ int adj; /* Amount family needs to be adjusted */ int flg = 0; /* Set if cursor window was placed on screen */ int ret; dostaupd = 1; tryagain: y = t->wind; left = t->h - y; pw = NULL; w = t->topwin; do { w->ny = -1; w->nh = geth(w); w = w->link.next; } while (w != t->topwin); /* Fit a group of windows on the screen */ w = t->topwin; do { req = getgrouph(w); if (req > left) /* If group is taller than lines left */ adj = req - left; /* then family gets shorter */ else adj = 0; /* Fit a family of windows on the screen */ do { w->ny = y; /* Set window's y position */ if (!w->win) { pw = w; w->nh -= adj; /* Adjust main window of the group */ } if (!w->win && w->nh < 2) while (w->nh < 2) w->nh += doabort(w->link.next, &ret); if (w == t->curwin) flg = 1; /* Set if we got window with cursor */ y += w->nh; left -= w->nh; /* Increment y value by height of window */ w = w->link.next; /* Next window */ } while (w != t->topwin && w->main == w->link.prev->main); } while (w != t->topwin && left >= FITHEIGHT); /* We can't use extra space to fit a new family on, so give space to parent of * previous family */ pw->nh += left; /* Adjust that family's children which are below the parent */ while ((pw = pw->link.next) != w) pw->ny += left; /* Make sure the cursor window got on the screen */ if (!flg) { t->topwin = findbotw(t->topwin)->link.next; goto tryagain; } /* All of the windows are now on the screen. Scroll the screen to reflect what * happened */ w = t->topwin; do { if (w->y >= 0 && w->ny >= 0) if (w->ny > w->y) { W *l = pw = w; while (pw->link.next != t->topwin && (pw->link.next->y < 0 || pw->link.next->ny < 0 || pw->link.next->ny > pw->link.next->y)) { pw = pw->link.next; if (pw->ny >= 0 && pw->y >= 0) l = pw; } /* Scroll windows between l and w */ loop1: if (l->ny >= 0 && l->y >= 0) nscrldn(t->t, l->y, l->ny + uns_min(l->h, l->nh), l->ny - l->y); if (w != l) { l = l->link.prev; goto loop1; } w = pw->link.next; } else if (w->ny < w->y) { W *l = pw = w; while (pw->link.next != t->topwin && (pw->link.next->y < 0 || pw->link.next->ny < 0 || pw->link.next->ny < pw->link.next->y)) { pw = pw->link.next; if (pw->ny >= 0 && pw->y >= 0) l = pw; } /* Scroll windows between l and w */ loop0: if (w->ny >= 0 && w->y >= 0) nscrlup(t->t, w->ny, w->y + uns_min(w->h, w->nh), w->y - w->ny); if (w != l) { w = w->link.next; goto loop0; } w = pw->link.next; } else w = w->link.next; else w = w->link.next; } while (w != t->topwin); /* Update current height and position values */ w = t->topwin; do { if (w->ny >= 0) { if (w->object) { if (w->watom->move) w->watom->move(w->object, w->x, w->ny); if (w->watom->resize) w->watom->resize(w->object, w->w, w->nh); } if (w->y == -1) { msetI(t->t->updtab + w->ny, 1, w->nh); } w->y = w->ny; } else w->y = -1; w->h = w->nh; w->reqh = 0; w = w->link.next; } while (w != t->topwin);}/* Goto next window */int wnext(Screen *t){ if (t->curwin->link.next != t->curwin) { t->curwin = t->curwin->link.next; if (t->curwin->y == -1) wfit(t); return 0; } else return -1;}/* Goto previous window */int wprev(Screen *t){ if (t->curwin->link.prev != t->curwin) { t->curwin = t->curwin->link.prev; if (t->curwin->y == -1) { t->topwin = findtopw(t->curwin); wfit(t); } return 0; } else return -1;}/* Grow window */int wgrow(W *w){ W *nextw; /* If we're the last window on the screen, shrink the previous window */ if ((w->link.next == w->t->topwin || w->link.next->y == -1) && w != w->t->topwin) return wshrink(w->link.prev->main); /* Get to next variable size window */ for (nextw = w->link.next; nextw->fixed && nextw != w->t->topwin; nextw = nextw->link.next) ; /* Is it below us, on screen and big enough to take space from? */ if (nextw == w->t->topwin || nextw->y == -1 || nextw->h <= FITHEIGHT) return -1; /* Increase this window's height */ seth(w, w->h + 1); /* Decrease next window's height */ seth(nextw, nextw->h - 1); /* Do it */ wfit(w->t); return 0;}/* Shrink window */int wshrink(W *w){ W *nextw; /* If we're the last window on the screen, grow the previous window */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -