Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145943294
D40858.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D40858.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D40858: Screenshot with vt(4)
Attached
Detach File
Event Timeline
Log In to Comment