From owner-freebsd-current@FreeBSD.ORG Mon Aug 30 07:11:22 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E79D416A4CE for ; Mon, 30 Aug 2004 07:11:22 +0000 (GMT) Received: from dd2626.kasserver.com (dd2626.kasserver.com [81.209.184.189]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0397E43D46 for ; Mon, 30 Aug 2004 07:11:22 +0000 (GMT) (envelope-from outi@bytephobia.de) Received: from [10.0.0.2] (pD9E4B231.dip.t-dialin.net [217.228.178.49]) by dd2626.kasserver.com (Postfix) with ESMTP id 9370A85501; Mon, 30 Aug 2004 09:11:18 +0200 (CEST) From: Patrick Hurrelmann To: cyrille.lefevre@laposte.net In-Reply-To: <200408291848.i7TImAq8072080@mail.gits.dyndns.org> References: <200408291848.i7TImAq8072080@mail.gits.dyndns.org> Content-Type: text/plain Message-Id: <1093845824.822.3.camel@duality.bytephobia.de> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 Date: Mon, 30 Aug 2004 08:03:44 +0200 Content-Transfer-Encoding: 7bit cc: Deng XueFeng cc: current@freebsd.org Subject: Re: [PATCH TO TEST] VESA [1024x768] mode support for FreeBSD-CURRENT X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: outi@bytephobia.de List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Aug 2004 07:11:23 -0000 Hi, thanks for reworking this patch. I'll test it later ;) 1024x768 console on my laptop would would be really nat. I see the mentioned error aka "vidcontrol: showing the mouse: Invalid argument", too. But it doesn't seem to affect behaviour of vidcontrol. On Sun, 2004-08-29 at 20:48, Cyrille Lefevre wrote: > On Aug 29, 2004 12:32:10 pm +0200, Patrick Hurrelmann wrote: > > Hi Cyrille, > > > > I tried you patch and it applies cleanly to 5.3-BETA1, but kernelbuild > > breaks due to syscons. Does anybody experience the same? > > ok, it seems I've missed some static void... don't understand why I don't > have the same warnings as yours using today's -current ? thanks anyway. > > > See attached log of kernelbuild. > > PS : did you notice the same vidcontrol error messages as Aurelien Nephtali > (aka "vidcontrol: showing the mouse: Invalid argument") ? > > however, here is the build fix (scvgarndr.c only) : > > Index: scvgarndr.c > =================================================================== > RCS file: /home/ncvs/src/sys/dev/syscons/scvgarndr.c,v > retrieving revision 1.15 > diff -u -I$Id.*$ -I$.+BSD.*$ -r1.15 scvgarndr.c > --- scvgarndr.c 30 May 2004 20:08:42 -0000 1.15 > +++ scvgarndr.c 29 Aug 2004 17:07:28 -0000 > @@ -47,7 +47,7 @@ > #include > > #ifndef SC_RENDER_DEBUG > -#define SC_RENDER_DEBUG 0 > +#define SC_RENDER_DEBUG 0 > #endif > > static vr_clear_t vga_txtclear; > @@ -59,7 +59,7 @@ > #ifndef SC_NO_CUTPASTE > static vr_draw_mouse_t vga_txtmouse; > #else > -#define vga_txtmouse (vr_draw_mouse_t *)vga_nop > +#define vga_txtmouse (vr_draw_mouse_t *)vga_nop > #endif > > #ifdef SC_PIXEL_MODE > @@ -73,7 +73,7 @@ > #ifndef SC_NO_CUTPASTE > static vr_draw_mouse_t vga_pxlmouse; > #else > -#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop > +#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop > #endif > #endif /* SC_PIXEL_MODE */ > > @@ -155,6 +155,37 @@ > #endif > #endif > > +#ifdef SC_PIXEL_MODE > +static uint32_t vga_palette32[16] = { > + 0x000000, 0x0000ad, 0x00ad00, 0x00adad, > + 0xad0000, 0xad00ad, 0xad5200, 0xadadad, > + 0x525252, 0x5252ff, 0x52ff52, 0x52ffff, > + 0xff5252, 0xff52ff, 0xffff52, 0xffffff > +}; > + > +static uint16_t vga_palette16[16] = { > + 0x0000, 0x0016, 0x0560, 0x0576, 0xb000, 0xb016, 0xb2a0, 0xb576, > + 0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff > +}; > + > +static uint16_t vga_palette15[16] = { > + 0x0000, 0x0016, 0x02c0, 0x02d6, 0x5800, 0x5816, 0x5940, 0x5ad6, > + 0x294a, 0x295f, 0x2bea, 0x2bff, 0x7d4a, 0x7d5f, 0x7fea, 0x7fff > +}; > + > +#define VIDEO_MEMORY_POS(scp, pos, x) \ > + scp->sc->adp->va_window + \ > + x * scp->xoff + \ > + scp->yoff * scp->font_size * scp->sc->adp->va_line_width + \ > + x * (pos % scp->xsize) + \ > + scp->font_size * scp->sc->adp->va_line_width * (pos / scp->xsize) > + > +#ifndef SC_NO_CUTPASTE > +static uint32_t mouse_buf32[256]; > +static uint16_t mouse_buf16[256]; > +#endif > +#endif > + > static void > vga_nop(scr_stat *scp, ...) > { > @@ -359,8 +390,8 @@ > yoffset = y%scp->font_size; > for (i = 0; i < 16; ++i) { > cursor[i + yoffset] = > - (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) > - | (mouse_or_mask[i] >> xoffset); > + (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) > + | (mouse_or_mask[i] >> xoffset); > } > for (i = 0; i < scp->font_size; ++i) { > font_buf[i] = (cursor[i] & 0xff00) >> 8; > @@ -431,7 +462,29 @@ > /* pixel (raster text) mode renderer */ > > static void > -vga_pxlclear(scr_stat *scp, int c, int attr) > +vga_pxlclear_direct(scr_stat *scp, int c, int attr) > +{ > + vm_offset_t p; > + int line_width; > + int pixel_size; > + int lines; > + int i; > + > + line_width = scp->sc->adp->va_line_width; > + pixel_size = scp->sc->adp->va_info.vi_pixel_size; > + lines = scp->ysize * scp->font_size; > + p = scp->sc->adp->va_window + > + line_width * scp->yoff * scp->font_size + > + scp->xoff * 8 * pixel_size; > + > + for (i = 0; i < lines; ++i) { > + bzero_io((void *)p, scp->xsize * 8 * pixel_size); > + p += line_width; > + } > +} > + > +static void > +vga_pxlclear_planar(scr_stat *scp, int c, int attr) > { > vm_offset_t p; > int line_width; > @@ -457,7 +510,121 @@ > } > > static void > -vga_pxlborder(scr_stat *scp, int color) > +vga_pxlclear(scr_stat *scp, int c, int attr) > +{ > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_DIRECT: > + vga_pxlclear_direct(scp, c, attr); > + break; > + case V_INFO_MM_PLANAR: > + vga_pxlclear_planar(scp, c, attr); > + break; > + } > +} > + > +static void > +vga_pxlborder_direct(scr_stat *scp, int color, int bpp) > +{ > + vm_offset_t s; > + vm_offset_t e; > + vm_offset_t f; > + int line_width; > + int pixel_size; > + int x; > + int y; > + int i; > + > + line_width = scp->sc->adp->va_line_width; > + pixel_size = scp->sc->adp->va_info.vi_pixel_size; > + > + if (scp->yoff > 0) { > + s = scp->sc->adp->va_window; > + e = s + line_width * scp->yoff * scp->font_size; > + > + for (f = s; f < e; f += pixel_size) { > + switch (bpp) { > + case 32: > + writel(f, vga_palette32[color]); > + break; > + case 16: > + writew(f, vga_palette16[color]); > + break; > + case 15: > + writew(f, vga_palette15[color]); > + break; > + } > + } > + } > + > + y = (scp->yoff + scp->ysize) * scp->font_size; > + > + if (scp->ypixel > y) { > + s = scp->sc->adp->va_window + line_width * y; > + e = s + line_width * (scp->ypixel - y); > + > + for (f = s; f < e; f += pixel_size) { > + switch (bpp) { > + case 32: > + writel(f, vga_palette32[color]); > + break; > + case 16: > + writew(f, vga_palette16[color]); > + break; > + case 15: > + writew(f, vga_palette15[color]); > + break; > + } > + } > + } > + > + y = scp->yoff * scp->font_size; > + x = scp->xpixel / 8 - scp->xoff - scp->xsize; > + > + for (i = 0; i < scp->ysize * scp->font_size; ++i) { > + if (scp->xoff > 0) { > + s = scp->sc->adp->va_window + line_width * (y + i); > + e = s + scp->xoff * 8 * pixel_size; > + > + for (f = s; f < e; f += pixel_size) { > + switch (bpp) { > + case 32: > + writel(f, vga_palette32[color]); > + break; > + case 16: > + writew(f, vga_palette16[color]); > + break; > + case 15: > + writew(f, vga_palette15[color]); > + break; > + } > + } > + } > + > + if (x > 0) { > + s = scp->sc->adp->va_window + line_width * (y + i) + > + scp->xoff * 8 * pixel_size + > + scp->xsize * 8 * pixel_size; > + e = s + x * 8 * pixel_size; > + > + for (f = s; f < e; f += pixel_size) { > + switch (bpp) { > + case 32: > + writel(f, vga_palette32[color]); > + break; > + case 16: > + writew(f, vga_palette16[color]); > + break; > + case 15: > + writew(f, vga_palette15[color]); > + break; > + } > + } > + } > + } > +} > + > +static void > +vga_pxlborder_planar(scr_stat *scp, int color) > { > vm_offset_t p; > int line_width; > @@ -492,6 +659,27 @@ > outw(GDCIDX, 0x0001); /* set/reset enable */ > } > > +static void > +vga_pxlborder(scr_stat *scp, int color) > +{ > + int bpp; > + > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_DIRECT: > + bpp = scp->sc->adp->va_info.vi_depth; > + > + if ((bpp == 16) && > + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) > + bpp = 15; > + > + vga_pxlborder_direct(scp, color, bpp); > + break; > + case V_INFO_MM_PLANAR: > + vga_pxlborder_planar(scp, color); > + break; > + } > +} > + > static void > vga_egadraw(scr_stat *scp, int from, int count, int flip) > { > @@ -506,11 +694,7 @@ > u_char c; > > line_width = scp->sc->adp->va_line_width; > - d = scp->sc->adp->va_window > - + scp->xoff > - + scp->yoff*scp->font_size*line_width > - + (from%scp->xsize) > - + scp->font_size*line_width*(from/scp->xsize); > + d = VIDEO_MEMORY_POS(scp, from, 1); > > outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ > outw(GDCIDX, 0x0003); /* data rotate/function select */ > @@ -541,7 +725,7 @@ > f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); > for (j = 0; j < scp->font_size; ++j, ++f) { > outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ > - writeb(e, 0); > + writeb(e, 0); > e += line_width; > } > ++d; > @@ -554,8 +738,87 @@ > outw(GDCIDX, 0xff08); /* bit mask */ > } > > -static void > -vga_vgadraw(scr_stat *scp, int from, int count, int flip) > +static void > +vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip, int bpp) > +{ > + vm_offset_t d = 0; > + vm_offset_t e; > + u_char *f; > + u_short col1, col2, idx; > + int line_width; > + int i, j, k; > + int a; > + > + line_width = scp->sc->adp->va_line_width; > + > + switch (bpp) { > + case 32: > + d = VIDEO_MEMORY_POS(scp, from, 32); > + break; > + case 16: > + /* FALLTHROUGH */ > + case 15: > + d = VIDEO_MEMORY_POS(scp, from, 16); > + break; > + } > + > + if (from + count > scp->xsize * scp->ysize) > + count = scp->xsize * scp->ysize - from; > + > + for (i = from; count-- > 0; ++i) { > + a = sc_vtb_geta(&scp->vtb, i); > + > + if (flip) { > + col1 = (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8; > + col2 = (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8; > + } else { > + col1 = (a & 0x0f00) >> 8; > + col2 = (a & 0xf000) >> 12; > + } > + > + e = d; > + f = &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]); > + > + for (j = 0; j < scp->font_size; ++j, ++f) { > + for (k = 7; k >= 0; --k) { > + idx = *f & (1 << (7 - k)) ? > + col1 : col2; > + > + switch (bpp) { > + case 32: > + writel(e + 4 * k, vga_palette32[idx]); > + break; > + case 16: > + writew(e + 2 * k, vga_palette16[idx]); > + break; > + case 15: > + writew(e + 2 * k, vga_palette15[idx]); > + break; > + } > + } > + > + e += line_width; > + } > + > + switch (bpp) { > + case 32: > + d += 32; > + break; > + case 16: > + /* FALLTHROUGH */ > + case 15: > + d += 16; > + break; > + } > + > + if ((i % scp->xsize) == scp->xsize - 1) > + d += scp->xoff * 16 * scp->sc->adp->va_info.vi_pixel_size + > + (scp->font_size - 1) * line_width; > + } > +} > + > +static void > +vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip) > { > vm_offset_t d; > vm_offset_t e; > @@ -568,11 +831,7 @@ > u_char c; > > line_width = scp->sc->adp->va_line_width; > - d = scp->sc->adp->va_window > - + scp->xoff > - + scp->yoff*scp->font_size*line_width > - + (from%scp->xsize) > - + scp->font_size*line_width*(from/scp->xsize); > + d = VIDEO_MEMORY_POS(scp, from, 1); > > outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ > outw(GDCIDX, 0x0003); /* data rotate/function select */ > @@ -604,7 +863,7 @@ > e = d; > f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); > for (j = 0; j < scp->font_size; ++j, ++f) { > - writeb(e, *f); > + writeb(e, *f); > e += line_width; > } > ++d; > @@ -617,6 +876,27 @@ > outw(GDCIDX, 0x0001); /* set/reset enable */ > } > > +static void > +vga_vgadraw(scr_stat *scp, int from, int count, int flip) > +{ > + int bpp; > + > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_DIRECT: > + bpp = scp->sc->adp->va_info.vi_depth; > + > + if ((bpp == 16) && > + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) > + bpp = 15; > + > + vga_vgadraw_direct(scp, from, count, flip, bpp); > + break; > + case V_INFO_MM_PLANAR: > + vga_vgadraw_planar(scp, from, count, flip); > + break; > + } > +} > + > static void > vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) > { > @@ -629,8 +909,70 @@ > #endif > } > > -static void > -draw_pxlcursor(scr_stat *scp, int at, int on, int flip) > +static void > +draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip, int bpp) > +{ > + vm_offset_t d = 0; > + u_char *f; > + int line_width; > + int height; > + int col1, col2, idx; > + int a; > + int i, j; > + > + line_width = scp->sc->adp->va_line_width; > + > + switch (bpp) { > + case 32: > + d = VIDEO_MEMORY_POS(scp, at, 32) + > + (scp->font_size - scp->curs_attr.base - 1) * line_width; > + break; > + case 16: > + /* FALLTHROUGH */ > + case 15: > + d = VIDEO_MEMORY_POS(scp, at, 16) + > + (scp->font_size - scp->curs_attr.base - 1) * line_width; > + break; > + } > + > + a = sc_vtb_geta(&scp->vtb, at); > + > + if (flip) { > + col1 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; > + col2 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; > + } else { > + col1 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; > + col2 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; > + } > + > + f = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size + > + scp->font_size - scp->curs_attr.base - 1]); > + > + height = imin(scp->curs_attr.height, scp->font_size); > + > + for (i = 0; i < height; ++i, --f) { > + for (j = 7; j >= 0; --j) { > + idx = *f & (1 << (7 - j)) ? col1 : col2; > + > + switch (bpp) { > + case 32: > + writel(d + 4 * j, vga_palette32[idx]); > + break; > + case 16: > + writew(d + 2 * j, vga_palette16[idx]); > + break; > + case 15: > + writew(d + 2 * j, vga_palette15[idx]); > + break; > + } > + } > + > + d -= line_width; > + } > +} > + > +static void > +draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip) > { > vm_offset_t d; > u_char *f; > @@ -642,12 +984,8 @@ > u_char c; > > line_width = scp->sc->adp->va_line_width; > - d = scp->sc->adp->va_window > - + scp->xoff > - + scp->yoff*scp->font_size*line_width > - + (at%scp->xsize) > - + scp->font_size*line_width*(at/scp->xsize) > - + (scp->font_size - scp->curs_attr.base - 1)*line_width; > + d = VIDEO_MEMORY_POS(scp, at, 1) + > + (scp->font_size - scp->curs_attr.base - 1) * line_width; > > outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ > outw(GDCIDX, 0x0003); /* data rotate/function select */ > @@ -673,7 +1011,7 @@ > height = imin(scp->curs_attr.height, scp->font_size); > for (i = 0; i < height; ++i, --f) { > outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ > - writeb(d, 0); > + writeb(d, 0); > d -= line_width; > } > outw(GDCIDX, 0x0000); /* set/reset */ > @@ -681,6 +1019,27 @@ > outw(GDCIDX, 0xff08); /* bit mask */ > } > > +static void > +draw_pxlcursor(scr_stat *scp, int at, int on, int flip) > +{ > + int bpp; > + > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_DIRECT: > + bpp = scp->sc->adp->va_info.vi_depth; > + > + if ((bpp == 16) && > + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) > + bpp = 15; > + > + draw_pxlcursor_direct(scp, at, on, flip, bpp); > + break; > + case V_INFO_MM_PLANAR: > + draw_pxlcursor_planar(scp, at, on, flip); > + break; > + } > +} > + > static int pxlblinkrate = 0; > > static void > @@ -726,7 +1085,87 @@ > #ifndef SC_NO_CUTPASTE > > static void > -draw_pxlmouse(scr_stat *scp, int x, int y) > +draw_pxlmouse_direct(scr_stat *scp, int x, int y, int bpp) > +{ > + vm_offset_t p; > + int line_width, pixel_size; > + int xend, yend; > + static int x_old = 0, xend_old = 0; > + static int y_old = 0, yend_old = 0; > + int i, j; > + uint32_t *u32; > + uint16_t *u16; > + > + line_width = scp->sc->adp->va_line_width; > + pixel_size = scp->sc->adp->va_info.vi_pixel_size; > + > + xend = imin(x + 16, scp->xpixel); > + yend = imin(y + 16, scp->ypixel); > + > + p = scp->sc->adp->va_window + y_old * line_width + x_old * pixel_size; > + > + for (i = 0; i < (yend_old - y_old); i++) { > + for (j = (xend_old - x_old - 1); j >= 0; j--) { > + switch (bpp) { > + case 32: > + u32 = (uint32_t*)(p + j * pixel_size); > + writel(u32, mouse_buf32[i * 16 + j]); > + break; > + case 16: > + /* FALLTHROUGH */ > + case 15: > + u16 = (uint16_t*)(p + j * pixel_size); > + writew(u16, mouse_buf16[i * 16 + j]); > + break; > + } > + } > + > + p += line_width; > + } > + > + p = scp->sc->adp->va_window + y * line_width + x * pixel_size; > + > + for (i = 0; i < (yend - y); i++) { > + for (j = (xend - x - 1); j >= 0; j--) { > + switch (bpp) { > + case 32: > + u32 = (uint32_t*)(p + j * pixel_size); > + mouse_buf32[i * 16 + j] = *u32; > + if (mouse_or_mask[i] & (1 << (15 - j))) > + writel(u32, vga_palette32[15]); > + else if (mouse_and_mask[i] & (1 << (15 - j))) > + writel(u32, 0); > + break; > + case 16: > + u16 = (uint16_t*)(p + j * pixel_size); > + mouse_buf16[i * 16 + j] = *u16; > + if (mouse_or_mask[i] & (1 << (15 - j))) > + writew(u16, vga_palette16[15]); > + else if (mouse_and_mask[i] & (1 << (15 - j))) > + writew(u16, 0); > + break; > + case 15: > + u16 = (uint16_t*)(p + j * pixel_size); > + mouse_buf16[i * 16 + j] = *u16; > + if (mouse_or_mask[i] & (1 << (15 - j))) > + writew(u16, vga_palette15[15]); > + else if (mouse_and_mask[i] & (1 << (15 - j))) > + writew(u16, 0); > + break; > + } > + } > + > + p += line_width; > + } > + > + x_old = x; > + y_old = y; > + xend_old = xend; > + yend_old = yend; > +} > + > +static void > +draw_pxlmouse_planar(scr_stat *scp, int x, int y) > { > vm_offset_t p; > int line_width; > @@ -801,7 +1240,28 @@ > } > > static void > -remove_pxlmouse(scr_stat *scp, int x, int y) > +draw_pxlmouse(scr_stat *scp, int x, int y) > +{ > + int bpp; > + > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_DIRECT: > + bpp = scp->sc->adp->va_info.vi_depth; > + > + if ((bpp == 16) && > + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) > + bpp = 15; > + > + draw_pxlmouse_direct(scp, x, y, bpp); > + break; > + case V_INFO_MM_PLANAR: > + draw_pxlmouse_planar(scp, x, y); > + break; > + } > +} > + > +static void > +remove_pxlmouse_planar(scr_stat *scp, int x, int y) > { > vm_offset_t p; > int col, row; > @@ -857,6 +1317,18 @@ > outw(GDCIDX, 0x0001); /* set/reset enable */ > } > > +static void > +remove_pxlmouse(scr_stat *scp, int x, int y) > +{ > + switch (scp->sc->adp->va_info.vi_mem_model) { > + case V_INFO_MM_PLANAR: > + remove_pxlmouse_planar(scp, x, y); > + break; > + default: > + break; > + } > +} > + > static void > vga_pxlmouse(scr_stat *scp, int x, int y, int on) > { > > Cyrille Lefevre -- =========================================================================== Patrick Hurrelmann | "Programming today is a race between software Mannheim, Germany | engineers striving to build bigger and better | idiot-proof programs, and the Universe trying outi at bytephobia.de | to produce bigger and better idiots. So far, www.bytephobia.de | the Universe is winning." - Rich Cook