about summary refs log tree commit diff stats
path: root/draw.c
blob: 0ded26b6c9fb454c206026fcef6fd99edfdf23fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */
#include "dwm.h"
#include <stdio.h>
#include <string.h>
#include <X11/Xlocale.h>

/* static */

static unsigned int
textnw(const char *text, unsigned int len)
{
	XRectangle r;

	if(dc.font.set) {
		XmbTextExtents(dc.font.set, text, len, NULL, &r);
		return r.width;
	}
	return XTextWidth(dc.font.xfont, text, len);
}

static void
drawtext(const char *text, Bool invert)
{
	int x, y, w, h;
	static char buf[256];
	unsigned int len, olen;
	XGCValues gcv;
	XPoint points[5];
	XRectangle r = { dc.x, dc.y, dc.w, dc.h };

	XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
	XSetForeground(dpy, dc.gc, dc.border);
	points[0].x = dc.x;
	points[0].y = dc.y;
	points[1].x = dc.w - 1;
	points[1].y = 0;
	points[2].x = 0;
	points[2].y = dc.h - 1;
	points[3].x = -(dc.w - 1);
	points[3].y = 0;
	points[4].x = 0;
	points[4].y = -(dc.h - 1);
	XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);

	if(!text)
		return;

	w = 0;
	olen = len = strlen(text);
	if(len >= sizeof(buf))
		len = sizeof(buf) - 1;
	memcpy(buf, text, len);
	buf[len] = 0;

	h = dc.font.ascent + dc.font.descent;
	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
	x = dc.x + (h / 2);

	/* shorten text if necessary */
	while(len && (w = textnw(buf, len)) > dc.w - h)
		buf[--len] = 0;
	if(len < olen) {
		if(len > 1)
			buf[len - 1] = '.';
		if(len > 2)
			buf[len - 2] = '.';
		if(len > 3)
			buf[len - 3] = '.';
	}

	if(w > dc.w)
		return; /* too long */

	gcv.foreground = invert ? dc.bg : dc.fg;
	gcv.background = invert ? dc.fg : dc.bg;
	if(dc.font.set) {
		XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv);
		XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,
				x, y, buf, len);
	}
	else {
		gcv.font = dc.font.xfont->fid;
		XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv);
		XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);
	}
}

/* extern */

void
drawall()
{
	Client *c;

	for(c = clients; c; c = getnext(c->next))
		drawtitle(c);
	drawstatus();
}

void
drawstatus()
{
	int i, x;
	Bool istile = arrange == dotile;

	dc.x = dc.y = 0;
	dc.w = bw;
	drawtext(NULL, !istile);

	dc.w = 0;
	for(i = 0; i < ntags; i++) {
		dc.x += dc.w;
		dc.w = textw(tags[i]);
		if(istile)
			drawtext(tags[i], seltag[i]);
		else
			drawtext(tags[i], !seltag[i]);
	}
	x = dc.x + dc.w;
	dc.w = textw(stext);
	dc.x = bx + bw - dc.w;
	drawtext(stext, !istile);
	if(sel && ((dc.w = dc.x - x) >= bh)) {
		dc.x = x;
		drawtext(sel->name, istile);
	}
	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
	XSync(dpy, False);
}

void
drawtitle(Client *c)
{
	int i;
	Bool istile = arrange == dotile;

	if(c == sel && issel) {
		drawstatus();
		XUnmapWindow(dpy, c->title);
		XSetWindowBorder(dpy, c->win, dc.fg);
		return;
	}

	XSetWindowBorder(dpy, c->win, dc.bg);
	XMapWindow(dpy, c->title);

	dc.x = dc.y = 0;

	dc.w = 0;
	for(i = 0; i < ntags; i++) {
		if(c->tags[i]) {
			dc.x += dc.w;
			dc.w = textw(tags[i]);
			drawtext(tags[i], !istile);
		}
	}
	dc.x += dc.w;
	dc.w = c->tw - dc.x;
	drawtext(c->name, !istile);
	XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 0);
	XSync(dpy, False);
}

unsigned long
getcolor(const char *colstr)
{
	Colormap cmap = DefaultColormap(dpy, screen);
	XColor color;

	XAllocNamedColor(dpy, cmap, colstr, &color, &color);
	return color.pixel;
}

void
setfont(const char *fontstr)
{
	char **missing, *def;
	int i, n;

	missing = NULL;
	setlocale(LC_ALL, "");
	if(dc.font.set)
		XFreeFontSet(dpy, dc.font.set);
	dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
	if(missing) {
		while(n--)
			fprintf(stderr, "missing fontset: %s\n", missing[n]);
		XFreeStringList(missing);
		if(dc.font.set) {
			XFreeFontSet(dpy, dc.font.set);
			dc.font.set = NULL;
		}
	}
	if(dc.font.set) {
		XFontSetExtents *font_extents;
		XFontStruct **xfonts;
		char **font_names;

		dc.font.ascent = dc.font.descent = 0;
		font_extents = XExtentsOfFontSet(dc.font.set);
		n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
		for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
			if(dc.font.ascent < (*xfonts)->ascent)
				dc.font.ascent = (*xfonts)->ascent;
			if(dc.font.descent < (*xfonts)->descent)
				dc.font.descent = (*xfonts)->descent;
			xfonts++;
		}
	}
	else {
		if(dc.font.xfont)
			XFreeFont(dpy, dc.font.xfont);
		dc.font.xfont = NULL;
		dc.font.xfont = XLoadQueryFont(dpy, fontstr);
		if (!dc.font.xfont)
			dc.font.xfont = XLoadQueryFont(dpy, "fixed");
		if (!dc.font.xfont)
			eprint("error, cannot init 'fixed' font\n");
		dc.font.ascent = dc.font.xfont->ascent;
		dc.font.descent = dc.font.xfont->descent;
	}
	dc.font.height = dc.font.ascent + dc.font.descent;
}

unsigned int
textw(const char *text)
{
	return textnw(text, strlen(text)) + dc.font.height;
}
(<em>/</em>) is treated purely as a separator, not as a designator for the root, and the <em>path</em> string if present is treated as in or under the login directory. For VMS ftp servers, if you wish to have the first element treated as a device rather than file or subdirectory name, begin it with a hex-escaped slash (<em>%2f</em>), e.g.:<BR> <pre> <em>ftp://user@myhost/%2fsys$common/syshlp</em> </pre> can be used for a listing of sys$common:[syshlp]<BR> Also, on VM/CMS ftp servers, if the <em>path</em> string begins with <em>vmsysu%3a</em> it receives special handling as an SFS path, e.g.: <pre> <em>ftp://ubvm.cc.buffalo.edu/vmsysu%3alistserv.webshare</em> </pre> <p>For Unix and Unix-emulation ftp servers, RFC1738 is not respected and the lead slash is treated as the root, i.e., the <em>/path</em> is handled equivalently to that in file URLs. The distinction is irrelevant for anonymous ftp, but matters when using ftp for non-anonymous accounts. If you are using ftp with a Unix server and do wish to get a listing of the login directory or have the <em>path</em> string treated as a file or path under the login directory, include a tilde (<em>~</em>) as for <a href="#file">file</a> URLs, e.g.: <pre> <em>ftp://user@myhost/~</em> </pre> <HR> <H2><a name="wais_url">The <em>wais</em> URL:</a></H2> The wais URL is used to retrieve resources using the Wide Area Information System protocol. The format is: <pre> <em>wais://host:port/database</em> <em>wais://host:port/database?wais_query</em> <em>wais://host:port/database/wais_type/wais_path</em> </pre> where <em>:port</em> defaults to <em>:210</em> <p>Direct wais support is built into Lynx for VMS, and can be compiled into Lynx on Unix. <p>If only a <em>database</em> is indicated in the URL, Lynx returns an ISINDEX cover page for searching that <em>database</em>, and will submit your search with the <em>wais_query</em> appended. Lynx will convert the server's reply into a hit list with URLs that include the <em>wais_type</em> and <em>wais_path</em> for retrieving items from the hit list. <HR> <H2><a name="news_url" >The <em>news</em>, <em>nntp</em>, and <em>snews</em> URLs:</a></H2> The news and nntp URLs are handled by Lynx as specified in RFC1738, but for compatibility with other clients, Lynx allows inclusion of host and port fields in news URLs, which properly should be used <em>only</em> in nntp and snews URLs. If not included in news URLs, Lynx will use the nntp server pointed to by the NNTPSERVER environment variable or configuration symbol (see lynx.cfg), with default port <em>:119</em>. A host field must be included in nntp URLs, and the port field is optional with the same default. <p>If the URL requires authentication, lynx will prompt you for the username and password. These are cached during a session, for reuse on the same host. If $HOME/.newsauth exists, lynx initializes its cache from this file. The .newsauth file contents are one line per entry: hostname, password and username (in that order) separated by a space. <p>The formats are:<BR> <pre> <em>news:newsgroup</em> (retrieves list of messages in newsgroup) <em>news:messageID</em> (retrieves the message) <em>news:*</em> (retrieves list of all available newsgroups) <em>nntp://host:port/newsgroup</em> <em>nntp://host:port/messageID</em> <em>nntp://host:port/*</em> </pre> (snews same as nntp, but the default port is <em>:563</em>) <p>The <em>messageID</em> is the message's unique identifier, consisting of an identification string and the host of origin for the message (<em>ident_string@origin_host</em>). <p>Lynx also supports wildcarding via an asterisk for listings of news hierarchies or sub-hierarchies, e.g.: <pre> <em>news:comp.infosystems.*</em> <em>nntp://host:port/comp.infosystems.*</em> </pre> (snews same as nntp, but the default port is <em>:563</em>)<BR> This is not in RFC1738 and may not be supported by all other clients. <p>Lynx allows you both to <em>reply</em> to the author of a news message via email, and, if news posting has been enabled, to send a <em>followup</em> message to the newsgroup (see <a href="#newspost">newspost, newsreply, snewspost, snewsreply</a>). <p>Lynx converts any strings in news messages which appear to be a URL with a supported scheme into a link for accessing that URL. <p>Lynx also supports the newsgroup and message number URL scheme:<BR> <pre> <em>news:newsgroup/startNo-endNo</em> (lists message range in newsgroup) <em>news:newsgroup/messageNo</em> (retrieves the message by number) <em>nntp://host:port/newsgroup/startNo-endNo</em> <em>nntp://host:port/newsgroup/messageNo</em> </pre> (snews same as nntp, but the default port is <em>:563</em>)<BR> Use of this scheme is not recommended, because the message numbers are specific to each nntp server, unlike the unique identifiers for news messages. <HR> <H2><a name="newspost_url" >The <em>newspost</em>, <em>newsreply</em>, <em>snewspost</em>, and <em>snewsreply</em> URLs:</a></H2> When Lynx receives group listings or articles via <em>news</em>, <em>nntp</em> or <em>snews</em> URLs, it also checks whether the nntp server supports posting from the Lynx user's site, and if so, includes links for posting new messages to that server, or for posting followups (replies) to previously posted messages. RFC1738, and IETF URL drafts through this release of Lynx, do not include any schemes for posting to news groups. Lynx has long supported newspost and newreply URL schemes for posting new messages or sending followups, respectively, to standard nntp servers, with default port <em>:119</em>. Lynx now also supports homologous snewspost and snewsreply URLs for use with SSL capable nntp servers. <p>The formats are: <pre> <em>newspost://host:port/newsgroup(s)</em>&nbsp;&nbsp;(post a new message) <em>newsreply://host:port/newsgroup(s)</em> (post a followup message) </pre> (snewspost and snewsreply have the same formats, but the default port is <em>:563</em>) <p>If the host field is omitted, it defaults to that pointed to by the NNTPSERVER configuration or environmental variable. Inclusion of at least one newsgroup in the URL is required, and additional groups can be specified as a comma-separated list. Wildcarding of newsgroup names is not supported for these URLs. For newsreply and snewsreply URLs, if an external editor has been defined via the <em>Options Menu</em>, the user is offered an option to include the currently displayed document, which presumably is a news article with a <em>followup</em> link that was activated, and if confirmed, each line of that document is prefixed with a right-angle-bracket. The user is expected to edit such an inclusion so that only the passages relevant to the followup message are retained. <p>These URLs can be used as command line startfiles (in which case, Lynx will exit after posting the message, and the newreply or snewsreply URLs degrade to newspost or snewpost URLs, respectively). They also can be used as HREF attribute values in any HTML document homologously to <a href="#mailto">mailto</a> URLs, with the qualification that they presently are supported only by Lynx. <HR> <H2><a name="mailto_url">The <em>mailto</em> URL:</a></H2> The mailto URL is used to provide links that when activated can be used to send a comment or the content of a FORM to an Internet email address (user@host). The format is: <pre> <em>mailto:user@host</em> </pre> <p>The description of the mailto URL in RFC1738 has been interpreted by some as allowing only a single recipient, but Lynx invented the mailto URL, has always supported a series of user@host addresses as a comma-separated list, and still does. For compatibility with Explorer, Lynx also accepts a semi-colon-separated list. <p>For compatibility with Netscape, Lynx parses any <em>?subject=The%20Subject</em> appended to the URL, trims the URL at the <em>?</em>, and uses the value as the default Subject: for the message or FORM content mailing. This is not recommended practice. The preferred way to indicate the default Subject: for a LINK or Anchor with a mailto HREF, or a FORM with a mailto ACTION, is via a TITLE attribute with the subject string as its value, e.g.: <pre> <em>&lt;LINK REV="made" HREF="mailto:me@myhost,her@herhost" TITLE="The Subject"&gt;</em> <em>&lt;A HREF="mailto:user@host" TITLE="The Subject"&gt;...&lt;/A&gt;</em> <em>&lt;FORM METHOD="post" ENCTYPE="text/plain" ACTION="mailto:WebMaster@host" TITLE="The Subject"&gt; ... &lt;/FORM&gt;</em> </pre> <p>Note that a TITLE attribute for FORM is now included in the HTML specifications. Some clients use a SUBJECT attribute for this purpose in FORM tags, and Lynx recognizes that as a synonym for TITLE. <p>Lynx also will process any <em>to=address(es)</em>, <em>cc=address(es)</em>, <em>keywords=word_list</em> and/or <em>body=message</em> fields in <em>?searchpart</em> tack-ons to mailto URLs. The <em>to</em> and/or <em>cc</em> values can be single addresses, or comma- or semi-colon-separated lists of addresses. All addresses, and any <em>body</em> values, will be offered for approval by the user before proceeding with a mailing. Any other name=value pairs in the <em>?searchpart</em> will be ignored. Also, if the mailto URL is the ACTION for a FORM, any <em>body</em> in a <em>?searchpart</em> tack-on will be ignored, because the body of the mailing must be constructed solely from the the FORM's content. Lynx expects multiple name=value pairs in a <em>?searchpart</em> tack-on to be separated by ampersands, as in the original Netscape implementation, and in an equally ill-advised IETF draft of that implementation (<a href="ftp://ftp.isi.edu/internet-drafts/draft-hoffman-mailto-url-03.txt" >draft-hoffman-mailto-url-03.txt</a>). These should be represented as entities (<em>&amp;amp;</em>) in the HTML markup. This functionality is generally desired, but the IETF backward compatibility principal normally would lead to a new scheme being used (e.g., <em>mail:</em>, or <em>smtp:</em>), rather than breaking <em>mailto:</em> implementations. <p>If <em>ENCTYPE="text/plain"</em> is specified for a FORM with a mailto ACTION, Lynx will not hex escape the name=value pairs of the FORM's content, and will use physical newlines instead of '<em>&amp;</em>' or '<em>;</em>' to separate the pairs, so that the content will be readable directly. Otherwise, Lynx will mail the content with the default: <pre> <em>ENCTYPE="application/x-www-form-urlencoded"</em> ('<em >&amp;</em>' separates pairs) </pre> or: <pre> <em>ENCTYPE="application/sgml-form-urlencoded"</em> ('<em >;</em>' separates pairs) </pre> if the latter was indicated. <p>Note that when mailing FORM content Lynx wraps any lines longer than 78 characters, to avoid buffer overflows in mail software and to ensure reliable transmission across gateways. If the ENCTYPE was not <em>text/plain</em>, any script which decodes the mailed content should ignore the physical newlines and recognize only hex escaped newline characters as intended to be present in the decoded content. <p>If the mailto URL is not the ACTION for a FORM, and if an external editor has been defined via the <em>Options Menu</em>, the user is offered an option to include the currently displayed document. If this option is accepted, each line of that document is prefixed with a right-angle-bracket, and the prefixed inclusion should be trimmed by the user to just those passages relevant to the message which will be sent. <HR> <H2><a name="finger_url">The <em>finger</em> URL:</a></H2> Lynx has full support for the finger protocol, but a format for finger URLs has not yet been adopted by the IETF. The formats supported by Lynx therefore include every possibility not inconsistent with RFC1738, including: <pre> finger://host finger://@host finger://host/ finger://@host/ finger://host/%2fw finger://@host/w finger://host/w finger://host/w/ finger://host/username[@host] finger://username@host finger://host/username[@host]/ finger://username@host/ finger://host/w/username[@host] finger://username@host/w finger://host/%2fw%20username[@host] finger://host/username[@host]/w finger://host/w/username </pre> <p>Activating a finger URL will send a request to the finger server via port 79 on the host specified. You can include <em>:79</em> in the URL, but no other value is allowed. The <em>/w</em> or <em>/%2fw</em> is used to request a full report for finger servers which support it, and is not case sensitive (i.e., can be <em>/W</em> or <em>/%2fW</em>). Any strings in the report which appear to be a URL with a supported scheme will be converted into a link for accessing that URL. <p>An alternative way to access finger servers is via gopher URLs with port 79 and the plain text (<em>0</em>) <em>gophertype</em> specified:<BR> <em>gopher://host:79/0</em><BR> Lynx will handle such URLs equivalently to overt finger URLs, including creation of links for any strings which appear to be supported URLs. <HR> <H2><a name="cso_url">The <em>cso</em> URL:</a></H2> The cso URL is intended to provide a gateway to CSO/PH (QI) servers. The requests are made on port 105 by default (<em>:105</em>), with the following overt cso URL format:<BR> <pre> <em>cso://host</em> </pre> <p>You also can use a gopher URL format with port 105 and the CSO (<em>2</em>) <em>gophertype</em> specified: <pre> <em>gopher://host:105/2</em> </pre> <p>Lynx will parse the stream returned by the server for the above URLs and create a FORM for submitting additional requests (searches) to the server. Any strings in the reports returned for these requests (searches) which appear to be a URL with a supported scheme will be converted into a link for accessing that URL. <HR> <H2><a name="bibp_url">The <em>bibp</em> URL:</a></H2> <p>Lynx provides built-in support for bibliographic protocol (BibP). BibP links are links to published works such as books or journal articles, without a predefined server. BibP links are intended for resolution by a local bibhost server (http://bibhost/) if it exists. Otherwise, resolution is performed by a document-specified server or a known global server. <H2><a name="exec_url">The <em>lynxexec</em> and <em>lynxprog</em> URLs:</a></H2> If execution of spawned commands has been enabled in your Lynx image, the lynxexec and lynxprog URLs can be used to execute arbitrary system commands or invoke system utilities. Any system command and associated switches or qualifiers can be used, with the syntax appropriate for a shell running Lynx on Unix, or for DCL on VMS, e.g.: <pre> <em>lynxexec:dir/date/size foo:[blah]</em> (VMS) <em>lynxexec:ls -l /foo/blah</em> (Unix) <em>lynxprog:news</em> </pre> (Note, however, that restrictions on acceptable commands or utilities may be imposed by the system administrator.) <p>You optionally can include <em>//localhost/</em> in the URL, between the scheme field and the command, but that is always implied. The lynxexec and lynxprog URLs differ only in that with lynxexec you are prompted to enter <em>RETURN</em> before Lynx clears the screen and restores the previously displayed document, so that you can read any screen output generated by the spawned command, whereas no such pause is imposed upon exit from the utility invoked via lynxprog. <p>These are Lynxisms and should be used only in local documents intended solely for Lynx. <HR> <H2><a name="cgi_url">The <em>lynxcgi</em> URL:</a></H2> The lynxcgi URL is implemented only on Unix, can be used as the ACTION for a FORM, and if enabled in your Lynx image has the format: <pre> <em>lynxcgi://localhost/path_to_CGI_script</em> </pre> where <em>//localhost</em> is optional and always implied; the full path should be specified, as `~' is not recognized; if the script is in the directory Lynx was started from, the simple file name is adequate. The output of the script should be text/html and is rendered and displayed by Lynx. Restrictions on use of lynxcgi and on acceptable paths can be imposed in <em>userdefs.h</em> and <em>lynx.cfg</em>, qv. <p>This is a Lynxism and should be used only in local documents intended solely for Lynx, or for limited local testing of CGI scripts without an http server. <HR> <H2><a name="ncftp_url">The <em>NcFTP</em> URL:</a></H2> Lynx recognizes the NcFTP-style ftp URL, e.g., <pre> <cite>ftpHost</cite>:<cite>fileSpecification</cite> </pre> for example <pre><code> ftp.gnu.org:/pub/gnu </code></pre> <HR> <H2><a name="internal_url">The <em>LYNXfoo</em> internal URLs:</a></H2> Lynx uses a variety of private URL schemes for communication among its internal modules. They start with uppercase letters <code>LYNX</code> by convention, although, as input, URL schemes are recognized in a case-insensitive manner. <p> As you discover what they are, and are tempted to use them externally in documents, you should <em>resist</em> that temptation: <UL><LI>There already is too much browser-specific markup around... <LI>The schemes, or their meanings, may change between Lynx versions. <LI>Even if a scheme stays the same, some aspect of its behavior may be modified without notice, or the context in which it is allowed may change. <LI>If it doesn't work as expected when used outside of the intended purpose, don't expect anyone to "fix" it. </UL> <p>For example, tempting though it might be, do not use these: <pre> <em>Return to your &lt;A HREF="LYNXHIST:0"&gt;Startfile&lt;/A&gt;</em> <em>Review your &lt;A HREF="LYNXKEYMAP:"&gt;Keymap&lt;/A&gt;</em> </pre> (No, they won't do any harm. Yes, they work. But don't rely on it.) <p>If you must try one, the second is OK from the command line:<BR> <pre> <em>lynx LYNXKEYMAP:</em> </pre> But within Lynx, use the '<em>K</em>' keystroke command. Sometimes it may be convenient to use a private scheme with '<em>g</em>'oto, as in: <pre> <em>g LYNXMESSAGES:</em> <em>g LYNXCOMPILEOPTS:</em> <em>g LYNXCFG:</em> </pre> But again, there usually is a way in which those special pages are meant to be reached that is more convenient. </BODY> </HTML>