Module Name:    src
Committed By:   isaki
Date:           Sat Oct  5 03:56:54 UTC 2024

Modified Files:
        src/sys/arch/x68k/conf: GENERIC files.x68k
        src/sys/arch/x68k/dev: ite.c ite_tv.c itevar.h

Log Message:
x68k: Add SIXEL graphics sequence support.
- The palette definition is fixed to the same color as the text (currently,
  it's RGB 8 colors).  Any palette definition sent will be ignored.
- Aspect ratio and bg color mode is not supported (yet).
- An OR mode is supported.  This is proposed by Y.Sugahara in this
  implementation and then the mlterm also supports it.  It's an advantageous
  way for the multi plane color VRAM.
- ITE_SIXEL kernel option is added and is disabled by default for now.

It was first written by me in 2014 and has been demonstrated in Open Source
Conference Hiroshima every year since then.  In this year, it's also
demonstrated on real X68030 at Japan NetBSD Users Group booth in OSC 2024
Hiroshima, last week.
https://x.com/OSC_official/status/1841381234804498608
It's useful for showing and explaining about the possibility of NetBSD and
old machines for younger (than X68030) engineers or students.


To generate a diff of this commit:
cvs rdiff -u -r1.209 -r1.210 src/sys/arch/x68k/conf/GENERIC
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/x68k/conf/files.x68k
cvs rdiff -u -r1.71 -r1.72 src/sys/arch/x68k/dev/ite.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/x68k/dev/ite_tv.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x68k/dev/itevar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/conf/GENERIC
diff -u src/sys/arch/x68k/conf/GENERIC:1.209 src/sys/arch/x68k/conf/GENERIC:1.210
--- src/sys/arch/x68k/conf/GENERIC:1.209	Sun Jan  7 07:58:33 2024
+++ src/sys/arch/x68k/conf/GENERIC	Sat Oct  5 03:56:54 2024
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.209 2024/01/07 07:58:33 isaki Exp $
+# $NetBSD: GENERIC,v 1.210 2024/10/05 03:56:54 isaki Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@ include 	"arch/x68k/conf/std.x68k"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.209 $"
+#ident 		"GENERIC-$Revision: 1.210 $"
 
 makeoptions	COPTS="-O2 -fno-reorder-blocks -fno-unwind-tables -fno-omit-frame-pointer"
 	# See share/mk/sys.mk. -fno-omit-frame-pointer is necessary for
@@ -229,6 +229,7 @@ kbd0	at mfp0				# standard keyboard
 ite0	at grf0 grfaddr 0		# internal terminal emulator
 options 	ITE_KERNEL_ATTR=4	# bold for kernel messages
 					# see /sys/arch/x68k/dev/itevar.h
+#options 	ITE_SIXEL
 
 ## floppy disks
 fdc0	at intio0 addr 0xe94000 intr 96 dma 0 dmaintr 100 # floppy controller

Index: src/sys/arch/x68k/conf/files.x68k
diff -u src/sys/arch/x68k/conf/files.x68k:1.84 src/sys/arch/x68k/conf/files.x68k:1.85
--- src/sys/arch/x68k/conf/files.x68k:1.84	Tue Jan  9 04:16:27 2024
+++ src/sys/arch/x68k/conf/files.x68k	Sat Oct  5 03:56:54 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: files.x68k,v 1.84 2024/01/09 04:16:27 thorpej Exp $
+#	$NetBSD: files.x68k,v 1.85 2024/10/05 03:56:54 isaki Exp $
 #
 # new style config file for x68k architecture
 #
@@ -68,6 +68,7 @@ file	arch/x68k/dev/grf_tv.c		grf | ite
 file	arch/x68k/dev/grf_gv.c		grf | ite
 
 defparam opt_ite.h	ITE_KERNEL_ATTR
+defflag opt_ite.h	ITE_SIXEL
 device	ite : tty
 attach	ite at grf
 file	arch/x68k/dev/ite.c		ite needs-flag

Index: src/sys/arch/x68k/dev/ite.c
diff -u src/sys/arch/x68k/dev/ite.c:1.71 src/sys/arch/x68k/dev/ite.c:1.72
--- src/sys/arch/x68k/dev/ite.c:1.71	Sun Jan  7 07:58:33 2024
+++ src/sys/arch/x68k/dev/ite.c	Sat Oct  5 03:56:54 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ite.c,v 1.71 2024/01/07 07:58:33 isaki Exp $	*/
+/*	$NetBSD: ite.c,v 1.72 2024/10/05 03:56:54 isaki Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.71 2024/01/07 07:58:33 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.72 2024/10/05 03:56:54 isaki Exp $");
 
 #include "ite.h"
 #if NITE > 0
@@ -91,6 +91,9 @@ void opm_bell(void);
 #define SUBR_CLEAR(ip,sy,sx,h,w)	ip->isw->ite_clear(ip,sy,sx,h,w)
 #define SUBR_SCROLL(ip,sy,sx,count,dir)	\
     ip->isw->ite_scroll(ip,sy,sx,count,dir)
+#if defined(ITE_SIXEL)
+#define SUBR_SIXEL(ip,sy,sx)	ip->isw->ite_sixel(ip,sy,sx)
+#endif
 
 struct consdev;
 
@@ -151,6 +154,9 @@ static u_char cons_tabs[MAX_TABS];
 static void itestart(struct tty *);
 
 static void iteputchar(int, struct ite_softc *);
+#if defined(ITE_SIXEL)
+static int ite_dcs(const int, struct ite_softc *);
+#endif
 static void ite_putstr(const u_char *, int, dev_t);
 
 static int itematch(device_t, cfdata_t, void *);
@@ -1207,10 +1213,18 @@ ite_putstr(const u_char *s, int len, dev
 	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
 		return;
 
+#if defined(ITE_SIXEL)
+	/* avoid flicking cursor */
+	if (ip->escape == 0)
+#endif
 	SUBR_CURSOR(ip, START_CURSOROPT);
 	for (i = 0; i < len; i++)
 		if (s[i] != 0)
 			iteputchar(s[i], ip);
+#if defined(ITE_SIXEL)
+	/* avoid flicking cursor */
+	if (ip->escape == 0)
+#endif
 	SUBR_CURSOR(ip, END_CURSOROPT);
 }
 
@@ -1220,7 +1234,11 @@ iteputchar(int c, struct ite_softc *ip)
 	int n, x, y;
 	char *cp;
 
+#if defined(ITE_SIXEL)
+	if ((c >= 0x20 && ip->escape != 0) || ip->escape == DCS) {
+#else
 	if (c >= 0x20 && ip->escape != 0) {
+#endif
 		switch (ip->escape) {
 
 		case ESC:
@@ -1284,6 +1302,11 @@ iteputchar(int c, struct ite_softc *ip)
 				/* String Terminator */
 				c = ST;
 				ip->escape = 0;
+#if defined(ITE_SIXEL)
+				if (ip->decsixel_y != 0) {
+					ite_lf(ip);
+				}
+#endif
 				break;
 
 			case ']':
@@ -1613,8 +1636,13 @@ iteputchar(int c, struct ite_softc *ip)
 							ite_sendstr(ip,
 							    "\033[?1;1c");
 						else
+#if defined(ITE_SIXEL)
+							ite_sendstr(ip,
+							    "\033[63;4c");
+#else
 							ite_sendstr(ip,
 							    "\033[63;0c");
+#endif
 						break;
 					}
 				}
@@ -2162,6 +2190,14 @@ iteputchar(int c, struct ite_softc *ip)
 			}
 			break;
 
+#if defined(ITE_SIXEL)
+		case DCS:
+			if (ite_dcs(c, ip) == 0) {
+				return;
+			}
+			break;
+#endif /* ITE_SIXEL */
+
 		default:
 			ip->escape = 0;
 			return;
@@ -2289,6 +2325,9 @@ iteputchar(int c, struct ite_softc *ip)
 
 	case DCS:	/* device control string introducer */
 		ip->escape = DCS;
+#if defined(ITE_SIXEL)
+		ip->dcs_cmd = DCS_START;
+#endif
 		ip->ap = ip->argbuf;
 		break;
 
@@ -2355,6 +2394,306 @@ iteputchar(int c, struct ite_softc *ip)
 	}
 }
 
+#if defined(ITE_SIXEL)
+/*
+ * Handle DCS.
+ * 0:  return in the caller.
+ * !0: break the switch-case in the caller.
+ */
+static int
+ite_dcs(const int c, struct ite_softc *ip)
+{
+	static const uint32_t table[64] = {
+		0x000000, 0x000001, 0x000010, 0x000011,
+		0x000100, 0x000101, 0x000110, 0x000111,
+		0x001000, 0x001001, 0x001010, 0x001011,
+		0x001100, 0x001101, 0x001110, 0x001111,
+		0x010000, 0x010001, 0x010010, 0x010011,
+		0x010100, 0x010101, 0x010110, 0x010111,
+		0x011000, 0x011001, 0x011010, 0x011011,
+		0x011100, 0x011101, 0x011110, 0x011111,
+		0x100000, 0x100001, 0x100010, 0x100011,
+		0x100100, 0x100101, 0x100110, 0x100111,
+		0x101000, 0x101001, 0x101010, 0x101011,
+		0x101100, 0x101101, 0x101110, 0x101111,
+		0x110000, 0x110001, 0x110010, 0x110011,
+		0x110100, 0x110101, 0x110110, 0x110111,
+		0x111000, 0x111001, 0x111010, 0x111011,
+		0x111100, 0x111101, 0x111110, 0x111111,
+	};
+
+	switch (ip->dcs_cmd) {
+	case DCS_DISCARD:
+		/* discard sixel cause kernel message interrupted */
+		switch (c) {
+		case '-':
+			/* restart from next SIXEL line */
+			ite_lf(ip);
+			goto sixel_restart;
+
+		case CAN:
+		case SUB:
+			/* SUB should also display a reverse question mark... */
+			ip->escape = 0;
+			return 0;
+
+		case ESC:
+			ip->escape = ESC;
+			return 0;
+
+		default:
+			return 0;
+		}
+		break;
+
+	case DCS_START:
+		/* the biggie... */
+		switch (c) {
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		case ';':
+		case '$':
+			if (ip->ap < ip->argbuf + MAX_ARGSIZE)
+				*ip->ap++ = c;
+			return 0;
+
+		case 'q':
+		{
+			char *cp;
+
+			/* init sixel */
+			/*
+			 * DCS <P1> ; <P2> ; <P3> q
+			 * P1 is aspect ratio, XXX not supported.
+			 * P2 is bgcolor mode.
+			 *  0..2: bgcolor mode, XXX not supported here.
+			 *  bit2 means 'OR'ed color mode.
+			 *  This is an original extension.
+			 */
+			ip->ap = ip->argbuf;
+			cp = strchr(ip->ap, ';');
+			if (cp != NULL) {
+				int mode;
+				mode = atoi(cp + 1) - '0';
+				ip->decsixel_ormode = (mode & 4);
+			} else {
+				ip->decsixel_ormode = 0;
+			}
+sixel_restart:
+			ip->dcs_cmd = DCS_SIXEL;
+			ip->decsixel_state = DECSIXEL_INIT;
+			ip->decsixel_ph = MAX_SIXEL_WIDTH;
+			ip->decsixel_x = 0;
+			ip->decsixel_y = 0;
+			ip->decsixel_repcount = 0;
+			ip->decsixel_color = ip->fgcolor;
+			memset(ip->decsixel_buf, 0, sizeof(ip->decsixel_buf));
+			return 0;
+		}
+
+		case CAN:
+		case SUB:
+			/* SUB should also display a reverse question mark... */
+			ip->escape = 0;
+			return 0;
+
+		case ESC:
+			ip->escape = ESC;
+			return 0;
+
+		default:
+			return 0;
+		}
+		break;
+
+	case DCS_SIXEL:
+sixel_loop:
+		switch (ip->decsixel_state) {
+		case DECSIXEL_INIT:
+			switch (c) {
+			case CAN:
+			case SUB:
+				/*
+				 * SUB should also display a reverse question
+				 * mark...
+				 */
+				ip->escape = 0;
+				return 0;
+
+			case ESC:
+				ip->escape = ESC;
+				return 0;
+
+			case DECSIXEL_REPEAT:
+				ip->decsixel_state = c;
+				ip->decsixel_repcount = 0;
+				return 0;
+
+			case DECSIXEL_RASTER:
+			case DECSIXEL_COLOR:
+				ip->decsixel_state = c;
+				ip->ap = ip->argbuf;
+				return 0;
+
+			case '$':	/* CR */
+				ip->decsixel_x = 0;
+				return 0;
+
+			case '-':	/* LF */
+				/*
+				 * XXX
+				 * FONTHEIGHT is defined in ite_tv.c, not here..
+				 */
+				if (ip->decsixel_y + 6 > 15) {
+					ite_lf(ip);
+					ip->decsixel_y -= 16;
+				}
+				SUBR_SIXEL(ip, ip->cury, ip->curx);
+				memset(ip->decsixel_buf, 0,
+				    sizeof(ip->decsixel_buf));
+				ip->decsixel_x = 0;
+				ip->decsixel_y += 6;
+				return 0;
+
+			default:
+				if ('?' <= c && c <= '~'
+				    && ip->decsixel_x < MAX_SIXEL_WIDTH) {
+					uint32_t d;
+					d = table[c - '?'] * ip->decsixel_color;
+					ip->decsixel_buf[ip->decsixel_x] |= d;
+					ip->decsixel_x++;
+				} else {
+					/* ignore */
+				}
+				return 0;
+			}
+			break;
+
+		case DECSIXEL_REPEAT:
+			if ('0' <= c && c <= '9') {
+				ip->decsixel_repcount =
+				    ip->decsixel_repcount * 10 + (c - '0');
+			} else if ('?' <= c && c <= '~') {
+				uint32_t d;
+				int i;
+				int cnt = MIN(ip->decsixel_repcount,
+				    MAX_SIXEL_WIDTH - ip->decsixel_x);
+				d = table[c - '?'] * ip->decsixel_color;
+				for (i = 0; i < cnt; i++) {
+					ip->decsixel_buf[ip->decsixel_x + i] |=
+					    d;
+				}
+				ip->decsixel_x += cnt;
+				ip->decsixel_state = DECSIXEL_INIT;
+			} else {
+				/* invalid ? */
+				ip->decsixel_state = DECSIXEL_INIT;
+			}
+			return 0;
+
+		case DECSIXEL_RASTER:
+		case DECSIXEL_RASTER_PAD:
+		case DECSIXEL_RASTER_PH:
+		case DECSIXEL_RASTER_PV:
+			switch (c) {
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				if (ip->ap < ip->argbuf + MAX_ARGSIZE)
+					*ip->ap++ = c;
+				return 0;
+
+			case ';':
+			default:
+				switch (ip->decsixel_state) {
+				case DECSIXEL_RASTER:
+					/* ignore PAN */
+					ip->ap = ip->argbuf;
+					ip->decsixel_state =
+					    DECSIXEL_RASTER_PAD;
+					return 0;
+
+				case DECSIXEL_RASTER_PAD:
+					/* ignore PAD */
+					ip->ap = ip->argbuf;
+					ip->decsixel_state = DECSIXEL_RASTER_PH;
+					return 0;
+
+				case DECSIXEL_RASTER_PH:
+					ip->decsixel_ph = ite_zargnum(ip);
+					ip->ap = ip->argbuf;
+					ip->decsixel_state = DECSIXEL_RASTER_PV;
+					return 0;
+
+				case DECSIXEL_RASTER_PV:
+					/* ignore PV */
+					ip->decsixel_state = DECSIXEL_INIT;
+					/* c is a next sequence char. */
+					goto sixel_loop;
+
+				default:
+					/* NOTREACHED */
+					return 0;
+				}
+			}
+			return 0;
+
+		case DECSIXEL_COLOR:
+			switch (c) {
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+			case ';':
+				if (ip->ap < ip->argbuf + MAX_ARGSIZE)
+					*ip->ap++ = c;
+				return 0;
+
+			default:
+				*ip->ap = '\0';
+				if (strchr(ip->argbuf, ';')) {
+					/* ignore the palette definition. */
+				} else {
+					/* otherwise, it specifies color. */
+					ip->decsixel_color =
+					    ite_zargnum(ip) & 7;
+				}
+				ip->decsixel_state = DECSIXEL_INIT;
+				ip->ap = ip->argbuf;
+				/* c is a next sequence char. */
+				goto sixel_loop;
+			}
+			return 0;
+		}
+		break;
+	}
+
+	/* Continue in caller's switch-case. */
+	return 1;
+}
+#endif /* ITE_SIXEL */
+
 static void
 iteprecheckwrap(struct ite_softc *ip)
 {
@@ -2547,12 +2886,23 @@ itecnputc(dev_t dev, int c)
 #ifdef ITE_KERNEL_ATTR
 	short save_attribute;
 #endif
+#if defined(ITE_SIXEL)
+	int save_escape;
+#endif
 
 	if (panicstr && !paniced &&
 	    (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
 		(void) iteon(dev, 3);
 		paniced = 1;
 	}
+
+#if defined(ITE_SIXEL)
+	save_escape = ip->escape;
+	if (ip->escape == DCS) {
+		ip->escape = 0;
+		ip->dcs_cmd = DCS_DISCARD;
+	}
+#endif
 #ifdef ITE_KERNEL_ATTR
 	save_attribute = ip->attribute;
 	ip->attribute = ITE_KERNEL_ATTR;
@@ -2561,5 +2911,10 @@ itecnputc(dev_t dev, int c)
 #ifdef ITE_KERNEL_ATTR
 	ip->attribute = save_attribute;
 #endif
+#if defined(ITE_SIXEL)
+	if (ip->escape == 0) {
+		ip->escape = save_escape;
+	}
+#endif
 }
 #endif

Index: src/sys/arch/x68k/dev/ite_tv.c
diff -u src/sys/arch/x68k/dev/ite_tv.c:1.20 src/sys/arch/x68k/dev/ite_tv.c:1.21
--- src/sys/arch/x68k/dev/ite_tv.c:1.20	Sun Jan  7 07:58:33 2024
+++ src/sys/arch/x68k/dev/ite_tv.c	Sat Oct  5 03:56:54 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ite_tv.c,v 1.20 2024/01/07 07:58:33 isaki Exp $	*/
+/*	$NetBSD: ite_tv.c,v 1.21 2024/10/05 03:56:54 isaki Exp $	*/
 
 /*
  * Copyright (c) 1997 Masaru Oki.
@@ -31,7 +31,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.20 2024/01/07 07:58:33 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.21 2024/10/05 03:56:54 isaki Exp $");
+
+#include "opt_ite.h"
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -71,6 +73,9 @@ __KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1
 
 static u_int  tv_top;
 static uint8_t *tv_row[PLANELINES];
+#if defined(ITE_SIXEL)
+static uint8_t *tv_end;
+#endif
 static uint8_t *tv_font[256];
 static volatile uint8_t *tv_kfont[0x7f];
 
@@ -89,6 +94,9 @@ static void tv_putc(struct ite_softc *, 
 static void tv_cursor(struct ite_softc *, int);
 static void tv_clear(struct ite_softc *, int, int, int, int);
 static void tv_scroll(struct ite_softc *, int, int, int, int);
+#if defined(ITE_SIXEL)
+static void tv_sixel(struct ite_softc *, int, int);
+#endif
 
 static inline uint32_t expbits(uint32_t);
 static inline void txrascpy(uint8_t, uint8_t, int16_t, uint16_t);
@@ -166,6 +174,9 @@ tv_init(struct ite_softc *ip)
 	for (i = 0; i < PLANELINES; i++)
 		tv_row[i] =
 		    (void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]);
+#if defined(ITE_SIXEL)
+	tv_end = (void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]);
+#endif
 	/* shadow ANK font */
 	memcpy(kern_font, (void *)&IODEVbase->cgrom0_8x16, 256 * FONTHEIGHT);
 	ite_set_glyph();
@@ -189,6 +200,9 @@ tv_init(struct ite_softc *ip)
 	ip->isw->ite_cursor = tv_cursor;
 	ip->isw->ite_clear  = tv_clear;
 	ip->isw->ite_scroll = tv_scroll;
+#if defined(ITE_SIXEL)
+	ip->isw->ite_sixel  = tv_sixel;
+#endif
 
 	/*
 	 * Initialize colormap
@@ -741,3 +755,54 @@ tv_scroll(struct ite_softc *ip, int srcy
 		break;
 	}
 }
+
+#if defined(ITE_SIXEL)
+/*
+ * put SIXEL graphics
+ */
+void
+tv_sixel(struct ite_softc *ip, int sy, int sx)
+{
+	uint8_t *p;
+	int width;
+	int y;
+	int cx;
+	int px;
+	uint16_t data[3];
+	uint8_t color;
+
+	width = MIN(ip->decsixel_ph, MAX_SIXEL_WIDTH);
+	width = MIN(width, PLANEWIDTH - sx * FONTWIDTH);
+
+	p = CHADDR(sy, sx);
+	p += ROWBYTES * ip->decsixel_y;
+	/* boundary check */
+	if (p < tv_row[0]) {
+		p = tv_end + (p - tv_row[0]);
+	}
+
+	for (y = 0; y < 6; y++) {
+		/* for each 16dot word */
+		for (cx = 0; cx < howmany(width, 16); cx++) {
+			data[0] = 0;
+			data[1] = 0;
+			data[2] = 0;
+			for (px = 0; px < 16; px++) {
+				color = ip->decsixel_buf[cx * 16 + px] >> (y * 4);
+				/* x68k console is 8 colors */
+				data[0] = (data[0] << 1) | ((color >> 0) & 1);
+				data[1] = (data[1] << 1) | ((color >> 1) & 1);
+				data[2] = (data[2] << 1) | ((color >> 2) & 1);
+			}
+			*(uint16_t *)(p + cx * 2          ) = data[0];
+			*(uint16_t *)(p + cx * 2 + 0x20000) = data[1];
+			*(uint16_t *)(p + cx * 2 + 0x40000) = data[2];
+		}
+
+		p += ROWBYTES;
+		if (p >= tv_end) {
+			p = tv_row[0] + (p - tv_end);
+		}
+	}
+}
+#endif /* ITE_SIXEL */

Index: src/sys/arch/x68k/dev/itevar.h
diff -u src/sys/arch/x68k/dev/itevar.h:1.17 src/sys/arch/x68k/dev/itevar.h:1.18
--- src/sys/arch/x68k/dev/itevar.h:1.17	Sun Jan  7 07:58:33 2024
+++ src/sys/arch/x68k/dev/itevar.h	Sat Oct  5 03:56:54 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: itevar.h,v 1.17 2024/01/07 07:58:33 isaki Exp $	*/
+/*	$NetBSD: itevar.h,v 1.18 2024/10/05 03:56:54 isaki Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -50,6 +50,7 @@ struct itesw {
 	void	(*ite_putc)(struct ite_softc *, int, int, int, int);
 	void	(*ite_cursor)(struct ite_softc *, int);
 	void	(*ite_scroll)(struct ite_softc *, int, int, int, int);
+	void	(*ite_sixel)(struct ite_softc *, int, int);
 };
 
 enum ite_arraymaxs {
@@ -94,6 +95,28 @@ struct ite_softc {
 	short	save_curx, save_cury, save_attribute, save_char;
 	char	sc_G0, sc_G1, sc_G2, sc_G3;
 	char	*sc_GL, *sc_GR;
+	enum {
+		DCS_START = 0,
+		DCS_SIXEL = 'q',	/* DECRQSS also use 'q'... */
+		DCS_DISCARD = -1,
+	} dcs_cmd;
+	enum {
+		DECSIXEL_INIT = 0,
+		DECSIXEL_RASTER_PAD,
+		DECSIXEL_RASTER_PH,
+		DECSIXEL_RASTER_PV,
+		DECSIXEL_REPEAT = '!',
+		DECSIXEL_RASTER = '\"',
+		DECSIXEL_COLOR = '#',
+	} decsixel_state;
+	int	decsixel_ph;
+	int	decsixel_x;
+	int	decsixel_y;
+	int	decsixel_repcount;
+	int	decsixel_color;
+	int	decsixel_ormode;
+#define MAX_SIXEL_WIDTH (768)
+	uint32_t decsixel_buf[MAX_SIXEL_WIDTH];
 };
 
 enum emul_level {

Reply via email to