diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0 index 81ceee1e902e..562b49bb5de4 100644 --- a/sys/arch/arm/xscale/files.pxa2x0 +++ b/sys/arch/arm/xscale/files.pxa2x0 @@ -1,4 +1,4 @@ -# $NetBSD: files.pxa2x0,v 1.12 2006/12/17 16:03:33 peter Exp $ +# $NetBSD: files.pxa2x0,v 1.13 2007/02/02 02:10:24 ober Exp $ # # Configuration info for Intel PXA2[751]0 CPU support # @@ -42,7 +42,7 @@ attach saost at pxaip file arch/arm/sa11x0/sa11x0_ost.c saost needs-flag # LCD controller -device lcd: wsemuldisplaydev, rasops16, rasops8, rasops4 +device lcd: wsemuldisplaydev, rasops16, rasops8, rasops4, rasops_rotation file arch/arm/xscale/pxa2x0_lcd.c lcd needs-flag # XXX this is a hack to use dev/pcmcia without fdc.c diff --git a/sys/arch/zaurus/dev/zlcd.c b/sys/arch/zaurus/dev/zlcd.c index 96667f4ae05d..c9172551005c 100644 --- a/sys/arch/zaurus/dev/zlcd.c +++ b/sys/arch/zaurus/dev/zlcd.c @@ -1,4 +1,4 @@ -/* $NetBSD: zlcd.c,v 1.3 2006/12/18 15:30:56 nonaka Exp $ */ +/* $NetBSD: zlcd.c,v 1.4 2007/02/02 02:10:24 ober Exp $ */ /* $OpenBSD: zaurus_lcd.c,v 1.20 2006/06/02 20:50:14 miod Exp $ */ /* NetBSD: lubbock_lcd.c,v 1.1 2003/08/09 19:38:53 bsh Exp */ @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: zlcd.c,v 1.3 2006/12/18 15:30:56 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: zlcd.c,v 1.4 2007/02/02 02:10:24 ober Exp $"); #include #include @@ -77,7 +77,7 @@ static struct pxa2x0_wsscreen_descr lcd_std_screen = { .capabilities = WSSCREEN_WSCOLORS, }, .depth = 16, /* bits per pixel */ - .flags = 0/*RI_ROTATE_CW*/, /* quarter clockwise rotation */ + .flags = RI_ROTATE_CW, /* quarter clockwise rotation */ }; static const struct wsscreen_descr *lcd_scr_descr[] = { diff --git a/sys/conf/files b/sys/conf/files index b2d509cfb3f5..7e3e8031699e 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.828 2007/01/19 14:49:08 hannken Exp $ +# $NetBSD: files,v 1.829 2007/02/02 02:10:24 ober Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -298,6 +298,7 @@ define rasops15 define rasops16 define rasops24 define rasops32 +define rasops_rotation # splash screen support include "dev/splash/files.splash" diff --git a/sys/dev/rasops/files.rasops b/sys/dev/rasops/files.rasops index edba10348779..79351b38db84 100644 --- a/sys/dev/rasops/files.rasops +++ b/sys/dev/rasops/files.rasops @@ -1,10 +1,10 @@ -# $NetBSD: files.rasops,v 1.11 2005/12/11 12:23:43 christos Exp $ +# $NetBSD: files.rasops,v 1.12 2007/02/02 02:10:24 ober Exp $ # Note: `rasops_glue' is only here to force the header file's name # hence it must be mentioned first (shudder...) file dev/rasops/rasops.c ( (rasops_glue | rasops1 | rasops2 | rasops4 | rasops8 | rasops15 | rasops16 | rasops24 | - rasops32) & + rasops32 | rasops_rotation) & (rasterconsole | wsdisplay)) needs-flag file dev/rasops/rasops_masks.c ((rasterconsole | wsdisplay) & diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c index fdb3f63aff34..10d485790031 100644 --- a/sys/dev/rasops/rasops.c +++ b/sys/dev/rasops/rasops.c @@ -1,4 +1,4 @@ -/* $NetBSD: rasops.c,v 1.54 2006/11/16 01:33:26 christos Exp $ */ +/* $NetBSD: rasops.c,v 1.55 2007/02/02 02:10:24 ober Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.54 2006/11/16 01:33:26 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.55 2007/02/02 02:10:24 ober Exp $"); #include "opt_rasops.h" #include "rasops_glue.h" @@ -135,6 +135,26 @@ static int rasops_allocattr_mono(void *, int, int, int, long *); static void rasops_do_cursor(struct rasops_info *); static void rasops_init_devcmap(struct rasops_info *); +#if NRASOPS_ROTATION > 0 +static void rasops_copychar(void *, int, int, int, int); +static void rasops_copycols_rotated(void *, int, int, int, int); +static void rasops_copyrows_rotated(void *, int, int, int); +static void rasops_erasecols_rotated(void *, int, int, int, long); +static void rasops_eraserows_rotated(void *, int, int, long); +static void rasops_putchar_rotated(void *, int, int, u_int, long); +static void rasops_rotate_font(int *); + +/* + * List of all rotated fonts + */ +SLIST_HEAD(, rotatedfont) rotatedfonts = SLIST_HEAD_INITIALIZER(rotatedfonts); +struct rotatedfont { + SLIST_ENTRY(rotatedfont) rf_next; + int rf_cookie; + int rf_rotated; +}; +#endif /* NRASOPS_ROTATION > 0 */ + /* * Initialize a 'rasops_info' descriptor. */ @@ -163,6 +183,15 @@ rasops_init(ri, wantrows, wantcols) return (-1); } +#if NRASOPS_ROTATION > 0 + /* + * Pick the rotated version of this font. This will create it + * if necessary. + */ + if (ri->ri_flg & RI_ROTATE_CW) + rasops_rotate_font(&cookie); +#endif + if (wsfont_lock(cookie, &ri->ri_font)) { printf("rasops_init: couldn't lock font\n"); return (-1); @@ -234,8 +263,17 @@ rasops_reconfig(ri, wantrows, wantcols) while ((ri->ri_emuwidth * bpp & 31) != 0) ri->ri_emuwidth--; - ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth; - ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight; +#if NRASOPS_ROTATION > 0 + if (ri->ri_flg & RI_ROTATE_CW) { + ri->ri_rows = ri->ri_emuwidth / ri->ri_font->fontwidth; + ri->ri_cols = ri->ri_emuheight / ri->ri_font->fontheight; + } else +#endif + { + + ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth; + ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight; + } ri->ri_emustride = ri->ri_emuwidth * bpp >> 3; ri->ri_delta = ri->ri_stride - ri->ri_emustride; ri->ri_ccol = 0; @@ -334,6 +372,17 @@ rasops_reconfig(ri, wantrows, wantcols) return (-1); } +#if NRASOPS_ROTATION > 0 + if (ri->ri_flg & RI_ROTATE_CW) { + ri->ri_real_ops = ri->ri_ops; + ri->ri_ops.copycols = rasops_copycols_rotated; + ri->ri_ops.copyrows = rasops_copyrows_rotated; + ri->ri_ops.erasecols = rasops_erasecols_rotated; + ri->ri_ops.eraserows = rasops_eraserows_rotated; + ri->ri_ops.putchar = rasops_putchar_rotated; + } +#endif + ri->ri_flg |= RI_CFGDONE; splx(s); return (0); @@ -853,8 +902,17 @@ rasops_do_cursor(ri) hrp = hp = NULL; - row = ri->ri_crow; - col = ri->ri_ccol; +#if NRASOPS_ROTATION > 0 + if (ri->ri_flg & RI_ROTATE_CW) { + /* Rotate rows/columns */ + row = ri->ri_ccol; + col = ri->ri_rows - ri->ri_crow - 1; + } else +#endif + { + row = ri->ri_crow; + col = ri->ri_ccol; + } rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; if (ri->ri_hwbits) @@ -1114,3 +1172,175 @@ rasops_erasecols(cookie, row, col, num, attr) } } } + +#if NRASOPS_ROTATION > 0 +/* + * Quarter clockwise rotation routines (originally intended for the + * built-in Zaurus C3x00 display in 16bpp). + */ + +#include + +static void +rasops_rotate_font(int *cookie) +{ + struct rotatedfont *f; + int ncookie; + + SLIST_FOREACH(f, &rotatedfonts, rf_next) { + if (f->rf_cookie == *cookie) { + *cookie = f->rf_rotated; + return; + } + } + + /* + * We did not find a rotated version of this font. Ask the wsfont + * code to compute one for us. + */ + + f = malloc(sizeof(struct rotatedfont), M_DEVBUF, M_WAITOK); + if (f == NULL) + return; + + if ((ncookie = wsfont_rotate(*cookie)) == -1) + return; + + f->rf_cookie = *cookie; + f->rf_rotated = ncookie; + SLIST_INSERT_HEAD(&rotatedfonts, f, rf_next); + + *cookie = ncookie; +} + +static void +rasops_copychar(cookie, srcrow, dstrow, srccol, dstcol) + void *cookie; + int srcrow, dstrow, srccol, dstcol; +{ + struct rasops_info *ri; + u_char *sp, *dp; + int height; + int r_srcrow, r_dstrow, r_srccol, r_dstcol; + + ri = (struct rasops_info *)cookie; + + r_srcrow = srccol; + r_dstrow = dstcol; + r_srccol = ri->ri_rows - srcrow - 1; + r_dstcol = ri->ri_rows - dstrow - 1; + + r_srcrow *= ri->ri_yscale; + r_dstrow *= ri->ri_yscale; + height = ri->ri_font->fontheight; + + sp = ri->ri_bits + r_srcrow + r_srccol * ri->ri_xscale; + dp = ri->ri_bits + r_dstrow + r_dstcol * ri->ri_xscale; + + while (height--) { + memmove(dp, sp, ri->ri_xscale); + dp += ri->ri_stride; + sp += ri->ri_stride; + } +} + +static void +rasops_putchar_rotated(cookie, row, col, uc, attr) + void *cookie; + int row, col; + u_int uc; + long attr; +{ + struct rasops_info *ri; + u_char *rp; + int height; + + ri = (struct rasops_info *)cookie; + + /* Do rotated char sans (side)underline */ + ri->ri_real_ops.putchar(cookie, col, ri->ri_rows - row - 1, uc, + attr & ~1); + + /* Do rotated underline */ + rp = ri->ri_bits + col * ri->ri_yscale + (ri->ri_rows - row - 1) * + ri->ri_xscale; + height = ri->ri_font->fontheight; + + /* XXX this assumes 16-bit color depth */ + if ((attr & 1) != 0) { + int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf]; + + while (height--) { + *(int16_t *)rp = c; + rp += ri->ri_stride; + } + } +} + +static void +rasops_erasecols_rotated(cookie, row, col, num, attr) + void *cookie; + int row, col, num; + long attr; +{ + struct rasops_info *ri; + int i; + + ri = (struct rasops_info *)cookie; + + for (i = col; i < col + num; i++) + ri->ri_ops.putchar(cookie, row, i, ' ', attr); +} + +/* XXX: these could likely be optimised somewhat. */ +static void +rasops_copyrows_rotated(cookie, src, dst, num) + void *cookie; + int src, dst, num; +{ + struct rasops_info *ri = (struct rasops_info *)cookie; + int col, roff; + + if (src > dst) + for (roff = 0; roff < num; roff++) + for (col = 0; col < ri->ri_cols; col++) + rasops_copychar(cookie, src + roff, dst + roff, + col, col); + else + for (roff = num - 1; roff >= 0; roff--) + for (col = 0; col < ri->ri_cols; col++) + rasops_copychar(cookie, src + roff, dst + roff, + col, col); +} + +static void +rasops_copycols_rotated(cookie, row, src, dst, num) + void *cookie; + int row, src, dst, num; +{ + int coff; + + if (src > dst) + for (coff = 0; coff < num; coff++) + rasops_copychar(cookie, row, row, src + coff, dst + coff); + else + for (coff = num - 1; coff >= 0; coff--) + rasops_copychar(cookie, row, row, src + coff, dst + coff); +} + +static void +rasops_eraserows_rotated(cookie, row, num, attr) + void *cookie; + int row, num; + long attr; +{ + struct rasops_info *ri; + int col, rn; + + ri = (struct rasops_info *)cookie; + + for (rn = row; rn < row + num; rn++) + for (col = 0; col < ri->ri_cols; col++) + ri->ri_ops.putchar(cookie, rn, col, ' ', attr); +} +#endif /* NRASOPS_ROTATION */ diff --git a/sys/dev/rasops/rasops.h b/sys/dev/rasops/rasops.h index 9a67a20b08e3..a42c3e3283bb 100644 --- a/sys/dev/rasops/rasops.h +++ b/sys/dev/rasops/rasops.h @@ -1,4 +1,4 @@ -/* $NetBSD: rasops.h,v 1.19 2006/02/18 13:57:33 jmcneill Exp $ */ +/* $NetBSD: rasops.h,v 1.20 2007/02/02 02:10:24 ober Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -50,6 +50,7 @@ struct wsdisplay_font; #define RI_CENTER 0x20 /* center onscreen output */ #define RI_CURSORCLIP 0x40 /* cursor is currently clipped */ #define RI_CFGDONE 0x80 /* rasops_reconfig() completed successfully */ +#define RI_ROTATE_CW 0x100 /* display is rotated, quarter clockwise */ struct rasops_info { /* These must be filled in by the caller */ @@ -110,6 +111,11 @@ struct rasops_info { /* Callbacks so we can share some code */ void (*ri_do_cursor)(struct rasops_info *); + +#if NRASOPS_ROTATION > 0 + /* Used to intercept putchar to permit display rotation */ + struct wsdisplay_emulops ri_real_ops; +#endif }; #define DELTA(p, d, cast) ((p) = (cast)((caddr_t)(p) + (d))) diff --git a/sys/dev/wsfont/files.wsfont b/sys/dev/wsfont/files.wsfont index 3b295fb04507..16cce5323c5f 100644 --- a/sys/dev/wsfont/files.wsfont +++ b/sys/dev/wsfont/files.wsfont @@ -1,8 +1,11 @@ -# $NetBSD: files.wsfont,v 1.14 2005/12/11 12:24:12 christos Exp $ +# $NetBSD: files.wsfont,v 1.15 2007/02/02 02:10:24 ober Exp $ defpseudo wsfont -file dev/wsfont/wsfont.c rasterconsole | wsdisplay | wsfont +# Note: `wsfont_glue' is only here to force the header file's name +# hence it must be mentioned first (shudder...) +file dev/wsfont/wsfont.c (wsfont_glue & rasops_rotation) | + rasterconsole | wsdisplay | wsfont needs-flag defflag opt_wsfont.h FONT_BOLD8x16 FONT_GALLANT12x22 diff --git a/sys/dev/wsfont/wsfont.c b/sys/dev/wsfont/wsfont.c index e29cfabb2b55..65973e3763c4 100644 --- a/sys/dev/wsfont/wsfont.c +++ b/sys/dev/wsfont/wsfont.c @@ -1,4 +1,4 @@ -/* $NetBSD: wsfont.c,v 1.43 2006/08/28 21:35:12 christos Exp $ */ +/* $NetBSD: wsfont.c,v 1.44 2007/02/02 02:10:24 ober Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.43 2006/08/28 21:35:12 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.44 2007/02/02 02:10:24 ober Exp $"); #include "opt_wsfont.h" @@ -51,6 +51,8 @@ __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.43 2006/08/28 21:35:12 christos Exp $") #include #include +#include "wsfont_glue.h" /* NRASOPS_ROTATION */ + #undef HAVE_FONT #ifdef FONT_QVSS8x15 @@ -300,6 +302,100 @@ wsfont_enum(void (*cb)(const char *, int, int, int)) } } +#if NRASOPS_ROTATION > 0 + +struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *); + +struct wsdisplay_font * +wsfont_rotate_internal(struct wsdisplay_font *font) +{ + int b, n, r, newstride; + struct wsdisplay_font *newfont; + char *newbits; + + /* Duplicate the existing font... */ + newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK); + if (newfont == NULL) + return (NULL); + + *newfont = *font; + + /* Allocate a buffer big enough for the rotated font. */ + newstride = (font->fontheight + 7) / 8; + newbits = malloc(newstride * font->fontwidth * font->numchars, + M_DEVBUF, M_WAITOK|M_ZERO); + if (newbits == NULL) { + free(newfont, M_DEVBUF); + return (NULL); + } + + + + /* Rotate the font a bit at a time. */ + for (n = 0; n < font->numchars; n++) { + unsigned char *ch = (unsigned char *)font->data + + (n * font->stride * font->fontheight); + + for (r = 0; r < font->fontheight; r++) { + for (b = 0; b < font->fontwidth; b++) { + unsigned char *rb; + + rb = ch + (font->stride * r) + (b / 8); + if (*rb & (0x80 >> (b % 8))) { + unsigned char *rrb; + + rrb = newbits + newstride - 1 - (r / 8) + + (n * newstride * font->fontwidth) + + (newstride * b); + *rrb |= (1 << (r % 8)); + } + } + } + } + + newfont->data = newbits; + + /* Update font sizes. */ + newfont->stride = newstride; + newfont->fontwidth = font->fontheight; + newfont->fontheight = font->fontwidth; + + if (wsfont_add(newfont, 0) != 0) { + /* + * If we seem to have rotated this font already, drop the + * new one... + */ + free(newbits, M_DEVBUF); + free(newfont, M_DEVBUF); + newfont = NULL; + } + + return (newfont); +} + +int +wsfont_rotate(int cookie) +{ + int s, ncookie; + struct wsdisplay_font *font; + struct font *origfont; + + s = splhigh(); + origfont = wsfont_find0(cookie, 0xffffffff); + splx(s); + + font = wsfont_rotate_internal(origfont->font); + if (font == NULL) + return (-1); + + ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight, + font->stride, 0, 0); + + return (ncookie); +} + +#endif /* NRASOPS_ROTATION */ + void wsfont_init(void) { diff --git a/sys/dev/wsfont/wsfont.h b/sys/dev/wsfont/wsfont.h index 2dd79d8bc9b4..675f0f38c89b 100644 --- a/sys/dev/wsfont/wsfont.h +++ b/sys/dev/wsfont/wsfont.h @@ -1,4 +1,4 @@ -/* $NetBSD: wsfont.h,v 1.17 2003/02/09 10:29:38 jdolecek Exp $ */ +/* $NetBSD: wsfont.h,v 1.18 2007/02/02 02:10:24 ober Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc. @@ -69,5 +69,6 @@ void wsfont_enum(void (*)(const char *, int, int, int)); int wsfont_lock(int, struct wsdisplay_font **); int wsfont_unlock(int); int wsfont_map_unichar(struct wsdisplay_font *, int); +int wsfont_rotate(int); #endif /* !_WSFONT_H_ */