diff options
| author | nonaka <nonaka@NetBSD.org> | 2010-04-17 13:36:21 +0000 |
|---|---|---|
| committer | nonaka <nonaka@NetBSD.org> | 2010-04-17 13:36:21 +0000 |
| commit | b62fc9e20372b08e1785ff6d769312d209fa2005 (patch) | |
| tree | 42cbcb1a5646aedce6ab49d25fd0006493aaccbe /sys/dev | |
| parent | 18871937ddfb05044415c362f07e6647b707262f (diff) | |
Added Sharp W-ZERO3 series support.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/hpc/hpckbdkeymap.h | 189 | ||||
| -rw-r--r-- | sys/dev/rasops/rasops.c | 194 | ||||
| -rw-r--r-- | sys/dev/rasops/rasops.h | 5 | ||||
| -rw-r--r-- | sys/dev/wsfont/wsfont.c | 97 | ||||
| -rw-r--r-- | sys/dev/wsfont/wsfont.h | 10 |
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_ */ |
