diff options
-rw-r--r-- | src/Makefile.in | 8 | ||||
-rw-r--r-- | src/help.c | 4 | ||||
-rw-r--r-- | src/list_display.c | 363 | ||||
-rw-r--r-- | src/list_generic.c | 266 | ||||
-rw-r--r-- | src/list_generic.h | 63 |
5 files changed, 492 insertions, 212 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 8120726..0706290 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,11 +62,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ - list_display.c + list_display.c list_generic.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ + list_generic.o list_display.o \ sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o all: screen @@ -303,7 +304,7 @@ loadav.o: layout.h viewport.h canvas.h loadav.c config.h screen.h os.h osdef.h a comm.h layer.h term.h image.h display.h window.h extern.h putenv.o: layout.h viewport.h canvas.h putenv.c config.h help.o: layout.h viewport.h canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ - comm.h layer.h term.h image.h display.h window.h extern.h list_display.c + comm.h layer.h term.h image.h display.h window.h extern.h list_display.c list_generic.h termcap.o: layout.h viewport.h canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h input.o: layout.h viewport.h canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ @@ -346,3 +347,6 @@ layout.o: layout.h viewport.h canvas.h layout.c config.h screen.h os.h osdef.h a viewport.o: layout.h viewport.h canvas.h viewport.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h \ braille.h +list_generic.o: list_generic.h list_generic.c layer.h +list_display.o: list_generic.h list_display.c layer.h + @@ -33,6 +33,8 @@ #include "screen.h" #include "extern.h" +#include "list_generic.h" + char version[60]; /* initialised by main() */ extern struct layer *flayer; @@ -681,8 +683,6 @@ int y, xs, xe, isblank; } -#include "list_display.c" - /* ** ** here is the windowlist diff --git a/src/list_display.c b/src/list_display.c index 3693f01..28ec7bb 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -28,150 +31,16 @@ /* Deals with the list of displays */ -#ifdef MULTI - -struct displaysdata -{ - struct display *selected; /* The selected display */ - struct display *current; /* The current display (that's showing this list) */ -}; - -static void DisplaysProcess __P((char **, int *)); -static void DisplaysRedisplayLine __P((int, int, int, int)); -static void displayspage __P((struct displaysdata *)); - -static struct LayFuncs DisplaysLf = -{ - DisplaysProcess, - HelpAbort, - DisplaysRedisplayLine, - DefClearLine, - DefRewrite, - DefResize, - DefRestore -}; +#include "config.h" -void -display_displays() -{ - struct displaysdata *ddata; - if (flayer->l_width < 10 || flayer->l_height < 5) - { - LMsg(0, "Window size too small for displays page"); - return; - } - if (InitOverlayPage(sizeof(struct displaysdata), &DisplaysLf, 0)) - return; - flayer->l_mode = 1; - flayer->l_x = 0; - flayer->l_y = flayer->l_height - 1; - ddata = flayer->l_data; - ddata->current = display; - ddata->selected = display; - displayspage(ddata); -} +#include "screen.h" +#include "list_generic.h" -static void -display_list_change(struct displaysdata *ddata, int dir) -{ - struct display *d; - for (d = displays; d; d = d->d_next) - { - if (dir == -1 && d->d_next == ddata->selected) - { - ddata->selected = d; - break; - } - else if (dir == 1 && d == ddata->selected && d->d_next) - { - ddata->selected = d->d_next; - break; - } - } - - if (d) - { - /* Selection changed */ - displayspage(ddata); - } -} - -static void -DisplaysProcess(ppbuf, plen) -char **ppbuf; -int *plen; -{ - int done = 0; - - ASSERT(flayer); - while (!done && *plen > 0) - { - unsigned char ch = (unsigned char)**ppbuf; - ++*ppbuf; - --*plen; - if (flayer->l_mouseevent.start) - { - int r = LayProcessMouse(flayer, ch); - if (r == -1) - LayProcessMouseSwitch(flayer, 0); - else - { - if (r) - ch = 0222; - else - continue; - } - } - switch (ch) - { - case ' ': - displayspage(flayer->l_data); - break; - case '\r': - case '\n': - HelpAbort(); - done = 1; - break; - - case 0220: /* up */ - case 16: /* ^P like emacs */ - case 'k': - display_list_change(flayer->l_data, -1); - break; - - case 0216: /* down */ - case 14: /* ^N like emacs */ - case 'j': - display_list_change(flayer->l_data, 1); - break; - - case 0222: /* mouse event */ - if (flayer->l_mouseevent.start) - { - /* All the data is available to process the mouse event. */ - int button = flayer->l_mouseevent.buffer[0]; - if (button == 'a') - { - /* Scroll down */ - display_list_change(flayer->l_data, 1); - } - else if (button == '`') - { - /* Scroll up */ - display_list_change(flayer->l_data, -1); - } - LayProcessMouseSwitch(flayer, 0); - } - else - LayProcessMouseSwitch(flayer, 1); - break; - - default: - break; - } - } -} +#ifdef MULTI +extern struct layer *flayer; +extern struct display *display, *displays; +extern struct mchar mchar_blank, mchar_so; /* * layout of the displays page is as follows: @@ -180,7 +49,7 @@ xterm 80x42 jnweiger@/dev/ttyp4 0(m11) &rWx facit 80x24 nb mlschroe@/dev/ttyhf 11(tcsh) rwx xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x - | | | | | | | | ¦___ window permissions + | | | | | | | | ¦___ window permissions | | | | | | | | (R. is locked r-only, | | | | | | | | W has wlock) | | | | | | | |___ Window is shared @@ -191,97 +60,175 @@ xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x | | |___ Display is in nonblocking mode. Shows 'NB' if obuf is full. | |___ Displays geometry as width x height. |___ the terminal type known by screen for this display. - + */ -static void -displayspage(ddata) -struct displaysdata *ddata; +static int +gl_Display_header(struct ListData *ldata) { - int y, l; + leftline("term-type size user interface window Perms", 0, 0); + leftline("---------- ------- ---------- ----------------- ---------- -----", 1, 0); + return 2; +} + +static int +gl_Display_footer(struct ListData *ldata) +{ + centerline("[Press Space to refresh; Return to end.]", flayer->l_height - 1); +} + +static int +gl_Display_row(struct ListData *ldata, struct ListRow *lrow) +{ + struct display *d = lrow->data; char tbuf[80]; - struct display *d; - struct win *w; static char *blockstates[5] = {"nb", "NB", "Z<", "Z>", "BL"}; + struct win *w = d->d_fore; struct mchar m_current = mchar_blank; m_current.attr = A_BD; - if (!ddata) - return; + sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", + d->d_termname, d->d_width, d->d_height, d->d_user->u_name, + d->d_usertty, + (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); - LClearAll(flayer, 0); + if (w) + { + int l = 10 - strlen(w->w_title); + if (l < 0) + l = 0; + sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", + w->w_number, w->w_title, l, "", + /* w->w_dlist->next */ 0 ? '&' : ' ', + /* + * The rwx triple: + * -,r,R no read, read, read only due to foreign wlock + * -,.,w,W no write, write suppressed by foreign wlock, + * write, own wlock + * -,x no execute, execute + */ +#ifdef MULTIUSER + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? + 'r' : 'R')), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF) ? 'w' : + ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') +#else + 'r', 'w', 'x' +#endif + ); + } + leftline(tbuf, lrow->y, lrow == ldata->selected ? &mchar_so : d == display ? &m_current : 0); - leftline("term-type size user interface window Perms", 0, 0); - leftline("---------- ------- ---------- ----------------- ---------- -----", 1, 0); - y = 2; + return 1; +} +static void +gl_Display_rebuild(struct ListData *ldata) +{ + /* recreate the rows */ + struct display *d; + struct ListRow *row = NULL; for (d = displays; d; d = d->d_next) { - struct mchar *mc; - w = d->d_fore; + row = glist_add_row(ldata, d, row); + if (d == display) + ldata->selected = row; + } - if (y >= flayer->l_height - 3) - break; - sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", - d->d_termname, d->d_width, d->d_height, d->d_user->u_name, - d->d_usertty, - (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); + glist_display_all(ldata); +} - if (w) - { - l = 10 - strlen(w->w_title); - if (l < 0) - l = 0; - sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", - w->w_number, w->w_title, l, "", - /* w->w_dlist->next */ 0 ? '&' : ' ', - /* - * The rwx triple: - * -,r,R no read, read, read only due to foreign wlock - * -,.,w,W no write, write suppressed by foreign wlock, - * write, own wlock - * -,x no execute, execute - */ -#ifdef MULTIUSER - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? - 'r' : 'R')), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF) ? 'w' : - ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') +static int +gl_Display_input(struct ListData *ldata, char **inp, int *len) +{ + struct display *cd = display; + unsigned char ch = (unsigned char) **inp; + + ++*inp; + --*len; + + switch (ch) + { + case ' ': /* Space to refresh */ + glist_remove_rows(ldata); + gl_Display_rebuild(ldata); + break; + + case '\r': + case '\n': + glist_abort(); + *len = 0; + break; + + case 'd': /* Detach */ + case 'D': /* Power detach */ + display = ldata->selected->data; + if (display == cd) /* We do not allow detaching the current display */ + break; + Detach( +#ifdef POW_DETACH + ch == 'D' ? D_REMOTE_POWER : D_REMOTE #else - 'r', 'w', 'x' + D_REMOTE #endif ); - } - leftline(tbuf, y, d == ddata->selected ? &mchar_so : d == ddata->current ? &m_current : 0); - if (d == ddata->selected) - flayer->l_y = y; - y++; + display = cd; + glist_remove_rows(ldata); + gl_Display_rebuild(ldata); + break; + + break; + + default: + /* We didn't actually process the input. */ + --*inp; + ++*len; + return 0; } - sprintf(tbuf,"[Press Space %s Return to end.]", - 1 ? "to refresh;" : "or"); - centerline(tbuf, flayer->l_height - 2); - LaySetCursor(); + return 1; } -static void -DisplaysRedisplayLine(y, xs, xe, isblank) -int y, xs, xe, isblank; +static int +gl_Display_freerow(struct ListData *ldata, struct ListRow *row) { - ASSERT(flayer); - if (y < 0) + /* There was no allocation when row->data was set. So nothing to do here. */ +} + +static struct GenericList gl_Display = +{ + gl_Display_header, + gl_Display_footer, + gl_Display_row, + gl_Display_input, + gl_Display_freerow +}; + +void +display_displays() +{ + struct display *d; + struct ListRow *row = NULL; + struct ListData *ldata; + if (flayer->l_width < 10 || flayer->l_height < 5) { - displayspage(flayer->l_data); + LMsg(0, "Window size too small for displays page"); return; } - if (y != 0 && y != flayer->l_height - 1) - return; - if (isblank) + + ldata = glist_display(&gl_Display); + if (!ldata) return; - LClearArea(flayer, xs, y, xe, y, 0, 0); - /* To be filled in... */ + + for (d = displays; d; d = d->d_next) + { + row = glist_add_row(ldata, d, row); + if (d == display) + ldata->selected = row; + } + glist_display_all(ldata); } #endif /* MULTI */ diff --git a/src/list_generic.c b/src/list_generic.c new file mode 100644 index 0000000..112b588 --- /dev/null +++ b/src/list_generic.c @@ -0,0 +1,266 @@ +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +#include "config.h" +#include "screen.h" +#include "list_generic.h" +#include "layer.h" + +/* Deals with a generic list display */ + +extern struct layer *flayer; + +static void ListProcess __P((char **, int *)); +static void ListAbort __P((void)); +static void ListRedisplayLine __P((int, int, int, int)); +static void ListClearLine __P((int, int, int, int)); +static int ListRewrite __P((int, int, int, struct mchar *, int)); +static int ListResize __P((int, int)); +static void ListRestore __P((void)); + +static struct LayFuncs ListLf = +{ + ListProcess, + ListAbort, + ListRedisplayLine, + ListClearLine, + ListRewrite, + ListResize, + ListRestore +}; + +/** Returns non-zero on success. */ +struct ListData * +glist_display(struct GenericList *list) +{ + struct ListData *ldata; + + if (InitOverlayPage(sizeof(struct ListData), &ListLf, 0)) + return NULL; + ldata = flayer->l_data; + + ldata->list_fn = list; + + flayer->l_mode = 1; + flayer->l_x = 0; + flayer->l_y = flayer->l_height - 1; + + return ldata; +} + +static void ListProcess(char **ppbuf, int *plen) +{ + struct ListData *ldata = flayer->l_data; + + while (*plen > 0) + { + struct ListRow *old; + unsigned char ch; + + if (ldata->list_fn->gl_pinput && + ldata->list_fn->gl_pinput(ldata, ppbuf, plen)) + continue; + + if (!ldata->selected) + *plen = 0; + + ch = **ppbuf; + ++*ppbuf; + --*plen; + + old = ldata->selected; + switch (ch) + { + case ' ': + break; + + case '\r': + case '\n': + break; + + case 0220: /* up */ + case 16: /* ^P */ + case 'k': + if (!ldata->selected->prev) /* There's no where to go */ + break; + ldata->selected = old->prev; + break; + + case 0216: /* down */ + case 14: /* ^N like emacs */ + case 'j': + if (!ldata->selected->next) /* Nothing to do */ + break; + old = ldata->selected; + ldata->selected = old->next; + break; + + case 007: + ListAbort(); + *plen = 0; + return; + } + + if (old == ldata->selected) /* The selection didn't change */ + continue; + + if (ldata->selected->y == -1) + { + /* We need to list all the rows, since we are scrolling down */ + glist_display_all(ldata); + } + else + { + /* just redisplay the two lines. */ + ldata->list_fn->gl_printrow(ldata, old); + ldata->list_fn->gl_printrow(ldata, ldata->selected); + } + } +} + +static void ListAbort(void) +{ + struct ListData *ldata = flayer->l_data; + glist_remove_rows(ldata); + LAY_CALL_UP(LRefreshAll(flayer, 0)); + ExitOverlayPage(); +} + +static void ListRedisplayLine(int y, int xs, int xe, int isblank) +{ + ASSERT(flayer); + if (y < 0) + { + glist_display_all(flayer->l_data); + return; + } + if (y != 0 && y != flayer->l_height - 1) + return; + + if (isblank) + return; + LClearArea(flayer, xs, y, xe, y, 0, 0); +} + +static void ListClearLine(int y, int xs, int xe, int bce) +{ + DefClearLine(y, xs, xe, bce); +} + +static int ListRewrite(int y, int xs, int xe, struct mchar *rend, int doit) +{ + return EXPENSIVE; +} + +static int ListResize (int wi, int he) +{ + if (wi < 10 || he < 5) + return -1; + + flayer->l_width = wi; + flayer->l_height = he; + flayer->l_y = he - 1; + + return 0; +} + +static void ListRestore (void) +{ + DefRestore(); +} + +struct ListRow * +glist_add_row(struct ListData *ldata, void *data, struct ListRow *after) +{ + struct ListRow *r = calloc(1, sizeof(struct ListRow)); + r->data = data; + + if (after) + { + r->next = after->next; + r->prev = after; + after->next = r; + if (r->next) + r->next->prev = r; + } + else + { + r->next = ldata->root; + if (ldata->root) + ldata->root->prev = r; + ldata->root = r; + } + + return r; +} + +void +glist_remove_rows(struct ListData *ldata) +{ + struct ListRow *row; + for (row = ldata->root; row; row = row->next) + { + ldata->list_fn->gl_freerow(ldata, row); + free(row); + } + ldata->root = ldata->selected = ldata->top = NULL; +} + +void +glist_display_all(struct ListData *list) +{ + int y; + struct ListRow *row; + + LClearAll(flayer, 0); + + y = list->list_fn->gl_printheader(list); + + if (!list->top) + list->top = list->root; + + for (row = list->root; row != list->top; row = row->next) + row->y = -1; + + for (row = list->top; row; row = row->next) + { + row->y = y++; + if (!list->list_fn->gl_printrow(list, row)) + { + row->y = -1; + y--; + } + if (y + 1 == flayer->l_height) + break; + } + for (; row; row = row->next) + row->y = -1; + + list->list_fn->gl_printfooter(list); + LaySetCursor(); +} + +void glist_abort(void) +{ + ListAbort(); +} + diff --git a/src/list_generic.h b/src/list_generic.h new file mode 100644 index 0000000..0c0e5b0 --- /dev/null +++ b/src/list_generic.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +struct ListData; + +struct ListRow +{ + void *data; /* Some data relevant to this row */ + struct ListRow *next, *prev; /* doubly linked list */ + struct ListRow *parent, *child; /* can also be tree */ + int y; /* -1 if not on display */ +}; + +struct GenericList +{ + int (*gl_printheader) __P((struct ListData *)); + int (*gl_printfooter) __P((struct ListData *)); + int (*gl_printrow) __P((struct ListData *, struct ListRow *)); + int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); + int (*gl_freerow) __P((struct ListData *, struct ListRow *)); +}; + +struct ListData +{ + struct ListRow *root; /* The first item in the list */ + struct ListRow *selected; /* The selected row */ + struct ListRow *top; /* The topmost visible row */ + + struct GenericList *list_fn; /* The functions that deal with the list */ +}; + + +struct ListRow * glist_add_row __P((struct ListData *ldata, void *data, struct ListRow *after)); + +void glist_remove_rows __P((struct ListData *ldata)); + +void glist_display_all __P((struct ListData *list)); + +struct ListData * glist_display __P((struct GenericList *list)); + +void glist_abort __P((void)); + +void display_displays __P((void)); + |