summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2018-02-20 10:13:24 +0800
committerJeremy Kerr <jk@ozlabs.org>2018-04-12 14:22:33 +0800
commitc368ccb16b1e996846f47a7c640250a380401e01 (patch)
tree215191c65fac87ffd971842b8f6020f5cabbe237
parent0a58169a7838f74332e74393c4b87f40840e0b41 (diff)
downloadfbterm-c368ccb16b1e996846f47a7c640250a380401e01.tar.gz
fbterm-c368ccb16b1e996846f47a7c640250a380401e01.zip
Add a shared-memory framebuffer output method
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/fbconfig.cpp4
-rw-r--r--src/fbshm.cpp157
-rw-r--r--src/fbshm.h39
-rw-r--r--src/screen.cpp17
5 files changed, 215 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e99f752..d942176 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@ bin_PROGRAMS = fbterm
fbterm_SOURCES = fbconfig.cpp fbconfig.h fbio.cpp fbio.h fbshell.cpp fbshell.h fbshellman.cpp fbshellman.h fbterm.cpp \
fbterm.h font.cpp font.h input.cpp input.h input_key.h mouse.cpp mouse.h screen.cpp screen.h improxy.cpp improxy.h \
- screen_render.cpp fbdev.cpp fbdev.h vesadev.cpp vesadev.h vbe.h
+ screen_render.cpp fbdev.cpp fbdev.h fbshm.cpp fbshm.h vesadev.cpp vesadev.h vbe.h
EXTRA_fbterm_SOURCES = signalfd.h
fbterm_CXXFLAGS = -fno-exceptions -fno-rtti -I$(top_srcdir)/src/lib @FT2_CFLAGS@ @FC_CFLAGS@
diff --git a/src/fbconfig.cpp b/src/fbconfig.cpp
index 14240b6..f1985d0 100644
--- a/src/fbconfig.cpp
+++ b/src/fbconfig.cpp
@@ -237,6 +237,7 @@ bool Config::parseArgs(s32 argc, s8 **argv)
{ "font-width", required_argument, 0, 2 },
{ "font-height", required_argument, 0, 4 },
{ "ambiguous-wide", no_argument, 0, 'a' },
+ { "shared-mem", required_argument, 0, 'm' },
#ifdef ENABLE_VESA
{ "vesa-mode", required_argument, 0, 3 },
#endif
@@ -244,7 +245,7 @@ bool Config::parseArgs(s32 argc, s8 **argv)
};
s32 index;
- while ((index = getopt_long(argc, argv, "Vvhn:s:f:b:e:r:i:a", options, 0)) != -1) {
+ while ((index = getopt_long(argc, argv, "Vvhn:s:f:b:e:r:i:m:a", options, 0)) != -1) {
switch (index) {
case 'V':
printf("FbTerm version " VERSION "\n");
@@ -269,6 +270,7 @@ bool Config::parseArgs(s32 argc, s8 **argv)
" -r, --screen-rotate=NUM specify orientation of screen display\n"
" -a, --ambiguous-wide treat ambiguous width characters as wide\n"
" -i, --input-method=TEXT specify input method program\n"
+ " -m, --shared-mem=DESC use shared-memory framebuffer DESC\n"
" --cursor-shape=NUM specify default cursor shape\n"
" --cursor-interval=NUM specify cursor flash interval\n"
#ifdef ENABLE_VESA
diff --git a/src/fbshm.cpp b/src/fbshm.cpp
new file mode 100644
index 0000000..48d0c38
--- /dev/null
+++ b/src/fbshm.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2018 IBM Corporation
+ * This file is part of FbTerm.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include "fbconfig.h"
+#include "fbshm.h"
+
+int FbShm::parse_shm_desc(const char *desc, char **file,
+ int *rows, int *cols, int *bpp)
+{
+ char *str, *sep, *endp;
+ unsigned long tmp;
+
+ str = strdup(desc);
+
+ /* <file>:<cols>x<rows>@<bpp> */
+
+ /* file */
+ sep = strchr(str, ':');
+ if (!sep)
+ goto err_free;
+
+ *file = str;
+ *sep = '\0';
+
+ /* cols */
+ str = sep + 1;
+ sep = strchr(str, 'x');
+ if (!sep) {
+ fprintf(stderr, "can't parse shm descriptor %s: no geom\n",
+ desc);
+ goto err_free;
+ }
+ *sep = '\0';
+
+ tmp = strtoul(str, &endp, 10);
+ if (endp != sep) {
+ fprintf(stderr,
+ "can't parse shm descriptor %s: invalid cols %s\n",
+ desc, str);
+ goto err_free;
+ }
+
+ *cols = (int)(tmp & 0xffffffff);
+
+ /* rows */
+ str = sep + 1;
+ sep = strchr(str, '@');
+ if (!sep) {
+ fprintf(stderr, "can't parse shm descriptor %s: no geom\n",
+ desc);
+ goto err_free;
+ }
+ *sep = '\0';
+
+ tmp = strtoul(str, &endp, 10);
+ if (endp != sep) {
+ fprintf(stderr,
+ "can't parse shm descriptor %s: invalid rows %s\n",
+ desc, str);
+ goto err_free;
+ }
+
+ *rows = (int)(tmp & 0xffffffff);
+
+ /* bpp */
+ tmp = strtoul(sep + 1, &endp, 10);
+ if (*endp != '\0' || endp == str) {
+ fprintf(stderr,
+ "can't parse shm descriptor %s: invalid bpp\n",
+ desc);
+ goto err_free;
+ }
+
+ *bpp = (int)(tmp & 0xff);
+
+ printf("%s: rows %d, cols %d, bpp %d\n", *file, *rows, *cols, *bpp);
+
+ return 0;
+
+err_free:
+ free(str);
+ return -1;
+}
+
+FbShm *FbShm::initFbShm()
+{
+ int rows, cols, bpp;
+ s8 *file, desc[4096];
+ int fd;
+
+ Config::instance()->getOption("shared-mem", desc, sizeof(desc));
+
+ if (!strlen(desc))
+ return 0;
+
+ if (parse_shm_desc(desc, &file, &rows, &cols, &bpp))
+ return 0;
+
+ fd = open(file, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "can't open frame buffer shm %s: %m\n", file);
+ free(file);
+ return 0;
+ }
+
+ free(file);
+
+ return new FbShm(fd, rows, cols, bpp);
+}
+
+FbShm::FbShm(int fd, int rows, int cols, int bpp)
+{
+ mWidth = cols;
+ mHeight = rows;
+ mBitsPerPixel = bpp;
+ mBytesPerLine = cols * (bpp >> 3);
+ mFD = fd;
+
+
+ mVMemBase = (u8 *)mmap(0, mHeight * mBytesPerLine,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+}
+
+FbShm::~FbShm()
+{
+ munmap(mVMemBase, mHeight * mBytesPerLine);
+ close(mFD);
+}
+
+const s8 *FbShm::drvId()
+{
+ return "shm";
+}
+
diff --git a/src/fbshm.h b/src/fbshm.h
new file mode 100644
index 0000000..3b85726
--- /dev/null
+++ b/src/fbshm.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2018 IBM Corporation
+ * This file is part of FbTerm.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef FBSHM_H
+#define FBSHM_H
+
+#include "screen.h"
+
+class FbShm : public Screen {
+private:
+ friend class Screen;
+ static FbShm *initFbShm();
+ static int parse_shm_desc(const char *desc, char **file,
+ int *rows, int *cols, int *bpp);
+ int mFD;
+
+ FbShm(int fd, int rows, int cols, int bpp);
+ ~FbShm();
+
+ virtual const s8 *drvId();
+};
+#endif
diff --git a/src/screen.cpp b/src/screen.cpp
index 4da2453..fee1f05 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -26,6 +26,7 @@
#include "fbshellman.h"
#include "fbconfig.h"
#include "fbdev.h"
+#include "fbshm.h"
#include "config.h"
#ifdef ENABLE_VESA
#include "vesadev.h"
@@ -45,6 +46,7 @@ DEFINE_INSTANCE(Screen)
Screen *Screen::createInstance()
{
+
if (!Font::instance() || !FW(1) || !FH(1)) {
fprintf(stderr, "init font error!\n");
return 0;
@@ -52,6 +54,9 @@ Screen *Screen::createInstance()
Screen *pScreen = 0;
+ s8 shm_info[2];
+ Config::instance()->getOption("shared-mem", shm_info, sizeof(shm_info));
+
#ifdef ENABLE_VESA
s8 buf[16];
Config::instance()->getOption("vesa-mode", buf, sizeof(buf));
@@ -63,10 +68,18 @@ Screen *Screen::createInstance()
u32 mode = 0;
Config::instance()->getOption("vesa-mode", mode);
- if (!mode) pScreen = FbDev::initFbDev();
+ if (!mode) {
+ if (strlen(shm_info))
+ pScreen = FbShm::initFbShm();
+ else
+ pScreen = FbDev::initFbDev();
+ }
if (!pScreen) pScreen = VesaDev::initVesaDev(mode);
#else
- pScreen = FbDev::initFbDev();
+ if (strlen(shm_info))
+ pScreen = FbShm::initFbShm();
+ else
+ pScreen = FbDev::initFbDev();
#endif
if (!pScreen) return 0;
OpenPOWER on IntegriCloud