Page MenuHomeFreeBSD

D40858.diff
No OneTemporary

D40858.diff

Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3447,6 +3447,7 @@
dev/vt/vt_core.c optional vt
dev/vt/vt_cpulogos.c optional vt splash
dev/vt/vt_font.c optional vt
+dev/vt/vt_screenshot.c optional vt
dev/vt/vt_sysmouse.c optional vt
dev/vte/if_vte.c optional vte pci
dev/watchdog/watchdog.c standard
Index: sys/dev/vt/vt.h
===================================================================
--- sys/dev/vt/vt.h
+++ sys/dev/vt/vt.h
@@ -425,6 +425,10 @@
#define VT_MOUSE_SHOW 1
#define VT_MOUSE_HIDE 0
+/* Screenshot. */
+int vt_screenshot_grph(struct vt_device *vd, vt_scrshot_grph_t *);
+int vt_screenshot_text(struct vt_window *vw, vt_scrshot_text_t *);
+
/* Utilities. */
void vt_compute_drawable_area(struct vt_window *);
void vt_determine_colors(term_char_t c, int cursor,
Index: sys/dev/vt/vt_core.c
===================================================================
--- sys/dev/vt/vt_core.c
+++ sys/dev/vt/vt_core.c
@@ -2558,6 +2558,7 @@
case FBIO_GETRGBOFFS: /* get RGB offsets */
if (vd->vd_driver->vd_fb_ioctl)
return (vd->vd_driver->vd_fb_ioctl(vd, cmd, data, td));
+ printf("VT(%s) not supported.\r\n", vd->vd_driver->vd_name);
break;
case CONS_BLANKTIME:
/* XXX */
@@ -2598,6 +2599,12 @@
if (vi->size != sizeof(struct vid_info))
return (EINVAL);
+ vi->mv_rsz = tm->tm_winsize.ws_row;
+ vi->mv_csz = tm->tm_winsize.ws_col;
+ vtbuf_lock(&vw->vw_buf);
+ vi->mv_hsz = vw->vw_buf.vb_history_size;
+ vtbuf_unlock(&vw->vw_buf);
+
if (vw == vd->vd_curwindow) {
mtx_lock(&Giant);
if ((kbd = vd->vd_keyboard) != NULL)
@@ -2647,6 +2654,16 @@
return (EINVAL);
}
}
+ case CONS_VTSCRSHOT_GRPH: {
+ vt_scrshot_grph_t *ptr = (vt_scrshot_grph_t *)data;
+ error = vt_screenshot_grph(vd, ptr);
+ return (error);
+ }
+ case CONS_VTSCRSHOT_TEXT: {
+ vt_scrshot_text_t *ptr = (vt_scrshot_text_t *)data;
+ error = vt_screenshot_text(vw, ptr);
+ return (error);
+ }
case PIO_VFONT: {
struct vt_font *vf;
Index: sys/dev/vt/vt_screenshot.c
===================================================================
--- /dev/null
+++ sys/dev/vt/vt_screenshot.c
@@ -0,0 +1,88 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/fbio.h>
+
+#include <dev/vt/vt.h>
+
+int
+vt_screenshot_grph(struct vt_device* vd, vt_scrshot_grph_t *ptr)
+{
+ struct fb_info *info;
+ void *from_p;
+
+ info = vd->vd_softc;
+ if (ptr->size != info->fb_size)
+ return (EINVAL);
+
+ from_p = (void *)info->fb_vbase;
+ return (copyout(from_p, ptr->buf, info->fb_size));
+}
+
+int
+vt_screenshot_text(struct vt_window* vw, vt_scrshot_text_t *ptr)
+{
+ int retval = 0;
+ struct vt_buf *vb;
+ int row, hrow;
+ const size_t csize = sizeof(u_int);
+ u_int *outp = ptr->buf;;
+ u_int **rows;
+ void *colp, *bufp;
+
+ if (ptr->x < 0 || ptr->y < 0 || ptr->xsize < 0 || ptr->ysize < 0)
+ return (EINVAL);
+
+ /* Check if virtual terminal is locked */
+ if (vw->vw_flags & VWF_VTYLOCK)
+ return (EBUSY);
+
+ vb = &vw->vw_buf;
+ rows = (u_int **)vb->vb_rows;
+ if ((ptr->xsize + ptr->x) > vb->vb_scr_size.tp_col ||
+ (ptr->ysize + ptr->y) > vb->vb_scr_size.tp_row) {
+ return (EINVAL);
+ }
+ /* Copy current window to output buffer */
+ for (row = ptr->y; row < (ptr->y + ptr->ysize); row++) {
+ /* Translate current view row number to history row */
+ hrow = (vb->vb_roffset + row) % vb->vb_history_size;
+ // colp = (void *)&vb->vb_rows[hrow][ptr->x];
+ colp = (void *)&rows[hrow][ptr->x];
+ bufp = (void *)outp;
+ retval = copyout(colp, bufp, ptr->xsize*csize);
+ if (retval != 0)
+ break;
+ outp += ptr->xsize;
+ }
+ return (retval);
+}
Index: sys/sys/consio.h
===================================================================
--- sys/sys/consio.h
+++ sys/sys/consio.h
@@ -293,10 +293,25 @@
int ysize;
u_int16_t* buf;
};
+struct vt_scrshot_text {
+ int x;
+ int y;
+ int xsize;
+ int ysize;
+ u_int *buf;
+};
+struct vt_scrshot_grph {
+ size_t size;
+ void *buf;
+};
typedef struct scrshot scrshot_t;
+typedef struct vt_scrshot_text vt_scrshot_text_t;
+typedef struct vt_scrshot_grph vt_scrshot_grph_t;
/* Snapshot the current video buffer */
#define CONS_SCRSHOT _IOWR('c', 105, scrshot_t)
+#define CONS_VTSCRSHOT_TEXT _IOWR('c', 114, vt_scrshot_text_t)
+#define CONS_VTSCRSHOT_GRPH _IOWR('c', 115, vt_scrshot_grph_t)
/* get/set the current terminal emulator info. */
#define TI_NAME_LEN 32
Index: usr.sbin/vidcontrol/vidcontrol.c
===================================================================
--- usr.sbin/vidcontrol/vidcontrol.c
+++ usr.sbin/vidcontrol/vidcontrol.c
@@ -40,10 +40,13 @@
#include <ctype.h>
#include <err.h>
+#include <iconv.h>
#include <limits.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <unistd.h>
#include <sys/fbio.h>
#include <sys/consio.h>
@@ -53,20 +56,29 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <teken/teken.h>
#include "path.h"
#include "decode.h"
#define DATASIZE(x) ((x).w * (x).h * 256 / 8)
+#define TCHAR_NONCHAR(c) ((c) & ~0x1fffff)
+/* from sys/terminal.h */
+#define TCHAR_CHARACTER(c) ((c) & 0x1fffff)
+#define TCHAR_FORMAT(c) (((c) >> 21) & 0x1f)
+#define TCHAR_FGCOLOR(c) (((c) >> 26) & 0x7)
+#define TCHAR_BGCOLOR(c) (((c) >> 29) & 0x7)
/* Screen dump modes */
#define DUMP_FMT_RAW 1
#define DUMP_FMT_TXT 2
+#define DUMP_FMT_CTXT 3
/* Screen dump options */
#define DUMP_FBF 0
#define DUMP_ALL 1
/* Screen dump file format revision */
#define DUMP_FMT_REV 1
+#define DUMP_FMT_REV_VT 2
static const char *legal_colors[16] = {
"black", "blue", "green", "cyan",
@@ -188,7 +200,7 @@
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: vidcontrol [-Cx] [-b color] [-c appearance] [-f [[size] file]]",
" [-g geometry] [-h size] [-i active | adapter | mode]",
-" [-M char] [-m on | off]",
+" [-M char] [-m on | off] [-p text | term | raw]",
" [-r foreground background] [-S on | off] [-s number]",
" [-T xterm | cons25] [-t N | off] [mode]",
" [foreground [background]] [show]");
@@ -1338,6 +1350,191 @@
}
+/*
+ * Snapshot the text buffer or video memory of the termnal.
+ */
+static void
+vt_dump_screen(int mode, int opt)
+{
+ struct fbtype fb;
+ vt_scrshot_grph_t gshot;
+ u_int32_t xs, ys, depth;
+ vt_scrshot_text_t tshot;
+ vid_info_t info;
+ int x, y, ret;
+ iconv_t cd;
+ teken_char_t oc, uc, fmt;
+ size_t isize, osize;
+ char obuf[8], escbuf[BUFSIZ], escsq[BUFSIZ];
+ char *ibuf_p, *obuf_p;
+ teken_char_t nc_curstate, nc_prevstate;
+ teken_char_t fg, bg;
+ bool need_fini = false;
+ int colormap[TC_NCOLORS] = {
+ [TC_BLACK] = 30,
+ [TC_RED] = 31,
+ [TC_GREEN] = 32,
+ [TC_YELLOW] = 33,
+ [TC_BLUE] = 34,
+ [TC_MAGENTA] = 35,
+ [TC_CYAN] = 36,
+ [TC_WHITE] = 37
+ };
+
+ if (mode == DUMP_FMT_RAW) {
+ if (ioctl(0, FBIOGTYPE, &fb) == -1) {
+ revert();
+ err(1, "Dumping in BMP not supported");
+ }
+ if (fb.fb_depth != 32) {
+ revert();
+ errx(0, "Pixel depth %d not supported", fb.fb_depth);
+ }
+ gshot.buf = (void *)malloc(fb.fb_size);
+ gshot.size = fb.fb_size;
+ if (gshot.buf == NULL) {
+ revert();
+ errx(1, "failed to allocate memory for dump");
+ }
+ if (ioctl(0, CONS_VTSCRSHOT_GRPH, &gshot) == -1) {
+ revert();
+ err(1, "getting frame buffer data");
+ }
+ /* output RAW */
+ xs = (u_int32_t)fb.fb_width;
+ ys = (u_int32_t)fb.fb_height;
+ depth = (u_int32_t)fb.fb_depth;
+ printf("SCRSHOT_%c%c", DUMP_FMT_REV_VT, 3);
+ fwrite(&xs, sizeof(u_int32_t), 1, stdout);
+ fwrite(&ys, sizeof(u_int32_t), 1, stdout);
+ fwrite(&depth, sizeof(u_int32_t), 1, stdout);
+ fwrite(gshot.buf, sizeof(u_int32_t), xs*ys, stdout);
+ fflush(stdout);
+ }
+ else {
+ info.size = sizeof(info);
+ if (ioctl(0, CONS_GETINFO, &info) == -1) {
+ revert();
+ err(1, "getting console information");
+ }
+ tshot.x = tshot.y = 0;
+ tshot.xsize = info.mv_csz;
+ tshot.ysize = info.mv_rsz;
+ if (opt == DUMP_ALL)
+ tshot.ysize = info.mv_hsz;
+ tshot.buf = (u_int *)alloca(tshot.xsize * tshot.ysize
+ * sizeof(u_int));
+ if (tshot.buf == NULL) {
+ revert();
+ errx(1, "failed to allocate memory for dump");
+ }
+ if (ioctl(0, CONS_VTSCRSHOT_TEXT, &tshot) == -1) {
+ revert();
+ err(1, "dumping screen");
+ }
+
+ cd = iconv_open("UTF-8", "UCS-4LE");
+ if (cd == (iconv_t)-1) {
+ revert();
+ err(1, "iconv_open()");
+ }
+ nc_prevstate = nc_curstate = 0;
+ for (y = 0; y < tshot.ysize; y++) {
+ for (x = 0; x < tshot.xsize; x++) {
+ oc = (teken_char_t)(0xffffffff & tshot.buf[tshot.xsize*y + x]);
+ nc_prevstate = nc_curstate;
+ nc_curstate = TCHAR_NONCHAR(oc);
+ fmt = TCHAR_FORMAT(oc);
+
+ if ((fmt & TF_CJK_RIGHT) == TF_CJK_RIGHT)
+ continue;
+
+ if (mode == DUMP_FMT_CTXT && nc_prevstate != nc_curstate) {
+ need_fini = true;
+ bzero(escsq, BUFSIZ);
+ fg = TCHAR_FGCOLOR(oc);
+ bg = TCHAR_BGCOLOR(oc);
+
+ strncat(escsq, "\e[", BUFSIZ - strlen(escsq) -1);
+ /* reset */
+ strncat(escsq, "0;", BUFSIZ - strlen(escsq) -1);
+ if ((fmt & TF_BOLD) == TF_BOLD)
+ strncat(escsq, "1;", BUFSIZ - strlen(escsq) -1);
+ if ((fmt & TF_UNDERLINE) == TF_UNDERLINE)
+ strncat(escsq, "4;", BUFSIZ - strlen(escsq) -1);
+ if ((fmt & TF_BLINK) == TF_BLINK)
+ strncat(escsq, "5;", BUFSIZ - strlen(escsq) -1);
+ if ((fmt & TF_REVERSE) == TF_REVERSE)
+ strncat(escsq, "7;", BUFSIZ - strlen(escsq) -1);
+
+ bzero(escbuf, BUFSIZ);
+ if (fg != TC_NCOLORS && (fg & TC_LIGHT) == TC_LIGHT)
+ strncat(escsq, "2;", BUFSIZ - strlen(escsq) -1);
+ switch(fg & ~TC_LIGHT) {
+ case TC_BLACK:
+ case TC_RED:
+ case TC_GREEN:
+ case TC_YELLOW:
+ case TC_BLUE:
+ case TC_MAGENTA:
+ case TC_CYAN:
+ case TC_WHITE:
+ snprintf(escbuf, sizeof(escbuf), "%2d;",
+ colormap[fg & ~TC_LIGHT]);
+ strncat(escsq, escbuf, BUFSIZ - strlen(escsq) -1);
+ }
+
+ bzero(escbuf, BUFSIZ);
+ if (bg != TC_NCOLORS && (bg & TC_LIGHT) == TC_LIGHT)
+ strncat(escsq, "2;", BUFSIZ - strlen(escsq) -1);
+ switch(bg & ~TC_LIGHT) {
+ case TC_BLACK:
+ case TC_RED:
+ case TC_GREEN:
+ case TC_YELLOW:
+ case TC_BLUE:
+ case TC_MAGENTA:
+ case TC_CYAN:
+ case TC_WHITE:
+ snprintf(escbuf, sizeof(escbuf), "%2d;",
+ colormap[bg & ~TC_LIGHT]);
+ strncat(escsq, escbuf, BUFSIZ - strlen(escsq) -1);
+ }
+
+ /* terminate */
+ escsq[strlen(escsq) - 1] = 'm';
+
+ printf("%s", escsq);
+ }
+
+ uc = TCHAR_CHARACTER(oc);
+ ibuf_p = (char *)&uc;
+ isize = sizeof(uc);
+ bzero(obuf, 8);
+ obuf_p = obuf;
+ osize = sizeof(obuf);
+ iconv(cd, &ibuf_p, &isize, &obuf_p, &osize);
+ if (isize != 0) {
+ iconv_close(cd);
+ revert();
+ err(1, "iconv()");
+ }
+ printf("%s", obuf);
+ }
+ printf("%s", "\r\n");
+ }
+ if (need_fini) {
+ printf("%s", "\e[0m");
+ }
+ ret = iconv_close(cd);
+ if (ret == -1) {
+ revert();
+ err(1, "iconv_close()");
+ }
+ }
+}
+
+
/*
* Set the console history buffer size.
*/
@@ -1427,7 +1624,7 @@
int
main(int argc, char **argv)
{
- char *font, *type, *termmode;
+ char *dumparg, *font, *type, *termmode;
const char *opts;
int dumpmod, dumpopt, opt;
@@ -1439,7 +1636,7 @@
dumpopt = DUMP_FBF;
termmode = NULL;
if (vt4_mode)
- opts = "b:Cc:fg:h:i:M:m:r:S:s:T:t:x";
+ opts = "b:Cc:fg:h:i:M:m:p:r:S:s:T:t:x";
else
opts = "b:Cc:deE:fg:h:Hi:l:LM:m:pPr:S:s:T:t:x";
@@ -1495,7 +1692,7 @@
warnx("incorrect geometry: %s", optarg);
usage();
}
- break;
+ break;
case 'h':
set_history(optarg);
break;
@@ -1522,9 +1719,26 @@
set_mouse(optarg);
break;
case 'p':
- dumpmod = DUMP_FMT_RAW;
+ if (vt4_mode) {
+ dumparg = optarg;
+ if (strcmp(dumparg, "text") == 0)
+ dumpmod = DUMP_FMT_TXT;
+ else if (strcmp(dumparg, "term") == 0)
+ dumpmod = DUMP_FMT_CTXT;
+ else if (strcmp(dumparg, "raw") == 0)
+ dumpmod = DUMP_FMT_RAW;
+ else {
+ revert();
+ err(1, "invalid argument for -p option.");
+ }
+ }
+ else {
+ dumpmod = DUMP_FMT_RAW;
+ }
break;
case 'P':
+ if (vt4_mode)
+ break;
dumpmod = DUMP_FMT_TXT;
break;
case 'r':
@@ -1552,8 +1766,10 @@
usage();
}
- if (dumpmod != 0)
+ if (!vt4_mode && dumpmod != 0)
dump_screen(dumpmod, dumpopt);
+ if (vt4_mode && dumpmod != 0)
+ vt_dump_screen(dumpmod, dumpopt);
video_mode(argc, argv, &optind);
set_normal_colors(argc, argv, &optind);

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 27, 9:42 AM (12 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29025038
Default Alt Text
D40858.diff (13 KB)

Event Timeline