Updates to allow Zaurus screen to rotate 90 degrees to a usable state with the keyboard. Patch from peter@ copied from OpenBSD. Feedback and OK from matt@

This commit is contained in:
ober 2007-02-02 02:10:24 +00:00
parent 340d62487a
commit 5c470843ae
9 changed files with 357 additions and 20 deletions

View File

@ -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

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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[] = {

View File

@ -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"

View File

@ -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) &

View File

@ -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 <sys/cdefs.h>
__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 <sys/malloc.h>
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 */

View File

@ -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)))

View File

@ -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

View File

@ -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 <sys/cdefs.h>
__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 <dev/wscons/wsconsio.h>
#include <dev/wsfont/wsfont.h>
#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)
{

View File

@ -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_ */