[dev] [st] tty widthheight
Changeset 317 (14adb004eb78) introduced tw and th in the XWindow struct. They are currently equivalent to the window width and height (x.w and x.h). What are their purpose?
Re: [dev] [st] tty widthheight
Hello. On Wed, 19 Sep 2012 13:42:02 +0200 Aurélien Aptel aurelien.ap...@gmail.com wrote: Changeset 317 (14adb004eb78) introduced tw and th in the XWindow struct. They are currently equivalent to the window width and height (x.w and x.h). What are their purpose? The tty size is different from the window size. The pty device gets a different size defined than what the window is. This is needed in custom geometry definitions and when the window manager isn’t respecting st’s size hints. If the real width and height isn’t kept artefacts will re‐ main on the unused borders. Sincerely, Christoph Lohmann
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
Somebody claiming to be Uriel wrote: CGD runs as a FastCGI wrapper (to be used with nginx or similar web server) or as a standalone HTTP server, handing over all requests to a given CGI script. Is this just a wrapper for compatability (which seems odd, since most servers also speak CGI), or does it do prefork stuff to improve performance? -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph signature.asc Description: Digital signature
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
prefork
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
On Wed, Sep 19, 2012 at 4:10 PM, Stephen Paul Weber singpol...@singpolyma.net wrote: Somebody claiming to be Uriel wrote: CGD runs as a FastCGI wrapper (to be used with nginx or similar web server) or as a standalone HTTP server, handing over all requests to a given CGI script. Is this just a wrapper for compatability (which seems odd, since most servers also speak CGI), or does it do prefork stuff to improve performance? Sadly not all servers speak CGI this days, most notably nginx, and others often have broken CGI support. Also CGD can act as a extremely minimal HTTP server itself to directly host stand-alone CGI scripts without a 'real' web server. The server itself uses goroutines which are very efficient, so has no need to pre-fork, the called CGI script can't be 'preforked' because before you fork a CGI script you have to set the relevant environment variables for the request. Still, forking is never the bottleneck (werc itself performs hundreds of fork per request) and I wouldn't be surprised if CGD is not more efficient than the CGI-handling code in most web servers, but if your web server already supports CGI i wouldn't really bother. Hope this answers most (all?) your questions. Uriel
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
Somebody claiming to be Uriel wrote: Sadly not all servers speak CGI this days, most notably nginx, and others often have broken CGI support. Oh? I guess I just never tried CGI with nginx. the called CGI script can't be 'preforked' because before you fork a CGI script you have to set the relevant environment variables for the request. Hmm, I suppose that's true. Still, forking is never the bottleneck Never? Isn't forking-as-bottleneck most of the reason alternatives to CGI exist? -- Stephen Paul Weber, @singpolyma See http://singpolyma.net for how I prefer to be contacted edition right joseph signature.asc Description: Digital signature
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
On 9/19/12, Stephen Paul Weber singpol...@singpolyma.net wrote: Still, forking is never the bottleneck Never? Isn't forking-as-bottleneck most of the reason alternatives to CGI exist? The bottleneck is more likely to be exec-ing an interpreter which parses/loads a huge pile of standard library modules every time it is started. Robert Ransom
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
* Stephen Paul Weber singpol...@singpolyma.net [2012-09-19 17:00]: Still, forking is never the bottleneck Never? Isn't forking-as-bottleneck most of the reason alternatives to CGI exist? One of the bottlenecks of CGI is that the popular web scripting languages (i.e. PHP, Perl, Python, Ruby) make it horribly inefficient. Every request doesn't only mean a fork, but also completely loading the application's source code including all dependencies. I once measured this (because the web hosting platform that I work on uses CGI + suexec to separate web scripts of different users on the same host), and every single request to a WordPress makes the PHP interpreter load more than 1 MB of PHP source. MediaWiki is even worse: I measured about 4 MB. For lightweight web apps, consisting of only a single binary or a single script that is loaded quickly, this obviously isn't a problem. Regards, Andreas
Re: [dev] POLL: most beautiful suckless cloud
2012/9/19 Christoph Lohmann 2...@r-36.net: Greetings. Suckless can't stand behind the developments of the sucking world. Because of this I have a request. Please vote for your most favourite suckless cloud implementation. Both are attached. The winner will be shown in art galleries all over Europe. Sincerely, Christoph Lohmann I'd like to know is this kind of jokes is considered funny here.
Re: [dev] POLL: most beautiful suckless cloud
I'd like to know is this kind of jokes is considered funny here. Which kind of joke? -- sic dicit magister P Université du Québec à Montréal / Loyola University Chicago http://individual.utoronto.ca/peterjh gpg 1024D/ED6EF59B (7D1A 522F D08E 30F6 FA42 B269 B860 352B ED6E F59B) gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B
Re: [dev] POLL: most beautiful suckless cloud
On Wed, Sep 19, 2012 at 5:55 PM, Peter Hartman peterjohnhart...@gmail.com wrote: I'd like to know is this kind of jokes is considered funny here. Which kind of joke? Those metajokes are indeed funny. I'm still not sure if he was relating to OP or just to himself.
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
On Wed, Sep 19, 2012 at 5:06 PM, Andreas Krennmair a...@synflood.at wrote: * Stephen Paul Weber singpol...@singpolyma.net [2012-09-19 17:00]: Still, forking is never the bottleneck Never? Isn't forking-as-bottleneck most of the reason alternatives to CGI exist? One of the bottlenecks of CGI is that the popular web scripting languages (i.e. PHP, Perl, Python, Ruby) make it horribly inefficient. Every request doesn't only mean a fork, but also completely loading the application's source code including all dependencies. I once measured this (because the web hosting platform that I work on uses CGI + suexec to separate web scripts of different users on the same host), and every single request to a WordPress makes the PHP interpreter load more than 1 MB of PHP source. MediaWiki is even worse: I measured about 4 MB. For lightweight web apps, consisting of only a single binary or a single script that is loaded quickly, this obviously isn't a problem. Exactly. For werc, which does hundreds of forks per request (and that is written in interpreted languages: rc, awk, sed), I measured that when using the markdown.pl Perl script for formatting, starting up perl took considerably longer than all the forks and executions of rc/awk/sed code. The real problem is how much popular scripting languages like Php, Perl, Python, etc, suck. And I wont mention Ruby because Ruby performance a joke nobody could ever take seriously: http://harmful.cat-v.org/software/ruby/ All that said, fork performance for statically linked binaries is really good on Linux, other platforms and dynamically loaded binaries are more problematic, but nowher near as much as others make it. (This reminds me, most such scripting languages are dynamically linked and load tons of dynamic modules at run time, more stupid overhead) Uriel Regards, Andreas
Re: [dev] [ANN] CGD - Ultra-minimalist HTTP and FastCGI wrapper for CGI programs.
On Wed, Sep 19, 2012 at 04:43:17PM +0200, Uriel wrote: On Wed, Sep 19, 2012 at 4:10 PM, Stephen Paul Weber singpol...@singpolyma.net wrote: Somebody claiming to be Uriel wrote: CGD runs as a FastCGI wrapper (to be used with nginx or similar web server) or as a standalone HTTP server, handing over all requests to a given CGI script. Is this just a wrapper for compatability (which seems odd, since most servers also speak CGI), or does it do prefork stuff to improve performance? Sadly not all servers speak CGI this days, most notably nginx, and others often have broken CGI support. Also CGD can act as a extremely minimal HTTP server itself to directly host stand-alone CGI scripts without a 'real' web server. The server itself uses goroutines which are very efficient, so has no need to pre-fork, the called CGI script can't be 'preforked' because before you fork a CGI script you have to set the relevant environment variables for the request. Still, forking is never the bottleneck (werc itself performs hundreds of fork per request) and I wouldn't be surprised if CGD is not more efficient than the CGI-handling code in most web servers, but if your web server already supports CGI i wouldn't really bother. I read somewhere that forking looks like a problem in combination with multithreaded webservers, since all threads are cloned, in order to be thrown away after during exec'd. And so FCGI deamons emerged: push the fork away from the threaded process. There seemed to be no need to use FCGI for single threaded webservers. Kurt
[dev] [st] Patches
Hi, A new serie of patches for st. Please send comments or suggestions. Best regards. From 703b3cfc0cdb4998abca6815dd32699705a9f912 Mon Sep 17 00:00:00 2001 From: Roberto E. Vargas Caballero k...@shike2.com Date: Wed, 19 Sep 2012 19:42:48 +0200 Subject: Clear X window in tsetreset() tsetreset() is called when it is necessary a full initialization of the terminal, so it also should clean the full X window and not only the terminal content. It is necessary change the order of the initialization in main(), and put xinit before of tnew(), because tnew() calls to tsetreset(), and this can cause a call to xreset() with incorrect values. --- st.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/st.c b/st.c index 35f6f16..7c05a6c 100644 --- a/st.c +++ b/st.c @@ -943,6 +943,7 @@ treset(void) { term.tabs[i] = 1; term.top = 0, term.bot = term.row - 1; term.mode = MODE_WRAP; + xclear(0, 0, xw.w, xw.h); tclearregion(0, 0, term.col-1, term.row-1); } @@ -2445,9 +2446,9 @@ main(int argc, char *argv[]) { run: setlocale(LC_CTYPE, ); + xinit(); tnew(80, 24); ttynew(); - xinit(); selinit(); run(); return 0; -- 1.7.10.4 From 4671ab2615b1bd5f6e77bd8ec24765707b5f Mon Sep 17 00:00:00 2001 From: Roberto E. Vargas Caballero k...@shike2.com Date: Wed, 19 Sep 2012 19:46:40 +0200 Subject: Remove unused parameters in ttyresize --- st.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/st.c b/st.c index 7c05a6c..43dbe32 100644 --- a/st.c +++ b/st.c @@ -283,7 +283,7 @@ static void tfulldirt(void); static void ttynew(void); static void ttyread(void); -static void ttyresize(int, int); +static void ttyresize(void); static void ttywrite(const char *, size_t); static void xdraws(char *, Glyph, int, int, int, int); @@ -890,7 +890,7 @@ ttywrite(const char *s, size_t n) { } void -ttyresize(int x, int y) { +ttyresize(void) { struct winsize w; w.ws_row = term.row; @@ -2339,7 +2339,7 @@ resize(XEvent *e) { xclear(0, 0, xw.w, xw.h); tresize(col, row); xresize(col, row); - ttyresize(col, row); + ttyresize(); } void -- 1.7.10.4 From b42c8e533bdbb694b35ba3d0ef74863e51c8808e Mon Sep 17 00:00:00 2001 From: Roberto E. Vargas Caballero k...@shike2.com Date: Wed, 19 Sep 2012 19:49:48 +0200 Subject: Add KAM sequence This sequence lock/unlock the keyboard ignoring all the key pressing events from X server. --- st.c |8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/st.c b/st.c index 43dbe32..7e369c7 100644 --- a/st.c +++ b/st.c @@ -107,7 +107,8 @@ enum term_mode { MODE_MOUSEBTN= 32, MODE_MOUSEMOTION = 64, MODE_MOUSE = 32|64, - MODE_REVERSE = 128 + MODE_REVERSE = 128, + MODE_KBDLOCK = 256 }; enum escape_state { @@ -1319,6 +1320,9 @@ tsetmode(bool priv, bool set, int *args, int narg) { } } else { switch(*args) { + case 2: +MODBIT(term.mode, set, MODE_KBDLOCK); +break; case 4: MODBIT(term.mode, set, MODE_INSERT); break; @@ -2269,6 +2273,8 @@ kpress(XEvent *ev) { int shift; Status status; + if (IS_SET(MODE_KBDLOCK)) + return; meta = e-state Mod1Mask; shift = e-state ShiftMask; len = XmbLookupString(xw.xic, e, buf, sizeof(buf), ksym, status); -- 1.7.10.4 From fada4a6e23741745b85f8c60eacd8bbcf07d7483 Mon Sep 17 00:00:00 2001 From: Roberto E. Vargas Caballero k...@shike2.com Date: Wed, 19 Sep 2012 20:00:56 +0200 Subject: Fix LNM sequence LNM sequence is a standard ANSI mode, not a DEC private mode. --- st.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/st.c b/st.c index 7e369c7..4dd7547 100644 --- a/st.c +++ b/st.c @@ -1283,9 +1283,6 @@ tsetmode(bool priv, bool set, int *args, int narg) { case 7: MODBIT(term.mode, set, MODE_WRAP); break; - case 20: -MODBIT(term.mode, set, MODE_CRLF); -break; case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; case 25: @@ -1326,6 +1323,9 @@ tsetmode(bool priv, bool set, int *args, int narg) { case 4: MODBIT(term.mode, set, MODE_INSERT); break; + case 20: +MODBIT(term.mode, set, MODE_CRLF); +break; default: fprintf(stderr, erresc: unknown set/reset mode %d\n, -- 1.7.10.4 From e328b3e0cf5db77cb3e37500cbed097d5477e117 Mon Sep 17 00:00:00 2001 From: Roberto E. Vargas Caballero k...@shike2.com Date: Wed, 19 Sep 2012 20:18:15 +0200 Subject: Add some documentetion to tsetmode The names of the terminal modes supported by vt102 are (taken from the VT220 programmer reference manual): Table 4-7 ANSI-Standardized Modes Name Mnemonic Parameter (Ps) Error (ignored) - 0 (3/0) Keyboard action KAM 2 (3/2) Insert/replace IRM 4 (3/4) Send/receive SRM 12 (3/1 3/2) Line feed/new line LNM 20 (3/2 3/0) Table 4-8 ANSI-Compatible DEC Private Modes Name Mnemonic Parameter (Ps) Error (ignored) - 0 (3/0) Cursor key DECCKM
Re: [dev] [st] Patches
On Wed, Sep 19, 2012 at 8:42 PM, Roberto E. Vargas Caballero k...@shike2.com wrote: Hi, A new serie of patches for st. Please send comments or suggestions. Best regards. Would you also port st to wayland? cheers! mar77i
Re: [dev] [st] Patches
How many patches are left to get scrollback buffer? On Sep 19, 2012, at 20:42, Roberto E. Vargas Caballero k...@shike2.com wrote: Hi, A new serie of patches for st. Please send comments or suggestions. Best regards. 0001-Clear-X-window-in-tsetreset.patch 0002-Remove-unused-parameters-in-ttyresize.patch 0003-Add-KAM-sequence.patch 0004-Fix-LNM-sequence.patch 0005-Add-some-documentetion-to-tsetmode.patch
Re: [dev] POLL: most beautiful suckless cloud
On Wed, Sep 19, 2012 at 11:34 AM, Christoph Lohmann 2...@r-36.net wrote: Because of this I have a request. Please vote for your most favourite suckless cloud implementation. Both are attached. cl has fewer lines of code, and a shorter name, so it sucks less. I don't really care if they perform different functions. --Andrew Hills
Re: [dev] POLL: most beautiful suckless cloud
computas are not art.
Re: [dev] [st] Patches
2012/9/19 pancake panc...@youterm.com: How many patches are left to get scrollback buffer? We don't want scrollback buffers. -- sic dicit magister P Université du Québec à Montréal / Loyola University Chicago http://individual.utoronto.ca/peterjh gpg 1024D/ED6EF59B (7D1A 522F D08E 30F6 FA42 B269 B860 352B ED6E F59B) gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B
Re: [dev] [st] Patches
Quoth Peter Hartman: 2012/9/19 pancake panc...@youterm.com: How many patches are left to get scrollback buffer? We don't want scrollback buffers. Some of us do.
Re: [dev] [st] Patches
Just use 9term.
Re: [dev] [st] Patches
Well... I was asking about comments and suggestion of the patches. I am not the person who can accept or deny new suggestion, but I am going to give my personal opinion. Would you also port st to wayland? I think in case of being possible, st is very far to do this, because it has a lot of things to fix before. How many patches are left to get scrollback buffer? Idea of main developers is not add this feature to st, because you can get it using other external programs, like for example tmux. This helps to keep st very simple, efficient and clear. Maybe a good solution could be integrate tmux inside of st (for example if STTMUX is defined, run tmux in starup).
[dev] [st] xft
Greetings. Attached is a port of the xft branch to the current tip of st. It will activate xft support and more fonts than just corefonts. I really tried to find corefonts that would look good and represent nearly all unicode characters – it's impossible. Please report back if it works. I will then simply apply it. config.h: #define FONT DejaVu Sans Mono:pixelsize=12 #define BOLDFONT FONT :weight=bold #define ITALICFONT FONT :slant=italic,oblique #define ITALICBOLDFONT BOLDFONT :slant=italic,oblique Sincerely, Christoph Lohmann diff -r 25183e42ebfd config.mk --- a/config.mk Tue Sep 18 19:13:19 2012 +0200 +++ b/config.mk Thu Sep 20 00:58:38 2012 +0200 @@ -11,8 +11,8 @@ X11LIB = /usr/X11R6/lib # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext +INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2 +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -lXext -lXft # flags CPPFLAGS = -DVERSION=\${VERSION}\ diff -r 25183e42ebfd st.c --- a/st.c Tue Sep 18 19:13:19 2012 +0200 +++ b/st.c Thu Sep 20 00:58:38 2012 +0200 @@ -25,6 +25,9 @@ #include X11/cursorfont.h #include X11/keysym.h #include X11/extensions/Xdbe.h +#include X11/Xft/Xft.h +#define Glyph Glyph_ +#define Font Font_ #if defined(__linux) #include pty.h @@ -195,10 +198,13 @@ Atom xembed; XIM xim; XIC xic; + XftDraw *xft_draw; + Visual *vis; int scr; Bool isfixed; /* is fixed geometry? */ int fx, fy, fw, fh; /* fixed geometry */ int tw, th; /* tty width and height */ + int bufw, bufh; /* pixmap width and height */ int w; /* window width */ int h; /* window height */ int ch; /* char height */ @@ -212,7 +218,6 @@ char s[ESC_BUF_SIZ]; } Key; - /* TODO: use better name for vars... */ typedef struct { int mode; @@ -228,17 +233,22 @@ #include config.h +/* Font structure */ +typedef struct { + int ascent; + int descent; + short lbearing; + short rbearing; + XFontSet set; + XftFont* xft_set; +} Font; + /* Drawing Context */ typedef struct { ulong col[LEN(colorname) 256 ? 256 : LEN(colorname)]; + XftColor xft_col[LEN(colorname) 256 ? 256 : LEN(colorname)]; GC gc; - struct { - int ascent; - int descent; - short lbearing; - short rbearing; - XFontSet set; - } font, bfont, ifont, ibfont; + Font font, bfont, ifont, ibfont; } DC; static void die(const char*, ...); @@ -1840,47 +1850,49 @@ xresize(int col, int row) { xw.tw = MAX(1, 2*BORDER + col * xw.cw); xw.th = MAX(1, 2*BORDER + row * xw.ch); + + XftDrawChange(xw.xft_draw, xw.buf); } void xloadcols(void) { int i, r, g, b; - XColor color; + XRenderColor xft_color = { .alpha = 0 }; ulong white = WhitePixel(xw.dpy, xw.scr); /* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */ for(i = 0; i LEN(colorname); i++) { if(!colorname[i]) continue; - if(!XAllocNamedColor(xw.dpy, xw.cmap, colorname[i], color, color)) { + if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, colorname[i], dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, Could not allocate color '%s'\n, colorname[i]); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; } /* load colors [16-255] ; same colors as xterm */ for(i = 16, r = 0; r 6; r++) for(g = 0; g 6; g++) for(b = 0; b 6; b++) { -color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; -color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; -color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; -if(!XAllocColor(xw.dpy, xw.cmap, color)) { +xft_color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; +xft_color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; +xft_color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; +if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, xft_color, dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, Could not allocate color %d\n, i); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; i++; } for(r = 0; r 24; r++, i++) { - color.red = color.green = color.blue = 0x0808 + 0x0a0a * r; - if(!XAllocColor(xw.dpy, xw.cmap, color)) { + xft_color.red = xft_color.green = xft_color.blue = 0x0808 + 0x0a0a * r; + if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, xft_color, dc.xft_col[i])) { dc.col[i] = white; fprintf(stderr, Could not allocate color %d\n, i); } else - dc.col[i] = color.pixel; + dc.col[i] = dc.xft_col[i].pixel; } } @@ -1917,58 +1929,25 @@ XFree(sizeh); } -XFontSet -xinitfont(char *fontstr) { - XFontSet set; - char *def, **missing; - int n; +void +xinitfont(Font *f, char *fontstr) { + f-xft_set = XftFontOpenName(xw.dpy, xw.scr, fontstr); - missing = NULL; - set = XCreateFontSet(xw.dpy, fontstr, missing, n, def); - if(missing) { - while(n--) - fprintf(stderr, st: missing fontset: %s\n, missing[n]); - XFreeStringList(missing); - } - return set; -} + if(!f-xft_set) + die(st: can't open font %s.\n, fontstr); -void -xgetfontinfo(XFontSet set, int *ascent, int *descent, short
Re: [dev] [st] Patches
On 19/09/2012, Roberto E. Vargas Caballero k...@shike2.com wrote: Maybe a good solution could be integrate tmux inside of st (for example if STTMUX is defined, run tmux in starup). Yeah! Oh, we could have a variable for everything that one could wish to start in st: STTMUX, STGNUSCREEN, STAALIBKDE... or we could just use -e.
[dev] st eight bit input
Hi, I wonder if it's possible to get something like xterm's eightBitInput=true in st. I would like to use the alt key for some vim mappings. I'm not at all savvy on terminal stuff so any hint about how to hack the code to get this working would be very much appreciated. Best regards -- Carlos
Re: [dev] [st] xft
What was wrong with -f commandline switch from the xft branch? Half the point is to avoid having to compile a unique binary per font. But whatever 2012/9/19 Christoph Lohmann 2...@r-36.net: Greetings. Attached is a port of the xft branch to the current tip of st. It will activate xft support and more fonts than just corefonts. I really tried to find corefonts that would look good and represent nearly all unicode characters – it's impossible. Please report back if it works. I will then simply apply it. config.h: #define FONT DejaVu Sans Mono:pixelsize=12 #define BOLDFONT FONT :weight=bold #define ITALICFONT FONT :slant=italic,oblique #define ITALICBOLDFONT BOLDFONT :slant=italic,oblique Sincerely, Christoph Lohmann -- sic dicit magister P Université du Québec à Montréal / Loyola University Chicago http://individual.utoronto.ca/peterjh gpg 1024D/ED6EF59B (7D1A 522F D08E 30F6 FA42 B269 B860 352B ED6E F59B) gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B