Created
August 27, 2014 12:56
-
-
Save ao-kenji/d745589e227aff0732d3 to your computer and use it in GitHub Desktop.
yaft ( http://uobikiemukot.github.io/yaft/ ) on OpenBSD/luna88k, take 5. Add getting back to original screen mode when exit, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/draw.h b/draw.h | |
index 541688d..afa3ef0 100644 | |
--- a/draw.h | |
+++ b/draw.h | |
@@ -1,6 +1,49 @@ | |
/* See LICENSE for licence details. */ | |
+ | |
+/* | |
+ * LUNA framebuffer support is based on: | |
+ * OpenBSD:src/sys/arch/luna88k/dev/omrasops.c | |
+ */ | |
+/* $OpenBSD: omrasops.c,v 1.11 2014/01/02 15:30:34 aoyama Exp $ */ | |
+/* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */ | |
+/*- | |
+ * Copyright (c) 2000 The NetBSD Foundation, Inc. | |
+ * All rights reserved. | |
+ * | |
+ * This code is derived from software contributed to The NetBSD Foundation | |
+ * by Tohru Nishimura. | |
+ * | |
+ * Redistribution and use in source and binary forms, with or without | |
+ * modification, are permitted provided that the following conditions | |
+ * are met: | |
+ * 1. Redistributions of source code must retain the above copyright | |
+ * notice, this list of conditions and the following disclaimer. | |
+ * 2. Redistributions in binary form must reproduce the above copyright | |
+ * notice, this list of conditions and the following disclaimer in the | |
+ * documentation and/or other materials provided with the distribution. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
+ * POSSIBILITY OF SUCH DAMAGE. | |
+ */ | |
+ | |
+#define ALL1BITS (~0U) | |
+#define BLITWIDTH (32) | |
+#define ALIGNMASK (0x1f) | |
+#define BYTESDONE (4) | |
+#define PLANESIZE 0x40000 | |
+ | |
static inline void draw_sixel(struct framebuffer *fb, int line, int col, uint8_t *pixmap) | |
{ | |
+#if 0 | |
int h, w, src_offset, dst_offset; | |
uint32_t pixel, color = 0; | |
@@ -14,10 +57,55 @@ static inline void draw_sixel(struct framebuffer *fb, int line, int col, uint8_t | |
memcpy(fb->buf + dst_offset, &pixel, fb->bytes_per_pixel); | |
} | |
} | |
+#else | |
+ int h, w, src_offset; | |
+ uint32_t pixel, color = 0; | |
+ int x, y, i; | |
+ uint32_t *p0, *p; | |
+ | |
+ for (h = 0; h < CELL_HEIGHT; h++) { | |
+ for (w = 0; w < CELL_WIDTH; w++) { | |
+ src_offset = BYTES_PER_PIXEL * (h * CELL_WIDTH + w); | |
+ memcpy(&color, pixmap + src_offset, BYTES_PER_PIXEL); | |
+ | |
+ pixel = color2pixel(&fb->vinfo, color); | |
+ | |
+ x = CELL_WIDTH * col + w; | |
+ y = CELL_HEIGHT * line + h; | |
+ p0 = (uint32_t *)((uint8_t *)fb->buf | |
+ + y * fb->line_length + ((x / 32) * 4)); | |
+ x &= ALIGNMASK; /* x % 32 */ | |
+ | |
+ for (i = 0; i < DEPTH; i++) { | |
+ p = (uint32_t *)((uint8_t *)p0 + PLANESIZE * i); | |
+ if (pixel & (0x01 << i)) | |
+ /* set */ | |
+ *p |= (0x00000001 << (31 - x)); | |
+ else | |
+ /* reset */ | |
+ *p &= ~(0x00000001 << (31 - x)); | |
+ } | |
+ } | |
+ } | |
+#endif | |
+} | |
+ | |
+static inline void draw_glyph(uint32_t *p0, int plane, uint32_t glyph, | |
+ int fg, int bg, uint32_t mask) | |
+{ | |
+ uint32_t glyphbg, fgpat, bgpat; | |
+ uint32_t *p; | |
+ | |
+ glyphbg = glyph ^ ALL1BITS; | |
+ fgpat = (fg & (0x01 << plane)) ? glyph : 0; | |
+ bgpat = (bg & (0x01 << plane)) ? glyphbg : 0; | |
+ p = (uint32_t *)((uint8_t *)p0 + PLANESIZE * plane); | |
+ *p = (*p & ~mask) | ((fgpat | bgpat) & mask); | |
} | |
static inline void draw_line(struct framebuffer *fb, struct terminal *term, int line) | |
{ | |
+#if 0 | |
int pos, size, bdf_padding, glyph_width, margin_right; | |
int col, w, h; | |
uint32_t pixel; | |
@@ -81,7 +169,118 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int | |
pos = (line * CELL_HEIGHT) * fb->line_length; | |
size = CELL_HEIGHT * fb->line_length; | |
memcpy(fb->fp + pos, fb->buf + pos, size); | |
+#else | |
+ int pos, size, col, glyph_width, bdf_shift; | |
+ struct color_pair_t color_pair; | |
+ struct cell_t *cellp; | |
+ | |
+ int x, y, width, height, align, fg, bg, plane; | |
+ u_int32_t lmask, rmask, glyph; | |
+ u_int8_t *p; | |
+ | |
+ for (col = term->cols - 1; col >= 0; col--) { | |
+ | |
+ /* target cell */ | |
+ cellp = &term->cells[line][col]; | |
+ | |
+ /* draw sixel pixmap */ | |
+ if (cellp->has_pixmap) { | |
+ draw_sixel(fb, line, col, cellp->pixmap); | |
+ continue; | |
+ } | |
+ | |
+ /* copy current color_pair (maybe changed) */ | |
+ color_pair = cellp->color_pair; | |
+ | |
+ /* check wide character or not */ | |
+ if (cellp->width == NEXT_TO_WIDE) | |
+ continue; | |
+ | |
+ glyph_width = (cellp->width == HALF) ? CELL_WIDTH: CELL_WIDTH * 2; | |
+ bdf_shift = 32 - my_ceil(glyph_width, BITS_PER_BYTE) * BITS_PER_BYTE; | |
+ /* check cursor positon */ | |
+ if ((term->mode & MODE_CURSOR && line == term->cursor.y) | |
+ && (col == term->cursor.x | |
+ || (cellp->width == WIDE && (col + 1) == term->cursor.x) | |
+ || (cellp->width == NEXT_TO_WIDE && (col - 1) == term->cursor.x))) { | |
+ color_pair.fg = DEFAULT_BG; | |
+ color_pair.bg = (!tty.visible && BACKGROUND_DRAW) ? PASSIVE_CURSOR_COLOR: ACTIVE_CURSOR_COLOR; | |
+ } | |
+ /* color palette */ | |
+ fg = term->color_palette[color_pair.fg]; | |
+ bg = term->color_palette[color_pair.bg]; | |
+#if 0 /* Not yet on LUNA */ | |
+ if (fb->wall && color_pair.bg == DEFAULT_BG) /* wallpaper */ | |
+ memcpy(&pixel, fb->wall + pos, fb->bytes_per_pixel); | |
+#endif | |
+ x = CELL_WIDTH * col; | |
+ y = CELL_HEIGHT * line; | |
+ | |
+ p = (u_int8_t *)fb->buf + y * fb->line_length + ((x / 32) * 4); | |
+ align = x & ALIGNMASK; | |
+ width = cellp->glyphp->width * CELL_WIDTH + align; | |
+ lmask = ALL1BITS >> align; | |
+ rmask = ALL1BITS << (-width & ALIGNMASK); | |
+ height = 0; | |
+ | |
+ if (width <= BLITWIDTH) { | |
+ lmask &= rmask; | |
+ while (height < CELL_HEIGHT) { | |
+ /* if UNDERLINE attribute on, swap bg/fg */ | |
+ if ((height == (CELL_HEIGHT - 1)) | |
+ && (cellp->attribute & attr_mask[ATTR_UNDERLINE])) | |
+ bg = fg; | |
+ glyph = (uint32_t)cellp->glyphp->bitmap[height]; | |
+ /* shift leftmost */ | |
+ glyph <<= bdf_shift; | |
+ glyph = glyph >> align; | |
+ | |
+ for (plane = 0; plane < DEPTH; plane++) | |
+ draw_glyph((uint32_t *)p, plane, glyph, fg, bg, lmask); | |
+ | |
+ p += fb->line_length; | |
+ height++; | |
+ } | |
+ } else { | |
+ u_int8_t *q = p; | |
+ u_int32_t lhalf, rhalf; | |
+ | |
+ while (height < CELL_HEIGHT) { | |
+ /* if UNDERLINE attribute on, swap bg/fg */ | |
+ if ((height == (CELL_HEIGHT - 1)) | |
+ && (cellp->attribute & attr_mask[ATTR_UNDERLINE])) | |
+ bg = fg; | |
+ glyph = (uint32_t)cellp->glyphp->bitmap[height]; | |
+ /* shift leftmost */ | |
+ glyph <<= bdf_shift; | |
+ lhalf = glyph >> align; | |
+ | |
+ for (plane = 0; plane < DEPTH; plane++) | |
+ draw_glyph((uint32_t *)p, plane, lhalf, fg, bg, lmask); | |
+ | |
+ p += BYTESDONE; | |
+ rhalf = glyph << (BLITWIDTH - align); | |
+ | |
+ for (plane = 0; plane < DEPTH; plane++) | |
+ draw_glyph((uint32_t *)p, plane, rhalf, fg, bg, rmask); | |
+ | |
+ p = (q += fb->line_length); | |
+ height++; | |
+ } | |
+ } | |
+ } | |
+ | |
+ /* actual display update (bit blit) */ | |
+ size = TERM_WIDTH / 8; | |
+ for (height = 0; height < CELL_HEIGHT; height++) { | |
+ for (plane = 0; plane < DEPTH; plane++) { | |
+ pos = (line * CELL_HEIGHT + height) * fb->line_length | |
+ + PLANESIZE * plane; | |
+ memcpy(fb->fp + pos, fb->buf + pos, size); | |
+ } | |
+ } | |
+#endif | |
/* TODO: page flip | |
if fb_fix_screeninfo.ypanstep > 0, we can use hardware panning. | |
set fb_fix_screeninfo.{yres_virtual,yoffset} and call ioctl(FBIOPAN_DISPLAY) | |
diff --git a/fb/openbsd.h b/fb/openbsd.h | |
index 05903c6..3796d8a 100644 | |
--- a/fb/openbsd.h | |
+++ b/fb/openbsd.h | |
@@ -15,9 +15,15 @@ typedef unsigned long u_long; | |
/* some structs for OpenBSD */ | |
enum term_size { | |
+#if 0 | |
TERM_WIDTH = 640, | |
TERM_HEIGHT = 480, | |
DEPTH = 8, | |
+#else | |
+ TERM_WIDTH = 1280, | |
+ TERM_HEIGHT = 1024, | |
+ DEPTH = 8, | |
+#endif | |
}; | |
enum fbtype_t { | |
@@ -45,6 +51,7 @@ struct fbinfo_t { | |
struct framebuffer { | |
uint8_t *fp; /* pointer of framebuffer(read only) */ | |
+ uint8_t *fp_org; /* pointer of framebuffer(original) */ | |
uint8_t *wall; /* buffer for wallpaper */ | |
uint8_t *buf; /* copy of framebuffer */ | |
int fd; /* file descriptor of framebuffer */ | |
@@ -52,6 +59,7 @@ struct framebuffer { | |
long screen_size; /* screen data size (byte) */ | |
int line_length; /* line length (byte) */ | |
int bytes_per_pixel; /* BYTES per pixel */ | |
+ int mode_org; /* original framebuffer mode */ | |
struct wsdisplay_cmap /* cmap for legacy framebuffer (8bpp pseudocolor) */ | |
*cmap, *cmap_org; | |
struct fbinfo_t vinfo; | |
@@ -169,7 +177,7 @@ static inline uint32_t color2pixel(struct fbinfo_t *vinfo, uint32_t color) | |
void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
{ | |
- int i, orig_mode, mode; | |
+ int i, mode; | |
char *path, *env; | |
struct wsdisplay_fbinfo finfo; | |
struct wsdisplay_gfx_mode gfx_mode; | |
@@ -179,7 +187,7 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
else | |
fb->fd = eopen(fb_path, O_RDWR); | |
- ioctl(fb->fd, WSDISPLAYIO_GMODE, &orig_mode); | |
+ ioctl(fb->fd, WSDISPLAYIO_GMODE, &(fb->mode_org)); | |
gfx_mode.width = TERM_WIDTH; | |
gfx_mode.height = TERM_HEIGHT; | |
@@ -197,12 +205,22 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
goto fb_init_error; | |
} | |
+ /* XXX: Should be check if WSDISPLAYIO_TYPE_LUNA ? */ | |
+ | |
fb->width = TERM_WIDTH; | |
fb->height = TERM_HEIGHT; | |
fb->bytes_per_pixel = my_ceil(DEPTH, BITS_PER_BYTE); | |
+#if 0 | |
fb->line_length = fb->bytes_per_pixel * fb->width; | |
fb->screen_size = fb->height * fb->line_length; | |
+#else | |
+ if (ioctl(fb->fd, WSDISPLAYIO_LINEBYTES, &(fb->line_length))) { | |
+ fatal("ioctl: WSDISPLAYIO_LINEBYTES failed"); | |
+ goto fb_init_error; | |
+ } | |
+ fb->screen_size = fb->height * fb->line_length * DEPTH; | |
+#endif | |
fb->vinfo = bpp_table[DEPTH]; | |
if (DEBUG) | |
@@ -214,7 +232,7 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
fb->cmap = fb->cmap_org = NULL; | |
fb->vinfo.fbtype = FBTYPE_RGB; | |
} | |
- else if (DEPTH == 8) { | |
+ else if (DEPTH == 8 || DEPTH == 4 || DEPTH == 1 ) { | |
cmap_create(&fb->cmap, COLORS); | |
cmap_create(&fb->cmap_org, finfo.cmsize); | |
cmap_init(fb); | |
@@ -226,7 +244,10 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
for (i = 0; i < COLORS; i++) /* init color palette */ | |
color_palette[i] = (fb->bytes_per_pixel == 1) ? (uint32_t) i: color2pixel(&fb->vinfo, color_list[i]); | |
- fb->fp = (uint8_t *) emmap(0, fb->screen_size, PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0); | |
+ fb->fp_org = (uint8_t *) emmap(0, fb->screen_size, PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0); | |
+ | |
+ fb->fp = fb->fp_org + 8; /* XXX: LUNA quirk; need 8 byte offset */ | |
+ | |
fb->buf = (uint8_t *) ecalloc(1, fb->screen_size); | |
//fb->wall = (WALLPAPER && fb->bytes_per_pixel > 1) ? load_wallpaper(fb): NULL; | |
@@ -238,7 +259,7 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette) | |
return; | |
fb_init_error: | |
- ioctl(fb->fd, WSDISPLAYIO_SMODE, &orig_mode); | |
+ ioctl(fb->fd, WSDISPLAYIO_SMODE, &(fb->mode_org)); | |
exit(EXIT_FAILURE); | |
} | |
@@ -251,6 +272,8 @@ void fb_die(struct framebuffer *fb) | |
} | |
free(fb->buf); | |
free(fb->wall); | |
- emunmap(fb->fp, fb->screen_size); | |
+ emunmap(fb->fp_org, fb->screen_size); | |
+ if (ioctl(fb->fd, WSDISPLAYIO_SMODE, &(fb->mode_org))) | |
+ fatal("ioctl: WSDISPLAYIO_SMODE failed"); | |
eclose(fb->fd); | |
} | |
diff --git a/makefile b/makefile | |
index caf405f..8fc5679 100644 | |
--- a/makefile | |
+++ b/makefile | |
@@ -1,7 +1,8 @@ | |
CC ?= gcc | |
#CC ?= clang | |
-CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe | |
+#CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe | |
+CFLAGS = -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe | |
LDFLAGS ?= | |
XCFLAGS ?= -std=c99 -pedantic -Wall -Wextra -I/usr/include/X11/ -O3 -s -pipe | |
diff --git a/yaft.c b/yaft.c | |
index 6068da2..a936c7b 100644 | |
--- a/yaft.c | |
+++ b/yaft.c | |
@@ -75,11 +75,13 @@ void tty_init(struct termios *save_tm) | |
vtm.mode = VT_PROCESS; | |
vtm.waitv = 0; | |
vtm.relsig = vtm.acqsig = vtm.frsig = SIGUSR1; | |
+#if 0 /* XXX: LUNA currently does not supoort these ioctls */ | |
if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm)) | |
fatal("ioctl: VT_SETMODE failed (maybe here is not console)"); | |
if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS)) | |
fatal("ioctl: KDSETMODE failed (maybe here is not console)"); | |
+#endif | |
etcgetattr(STDIN_FILENO, save_tm); | |
set_rawmode(STDIN_FILENO, save_tm); | |
@@ -100,8 +102,10 @@ void tty_die(struct termios *save_tm) | |
vtm.mode = VT_AUTO; | |
vtm.waitv = 0; | |
vtm.relsig = vtm.acqsig = vtm.frsig = 0; | |
+#if 0 /* XXX: LUNA currently does not supoort these ioctls */ | |
ioctl(STDIN_FILENO, VT_SETMODE, &vtm); | |
ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); | |
+#endif | |
tcsetattr(STDIN_FILENO, TCSAFLUSH, save_tm); | |
fflush(stdout); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment