this patch makes use of unifont with genfont2 and introduces support for
wide-characters and combining glyphs
for this we have to save the width and possible diacritic in the
textcell, which means we also have to reset them properly and give those
values also to draw_char_at
to determine the width we use the wcwidth provided by unifont
(because in unifont some characters are wide which normally are not)
we mmap the generated fontfile, and drop the glyphs.h, which reduces
the initial memory use, and shares the pages between processes
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
-glyphs.h: genfont
- ./genfont > glyphs.h.tmp
- mv glyphs.h.tmp glyphs.h
-
-genfont: genfont.c
- gcc -g -O2 -o $@ genfont.c -Wall -D_GNU_SOURCE -lz
-
font.data: genfont2
./genfont2 -o font.data.tmp -i /usr/share/unifont/unifont.hex
mv font.data.tmp font.data
font.data: genfont2
./genfont2 -o font.data.tmp -i /usr/share/unifont/unifont.hex
mv font.data.tmp font.data
cd ${VNCDIR}; ./autogen.sh --without-ssl --without-websockets --without-tightvnc-filetransfer;
cd ${VNCDIR}; make
cd ${VNCDIR}; ./autogen.sh --without-ssl --without-websockets --without-tightvnc-filetransfer;
cd ${VNCDIR}; make
-vncterm: vncterm.c glyphs.h ${VNCLIB}
- gcc -O2 -g -o $@ vncterm.c -Wall -Wno-deprecated-declarations -D_GNU_SOURCE -I ${VNCDIR} ${VNCLIB} -lnsl -lpthread -lz -ljpeg -lutil -lgnutls -lpng
+vncterm: vncterm.c ${VNCLIB} wchardata.c
+ gcc -O2 -g -o $@ vncterm.c wchardata.c -Wall -Wno-deprecated-declarations -D_GNU_SOURCE -I ${VNCDIR} ${VNCLIB} -lnsl -lpthread -lz -ljpeg -lutil -lgnutls -lpng
+wchardata.c:
+ cp /usr/share/unifont/$@ $@
-install: vncterm vncterm.1
+install: vncterm vncterm.1 font.data
mkdir -p ${DESTDIR}/usr/share/doc/${PACKAGE}
install -m 0644 copyright ${DESTDIR}/usr/share/doc/${PACKAGE}
mkdir -p ${DESTDIR}/usr/share/doc/${PACKAGE}
install -m 0644 copyright ${DESTDIR}/usr/share/doc/${PACKAGE}
+ mkdir -p ${DESTDIR}/usr/share/${PACKAGE}
+ install -m 0644 font.data ${DESTDIR}/usr/share/${PACKAGE}
mkdir -p ${DESTDIR}/usr/share/man/man1
install -m 0644 vncterm.1 ${DESTDIR}/usr/share/man/man1
mkdir -p ${DESTDIR}/usr/bin
mkdir -p ${DESTDIR}/usr/share/man/man1
install -m 0644 vncterm.1 ${DESTDIR}/usr/share/man/man1
mkdir -p ${DESTDIR}/usr/bin
- rm -rf vncterm vncterm.1 vncterm_*.deb genfont genfont2 *~ ${VNCDIR} vncterm-*.tar.gz glyph.h.tmp build *.changes font.data.tmp font.data
+ rm -rf vncterm vncterm.1 vncterm_*.deb genfont genfont2 *~ ${VNCDIR} vncterm-*.tar.gz glyph.h.tmp build *.changes wchardata.c font.data.tmp font.data *.buildinfo
.PHONY: distclean
distclean: clean
.PHONY: distclean
distclean: clean
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <rfb/rfb.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <rfb/rfb.h>
#include <locale.h>
#include "vncterm.h"
#include <locale.h>
#include "vncterm.h"
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
+extern int wcwidth (wchar_t wc);
+unsigned char *fontdata;
+
+#define FONTFILE "/usr/share/vncterm/font.data"
+#define GLYPHLINES 16
+
static char *
urlencode(char *buf, const char *value)
{
static char *
urlencode(char *buf, const char *value)
{
static void
rfb_draw_char (rfbScreenInfoPtr rfbScreen, int x, int y,
static void
rfb_draw_char (rfbScreenInfoPtr rfbScreen, int x, int y,
- unsigned short c, rfbPixel col)
+ unicode c, rfbPixel col, short width)
- if (c > vt_font_size) {
- rfbLog ("undefined font glyph %d\n", c);
- return;
- }
-
- unsigned char *data= vt_font_data + c*16;
+ unsigned char *data= fontdata + c*(GLYPHLINES*2);
unsigned char d=*data;
int rowstride=rfbScreen->paddedWidthInBytes;
char *colour=(char*)&col;
unsigned char d=*data;
int rowstride=rfbScreen->paddedWidthInBytes;
char *colour=(char*)&col;
- for(j = 0; j < 16; j++) {
- for(i = 0; i < 8; i++) {
+ for(j = 0; j < GLYPHLINES; j++) {
+ for(i = 0; i < 8*width; i++) {
if ((i&7) == 0) {
d=*data;
data++;
if ((i&7) == 0) {
d=*data;
data++;
-draw_char_at (vncTerm *vt, int x, int y, unicode ch, TextAttributes attrib)
+draw_char_at (vncTerm *vt, int x, int y, unicode ch, TextAttributes attrib, short width, unicode combiningglyph)
{
if (x < 0 || y < 0 || x >= vt->width || y >= vt->height) { return; }
{
if (x < 0 || y < 0 || x >= vt->width || y >= vt->height) { return; }
+ // non printable character
+ if (width < 1) return;
+
int rx = x*8;
int ry = y*16;
int rx = x*8;
int ry = y*16;
int rye = y*16+16;
int fg, bg;
int rye = y*16+16;
int fg, bg;
- int ec = vt_fontmap[ch];
-
rfbFillRect (vt->screen, rx, ry, rxe, rye, bg);
if (attrib.bold) {
rfbFillRect (vt->screen, rx, ry, rxe, rye, bg);
if (attrib.bold) {
// unsuported attributes = (attrib.blink || attrib.unvisible)
// unsuported attributes = (attrib.blink || attrib.unvisible)
- rfb_draw_char (vt->screen, rx, ry, ec, fg);
+ rfb_draw_char (vt->screen, rx, ry, ch, fg, width);
+
+ if (combiningglyph) {
+ rfb_draw_char (vt->screen, rx, ry, combiningglyph, fg, 1);
+ }
if (attrib.uline) {
rfbDrawLine (vt->screen, rx, ry + 14, rxe, ry + 14, fg);
if (attrib.uline) {
rfbDrawLine (vt->screen, rx, ry + 14, rxe, ry + 14, fg);
}
if (y2 < vt->height) {
TextCell *c = &vt->cells[y1 * vt->width + x];
}
if (y2 < vt->height) {
TextCell *c = &vt->cells[y1 * vt->width + x];
- draw_char_at (vt, x, y2, c->ch, c->attrib);
+ draw_char_at (vt, x, y2, c->ch, c->attrib, c->width, c->combiningglyph);
c->attrib = vt->default_attrib;
c->attrib.fgcol = vt->cur_attrib.fgcol;
c->attrib.bgcol = vt->cur_attrib.bgcol;
c->attrib = vt->default_attrib;
c->attrib.fgcol = vt->cur_attrib.fgcol;
c->attrib.bgcol = vt->cur_attrib.bgcol;
+ c->width = 1;
+ c->combiningglyph = 0;
- draw_char_at (vt, x, y, c->ch, c->attrib);
+ draw_char_at (vt, x, y, c->ch, c->attrib, c->width, c->combiningglyph);
if (show) {
TextAttributes attrib = vt->default_attrib;
attrib.invers = !(attrib.invers); /* invert fg and bg */
if (show) {
TextAttributes attrib = vt->default_attrib;
attrib.invers = !(attrib.invers); /* invert fg and bg */
- draw_char_at (vt, x, y, c->ch, attrib);
+ draw_char_at (vt, x, y, c->ch, attrib, c->width, c->combiningglyph);
- draw_char_at (vt, x, y, c->ch, c->attrib);
+ draw_char_at (vt, x, y, c->ch, c->attrib, c->width, c->combiningglyph);
for(y = 0; y < vt->height; y++) {
TextCell *c = vt->cells + y1 * vt->width;
for(x = 0; x < vt->width; x++) {
for(y = 0; y < vt->height; y++) {
TextCell *c = vt->cells + y1 * vt->width;
for(x = 0; x < vt->width; x++) {
- draw_char_at (vt, x, y, c->ch, c->attrib);
- c++;
+ draw_char_at (vt, x, y, c->ch, c->attrib, c->width, c->combiningglyph);
+ c += c->width;
}
if (++y1 == vt->total_height)
y1 = 0;
}
if (++y1 == vt->total_height)
y1 = 0;
for(j = 0; j < vt->width; j++) {
c->attrib = vt->default_attrib;
c->ch = ' ';
for(j = 0; j < vt->width; j++) {
c->attrib = vt->default_attrib;
c->ch = ' ';
+ c->width = 1;
+ c->combiningglyph = 0;
for(j = 0; j < vt->width; j++) {
c->attrib = vt->default_attrib;
c->ch = ' ';
for(j = 0; j < vt->width; j++) {
c->attrib = vt->default_attrib;
c->ch = ' ';
+ c->width = 1;
+ c->combiningglyph = 0;
int x;
for (x = 0; x < vt->width; x++) {
c->ch = ' ';
int x;
for (x = 0; x < vt->width; x++) {
c->ch = ' ';
+ c->width = 1;
+ c->combiningglyph = 0;
c->attrib = vt->default_attrib;
c++;
}
c->attrib = vt->default_attrib;
c++;
}
- }
-
- if (x >= vt->width) {
+ } else if (x >= vt->width) {
- }
-
- if (y >= vt->height) {
+ } else if (y >= vt->height) {
*dst = *src;
vncterm_update_xy (vt, x + c, vt->cy);
src->ch = ' ';
*dst = *src;
vncterm_update_xy (vt, x + c, vt->cy);
src->ch = ' ';
+ src->width = 1;
+ src->combiningglyph = 0;
src->attrib = vt->default_attrib;
vncterm_update_xy (vt, x, vt->cy);
}
src->attrib = vt->default_attrib;
vncterm_update_xy (vt, x, vt->cy);
}
*dst = *src;
vncterm_update_xy (vt, x + c, vt->cy);
src->ch = ' ';
*dst = *src;
vncterm_update_xy (vt, x + c, vt->cy);
src->ch = ' ';
+ src->width = 1;
+ src->combiningglyph = 0;
src->attrib = vt->cur_attrib;
vncterm_update_xy (vt, x, vt->cy);
}
src->attrib = vt->cur_attrib;
vncterm_update_xy (vt, x, vt->cy);
}
}
int y1 = (vt->y_base + vt->cy) % vt->total_height;
}
int y1 = (vt->y_base + vt->cy) % vt->total_height;
- TextCell *c = &vt->cells[y1*vt->width + vt->cx];
- c->attrib = vt->cur_attrib;
- c->ch = ch;
- vncterm_update_xy (vt, vt->cx, vt->cy);
- vt->cx++;
+ int width = wcwidth(ch);
+ if (width > 0) {
+ // normal/wide character
+ TextCell *c = &vt->cells[y1*vt->width + vt->cx];
+ c->attrib = vt->cur_attrib;
+ c->ch = ch;
+ c->width = width;
+ c->combiningglyph = 0;
+ vncterm_update_xy (vt, vt->cx, vt->cy);
+ vt->cx += width;
+ } else if (width == 0) {
+ // combiningglyph
+ TextCell *c = &vt->cells[y1*vt->width + vt->cx - 1];
+ c->attrib = vt->cur_attrib;
+ c->combiningglyph = ch;
+ vncterm_update_xy (vt, vt->cx - 1, vt->cy);
+ } else {
+ // non printable character, so we do not save them
+ }
int i;
char **cmdargv = NULL;
char *command = "/bin/bash"; // execute normal shell as default
int i;
char **cmdargv = NULL;
char *command = "/bin/bash"; // execute normal shell as default
+ int fontfd;
+ struct stat sb;
int pid;
int master;
char ptyname[1024];
int pid;
int master;
char ptyname[1024];
+ // mmap font file
+ fontfd = open(FONTFILE, O_RDONLY);
+ if (fontfd == -1) {
+ perror("Error opening Fontfile 'FONTFILE'");
+ exit (-1);
+ }
+ if (fstat(fontfd, &sb) == -1) {
+ perror("Stat on 'FONTFILE' failed");
+ exit (-1);
+ }
+ fontdata = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fontfd, 0);
+ if (fontdata == MAP_FAILED) {
+ perror("Could not mmap 'FONTFILE'");
+ exit (-1);
+ }
+
+ close(fontfd);
vncTerm *vt = create_vncterm (argc, argv, screen_width, screen_height);
setlocale(LC_ALL, ""); // set from environment
vncTerm *vt = create_vncterm (argc, argv, screen_width, screen_height);
setlocale(LC_ALL, ""); // set from environment
+ rfbScreenCleanup(vt->screen);
+
kill (pid, 9);
int status;
waitpid(pid, &status, 0);
kill (pid, 9);
int status;
waitpid(pid, &status, 0);
+ munmap(fontdata, sb.st_size);
typedef struct TextCell {
unicode ch;
typedef struct TextCell {
unicode ch;
+ unicode combiningglyph;
+ short width;
TextAttributes attrib;
} TextCell;
TextAttributes attrib;
} TextCell;