summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authornonaka <nonaka@NetBSD.org>2010-04-17 13:36:21 +0000
committernonaka <nonaka@NetBSD.org>2010-04-17 13:36:21 +0000
commitb62fc9e20372b08e1785ff6d769312d209fa2005 (patch)
tree42cbcb1a5646aedce6ab49d25fd0006493aaccbe /sys/dev
parent18871937ddfb05044415c362f07e6647b707262f (diff)
Added Sharp W-ZERO3 series support.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hpc/hpckbdkeymap.h189
-rw-r--r--sys/dev/rasops/rasops.c194
-rw-r--r--sys/dev/rasops/rasops.h5
-rw-r--r--sys/dev/wsfont/wsfont.c97
-rw-r--r--sys/dev/wsfont/wsfont.h10
5 files changed, 453 insertions, 42 deletions
diff --git a/sys/dev/hpc/hpckbdkeymap.h b/sys/dev/hpc/hpckbdkeymap.h
index ddf2124bf37..322fcb860ce 100644
--- a/sys/dev/hpc/hpckbdkeymap.h
+++ b/sys/dev/hpc/hpckbdkeymap.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hpckbdkeymap.h,v 1.48 2008/04/28 20:23:48 martin Exp $ */
+/* $NetBSD: hpckbdkeymap.h,v 1.49 2010/04/17 13:36:21 nonaka Exp $ */
/*-
* Copyright (c) 1999-2002 The NetBSD Foundation, Inc.
@@ -831,6 +831,157 @@ const int jornada7xx_special_keymap[] = {
[KEY_SPECIAL_OFF] = 127,
[KEY_SPECIAL_LIGHT] = -1
};
+
+/*
+ * Sharp W-ZERO3 series
+ */
+/*
+ * WS003SH/WS004SH/WS007SH keyscan map
+ CTRL (none) TAB (none) CALL MAIL IE
+ 1 2 q w a z MOJI
+ 3 4 e s d x (none)
+ 5 r t f c - OK
+ 6 y g v b SPACE ACTION
+ 7 8 u h n / ,
+ 9 i j m . (none) LEFT
+ 0 o k l (none) UP DOWN
+ BS p (none) (none) ENTER (none) RIGHT
+ (none) (none) (none) (none) (none) (none) (none)
+ ROTATE VOL- (none) SHIFT WIN LSOFT RSOFT
+ CAMERA VOL+ (none) (none) (none) FN (none)
+*/
+/* Japanese */
+const uint8_t ws003sh_jp_keytrans[] = {
+/* row#0, row#1, row#2, row#3, row#4, row#5, row#6, */
+/*00*/ 29, UNK, 15, UNK, IGN, IGN, IGN,
+/*01*/ 2, 3, 16, 17, 30, 44, 1,
+/*02*/ 4, 5, 18, 31, 32, 45, UNK,
+/*03*/ 6, 19, 20, 33, 46, 12, 28,
+/*04*/ 7, 21, 34, 47, 48, 57, 28,
+/*05*/ 8, 9, 22, 35, 49, 53, 51,
+/*06*/ 10, 23, 36, 50, 52, UNK, 203,
+/*07*/ 11, 24, 37, 38, UNK, 200, 208,
+/*08*/ 14, 25, UNK, UNK, 28, UNK, 205,
+/*09*/ UNK, UNK, UNK, UNK, UNK, UNK, UNK,
+/*10*/ IGN, 174, UNK, 42, IGN, IGN, IGN,
+/*11*/ IGN, 176, UNK, UNK, UNK, 184, SPL,
+};
+
+const int ws003sh_special_keymap[] = {
+ [KEY_SPECIAL_OFF] = 83,
+ [KEY_SPECIAL_LIGHT] = -1
+};
+
+static const keysym_t ws003sh_jp_keydesc[] = {
+/* pos normal shifted altgr */
+ KC(4), KS_3, KS_numbersign, KS_Cmd_BrightnessDown,
+ KC(5), KS_4, KS_dollar, KS_Cmd_BrightnessUp,
+ KC(8), KS_7, KS_apostrophe, KS_grave,
+ KC(9), KS_8, KS_parenleft, KS_braceleft,
+ KC(10), KS_9, KS_parenright, KS_braceright,
+ KC(12), KS_minus, KS_equal, KS_backslash,
+ KC(14), KS_Delete, KS_Delete, KS_BackSpace,
+ KC(15), KS_Tab, KS_Tab, KS_Escape,
+ KC(17), KS_w, KS_W, KS_asciicircum,
+ KC(18), KS_e, KS_E, KS_asciitilde,
+ KC(19), KS_r, KS_R, KS_bar,
+ KC(22), KS_u, KS_U, KS_bracketleft,
+ KC(23), KS_i, KS_I, KS_bracketright,
+ KC(24), KS_o, KS_O, KS_underscore,
+ KC(25), KS_p, KS_P, KS_at,
+ KC(37), KS_k, KS_K, KS_plus,
+ KC(38), KS_l, KS_L, KS_asterisk,
+ KC(42), KS_Shift_L, KS_Shift_L, KS_Shift_Lock,
+ KC(51), KS_comma, KS_semicolon, KS_less,
+ KC(52), KS_period, KS_colon, KS_greater,
+ KC(184), KS_Mode_switch, KS_Multi_key,
+ KC(200), KS_Up, KS_Up, KS_Prior,
+ KC(203), KS_Left, KS_Left, KS_Home,
+ KC(205), KS_Right, KS_Right, KS_End,
+ KC(208), KS_Down, KS_Down, KS_Next,
+};
+
+/*
+ * WS011SH/WS020SH keyscan map
+ Ctrl (none) Tab (none) (none) (none) (none)
+ (none) (none) Q W A Z MOJI
+ (none) (none) E S D X HAN/ZEN
+ (none) R T F C - OK
+ (none) Y G V B Space (none)
+ (none) (none) U H N / ,
+ (none) I J M . (none) LEFT
+ (none) O K L (none) UP DOWN
+ Del (none) (none) (none) Enter (none) RIGHT
+ (none) (none) (none) (none) (none) (none) (none)
+ ROTATE (none) (none) SHIFT (none) (none) (none)
+ (none) (none) (none) (none) (none) FN (none)
+*/
+/* Japanese */
+const uint8_t ws011sh_jp_keytrans[] = {
+/* row#0, row#1, row#2, row#3, row#4, row#5, row#6, */
+/*00*/ 29, UNK, 15, UNK, UNK, UNK, UNK,
+/*01*/ UNK, UNK, 16, 17, 30, 44, 1,
+/*02*/ UNK, UNK, 18, 31, 32, 45, 41,
+/*03*/ UNK, 19, 20, 33, 46, 12, 3,
+/*04*/ UNK, 21, 34, 47, 48, 57, UNK,
+/*05*/ UNK, UNK, 22, 35, 49, 53, 51,
+/*06*/ UNK, 23, 36, 50, 52, UNK, 203,
+/*07*/ UNK, 24, 37, 38, UNK, 200, 208,
+/*08*/ 14, 25, UNK, UNK, 28, UNK, 205,
+/*09*/ UNK, UNK, UNK, UNK, UNK, UNK, UNK,
+/*10*/ IGN, UNK, UNK, 42, UNK, UNK, UNK,
+/*11*/ UNK, UNK, UNK, UNK, UNK, 184, SPL,
+};
+
+const int ws011sh_special_keymap[] = {
+ [KEY_SPECIAL_OFF] = 83,
+ [KEY_SPECIAL_LIGHT] = -1
+};
+
+static const keysym_t ws011sh_jp_keydesc[] = {
+/* pos normal shifted altgr */
+ KC(3), KS_grave, KS_braceleft, KS_braceright,
+ KC(12), KS_minus, KS_equal, KS_backslash,
+ KC(14), KS_Delete, KS_Delete, KS_BackSpace,
+ KC(15), KS_Tab, KS_Tab, KS_Escape,
+ KC(16), KS_q, KS_Q, KS_quotedbl,
+ KC(17), KS_w, KS_W, KS_numbersign,
+ KC(18), KS_e, KS_E, KS_dollar,
+ KC(19), KS_r, KS_R, KS_percent,
+ KC(20), KS_t, KS_T, KS_ampersand,
+ KC(21), KS_y, KS_Y, KS_1,
+ KC(22), KS_u, KS_U, KS_2,
+ KC(23), KS_i, KS_I, KS_3,
+ KC(24), KS_o, KS_O, KS_underscore,
+ KC(25), KS_p, KS_P, KS_at,
+ KC(30), KS_a, KS_A, KS_bracketleft,
+ KC(31), KS_s, KS_S, KS_apostrophe,
+ KC(32), KS_d, KS_D, KS_parenleft,
+ KC(33), KS_f, KS_F, KS_parenright,
+ KC(34), KS_g, KS_G, KS_asterisk,
+ KC(35), KS_h, KS_H, KS_4,
+ KC(36), KS_j, KS_J, KS_5,
+ KC(37), KS_k, KS_K, KS_6,
+ KC(38), KS_l, KS_L, KS_plus,
+ KC(41), KS_Zenkaku_Hankaku, KS_Zenkaku_Hankaku, KS_exclam,
+ KC(42), KS_Shift_L, KS_Shift_L, KS_Shift_Lock,
+ KC(44), KS_z, KS_Z, KS_bracketright,
+ KC(45), KS_x, KS_X, KS_asciicircum,
+ KC(46), KS_c, KS_C, KS_asciitilde,
+ KC(47), KS_v, KS_V, KS_bar,
+ KC(48), KS_b, KS_B, KS_7,
+ KC(49), KS_n, KS_N, KS_8,
+ KC(50), KS_m, KS_M, KS_9,
+ KC(51), KS_comma, KS_less, KS_semicolon,
+ KC(52), KS_period, KS_greater, KS_colon,
+ KC(53), KS_slash, KS_question, KS_0,
+ KC(57), KS_space,
+ KC(184), KS_Mode_switch, KS_Multi_key,
+ KC(200), KS_Up, KS_Up, KS_Prior,
+ KC(203), KS_Left, KS_Left, KS_Home,
+ KC(205), KS_Right, KS_Right, KS_End,
+ KC(208), KS_Down, KS_Down, KS_Next,
+};
#endif /* hpcarm */
#if defined(hpcarm) || defined(hpcsh)
@@ -1227,6 +1378,9 @@ const struct hpckbd_keymap_table {
#endif /* hpcsh */
#ifdef hpcarm
+ /*
+ * HP Jornada 710/720/728
+ */
/* US (ABA), UK (ABU) */
{ &platid_mask_MACH_HP_JORNADA_720,
jornada7xx_us_keytrans,
@@ -1269,6 +1423,39 @@ const struct hpckbd_keymap_table {
jornada7xx_special_keymap,
CMDMAP(jornada_es_keydesc),
KB_ES },
+ /*
+ * Sharp W-ZERO3
+ */
+ /* WS003SH */
+ { &platid_mask_MACH_SHARP_WZERO3_WS003SH,
+ ws003sh_jp_keytrans,
+ ws003sh_special_keymap,
+ CMDMAP(ws003sh_jp_keydesc),
+ KB_JP },
+ /* WS004SH */
+ { &platid_mask_MACH_SHARP_WZERO3_WS004SH,
+ ws003sh_jp_keytrans,
+ ws003sh_special_keymap,
+ CMDMAP(ws003sh_jp_keydesc),
+ KB_JP },
+ /* WS007SH */
+ { &platid_mask_MACH_SHARP_WZERO3_WS007SH,
+ ws003sh_jp_keytrans,
+ ws003sh_special_keymap,
+ CMDMAP(ws003sh_jp_keydesc),
+ KB_JP },
+ /* WS011SH */
+ { &platid_mask_MACH_SHARP_WZERO3_WS011SH,
+ ws011sh_jp_keytrans,
+ ws011sh_special_keymap,
+ CMDMAP(ws011sh_jp_keydesc),
+ KB_JP },
+ /* WS020SH */
+ { &platid_mask_MACH_SHARP_WZERO3_WS020SH,
+ ws011sh_jp_keytrans,
+ ws011sh_special_keymap,
+ CMDMAP(ws011sh_jp_keydesc),
+ KB_JP },
#endif /* hpcarm */
{ .ht_platform = NULL } /* end mark */
diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c
index 7974726ef2d..f37f15c2ae8 100644
--- a/sys/dev/rasops/rasops.c
+++ b/sys/dev/rasops/rasops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rasops.c,v 1.61 2010/01/21 05:32:18 macallan Exp $ */
+/* $NetBSD: rasops.c,v 1.62 2010/04/17 13:36:22 nonaka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.61 2010/01/21 05:32:18 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.62 2010/04/17 13:36:22 nonaka Exp $");
#include "opt_rasops.h"
#include "rasops_glue.h"
@@ -129,13 +129,23 @@ static void rasops_do_cursor(struct rasops_info *);
static void rasops_init_devcmap(struct rasops_info *);
#if NRASOPS_ROTATION > 0
+static void rasops_rotate_font(int *, int);
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 *);
+
+/* rotate clockwise */
+static void rasops_copycols_rotated_cw(void *, int, int, int, int);
+static void rasops_copyrows_rotated_cw(void *, int, int, int);
+static void rasops_erasecols_rotated_cw(void *, int, int, int, long);
+static void rasops_eraserows_rotated_cw(void *, int, int, long);
+static void rasops_putchar_rotated_cw(void *, int, int, u_int, long);
+
+/* rotate counter-clockwise */
+static void rasops_copychar_ccw(void *, int, int, int, int);
+static void rasops_copycols_rotated_ccw(void *, int, int, int, int);
+static void rasops_copyrows_rotated_ccw(void *, int, int, int);
+#define rasops_erasecols_rotated_ccw rasops_erasecols_rotated_cw
+#define rasops_eraserows_rotated_ccw rasops_eraserows_rotated_cw
+static void rasops_putchar_rotated_ccw(void *, int, int, u_int, long);
/*
* List of all rotated fonts
@@ -179,8 +189,12 @@ rasops_init(struct rasops_info *ri, int wantrows, int wantcols)
* Pick the rotated version of this font. This will create it
* if necessary.
*/
- if (ri->ri_flg & RI_ROTATE_CW)
- rasops_rotate_font(&cookie);
+ if (ri->ri_flg & RI_ROTATE_MASK) {
+ if (ri->ri_flg & RI_ROTATE_CW)
+ rasops_rotate_font(&cookie, WSFONT_ROTATE_CW);
+ else if (ri->ri_flg & RI_ROTATE_CCW)
+ rasops_rotate_font(&cookie, WSFONT_ROTATE_CCW);
+ }
#endif
if (wsfont_lock(cookie, &ri->ri_font)) {
@@ -253,7 +267,7 @@ rasops_reconfig(struct rasops_info *ri, int wantrows, int wantcols)
ri->ri_emuwidth--;
#if NRASOPS_ROTATION > 0
- if (ri->ri_flg & RI_ROTATE_CW) {
+ if (ri->ri_flg & (RI_ROTATE_CW|RI_ROTATE_CCW)) {
ri->ri_rows = ri->ri_emuwidth / ri->ri_font->fontwidth;
ri->ri_cols = ri->ri_emuheight / ri->ri_font->fontheight;
} else
@@ -368,13 +382,22 @@ rasops_reconfig(struct rasops_info *ri, int wantrows, int wantcols)
}
#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;
+ if (ri->ri_flg & RI_ROTATE_MASK) {
+ if (ri->ri_flg & RI_ROTATE_CW) {
+ ri->ri_real_ops = ri->ri_ops;
+ ri->ri_ops.copycols = rasops_copycols_rotated_cw;
+ ri->ri_ops.copyrows = rasops_copyrows_rotated_cw;
+ ri->ri_ops.erasecols = rasops_erasecols_rotated_cw;
+ ri->ri_ops.eraserows = rasops_eraserows_rotated_cw;
+ ri->ri_ops.putchar = rasops_putchar_rotated_cw;
+ } else if (ri->ri_flg & RI_ROTATE_CCW) {
+ ri->ri_real_ops = ri->ri_ops;
+ ri->ri_ops.copycols = rasops_copycols_rotated_ccw;
+ ri->ri_ops.copyrows = rasops_copyrows_rotated_ccw;
+ ri->ri_ops.erasecols = rasops_erasecols_rotated_ccw;
+ ri->ri_ops.eraserows = rasops_eraserows_rotated_ccw;
+ ri->ri_ops.putchar = rasops_putchar_rotated_ccw;
+ }
}
#endif
@@ -886,10 +909,19 @@ rasops_do_cursor(struct rasops_info *ri)
hrp = hp = NULL;
#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;
+ if (ri->ri_flg & RI_ROTATE_MASK) {
+ if (ri->ri_flg & RI_ROTATE_CW) {
+ /* Rotate rows/columns */
+ row = ri->ri_ccol;
+ col = ri->ri_rows - ri->ri_crow - 1;
+ } else if (ri->ri_flg & RI_ROTATE_CCW) {
+ /* Rotate rows/columns */
+ row = ri->ri_cols - ri->ri_ccol - 1;
+ col = ri->ri_crow;
+ } else { /* upside-down */
+ row = ri->ri_crow;
+ col = ri->ri_ccol;
+ }
} else
#endif
{
@@ -1169,7 +1201,7 @@ rasops_erasecols(void *cookie, int row, int col, int num, long attr)
#include <sys/malloc.h>
static void
-rasops_rotate_font(int *cookie)
+rasops_rotate_font(int *cookie, int rotate)
{
struct rotatedfont *f;
int ncookie;
@@ -1190,7 +1222,7 @@ rasops_rotate_font(int *cookie)
if (f == NULL)
return;
- if ((ncookie = wsfont_rotate(*cookie)) == -1)
+ if ((ncookie = wsfont_rotate(*cookie, rotate)) == -1)
return;
f->rf_cookie = *cookie;
@@ -1230,7 +1262,7 @@ rasops_copychar(void *cookie, int srcrow, int dstrow, int srccol, int dstcol)
}
static void
-rasops_putchar_rotated(void *cookie, int row, int col, u_int uc, long attr)
+rasops_putchar_rotated_cw(void *cookie, int row, int col, u_int uc, long attr)
{
struct rasops_info *ri;
u_char *rp;
@@ -1267,7 +1299,7 @@ rasops_putchar_rotated(void *cookie, int row, int col, u_int uc, long attr)
}
static void
-rasops_erasecols_rotated(void *cookie, int row, int col, int num, long attr)
+rasops_erasecols_rotated_cw(void *cookie, int row, int col, int num, long attr)
{
struct rasops_info *ri;
int i;
@@ -1280,7 +1312,7 @@ rasops_erasecols_rotated(void *cookie, int row, int col, int num, long attr)
/* XXX: these could likely be optimised somewhat. */
static void
-rasops_copyrows_rotated(void *cookie, int src, int dst, int num)
+rasops_copyrows_rotated_cw(void *cookie, int src, int dst, int num)
{
struct rasops_info *ri = (struct rasops_info *)cookie;
int col, roff;
@@ -1298,7 +1330,7 @@ rasops_copyrows_rotated(void *cookie, int src, int dst, int num)
}
static void
-rasops_copycols_rotated(void *cookie, int row, int src, int dst, int num)
+rasops_copycols_rotated_cw(void *cookie, int row, int src, int dst, int num)
{
int coff;
@@ -1311,7 +1343,7 @@ rasops_copycols_rotated(void *cookie, int row, int src, int dst, int num)
}
static void
-rasops_eraserows_rotated(void *cookie, int row, int num, long attr)
+rasops_eraserows_rotated_cw(void *cookie, int row, int num, long attr)
{
struct rasops_info *ri;
int col, rn;
@@ -1322,4 +1354,108 @@ rasops_eraserows_rotated(void *cookie, int row, int num, long attr)
for (col = 0; col < ri->ri_cols; col++)
ri->ri_ops.putchar(cookie, rn, col, ' ', attr);
}
+
+/*
+ * Quarter counter-clockwise rotation routines (originally intended for the
+ * built-in Sharp W-ZERO3 display in 16bpp).
+ */
+static void
+rasops_copychar_ccw(void *cookie, int srcrow, int dstrow, int srccol, int 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 = ri->ri_cols - srccol - 1;
+ r_dstrow = ri->ri_cols - dstcol - 1;
+ r_srccol = srcrow;
+ r_dstcol = dstrow;
+
+ 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_ccw(void *cookie, int row, int col, u_int uc, long attr)
+{
+ struct rasops_info *ri;
+ u_char *rp;
+ int height;
+
+ ri = (struct rasops_info *)cookie;
+
+ if (__predict_false((unsigned int)row > ri->ri_rows ||
+ (unsigned int)col > ri->ri_cols))
+ return;
+
+ /* Avoid underflow */
+ if ((ri->ri_cols - col - 1) < 0)
+ return;
+
+ /* Do rotated char sans (side)underline */
+ ri->ri_real_ops.putchar(cookie, ri->ri_cols - col - 1, row, uc,
+ attr & ~1);
+
+ /* Do rotated underline */
+ rp = ri->ri_bits + (ri->ri_cols - col - 1) * ri->ri_yscale +
+ row * 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;
+ }
+ }
+}
+
+/* XXX: these could likely be optimised somewhat. */
+static void
+rasops_copyrows_rotated_ccw(void *cookie, int src, int dst, int 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_ccw(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_ccw(cookie,
+ src + roff, dst + roff, col, col);
+}
+
+static void
+rasops_copycols_rotated_ccw(void *cookie, int row, int src, int dst, int num)
+{
+ int coff;
+
+ if (src > dst)
+ for (coff = 0; coff < num; coff++)
+ rasops_copychar_ccw(cookie, row, row,
+ src + coff, dst + coff);
+ else
+ for (coff = num - 1; coff >= 0; coff--)
+ rasops_copychar_ccw(cookie, row, row,
+ src + coff, dst + coff);
+}
#endif /* NRASOPS_ROTATION */
diff --git a/sys/dev/rasops/rasops.h b/sys/dev/rasops/rasops.h
index ea0c26fb1be..3e00b900f37 100644
--- a/sys/dev/rasops/rasops.h
+++ b/sys/dev/rasops/rasops.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rasops.h,v 1.23 2010/01/21 05:32:18 macallan Exp $ */
+/* $NetBSD: rasops.h,v 1.24 2010/04/17 13:36:22 nonaka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -44,6 +44,9 @@ struct wsdisplay_font;
#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 */
+#define RI_ROTATE_CCW 0x200 /* display is rotated, quarter counter-clockwise */
+#define RI_ROTATE_UD 0x400 /* display is rotated, upside-down */
+#define RI_ROTATE_MASK 0x700
struct rasops_info {
/* These must be filled in by the caller */
diff --git a/sys/dev/wsfont/wsfont.c b/sys/dev/wsfont/wsfont.c
index 40af5dd1579..d509481a0b0 100644
--- a/sys/dev/wsfont/wsfont.c
+++ b/sys/dev/wsfont/wsfont.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wsfont.c,v 1.45 2008/04/28 20:24:02 martin Exp $ */
+/* $NetBSD: wsfont.c,v 1.46 2010/04/17 13:36:22 nonaka Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.45 2008/04/28 20:24:02 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.46 2010/04/17 13:36:22 nonaka Exp $");
#include "opt_wsfont.h"
@@ -297,10 +297,11 @@ 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_cw_internal(struct wsdisplay_font *);
+struct wsdisplay_font *wsfont_rotate_ccw_internal(struct wsdisplay_font *);
struct wsdisplay_font *
-wsfont_rotate_internal(struct wsdisplay_font *font)
+wsfont_rotate_cw_internal(struct wsdisplay_font *font)
{
int b, n, r, newstride;
struct wsdisplay_font *newfont;
@@ -322,8 +323,6 @@ wsfont_rotate_internal(struct wsdisplay_font *font)
return (NULL);
}
-
-
/* Rotate the font a bit at a time. */
for (n = 0; n < font->numchars; n++) {
unsigned char *ch = (unsigned char *)font->data +
@@ -366,8 +365,74 @@ wsfont_rotate_internal(struct wsdisplay_font *font)
return (newfont);
}
+struct wsdisplay_font *
+wsfont_rotate_ccw_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;
+ int w = font->fontwidth;
+
+ rrb = newbits + (r / 8)
+ + (n * newstride * w)
+ + (newstride * (w - 1 - b));
+ *rrb |= (0x80 >> (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)
+wsfont_rotate(int cookie, int rotate)
{
int s, ncookie;
struct wsdisplay_font *font;
@@ -377,9 +442,23 @@ wsfont_rotate(int cookie)
origfont = wsfont_find0(cookie, 0xffffffff);
splx(s);
- font = wsfont_rotate_internal(origfont->font);
- if (font == NULL)
+ switch (rotate) {
+ case WSFONT_ROTATE_CW:
+ font = wsfont_rotate_cw_internal(origfont->font);
+ if (font == NULL)
+ return (-1);
+ break;
+
+ case WSFONT_ROTATE_CCW:
+ font = wsfont_rotate_ccw_internal(origfont->font);
+ if (font == NULL)
+ return (-1);
+ break;
+
+ case WSFONT_ROTATE_UD:
+ default:
return (-1);
+ }
ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight,
font->stride, 0, 0);
diff --git a/sys/dev/wsfont/wsfont.h b/sys/dev/wsfont/wsfont.h
index 0c69ed8322c..d0f42cce95a 100644
--- a/sys/dev/wsfont/wsfont.h
+++ b/sys/dev/wsfont/wsfont.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wsfont.h,v 1.19 2008/04/28 20:24:02 martin Exp $ */
+/* $NetBSD: wsfont.h,v 1.20 2010/04/17 13:36:22 nonaka Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -62,6 +62,12 @@ 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);
+int wsfont_rotate(int, int);
+
+enum {
+ WSFONT_ROTATE_CW,
+ WSFONT_ROTATE_CCW,
+ WSFONT_ROTATE_UD
+};
#endif /* !_WSFONT_H_ */