diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2011-09-03 14:05:24 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2011-09-03 14:05:24 +0200 |
commit | 0e9a09d7718f02726b12924f7ddb05a992202aa3 (patch) | |
tree | 7b78a28379fdbe3a9dba37cd99c780c5d42c1e6c /help.c | |
parent | bdf45bc45637eefdbdee913465729f9d31d6c255 (diff) | |
download | screen-0e9a09d7718f02726b12924f7ddb05a992202aa3.tar.gz |
Imported Upstream version 3.9.11upstream/3.9.11
Diffstat (limited to 'help.c')
-rw-r--r-- | help.c | 540 |
1 files changed, 483 insertions, 57 deletions
@@ -1,4 +1,4 @@ -/* Copyright (c) 1993 +/* Copyright (c) 1993-2002 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Copyright (c) 1987 Oliver Laumann @@ -34,13 +34,16 @@ RCS_ID("$Id: help.c,v 1.7 1994/05/31 12:32:04 mlschroe Exp $ FAU") char version[40]; /* initialised by main() */ extern struct layer *flayer; -extern struct display *displays; +extern struct display *display, *displays; extern char *noargs[]; -extern struct mchar mchar_blank; +extern struct mchar mchar_blank, mchar_so; extern char *blank; +extern struct win *wtab[]; static void PadStr __P((char *, int, int, int)); +extern char *wliststr; +extern char *wlisttit; void exit_with_usage(myname, message, arg) @@ -76,11 +79,15 @@ char *myname, *message, *arg; printf("-S sockname Name this session <pid>.sockname instead of <pid>.<tty>.<host>.\n"); printf("-t title Set title. (window's name).\n"); printf("-T term Use term as $TERM for windows, rather than \"screen\".\n"); +#ifdef UTF8 + printf("-U Tell screen to use UTF-8 encoding.\n"); +#endif printf("-v Print \"Screen version %s\".\n", version); printf("-wipe Do nothing, just clean up SockDir.\n"); #ifdef MULTI printf("-x Attach to a not detached screen. (Multi display mode).\n"); #endif /* MULTI */ + printf("-X Execute <cmd> as a screen command in the specified session.\n"); if (message && *message) { printf("\nError: "); @@ -106,6 +113,8 @@ static int helppage __P((void)); struct helpdata { + char *class; + struct action *ktabp; int maxrow, grow, numcols, numrows, num_names; int numskip, numpages; int command_search, command_bindings; @@ -129,7 +138,9 @@ static struct LayFuncs HelpLf = void -display_help() +display_help(class, ktabp) +char *class; +struct action *ktabp; { int i, n, key, mcom, mkey, l; struct helpdata *helpdata; @@ -144,6 +155,8 @@ display_help() return; helpdata = (struct helpdata *)flayer->l_data; + helpdata->class = class; + helpdata->ktabp = ktabp; helpdata->num_names = helpdata->command_bindings = 0; helpdata->command_search = 0; for (n = 0; n <= RC_LAST; n++) @@ -152,13 +165,13 @@ display_help() mkey = 0; for (key = 0; key < 256; key++) { - n = ktab[key].nr; + n = ktabp[key].nr; if (n == RC_ILLEGAL) continue; - if (ktab[key].args == noargs) + if (ktabp[key].args == noargs) { - used[n] += (key <= ' ' || key == 0x7f) ? 3 : - (key > 0x7f) ? 5 : 2; + used[n] += (key <= ' ' || key == 0x7f) ? 3 : + (key > 0x7f) ? 5 : 2; } else helpdata->command_bindings++; @@ -171,7 +184,7 @@ display_help() mcom = l; if (used[n] > mkey) mkey = used[n]; - helpdata->nact[i++] = n; + helpdata->nact[i++] = n; } debug1("help: %d commands bound to keys with no arguments\n", i); debug2("mcom: %d mkey: %d\n", mcom, mkey); @@ -223,7 +236,7 @@ int *plen; { case ' ': if (helppage() == 0) - break; + break; /* FALLTHROUGH */ case '\r': case '\n': @@ -242,7 +255,7 @@ int *plen; static void HelpAbort() { - LAY_CALL_UP(RedisplayLayer(flayer, 0)); + LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } @@ -253,16 +266,18 @@ helppage() struct helpdata *helpdata; int col, crow, n, key, x; char buf[MAXKLEN], Esc_buf[5], cbuf[256]; + struct action *ktabp; helpdata = (struct helpdata *)flayer->l_data; + ktabp = helpdata->ktabp; if (helpdata->grow >= helpdata->maxrow) return -1; helpdata->refgrow = helpdata->grow; helpdata->refcommand_search = helpdata->command_search; /* Clear the help screen */ - ClearLayer(flayer, 0); + LClearAll(flayer, 0); sprintf(cbuf,"Screen key bindings, page %d of %d.", helpdata->grow / (flayer->l_height-5) + 1, helpdata->numpages); centerline(cbuf, 0); @@ -285,11 +300,14 @@ helppage() for (; crow < flayer->l_height - 3; crow++) { if (helpdata->grow < 1) - { - sprintf(cbuf,"Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf); - centerline(cbuf, crow); + { + if (ktabp == ktab) + sprintf(cbuf,"Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf); + else + sprintf(cbuf,"Command class: '%.80s'", helpdata->class); + centerline(cbuf, crow); helpdata->grow++; - } + } else if (helpdata->grow >= 2 && helpdata->grow-2 < helpdata->numrows) { x = 0; @@ -299,7 +317,7 @@ helppage() n = helpdata->nact[n]; buf[0] = '\0'; for (key = 0; key < 256; key++) - if (ktab[key].nr == n && ktab[key].args == noargs && strlen(buf) < sizeof(buf) - 7) + if (ktabp[key].nr == n && ktabp[key].args == noargs && strlen(buf) < sizeof(buf) - 7) { strcat(buf, " "); add_key_to_buf(buf, key); @@ -309,13 +327,13 @@ helppage() PadStr(buf, helpdata->mkey, x, crow); x += helpdata->mkey; } - helpdata->grow++; - } + helpdata->grow++; + } else if (helpdata->grow-2-helpdata->numrows >= helpdata->numskip - && helpdata->grow-2-helpdata->numrows-helpdata->numskip < helpdata->command_bindings) + && helpdata->grow-2-helpdata->numrows-helpdata->numskip < helpdata->command_bindings) { - while ((n = ktab[helpdata->command_search].nr) == RC_ILLEGAL - || ktab[helpdata->command_search].args == noargs) + while ((n = ktabp[helpdata->command_search].nr) == RC_ILLEGAL + || ktabp[helpdata->command_search].args == noargs) { if (++helpdata->command_search >= 256) return -1; @@ -323,7 +341,7 @@ helppage() buf[0] = '\0'; add_key_to_buf(buf, helpdata->command_search); PadStr(buf, 4, 0, crow); - AddAction(&ktab[helpdata->command_search++], 4, crow); + AddAction(&ktabp[helpdata->command_search++], 4, crow); helpdata->grow++; } else @@ -332,7 +350,7 @@ helppage() sprintf(cbuf,"[Press Space %s Return to end.]", helpdata->grow < helpdata->maxrow ? "for next page;" : "or"); centerline(cbuf, flayer->l_height - 2); - SetCursor(); + LaySetCursor(); return 0; } @@ -375,7 +393,7 @@ int x, y; *bp++ = del = '\''; } while (*cp && bp < buf + 250) - bp += AddXChar(bp, *(unsigned char *)cp++); + bp += AddXChar(bp, *(unsigned char *)cp++); if (del) *bp++ = del; *bp = 0; @@ -392,7 +410,7 @@ int x, y; x += strlen(buf); pp++; if (*pp) - LPutChar(flayer, fr ? &mchar_blank : &mchar_dol, x++, y); + LPutChar(flayer, fr ? &mchar_blank : &mchar_dol, x++, y); } } @@ -428,7 +446,7 @@ int y, xs, xe, isblank; if (y != 0 && y != flayer->l_height - 1) return; if (!isblank) - LClear(flayer, xs, y, xe, y, 0); + LClearArea(flayer, xs, y, xe, y, 0, 0); } @@ -464,7 +482,7 @@ static const char cpmsg[] = "\ \n\ Screen version %v\n\ \n\ -Copyright (c) 1993-1999 Juergen Weigert, Michael Schroeder\n\ +Copyright (c) 1993-2000 Juergen Weigert, Michael Schroeder\n\ Copyright (c) 1987 Oliver Laumann\n\ \n\ This program is free software; you can redistribute it and/or \ @@ -500,7 +518,7 @@ int *plen; switch (**ppbuf) { case ' ': - if (*copydata->cps) + if (*copydata->cps) { copypage(); break; @@ -522,7 +540,7 @@ int *plen; static void CopyrightAbort() { - LAY_CALL_UP(RedisplayLayer(flayer, 0)); + LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } @@ -558,7 +576,7 @@ copypage() ASSERT(flayer); copydata = (struct copydata *)flayer->l_data; - ClearLayer(flayer, 0); + LClearAll(flayer, 0); x = y = 0; cps = copydata->cps; copydata->refcps = cps; @@ -592,7 +610,7 @@ copypage() x++; } if (l) - LPutStr(flayer, ws, l, &mchar_blank, x, y); + LPutStr(flayer, ws, l, &mchar_blank, x, y); x += l; cps += l; if (*cps == 0 && copydata->savedcps) @@ -614,7 +632,7 @@ copypage() *cps ? "for next page;" : "or"); centerline(cbuf, flayer->l_height - 2); copydata->cps = cps; - SetCursor(); + LaySetCursor(); } static void @@ -636,7 +654,7 @@ int y, xs, xe, isblank; return; if (isblank) return; - LClear(flayer, xs, y, xe, y, 0); + LClearArea(flayer, xs, y, xe, y, 0, 0); } @@ -647,6 +665,8 @@ int y, xs, xe, isblank; ** */ +#ifdef MULTI + static void DisplaysProcess __P((char **, int *)); static void DisplaysRedisplayLine __P((int, int, int, int)); static void displayspage __P((void)); @@ -673,10 +693,8 @@ char **ppbuf; int *plen; { int done = 0; - struct displaysdata *displaysdata; ASSERT(flayer); - displaysdata = (struct displaysdata *)flayer->l_data; while (!done && *plen > 0) { switch (**ppbuf) @@ -684,7 +702,6 @@ int *plen; case ' ': displayspage(); break; - /* FALLTHROUGH */ case '\r': case '\n': HelpAbort(); @@ -698,19 +715,17 @@ int *plen; } } + void display_displays() { - struct displaysdata *displaysdata; - if (flayer->l_width < 10 || flayer->l_height < 5) { LMsg(0, "Window size too small for displays page"); return; } - if (InitOverlayPage(sizeof(*displaysdata), &DisplaysLf, 0)) + if (InitOverlayPage(sizeof(struct displaysdata), &DisplaysLf, 0)) return; - displaysdata = (struct displaysdata *)flayer->l_data; flayer->l_x = 0; flayer->l_y = flayer->l_height - 1; displayspage(); @@ -742,13 +757,10 @@ displayspage() { int y, l; char tbuf[80]; - struct displaysdata *displaysdata; struct display *d; struct win *w; - displaysdata = (struct displaysdata *)flayer->l_data; - - ClearLayer(flayer, 0); + LClearAll(flayer, 0); leftline("term-type size user interface window", 0); leftline("---------- ------- ---------- ----------------- ----------", 1); @@ -764,11 +776,11 @@ displayspage() d->d_termname, d->d_width, d->d_height, d->d_user->u_name, d->d_usertty, d->d_nonblock ? ((( d->d_obufp - d->d_obuf) > d->d_obufmax) ? - "NB" : "nb") : " "); + "NB" : "nb") : " "); if (w) { - l = 10 - strlen(w->w_title); + l = 10 - strlen(w->w_title); if (l < 0) l = 0; sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", @@ -800,7 +812,7 @@ displayspage() sprintf(tbuf,"[Press Space %s Return to end.]", 1 ? "to refresh;" : "or"); centerline(tbuf, flayer->l_height - 2); - SetCursor(); + LaySetCursor(); } static void @@ -810,9 +822,6 @@ int y, xs, xe, isblank; ASSERT(flayer); if (y < 0) { - struct displaysdata *displaysdata; - - displaysdata = (struct displaysdata *)flayer->l_data; displayspage(); return; } @@ -820,10 +829,427 @@ int y, xs, xe, isblank; return; if (isblank) return; - LClear(flayer, xs, y, xe, y, 0); + LClearArea(flayer, xs, y, xe, y, 0, 0); /* To be filled in... */ } +#endif /* MULTI */ + + +/* +** +** here is the windowlist +** +*/ + +static void WListProcess __P((char **, int *)); +static void WListRedisplayLine __P((int, int, int, int)); +static void wlistpage __P((void)); +static void WListLine __P((int, int, int, int)); +static void WListLines __P((int, int)); +static void WListMove __P((int, int)); +static void WListUpdate __P((struct win *)); +static int WListNormalize __P((void)); +static int WListResize __P((int, int)); + +struct wlistdata { + int pos; + int ypos; + int npos; + int numwin; + int first; + int last; + int start; +}; + +static struct LayFuncs WListLf = +{ + WListProcess, + HelpAbort, + WListRedisplayLine, + DefClearLine, + DefRewrite, + WListResize, + DefRestore +}; + +static int +WListResize(wi, he) +int wi, he; +{ + struct wlistdata *wlistdata; + if (wi < 10 || he < 5) + return -1; + wlistdata = (struct wlistdata *)flayer->l_data; + flayer->l_width = wi; + flayer->l_height = he; + wlistdata->numwin = he - 3; + if (wlistdata->ypos >= wlistdata->numwin) + wlistdata->ypos = wlistdata->numwin - 1; + flayer->l_y = he - 1; + return 0; +} + +static void +WListProcess(ppbuf, plen) +char **ppbuf; +int *plen; +{ + int done = 0; + struct wlistdata *wlistdata; + int h; + + ASSERT(flayer); + wlistdata = (struct wlistdata *)flayer->l_data; + h = wlistdata->numwin; + while (!done && *plen > 0) + { + switch ((unsigned char)**ppbuf) + { + case 0220: + case 'k': + WListMove(-1, -1); + break; + case 0216: + case 'j': + WListMove(1, -1); + break; + case '\025': + WListMove(-(h / 2), wlistdata->ypos); + break; + case '\004': + WListMove(h / 2, wlistdata->ypos); + break; + case 0002: + case 'b': + WListMove(-h, -1); + break; + case 0006: + case 'f': + WListMove(h, -1); + break; + case 0201: + WListMove(-wlistdata->pos, -1); + break; + case 0205: + WListMove(MAXWIN, -1); + break; + case '\r': + case '\n': + case ' ': + done = 1; + h = wlistdata->pos; + if (!display || !wtab[h] || wtab[h] == D_fore || (flayer->l_cvlist && flayer->l_cvlist->c_lnext)) + HelpAbort(); +#ifdef MULTIUSER + else if (AclCheckPermWin(D_user, ACL_READ, wtab[h])) + HelpAbort(); +#endif + else + ExitOverlayPage(); /* no need to redisplay */ + SwitchWindow(h); + break; + case 0033: + case 0007: + h = wlistdata->start; + HelpAbort(); + if (h >= 0 && wtab[h]) + SwitchWindow(h); + else if (h == -2) + { + struct win *p = FindNiceWindow(display ? D_other : (struct win *)0, 0); + if (p) + SwitchWindow(p->w_number); + } + done = 1; + break; + default: + break; + } + ++*ppbuf; + --*plen; + } +} + +static void +WListLine(y, i, pos, isblank) +int y, i; +int pos; +int isblank; +{ + char *str; + int n; + + display = 0; + str = MakeWinMsgEv(wliststr, wtab[i], '%', flayer->l_width, (struct event *)0); + n = strlen(str); + if (i != pos && isblank) + while (n && str[n - 1] == ' ') + n--; + LPutWinMsg(flayer, str, (i == pos || !isblank) ? flayer->l_width : n, i == pos ? &mchar_so : &mchar_blank, 0, y + 2); +#if 0 + LPutStr(flayer, str, n, i == pos ? &mchar_so : &mchar_blank, 0, y + 2); + if (i == pos || !isblank) + while(n < flayer->l_width) + LPutChar(flayer, i == pos ? &mchar_so : &mchar_blank, n++, y + 2); +#endif + return; +} + +static void +WListLines(up, oldpos) +int up, oldpos; +{ + struct wlistdata *wlistdata; + int ypos, pos; + int y, i, first; + + wlistdata = (struct wlistdata *)flayer->l_data; + ypos = wlistdata->ypos; + pos = wlistdata->pos; + + first = ypos; + for (i = pos; i >= 0; i--) + if (wtab[i] && first-- == 0) + break; + for (y = 0; y < wlistdata->numwin; y++) + { + while (i < MAXWIN && wtab[i] == 0) + i++; + if (i == MAXWIN) + continue; + if (y == 0) + wlistdata->first = i; + wlistdata->last = i; + if (((i == oldpos || i == pos) && pos != oldpos) || (up > 0 && y >= wlistdata->numwin - up) || (up < 0 && y < -up)) + WListLine(y, i, pos, i != oldpos); + if (i == pos) + wlistdata->ypos = y; + i++; + } +} + +static int +WListNormalize() +{ + struct wlistdata *wlistdata; + int i, n; + int ypos, pos; + + wlistdata = (struct wlistdata *)flayer->l_data; + ypos = wlistdata->ypos; + pos = wlistdata->pos; + if (ypos < 0) + ypos = 0; + if (ypos >= wlistdata->numwin) + ypos = wlistdata->numwin - 1; + for (n = 0, i = pos; i < MAXWIN && n < wlistdata->numwin; i++) + if (wtab[i]) + n++; + if (ypos < wlistdata->numwin - n) + ypos = wlistdata->numwin - n; + for (n = i = 0; i < pos; i++) + if (wtab[i]) + n++; + if (ypos > n) + ypos = n; + wlistdata->ypos = ypos; + wlistdata->npos = n; + return ypos; +} + +static void +WListMove(num, ypos) +int num; +int ypos; +{ + struct wlistdata *wlistdata; + int oldpos, oldypos, oldnpos; + int pos, up, i; + + wlistdata = (struct wlistdata *)flayer->l_data; + oldpos = wlistdata->pos; + oldypos = wlistdata->ypos; + oldnpos = wlistdata->npos; + wlistdata->ypos = ypos == -1 ? oldypos + num : ypos; + pos = oldpos; + i = pos; + while (num > 0 && i < MAXWIN - 1) + if (wtab[++i]) + { + pos = i; + num--; + } + while (num < 0 && i > 0) + if (wtab[--i]) + { + pos = i; + num++; + } + wlistdata->pos = pos; + ypos = WListNormalize(); + up = wlistdata->npos - ypos - (oldnpos - oldypos); + if (up) + { + LScrollV(flayer, up, 2, 2 + wlistdata->numwin - 1, 0); + WListLines(up, oldpos); + LaySetCursor(); + return; + } + if (pos == oldpos) + return; + WListLine(oldypos, oldpos, pos, 0); + WListLine(ypos, pos, pos, 1); + LaySetCursor(); +} + +static void +WListRedisplayLine(y, xs, xe, isblank) +int y, xs, xe, isblank; +{ + ASSERT(flayer); + if (y < 0) + { + wlistpage(); + return; + } + if (y != 0 && y != flayer->l_height - 1) + return; + if (!isblank) + LClearArea(flayer, xs, y, xe, y, 0, 0); +} + +void +display_wlist(onblank) +int onblank; +{ + struct win *p; + struct wlistdata *wlistdata; + + if (flayer->l_width < 10 || flayer->l_height < 5) + { + 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; + SetForeWindow((struct win *)0); + Activate(0); + if (flayer->l_width < 10 || flayer->l_height < 5) + { + LMsg(0, "Window size too small for window list page"); + return; + } + debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); + } + else + p = Layer2Window(flayer); + if (InitOverlayPage(sizeof(*wlistdata), &WListLf, 0)) + return; + wlistdata = (struct wlistdata *)flayer->l_data; + flayer->l_x = 0; + flayer->l_y = flayer->l_height - 1; + wlistdata->start = onblank && p ? p->w_number : -1; + wlistdata->pos = p ? p->w_number : 0; + wlistdata->ypos = 0; + wlistdata->numwin= flayer->l_height - 3; + wlistpage(); +} + +static void +wlistpage() +{ + struct wlistdata *wlistdata; + char *str; + int pos; + + wlistdata = (struct wlistdata *)flayer->l_data; + + LClearAll(flayer, 0); + if (wlistdata->start >= 0 && wtab[wlistdata->start] == 0) + wlistdata->start = -2; + + pos = wlistdata->pos; + if (wtab[pos] == 0) + { + /* find new position */ + while(++pos < MAXWIN) + if (wtab[pos]) + break; + if (pos == MAXWIN) + while (--pos > 0) + if (wtab[pos]) + break; + } + wlistdata->pos = pos; + + display = 0; + str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0); + LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 0); + WListNormalize(); + WListLines(wlistdata->numwin, -1); + LaySetCursor(); +} + +static void +WListUpdate(p) +struct win *p; +{ + struct wlistdata *wlistdata; + int i, n, y; + + if (p == 0) + { + wlistpage(); + return; + } + wlistdata = (struct wlistdata *)flayer->l_data; + n = p->w_number; + if (n < wlistdata->first || n > wlistdata->last) + return; + i = wlistdata->first; + for (y = 0; y < wlistdata->numwin; y++) + { + while (i < MAXWIN && wtab[i] == 0) + i++; + if (i == MAXWIN) + return; + if (i == n) + break; + i++; + } + if (y == wlistdata->numwin) + return; + WListLine(y, i, wlistdata->pos, 0); + LaySetCursor(); +} + +void +WListUpdatecv(cv, p) +struct canvas *cv; +struct win *p; +{ + if (cv->c_layer->l_layfn != &WListLf) + return; + CV_CALL(cv, WListUpdate(p)); +} + +int +InWList() +{ + if (flayer && flayer->l_layfn == &WListLf) + return 1; + return 0; +} + + /* ** @@ -903,7 +1329,7 @@ struct action *tab; static void BindkeyAbort() { - LAY_CALL_UP(RedisplayLayer(flayer, 0)); + LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } @@ -918,7 +1344,7 @@ bindkeypage() bindkeydata = (struct bindkeydata *)flayer->l_data; - ClearLayer(flayer, 0); + LClearAll(flayer, 0); sprintf(tbuf, "%s key bindings, page %d of %d.", bindkeydata->title, bindkeydata->page, bindkeydata->pages); centerline(tbuf, 0); @@ -954,7 +1380,7 @@ bindkeypage() *p++ = del; *p++ = ' '; while (p < tbuf + 15) - *p++ = ' '; + *p++ = ' '; sprintf(p, "%s -> ", xch); p += 7; if (p - tbuf > flayer->l_width - 1) @@ -970,7 +1396,7 @@ bindkeypage() bindkeydata->last = i; sprintf(tbuf,"[Press Space %s Return to end.]", bindkeydata->page < bindkeydata->pages ? "for next page;" : "or"); centerline(tbuf, flayer->l_height - 2); - SetCursor(); + LaySetCursor(); } static void @@ -1021,7 +1447,7 @@ int y, xs, xe, isblank; if (y != 0 && y != flayer->l_height - 1) return; if (!isblank) - LClear(flayer, xs, y, xe, y, 0); + LClearArea(flayer, xs, y, xe, y, 0, 0); } #endif /* MAPKEYS */ |