summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-22 20:50:31 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-22 20:50:31 -0500
commit04f2e5342014efbbc6ba2d7277d33d3be388b2fd (patch)
treed896dca6a9ad8d82462959a0fa447547116b723d
parente29d6de0f8f4c40806e9b3300ed3609aaefc104b (diff)
downloadscreen-04f2e5342014efbbc6ba2d7277d33d3be388b2fd.tar.gz
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.
-rw-r--r--src/Makefile.in7
-rw-r--r--src/help.c17
-rw-r--r--src/list_display.c27
-rw-r--r--src/list_generic.c10
-rw-r--r--src/list_generic.h15
-rw-r--r--src/list_window.c288
6 files changed, 343 insertions, 21 deletions
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);
+}
+