From 04f2e5342014efbbc6ba2d7277d33d3be388b2fd Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 22 Feb 2010 20:50:31 -0500 Subject: Revamp the window list. The window list now uses the list-framework. The basic window list is working. The list for a group, or nested/mru lists still need some work. This is going to be a much simpler code than before. --- src/Makefile.in | 7 +- src/help.c | 17 ++++ src/list_display.c | 27 +++-- src/list_generic.c | 10 +- src/list_generic.h | 15 ++- src/list_window.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 343 insertions(+), 21 deletions(-) create mode 100644 src/list_window.c diff --git a/src/Makefile.in b/src/Makefile.in index 0706290..2ae57d0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,12 +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_generic.c + list_display.c list_generic.c list_window.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 \ + list_generic.o list_display.o list_window.o \ sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o all: screen @@ -304,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 list_generic.h + comm.h layer.h term.h image.h display.h window.h extern.h 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 \ @@ -349,4 +349,5 @@ viewport.o: layout.h viewport.h canvas.h viewport.c config.h screen.h os.h osdef braille.h list_generic.o: list_generic.h list_generic.c layer.h list_display.o: list_generic.h list_display.c layer.h +list_window.o: list_generic.h list_window.c window.h layer.h diff --git a/src/help.c b/src/help.c index 1e37354..ebcf1d5 100644 --- a/src/help.c +++ b/src/help.c @@ -717,6 +717,7 @@ struct wlistdata { int *list; }; +#if 0 static struct LayFuncs WListLf = { WListProcess, @@ -727,9 +728,11 @@ static struct LayFuncs WListLf = WListResize, DefRestore }; +#endif #define WTAB_GROUP_MATCHES(i) (group == wtab[i]->w_group) +#if 0 static int WListResize(wi, he) int wi, he; @@ -1155,6 +1158,7 @@ struct win *group; return ind; return WListOrder(wlistdata, ind, start, group); } +#endif void display_wlist(onblank, order, group) @@ -1162,9 +1166,13 @@ int onblank; int order; struct win *group; { + display_windows(onblank, order, group); + return; +#if 0 struct win *p; struct wlistdata *wlistdata; + if (flayer->l_width < 10 || flayer->l_height < 6) { LMsg(0, "Window size too small for window list page"); @@ -1214,8 +1222,10 @@ struct win *group; wlistdata->numwin = flayer->l_height - (group ? 4 : 3); wlistdata->nested = (order & WLIST_NESTED); wlistpage(); +#endif } +#if 0 static void wlistpage() { @@ -1299,20 +1309,25 @@ struct win *p; WListLine(y, i, wlistdata->pos, 0); LaySetCursor(); } +#endif void WListUpdatecv(cv, p) struct canvas *cv; struct win *p; { +#if 0 if (cv->c_layer->l_layfn != &WListLf) return; CV_CALL(cv, WListUpdate(p)); +#endif +#warning Fixme } void WListLinkChanged() { +#if 0 struct display *olddisplay = display; struct canvas *cv; struct wlistdata *wlistdata; @@ -1328,6 +1343,8 @@ WListLinkChanged() CV_CALL(cv, WListUpdate(0)); } display = olddisplay; +#endif +#warning Fix me too! } diff --git a/src/list_display.c b/src/list_display.c index 28ec7bb..9223fd8 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -145,8 +145,12 @@ static int gl_Display_input(struct ListData *ldata, char **inp, int *len) { struct display *cd = display; - unsigned char ch = (unsigned char) **inp; + unsigned char ch; + if (!ldata->selected) + return 0; + + ch = (unsigned char) **inp; ++*inp; --*len; @@ -195,6 +199,14 @@ static int gl_Display_freerow(struct ListData *ldata, struct ListRow *row) { /* There was no allocation when row->data was set. So nothing to do here. */ + return 0; +} + +static int +gl_Display_free(struct ListData *ldata) +{ + /* There was no allocation in ldata->data. So nothing to do here. */ + return 0; } static struct GenericList gl_Display = @@ -203,14 +215,13 @@ static struct GenericList gl_Display = gl_Display_footer, gl_Display_row, gl_Display_input, - gl_Display_freerow + gl_Display_freerow, + gl_Display_free }; void display_displays() { - struct display *d; - struct ListRow *row = NULL; struct ListData *ldata; if (flayer->l_width < 10 || flayer->l_height < 5) { @@ -222,13 +233,7 @@ display_displays() if (!ldata) return; - 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); + gl_Display_rebuild(ldata); } #endif /* MULTI */ diff --git a/src/list_generic.c b/src/list_generic.c index 112b588..3d93438 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -81,7 +81,10 @@ static void ListProcess(char **ppbuf, int *plen) continue; if (!ldata->selected) - *plen = 0; + { + *plen = 0; + break; + } ch = **ppbuf; ++*ppbuf; @@ -114,7 +117,8 @@ static void ListProcess(char **ppbuf, int *plen) ldata->selected = old->next; break; - case 007: + case 033: /* escape */ + case 007: /* ^G */ ListAbort(); *plen = 0; return; @@ -141,6 +145,8 @@ static void ListAbort(void) { struct ListData *ldata = flayer->l_data; glist_remove_rows(ldata); + if (ldata->list_fn->gl_free) + ldata->list_fn->gl_free(ldata); LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } diff --git a/src/list_generic.h b/src/list_generic.h index 0c0e5b0..c9631ed 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -32,11 +32,12 @@ struct ListRow 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 *)); + int (*gl_printheader) __P((struct ListData *)); /* Print the header */ + int (*gl_printfooter) __P((struct ListData *)); /* Print the footer */ + int (*gl_printrow) __P((struct ListData *, struct ListRow *)); /* Print one row */ + int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); /* Process input */ + int (*gl_freerow) __P((struct ListData *, struct ListRow *)); /* Free data for a row */ + int (*gl_free) __P((struct ListData *)); /* Free data for the list */ }; struct ListData @@ -46,6 +47,8 @@ struct ListData struct ListRow *top; /* The topmost visible row */ struct GenericList *list_fn; /* The functions that deal with the list */ + + void *data; /* List specific data */ }; @@ -61,3 +64,5 @@ void glist_abort __P((void)); void display_displays __P((void)); +void display_windows __P((int onblank, int order, struct win *group)); + diff --git a/src/list_window.c b/src/list_window.c new file mode 100644 index 0000000..873e894 --- /dev/null +++ b/src/list_window.c @@ -0,0 +1,288 @@ +/* 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 + * + **************************************************************** + */ + +/* Deals with the list of windows */ + +#include "config.h" +#include "screen.h" +#include "layer.h" +#include "extern.h" +#include "list_generic.h" + +extern struct layer *flayer; +extern struct display *display; + +extern char *wlisttit; +extern char *wliststr; + +extern struct mchar mchar_blank, mchar_so; +extern int renditions[]; + +extern struct win **wtab, *windows; +extern int maxwin; + +struct gl_Window_Data +{ + struct win *group; /* Currently displaying this group */ + int order; /* MRU? NESTED? etc. */ + int onblank; + struct win *fore; /* The foreground window we had. */ +}; + +static void +gl_Window_rebuild(struct ListData *ldata) +{ + struct ListRow *row = NULL; + struct gl_Window_Data *wdata = ldata->data; + + if (wdata->order == WLIST_MRU) + { + struct win *w; + for (w = windows; w; w = w->w_next) + { + if (w->w_group == wdata->group) + { + row = glist_add_row(ldata, w, row); + if (w == wdata->fore) + ldata->selected = row; + } + } + } + else + { + struct win **w; + struct win *wlist; + for (w = wtab, wlist = windows; wlist && w - wtab < maxwin; w++) + { + if (*w && (*w)->w_group == wdata->group) + { + row = glist_add_row(ldata, *w, row); + if (*w == wdata->fore) + ldata->selected = row; + wlist = wlist->w_next; + } + } + } + glist_display_all(ldata); +} + +static int +gl_Window_header(struct ListData *ldata) +{ + char *str; + + display = 0; + str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0, 0); + + LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 0); + return 2; +} + +static int +gl_Window_footer(struct ListData *ldata) +{ + return 0; +} + +static int +gl_Window_row(struct ListData *ldata, struct ListRow *lrow) +{ + char *str; + struct win *w; + int xoff; + struct mchar *mchar; + struct mchar mchar_rend = mchar_blank; + struct ListRow *par = lrow; + + w = lrow->data; + + /* XXX: First, make sure we want to display this window in the list. + * If we are showing a list for a group, and not on blank, then we must + * only show the windows directly belonging to that group. + * Otherwise, do some more checks. */ + + for (xoff = 0, par = lrow->parent; par; par = par->parent) + { + if (par->y == -1) + break; + xoff += 2; + } + display = Layer2Window(flayer) ? 0 : flayer->l_cvlist ? flayer->l_cvlist->c_display : 0; + str = MakeWinMsgEv(wliststr, w, '%', flayer->l_width - xoff, NULL, 0); + if (ldata->selected == lrow) + mchar = &mchar_so; + else if (w->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_MONITOR], mchar); + } + else if ((w->w_bell == BELL_DONE || w->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_BELL], mchar); + } + else + mchar = &mchar_blank; + + LPutWinMsg(flayer, str, flayer->l_width, mchar, xoff, lrow->y); + return 1; +} + +static int +gl_Window_input(struct ListData *ldata, char **inp, int *len) +{ + struct win *win; + unsigned char ch; + struct display *cd = display; + struct gl_Window_Data *wdata = ldata->data; + + if (!ldata->selected) + return 0; + + ch = (unsigned char) **inp; + ++*inp; + --*len; + + switch (ch) + { + case ' ': + case '\n': + case '\r': + win = ldata->selected->data; + if (!win) + break; +#ifdef MULTIUSER + if (display && AclCheckPermWin(D_user, ACL_READ, win)) + return; /* Not allowed to switch to this window. */ +#endif + glist_abort(); + display = cd; + SwitchWindow(win->w_number); + break; + + case 033: /* escape */ + case 007: /* ^G */ + if (wdata->onblank) + { + glist_abort(); + display = cd; + SwitchWindow(wdata->fore->w_number); + *len = 0; + break; + } + /* else FALLTHROUGH */ + default: + --*inp; + ++*len; + return 0; + } + return 1; +} + +static int +gl_Window_freerow(struct ListData *ldata, struct ListRow *row) +{ + return 0; +} + +static int +gl_Window_free(struct ListData *ldata) +{ + Free(ldata->data); + return 0; +} + +static struct GenericList gl_Window = +{ + gl_Window_header, + gl_Window_footer, + gl_Window_row, + gl_Window_input, + gl_Window_freerow, + gl_Window_free +}; + +void +display_windows(int onblank, int order, struct win *group) +{ + struct win *p; + struct wlistdata *wlistdata; + + if (flayer->l_width < 10 || flayer->l_height < 6) + { + LMsg(0, "Window size too small for window list page"); + return; + } + if (onblank) + { + debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); + if (!display) + { + LMsg(0, "windowlist -b: display required"); + return; + } + p = D_fore; + if (p) + { + SetForeWindow((struct win *)0); + if (p->w_group) + { + D_fore = p->w_group; + flayer->l_data = (char *)p->w_group; + } + Activate(0); + } + if (flayer->l_width < 10 || flayer->l_height < 6) + { + LMsg(0, "Window size too small for window list page"); + return; + } + } + else + p = Layer2Window(flayer); + if (!group && p) + group = p->w_group; + + struct ListData *ldata; + struct gl_Window_Data *wdata; + ldata = glist_display(&gl_Window); + if (!ldata) + { + if (onblank && p) + { + /* Could not display the list. So restore the window. */ + SetForeWindow(p); + Activate(1); + } + return; + } + + wdata = calloc(1, sizeof(struct gl_Window_Data)); + wdata->group = group; + wdata->order = order; + wdata->onblank = onblank; + wdata->fore = p; + ldata->data = wdata; + + gl_Window_rebuild(ldata); +} + -- cgit v1.2.1