mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 17:01:15 +02:00
yaft: remove unused files
Conflicts: src/gui/widget/yaft/tools/bdf.h Signed-off-by: Thilo Graf <dbt@novatux.de>
This commit is contained in:
@@ -1,139 +0,0 @@
|
||||
## 2012-06-19
|
||||
- version 0.1.0
|
||||
- initial release
|
||||
|
||||
## 2012-06-19
|
||||
- version 0.1.1
|
||||
- bug fix
|
||||
|
||||
## 2012-06-20
|
||||
- version 0.1.2
|
||||
- bug fix
|
||||
|
||||
## 2012-06-20
|
||||
- version 0.1.3
|
||||
- bug fix
|
||||
|
||||
## 2012-06-21
|
||||
- version 0.1.4
|
||||
- add eat_newline_glitch (xel)
|
||||
- remove auto_right_margin (bw)
|
||||
- remove OSC 4 (ccc, initc)
|
||||
|
||||
## 2012-06-24
|
||||
- version 0.1.5
|
||||
- change fonts format
|
||||
- fix glyph drawing
|
||||
- change effects of BOLD and REVERSE
|
||||
|
||||
## 2012-06-29
|
||||
- version 0.1.6
|
||||
- support more than one font
|
||||
- support glyph alias
|
||||
|
||||
## 2012-10-06
|
||||
- version 0.1.7
|
||||
- support following framebuffer types:
|
||||
- 15/16/24/32bpp true color (and maybe direct color)
|
||||
- 8bpp pseudo color
|
||||
|
||||
## 2012-10-17
|
||||
- version 0.1.8
|
||||
- add some opitons
|
||||
- yaft reads environment value, YAFT
|
||||
- wall: display wallpaper
|
||||
- w=N: set terminal width (pixel)
|
||||
- h=N: set terminal height (pixel)
|
||||
- x=N: set x offset
|
||||
- y=N: set y offset
|
||||
|
||||
~~~
|
||||
$ export YAFT="wall w=640 h=384 x=32 y=32"; yaft
|
||||
~~~
|
||||
|
||||
## 2012-10-18
|
||||
- version 0.1.9
|
||||
- add some codes related to virtual console
|
||||
- remove all optios without "YAFT=wall"
|
||||
|
||||
## 2012-11-09
|
||||
- version 0.2.0
|
||||
- support BDF
|
||||
|
||||
~~~
|
||||
$ ./mkfont alias-file your/favorite/bdf > glyph.h
|
||||
$ make yaft
|
||||
~~~
|
||||
|
||||
## 2012-11-30
|
||||
- version 0.2.1
|
||||
- bug fix
|
||||
- single CSI u (not following CSI s) causes Segmentation fault (reported by saitoha ([@kefir_]))
|
||||
|
||||
[@kefir_]: http://saitoha.github.com/
|
||||
|
||||
## 2012-12-02
|
||||
- version 0.2.2
|
||||
- improve UTF-8 parser (valid for [UTF-8 decoder capability and stress test])
|
||||
- bug fix
|
||||
- not working glyph substitution
|
||||
|
||||
[UTF-8 decoder capability and stress test]: http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
|
||||
|
||||
## 2012-12-19
|
||||
- version 0.2.3
|
||||
- bug fix
|
||||
- wrong behavior of bce (ED, EL, DL, IL, ICH, DCH, ECH) (reported by IWAMOTO Kouichi ([@ttdoda]))
|
||||
|
||||
[@ttdoda]: http://doda.teraterm.org/whoami.xhtm
|
||||
|
||||
## 2014-03-07
|
||||
- version 0.2.4
|
||||
- add some parameters in conf.h
|
||||
- ROTATE: NORMAL or CLOCKWISE or COUNTER_CLOCKWISE or UPSIDE_DOWN
|
||||
- LAZY_DRAW (reduce drawing)
|
||||
- BACKGROUND_DRAW (after vt switch, continue drawing)
|
||||
|
||||
## 2014-03-24
|
||||
- version 0.2.5
|
||||
- remove ROTATE, LAZY_DRAW, BACKGROUND_DRAW options
|
||||
- add some environment options
|
||||
- rotate: clockwise (cw), counter_clockwise (ccw), upside_down (ud)
|
||||
- background drawing: wallpaper (wall)
|
||||
ex) $ YAFT="wall cw ccw ud" yaft
|
||||
- framebuffer device:
|
||||
ex) $ FRAMEBUFFER="/dev/fb1" yaft
|
||||
- add OSC4/OSC104/OSC8900 (glyph width report)
|
||||
(ref: http://uobikiemukot.github.io/yaft/glyph_width_report.html)
|
||||
|
||||
## 2014-05-16
|
||||
- version 0.2.6
|
||||
- remove rotate option
|
||||
- support glyph width report rev.3
|
||||
(ref: http://uobikiemukot.github.io/yaft/glyph_width_report.html)
|
||||
- support DRCS/DRCSMMv1
|
||||
- bug fix
|
||||
- never refresh cmap at vt switch (8bpp mode)
|
||||
|
||||
## 2014-05-18
|
||||
- version 0.2.7
|
||||
- support xim (yaftx)
|
||||
|
||||
## 2014-08-27
|
||||
- version 0.2.8
|
||||
- support sixel
|
||||
- support copy/paste (yaftx)
|
||||
- support NetBSD/OpenBSD wscons
|
||||
- refer SHELL environment variable
|
||||
- remove WALLPAPER option (use YAFT="wall" environment variable)
|
||||
- add man page
|
||||
|
||||
## 2015-07-26
|
||||
- version 0.2.8
|
||||
- rewrite framebuffer code
|
||||
- support direct color
|
||||
- add some new options (conf.h)
|
||||
VT_CONTROL : don't handle vt-switching (vt-switching only works in linux)
|
||||
FORCE_TEXT_MODE: need this option for switching from X to yaft
|
||||
- various bug fixes
|
||||
- mkfont_bdf was broken (not affect SUBSTITUTE_WIDE/REPLACEMENT_CHAR)
|
@@ -1,216 +0,0 @@
|
||||
2012-06-19 haru
|
||||
* version 0.1.0
|
||||
* 試験的に公開
|
||||
|
||||
2012-06-19 haru
|
||||
* version 0.1.1
|
||||
* 細かなバグ修正
|
||||
* UCS_CHARSの値が要素数+1になってなかったのを修正 (common.h)
|
||||
* esc_func, csi_func, osc_funcも同様に配列の要素数が1足りなかったのを修正 (common.h)
|
||||
* parse_esc()の実体参照(*argc)がargcになってたのを修正 (parse.h)
|
||||
* dumpするときにstdoutのバッファリングを無効にするようにした (yaft.c)
|
||||
* delete_line(), erase_line()でスクロールが発生するときにDECSTBMの設定が反映されてなかったのを修正 (function.h)
|
||||
|
||||
2012-06-20 haru
|
||||
* version 0.1.2
|
||||
* 設定やフォントに不備があった場合に回避できないか頑張ってみることにした
|
||||
* 端末のサイズ(TERM_WIDTH/TERM_HEIGHT)が不正な場合にはフルスクリーンで起動する (yaft.c, terminal.h)
|
||||
* DEFAULT_CHARが見つからない場合にはSPACEを流用してみる (load.h)
|
||||
* コメントを追加 (common.h)
|
||||
* terminfoの別名を定義した (info/yaft.info)
|
||||
|
||||
2012-06-20 haru
|
||||
* version 0.1.3
|
||||
* 背景画像の表示方法をfbtermと同等のものに変更した (load.h, conf.h)
|
||||
* framebufferの書き込みアドレスがおかしかったのを修正した (framebuffer.h)
|
||||
* writeのエラー処理を真面目にやるようにした (util.h)
|
||||
* 色を定義する箇所が重複していたのをまとめた (color.h)
|
||||
* 端末のサイズとしてcell_sizeよりも小さなサイズは指定できないようにした (terminal.h)
|
||||
* 上記の修正に伴って色々変更.DEFAULT_CHARはSPACEにした (common.h)
|
||||
|
||||
2012-06-21 haru
|
||||
* version 0.1.4
|
||||
* indent -kr -ut -ts4 な感じのスタイルで書くことにした
|
||||
* gcc -std=c99 -pedantic -Wall -Os で通るように色々書き換えた
|
||||
* eat_newline_glitch(xel)を実装した (terminal.h)
|
||||
* auto_right_margin(bw)を廃止した (terminal.h, function.h)
|
||||
* OSCを廃止した (parse.h, function.h)
|
||||
* 上記の変更に伴ってterminfoを更新 (info/yaft.src)
|
||||
|
||||
2012-06-24 haru
|
||||
* version 0.1.5
|
||||
* スタイルはたぶん元に戻した
|
||||
* mplus fontをsampleとして追加
|
||||
* フォントの形式がおかしかったのでBDFと完全に互換なものに直した (load.h, framebuffer.h)
|
||||
* 8x16dotのフォント以外では正常に描画できていなかったのを修正した (load.h, framebuffer.h)
|
||||
* BOLD/REVERSEの処理方法を変更した (terminal.h, framebuffer.h)
|
||||
* 色の参照方法を変更した (function.h, framebuffer.h, conf.h)
|
||||
* その他色々?
|
||||
|
||||
2012-06-29 haru
|
||||
* version 0.1.6
|
||||
* フォントを複数指定できるようにした(load.h, terminal.h, conf.h)
|
||||
(一部のグリフしかない場合に使用するメモリが減った)
|
||||
* グリフの代用を指定できるようにした(load.h, terminal.h, conf.h)
|
||||
* その他ちょっとした修正等
|
||||
|
||||
2012-10-06 haru
|
||||
* version 0.1.7
|
||||
* 以下のframebuffer環境に対応した (framebuffer.h)
|
||||
15/16/24/32bpp True Color(Direct Colorにもたぶん対応)
|
||||
8bpp Pseudo Color
|
||||
|
||||
2012-10-17 haru
|
||||
* version 0.1.8
|
||||
* いくつかのoptionを追加 (yaft.c)
|
||||
例) $ export YAFT="wall w=640 h=384 x=32 y=32"; yaft
|
||||
wall: display wallpaper
|
||||
w=N: set terminal width (pixel)
|
||||
h=N: set terminal height (pixel)
|
||||
x=N: set x offset
|
||||
y=N: set y offset
|
||||
|
||||
2012-10-18 haru
|
||||
* version 0.1.9
|
||||
* 仮想コンソールの切り替え時にyaftの停止・再描画を行う用にした (yaft.c)
|
||||
* 壁紙を表示するときの環境変数の設定の仕方がちょっと変わった (yaft.c)
|
||||
* 壁紙以外のoptionを廃止した
|
||||
* 他にもたぶん色々
|
||||
|
||||
2012-11-09 haru
|
||||
* version 0.2.0
|
||||
* 独自フォントを廃止してBDFを使うようにした
|
||||
ex)
|
||||
$ ./mkfont alias-file your/favorite/bdf > glyph.h
|
||||
$ make yaft
|
||||
|
||||
2012-11-30
|
||||
- version 0.2.1
|
||||
- bug fix
|
||||
- single CSI u (not following CSI s) causes Segmentation fault (reported by saitoha ([@kefir_]))
|
||||
|
||||
[@kefir_]: http://saitoha.github.com/
|
||||
|
||||
2012-12-02
|
||||
- version 0.2.2
|
||||
- improved UTF-8 parser (valid for [UTF-8 decoder capability and stress test])
|
||||
- bug fix
|
||||
- not working glyph substitution
|
||||
|
||||
[UTF-8 decoder capability and stress test]: http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
|
||||
|
||||
2012-12-19
|
||||
- version 0.2.3
|
||||
- bug fix
|
||||
- wrong behavior of bce (ED, EL, DL, IL, ICH, DCH, ECH) (reported by IWAMOTO Kouichi ([@ttdoda]))
|
||||
|
||||
[@ttdoda]: http://doda.teraterm.org/whoami.xhtm
|
||||
|
||||
2014-03-07 haru
|
||||
* version 0.2.4
|
||||
* conf.hにいくつかの設定を追加
|
||||
* ROTATE = NORMAL or CLOCKWISE or COUNTER_CLOCKWISE or UPSIDE_DOWN
|
||||
* LAZY_DRAW(データ量が多いときに描画を抑制する)を追加
|
||||
* BACKGROUND_DRAW(VT切り替え後も描画を続ける)を追加
|
||||
* struct terminalのoffsetを削除
|
||||
|
||||
2014-03-24
|
||||
* version 0.2.5
|
||||
* BACKGROUND_DRAW, ROTATEの設定をconf.hでなく環境変数YAFTでするようにした
|
||||
(実行時に変更する必要がないと思われるものは相変わらずconf.hで指定)
|
||||
* 環境変数YAFTで有効なオプション
|
||||
wall: 背景画像を有効にする
|
||||
background or bg: activeになっていないVTでも描画を続ける(2画面用)
|
||||
clockwise or cw: 90度描画を回転
|
||||
counter_clockwise or ccw: 270度描画を回転
|
||||
upside_down or ud: 180度描画を回転
|
||||
ex) YAFT="wall cw bg" yaft
|
||||
* 環境変数FRAMEBUFFER
|
||||
framebuffer deviceを指定する
|
||||
ex) FRAMEBUFFER="/dev/fb0" yaft
|
||||
* 幾つかのOSCを実装した
|
||||
OSC 4: color paletteの変更
|
||||
色の設定(rgbの指定は1-4桁)
|
||||
OSC 4 ; c ; rgb:rr/gg/bb ST
|
||||
OSC 4 ; c ; #rrggbb ST
|
||||
c番目の色設定の応答
|
||||
request
|
||||
OSC 4 ; c ; ? ST
|
||||
response
|
||||
OSC 4 ; c ; rgb:rr/gg/bb ST
|
||||
OSC 104: color paletteの初期化
|
||||
c番目の色を初期化
|
||||
OSC 104 ; c ST
|
||||
全ての色を初期化
|
||||
OSC 104 ST
|
||||
OSC 8900: glyph width report
|
||||
requestの際にwidth, from, toの指定を強制するようにした
|
||||
* request *
|
||||
OSC 8900 ; Ps ; ? : Pw : Pf : Pt ST
|
||||
Ps: reserved
|
||||
Pw: width (0 or 1 or 2)
|
||||
Pf: beginning of unicode code point
|
||||
Pt: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
* answer *
|
||||
OSC 8900 ; Ps ; Pt ; Pf : Pt ; Pf : Pt ; ... ST
|
||||
Ps: responce code
|
||||
0: ok (default)
|
||||
1: recognized but not supported
|
||||
2: not recognized
|
||||
Pt: reserved (maybe East Asian Width Version)
|
||||
<!-- Pw: width (0 or 1 or 2) depricated -->
|
||||
Pf: beginning of unicode code point
|
||||
Pt: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
(ref)
|
||||
http://uobikiemukot.github.io/yaft/glyph_width_report.html
|
||||
https://gist.github.com/saitoha/8767268
|
||||
* コードを色々整理した
|
||||
|
||||
2014-05-16
|
||||
* version 0.2.6
|
||||
* rorateオプションを消した
|
||||
* glyph.hの書式を変更 (フォントによってはyaftのバイナリがかなり小さく)
|
||||
* それに伴いtools/以下のソースを書き換え
|
||||
* glyph width report rev.3 に対応 (ref: http://uobikiemukot.github.io/yaft/glyph_width_report.html)
|
||||
* DRCSの領域(Unicode Private Area)の応答にはまだ未対応
|
||||
* DRCS/DRCSMMv1に試験的に対応 (無視しているパラメータが多いので注意)
|
||||
* yaftにはSCS(Select Character Set)が実装されていないので常にDRCSMMv1が有効
|
||||
* OSC/DCSはソースファイルを分離 (osc.h, dcs.h)
|
||||
* 8bpp時にVT switchが起きてもcmapを復元していなかったのを修正
|
||||
* その他にも色々コードを整理
|
||||
|
||||
2014-05-18
|
||||
* version 0.2.7
|
||||
* 主にX版(yaftx)の修正
|
||||
* ximが使えるようにした (scimのみで動作確認)
|
||||
* 描画の処理をfb版に合わせて修正
|
||||
* resizeの度にmalloc/freeをしていたのを止めた
|
||||
* ioctl(TIOCSWINSZ)の位置おかしかったのを修正
|
||||
* perror()の前にerrnoをちゃんと初期化するようにした (util.h)
|
||||
* forkpty(), openpty()を書き直した (util.h)
|
||||
* X版でMod1Mask(Alt)の修飾キーが効かなかったのを修正 (thanks to @H_Kobo)
|
||||
* Alt + [Up/Down/Left/Right]等の特殊キーに対応
|
||||
* XIMのinput styleの選択方法がバグってたのを修正
|
||||
* eopenpty()でcompilerのwarningが出る箇所を修正 (util.h)
|
||||
|
||||
2014-08-27
|
||||
* version 0.2.8
|
||||
* sixelのサポートを追加
|
||||
* マウスによるコピー/ペイストに対応 (yaftx)
|
||||
* NetBSD/OpenBSDのサポート
|
||||
* 環境変数SHELLを見るように (conf.hのshell_cmdよりも優先)
|
||||
* WALLPAPERオプションをconf.hから削除 (代わりにYAFT="wall"という環境変数を見るように)
|
||||
* man pageを作成
|
||||
|
||||
2015-07-26
|
||||
* version 0.2.8
|
||||
* フレームバッファ関連のコードを書き直した
|
||||
* direct colorをサポート (古いradeonのグラボ等で用いられる)
|
||||
* 幾つかのオプションを追加
|
||||
VT_CONTROL : vt switchingの処理を行わない (linux以外ではたぶん処理しなくても良い)
|
||||
FORCE_TEXT_MODE: KD_GRAPHICSへ変更しない (linux consoleの描画と競合するるが,Xとyaftを切り替える場合には必要)
|
||||
* 色々なバグ修正
|
||||
* mkfont_bdfによるフォント生成の不具合等
|
||||
* コードのrefine
|
@@ -1,135 +0,0 @@
|
||||
# yaft (yet another framebuffer terminal)
|
||||
|
||||
## test environment
|
||||
|
||||
using qemu (i386, vga cirrus)
|
||||
|
||||
- FreeBSD 10.1
|
||||
- OpenBSD 5.7
|
||||
- NetBSD 6.1.5
|
||||
|
||||
## FreeBSD
|
||||
|
||||
### kernel rebuild
|
||||
|
||||
edit /usr/src/sys/i386/conf/GENERIC
|
||||
|
||||
~~~
|
||||
options VESA
|
||||
options SC_PIXEL_MODE
|
||||
~~~
|
||||
|
||||
build
|
||||
|
||||
~~~
|
||||
# cd /usr/src
|
||||
# make buildkernel
|
||||
# make installkernel
|
||||
~~~
|
||||
|
||||
### module load (no kernel rebuild)
|
||||
|
||||
~~~
|
||||
# kldload vesa
|
||||
# echo "vesa_load=\"YES\"" >> /boot/loader.conf
|
||||
~~~
|
||||
|
||||
### vesa mode
|
||||
|
||||
check available mode
|
||||
|
||||
~~~
|
||||
# vidcontrol -i mode
|
||||
~~~
|
||||
|
||||
change mode
|
||||
|
||||
~~~
|
||||
# vidcontrol MODE_XXX
|
||||
# echo "allscreens_flags=\"MODE_XXX\"" >> /etc/rc.conf
|
||||
~~~
|
||||
|
||||
### keyrepeat
|
||||
|
||||
~~~
|
||||
# kbdcontrol -r fast
|
||||
~~~
|
||||
|
||||
### write-combine
|
||||
|
||||
~~~
|
||||
# memcontrol set -b 0xe0000000 -l 0x10000000 -o SVGA write-combine
|
||||
~~~
|
||||
|
||||
## NetBSD
|
||||
|
||||
### vesa mode
|
||||
|
||||
check available mode
|
||||
|
||||
~~~
|
||||
(boot prompt)
|
||||
> vesa list
|
||||
~~~
|
||||
|
||||
edit /boot.cfg
|
||||
|
||||
~~~
|
||||
menu=Boot normally:rndseed /var/db/entropy-file;vesa 1024x768x32;boot netbsd
|
||||
~~~
|
||||
|
||||
### key repeat
|
||||
|
||||
~~~
|
||||
# wsconsctl -w repeat.del1=200 repeat.deln=50
|
||||
~~~
|
||||
|
||||
~~~
|
||||
# echo "setvar repeat.del1=200" >> /etc/wscons.conf
|
||||
# echo "setvar repeat.deln=50" >> /etc/wscons.conf
|
||||
~~~
|
||||
|
||||
## OpenBSD
|
||||
|
||||
### kernel
|
||||
|
||||
- patch http://mlterm.sf.net/openbsd-5.3-fixvesa.patch
|
||||
|
||||
edit /usr/src/sys/arch/i386/conf/GENERIC
|
||||
|
||||
~~~
|
||||
vesabios0 at mainbus?
|
||||
option VESAFB
|
||||
~~~
|
||||
|
||||
build
|
||||
|
||||
~~~
|
||||
# cd /usr/src/sys/arch/i386/compile/GENERIC
|
||||
# make clean && make depend && make
|
||||
# make install
|
||||
# reboot
|
||||
~~~
|
||||
|
||||
### change vesa mode
|
||||
|
||||
edit yaft/fb/openbsd.h
|
||||
|
||||
~~~
|
||||
enum {
|
||||
FB_WIDTH = 640,
|
||||
FB_HEIGHT = 480,
|
||||
FB_DEPTH = 8,
|
||||
};
|
||||
~~~
|
||||
|
||||
### key repeat
|
||||
|
||||
~~~
|
||||
# wsconsctl -w repeat.del1=200 repeat.deln=50
|
||||
~~~
|
||||
|
||||
~~~
|
||||
# echo "setvar repeat.del1=200" >> /etc/wscons.conf
|
||||
# echo "setvar repeat.deln=50" >> /etc/wscons.conf
|
||||
~~~
|
@@ -1,108 +0,0 @@
|
||||
# yaft (yet another framebuffer terminal)
|
||||
|
||||
Last update: Mon Jul 27 10:36:02 JST 2015
|
||||
|
||||
## description
|
||||
|
||||
Yet Another Framebuffer Terminal (aka "yaft") is simple terminal emulator for minimalist.
|
||||
|
||||
Features:
|
||||
|
||||
+ various framebuffer types (8/15/16/24/32bpp)
|
||||
+ compatible with vt102 and Linux console ([detail](http://uobikiemukot.github.io/yaft/escape.html))
|
||||
+ UTF-8 encoding and UCS2 gylphs
|
||||
+ 256 colors (same as xterm)
|
||||
+ wallpaper
|
||||
+ DRCS (DECDLD/DRCSMMv1) (experimental)
|
||||
+ sixel (experimental)
|
||||
|
||||
There are Several ports:
|
||||
|
||||
- yaft for framebuffer console
|
||||
- Linux console
|
||||
- FreeBSD console
|
||||
- NetBSD/OpenBSD wscons (experimental)
|
||||
- yaftx for X Window System
|
||||
- [yaft-android](https://github.com/uobikiemukot/yaft-android) for Android
|
||||
|
||||
## download
|
||||
|
||||
- [yaft-0.2.9.tar.gz](https://github.com/uobikiemukot/yaft/archive/v0.2.9.tar.gz)
|
||||
|
||||
## configuration
|
||||
|
||||
If you want to change configuration, rewrite "conf.h".
|
||||
|
||||
## environment variables
|
||||
|
||||
- FRAMEBUFFER=/dev/fb0: specify farmebuffer device
|
||||
- SHELL=/bin/bash: specify shell command
|
||||
- YAFT="wall": use current background as wallpaper (need [idump](https://github.com/uobikiemukot/idump) or fbv)
|
||||
|
||||
~~~
|
||||
$ idump /path/to/wallpaper.png; tput civis; YAFT="wall" FRAMEBUFFER="/dev/fb1" SHELL="/bin/csh" yaft
|
||||
~~~
|
||||
|
||||
## how to use your favorite fonts
|
||||
|
||||
You can use tools/mkfont_bdf to create "glyph.h".
|
||||
|
||||
usage: tools/mkfont_bdf ALIAS_FILE BDF1 BDF2 BDF3 ... > glyph.h
|
||||
|
||||
- ALIAS_FILE: glyph substitution rule file (see table/alias)
|
||||
- BDF1, BDF2, BDF3...: bdf files
|
||||
+ yaft supports only "monospace" bdf font
|
||||
+ you can specify mulitiple bdf fonts (but these fonts MUST be the same size)
|
||||
+ If there is more than one glyph of the same codepoint, the glyph included in the FIRST bdf file is choosed
|
||||
|
||||
~~~
|
||||
$ ./mkfont_bdf table/your_alias your/favorite/fonts.bdf > glyph.h
|
||||
~~~
|
||||
|
||||
## build and install
|
||||
|
||||
*BSD users should check README.bsd
|
||||
|
||||
~~~
|
||||
$ export LANG=en_US.UTF-8 # yaft uses libc's wcwidth for calculating glyph width
|
||||
$ make
|
||||
# make install
|
||||
or
|
||||
$ make yaftx
|
||||
# make installx
|
||||
~~~
|
||||
|
||||
## how to use your favorite fonts
|
||||
|
||||
You can use tools/mkfont_bdf to create "glyph.h".
|
||||
|
||||
usage: tools/mkfont_bdf ALIAS_FILE BDF1 BDF2 BDF3 ... > glyph.h
|
||||
|
||||
- ALIAS_FILE: glyph substitution rule file (see table/alias)
|
||||
- BDF1, BDF2, BDF3...: bdf files
|
||||
+ yaft supports only "monospace" bdf font
|
||||
+ you can specify mulitiple bdf fonts (but these fonts MUST be the same size)
|
||||
+ If there is more than one glyph of the same codepoint, the glyph included in the FIRST bdf file is choosed
|
||||
|
||||
~~~
|
||||
$ ./mkfont_bdf table/your_alias your/favorite/fonts.bdf > glyph.h
|
||||
~~~
|
||||
|
||||
Or try glyph_builder.sh (bash script for creating yaft's glyph.h)
|
||||
|
||||
- supported fonts: mplus, efont, milkjf, unifont, dina, terminus, profont, tamsyn
|
||||
|
||||
## screenshot
|
||||
|
||||

|
||||
|
||||
## license
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 haru (uobikiemukot at gmail dot com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,50 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* conf.h: define custom variables */
|
||||
|
||||
/* color: index number of color_palette[] (see color.h) */
|
||||
enum {
|
||||
DEFAULT_FG = 7,
|
||||
DEFAULT_BG = 0,
|
||||
ACTIVE_CURSOR_COLOR = 2,
|
||||
PASSIVE_CURSOR_COLOR = 1,
|
||||
};
|
||||
|
||||
/* misc */
|
||||
enum {
|
||||
VERBOSE = false, /* write dump of input to stdout, debug message to stderr */
|
||||
TABSTOP = 8, /* hardware tabstop */
|
||||
LAZY_DRAW = true, /* don't draw when input data size is larger than BUFSIZE */
|
||||
BACKGROUND_DRAW = false, /* always draw even if vt is not active */
|
||||
VT_CONTROL = true, /* handle vt switching */
|
||||
FORCE_TEXT_MODE = false, /* force KD_TEXT mode (not use KD_GRAPHICS mode) */
|
||||
SUBSTITUTE_HALF = 0x0020, /* used for missing glyph(single width): U+0020 (SPACE) */
|
||||
SUBSTITUTE_WIDE = 0x3000, /* used for missing glyph(double width): U+3000 (IDEOGRAPHIC SPACE) */
|
||||
REPLACEMENT_CHAR = 0x003F, /* used for malformed UTF-8 sequence : U+003F (QUESTION MARK) */
|
||||
};
|
||||
|
||||
/* TERM value */
|
||||
const char *term_name = "linux";
|
||||
|
||||
#if 0
|
||||
/* framubuffer device */
|
||||
#if defined(__linux__)
|
||||
const char *fb_path = "/dev/fb0";
|
||||
#elif defined(__FreeBSD__)
|
||||
const char *fb_path = "/dev/ttyv0";
|
||||
#elif defined(__NetBSD__)
|
||||
const char *fb_path = "/dev/ttyE0";
|
||||
#elif defined(__OpenBSD__)
|
||||
const char *fb_path = "/dev/ttyC0";
|
||||
#elif defined(__ANDROID__)
|
||||
const char *fb_path = "/dev/graphics/fb0";
|
||||
#endif
|
||||
|
||||
/* shell: refer SHELL environment variable at first */
|
||||
#if defined(__linux__) || defined(__MACH__)
|
||||
const char *shell_cmd = "/bin/bash";
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
const char *shell_cmd = "/bin/csh";
|
||||
#elif defined(__ANDROID__)
|
||||
const char *shell_cmd = "/system/bin/sh";
|
||||
#endif
|
||||
#endif
|
@@ -1,390 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* function for csi sequence */
|
||||
void insert_blank(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
for (i = term->cols - 1; term->cursor.x <= i; i--) {
|
||||
if (term->cursor.x <= (i - num))
|
||||
copy_cell(term, term->cursor.y, i, term->cursor.y, i - num);
|
||||
else
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
}
|
||||
}
|
||||
|
||||
void curs_up(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, -num, 0);
|
||||
}
|
||||
|
||||
void curs_down(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, num, 0);
|
||||
}
|
||||
|
||||
void curs_forward(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, 0, num);
|
||||
}
|
||||
|
||||
void curs_back(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, 0, -num);
|
||||
}
|
||||
|
||||
void curs_nl(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, num, 0);
|
||||
cr(term);
|
||||
}
|
||||
|
||||
void curs_pl(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
move_cursor(term, -num, 0);
|
||||
cr(term);
|
||||
}
|
||||
|
||||
void curs_col(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = (parm->argc <= 0) ? 0: dec2num(parm->argv[parm->argc - 1]) - 1;
|
||||
set_cursor(term, term->cursor.y, num);
|
||||
}
|
||||
|
||||
void curs_pos(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int line, col;
|
||||
|
||||
if (parm->argc <= 0) {
|
||||
line = col = 0;
|
||||
} else if (parm->argc == 2) {
|
||||
line = dec2num(parm->argv[0]) - 1;
|
||||
col = dec2num(parm->argv[1]) - 1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (line < 0)
|
||||
line = 0;
|
||||
if (col < 0)
|
||||
col = 0;
|
||||
|
||||
set_cursor(term, line, col);
|
||||
}
|
||||
|
||||
void curs_line(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num;
|
||||
|
||||
num = (parm->argc <= 0) ? 0: dec2num(parm->argv[parm->argc - 1]) - 1;
|
||||
set_cursor(term, num, term->cursor.x);
|
||||
}
|
||||
|
||||
void erase_display(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, j, mode;
|
||||
|
||||
mode = (parm->argc <= 0) ? 0: dec2num(parm->argv[parm->argc - 1]);
|
||||
|
||||
if (mode < 0 || 2 < mode)
|
||||
return;
|
||||
|
||||
if (mode == 0) {
|
||||
for (i = term->cursor.y; i < term->lines; i++)
|
||||
for (j = 0; j < term->cols; j++)
|
||||
if (i > term->cursor.y || (i == term->cursor.y && j >= term->cursor.x))
|
||||
erase_cell(term, i, j);
|
||||
} else if (mode == 1) {
|
||||
for (i = 0; i <= term->cursor.y; i++)
|
||||
for (j = 0; j < term->cols; j++)
|
||||
if (i < term->cursor.y || (i == term->cursor.y && j <= term->cursor.x))
|
||||
erase_cell(term, i, j);
|
||||
} else if (mode == 2) {
|
||||
for (i = 0; i < term->lines; i++)
|
||||
for (j = 0; j < term->cols; j++)
|
||||
erase_cell(term, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void erase_line(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, mode;
|
||||
|
||||
mode = (parm->argc <= 0) ? 0: dec2num(parm->argv[parm->argc - 1]);
|
||||
|
||||
if (mode < 0 || 2 < mode)
|
||||
return;
|
||||
|
||||
if (mode == 0) {
|
||||
for (i = term->cursor.x; i < term->cols; i++)
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
} else if (mode == 1) {
|
||||
for (i = 0; i <= term->cursor.x; i++)
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
} else if (mode == 2) {
|
||||
for (i = 0; i < term->cols; i++)
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
}
|
||||
}
|
||||
|
||||
void insert_line(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (term->mode & MODE_ORIGIN) {
|
||||
if (term->cursor.y < term->scroll.top
|
||||
|| term->cursor.y > term->scroll.bottom)
|
||||
return;
|
||||
}
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
scroll(term, term->cursor.y, term->scroll.bottom, -num);
|
||||
}
|
||||
|
||||
void delete_line(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int num = sum(parm);
|
||||
|
||||
if (term->mode & MODE_ORIGIN) {
|
||||
if (term->cursor.y < term->scroll.top
|
||||
|| term->cursor.y > term->scroll.bottom)
|
||||
return;
|
||||
}
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
scroll(term, term->cursor.y, term->scroll.bottom, num);
|
||||
}
|
||||
|
||||
void delete_char(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
for (i = term->cursor.x; i < term->cols; i++) {
|
||||
if ((i + num) < term->cols)
|
||||
copy_cell(term, term->cursor.y, i, term->cursor.y, i + num);
|
||||
else
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
}
|
||||
}
|
||||
|
||||
void erase_char(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, num = sum(parm);
|
||||
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
else if (num + term->cursor.x > term->cols)
|
||||
num = term->cols - term->cursor.x;
|
||||
|
||||
for (i = term->cursor.x; i < term->cursor.x + num; i++)
|
||||
erase_cell(term, term->cursor.y, i);
|
||||
}
|
||||
|
||||
void set_attr(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, num;
|
||||
|
||||
if (parm->argc <= 0) {
|
||||
term->attribute = ATTR_RESET;
|
||||
term->color_pair.fg = DEFAULT_FG;
|
||||
term->color_pair.bg = DEFAULT_BG;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < parm->argc; i++) {
|
||||
num = dec2num(parm->argv[i]);
|
||||
|
||||
if (num == 0) { /* reset all attribute and color */
|
||||
term->attribute = ATTR_RESET;
|
||||
term->color_pair.fg = DEFAULT_FG;
|
||||
term->color_pair.bg = DEFAULT_BG;
|
||||
} else if (1 <= num && num <= 7) { /* set attribute */
|
||||
term->attribute |= attr_mask[num];
|
||||
} else if (21 <= num && num <= 27) { /* reset attribute */
|
||||
term->attribute &= ~attr_mask[num - 20];
|
||||
} else if (30 <= num && num <= 37) { /* set foreground */
|
||||
term->color_pair.fg = (num - 30);
|
||||
} else if (num == 38) { /* set 256 color to foreground */
|
||||
if ((i + 2) < parm->argc && dec2num(parm->argv[i + 1]) == 5) {
|
||||
term->color_pair.fg = dec2num(parm->argv[i + 2]);
|
||||
i += 2;
|
||||
}
|
||||
} else if (num == 39) { /* reset foreground */
|
||||
term->color_pair.fg = DEFAULT_FG;
|
||||
} else if (40 <= num && num <= 47) { /* set background */
|
||||
term->color_pair.bg = (num - 40);
|
||||
} else if (num == 48) { /* set 256 color to background */
|
||||
if ((i + 2) < parm->argc && dec2num(parm->argv[i + 1]) == 5) {
|
||||
term->color_pair.bg = dec2num(parm->argv[i + 2]);
|
||||
i += 2;
|
||||
}
|
||||
} else if (num == 49) { /* reset background */
|
||||
term->color_pair.bg = DEFAULT_BG;
|
||||
} else if (90 <= num && num <= 97) { /* set bright foreground */
|
||||
term->color_pair.fg = (num - 90) + BRIGHT_INC;
|
||||
} else if (100 <= num && num <= 107) { /* set bright background */
|
||||
term->color_pair.bg = (num - 100) + BRIGHT_INC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void status_report(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, num;
|
||||
char buf[BUFSIZE];
|
||||
|
||||
for (i = 0; i < parm->argc; i++) {
|
||||
num = dec2num(parm->argv[i]);
|
||||
if (num == 5) { /* terminal response: ready */
|
||||
ewrite(term->fd, "\033[0n", 4);
|
||||
} else if (num == 6) { /* cursor position report */
|
||||
snprintf(buf, BUFSIZE, "\033[%d;%dR", term->cursor.y + 1, term->cursor.x + 1);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
} else if (num == 15) { /* terminal response: printer not connected */
|
||||
ewrite(term->fd, "\033[?13n", 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void device_attribute(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
/* TODO: refer VT525 DA */
|
||||
(void) parm;
|
||||
ewrite(term->fd, "\033[?6c", 5); /* "I am a VT102" */
|
||||
}
|
||||
|
||||
void set_mode(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, mode;
|
||||
|
||||
for (i = 0; i < parm->argc; i++) {
|
||||
mode = dec2num(parm->argv[i]);
|
||||
if (*(term->esc.buf + 1) != '?')
|
||||
continue; /* not supported */
|
||||
|
||||
if (mode == 6) { /* private mode */
|
||||
term->mode |= MODE_ORIGIN;
|
||||
set_cursor(term, 0, 0);
|
||||
} else if (mode == 7) {
|
||||
term->mode |= MODE_AMRIGHT;
|
||||
} else if (mode == 25) {
|
||||
term->mode |= MODE_CURSOR;
|
||||
} else if (mode == 8901) {
|
||||
term->mode |= MODE_VWBS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void reset_mode(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, mode;
|
||||
|
||||
for (i = 0; i < parm->argc; i++) {
|
||||
mode = dec2num(parm->argv[i]);
|
||||
if (*(term->esc.buf + 1) != '?')
|
||||
continue; /* not supported */
|
||||
|
||||
if (mode == 6) { /* private mode */
|
||||
term->mode &= ~MODE_ORIGIN;
|
||||
set_cursor(term, 0, 0);
|
||||
} else if (mode == 7) {
|
||||
term->mode &= ~MODE_AMRIGHT;
|
||||
term->wrap_occured = false;
|
||||
} else if (mode == 25) {
|
||||
term->mode &= ~MODE_CURSOR;
|
||||
} else if (mode == 8901) {
|
||||
term->mode &= ~MODE_VWBS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void set_margin(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int top, bottom;
|
||||
|
||||
if (parm->argc <= 0) { /* CSI r */
|
||||
top = 0;
|
||||
bottom = term->lines - 1;
|
||||
} else if (parm->argc == 2) { /* CSI ; r -> use default value */
|
||||
top = (parm->argv[0] == NULL) ? 0: dec2num(parm->argv[0]) - 1;
|
||||
bottom = (parm->argv[1] == NULL) ? term->lines - 1: dec2num(parm->argv[1]) - 1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (top < 0 || top >= term->lines)
|
||||
top = 0;
|
||||
if (bottom < 0 || bottom >= term->lines)
|
||||
bottom = term->lines - 1;
|
||||
|
||||
if (top >= bottom)
|
||||
return;
|
||||
|
||||
term->scroll.top = top;
|
||||
term->scroll.bottom = bottom;
|
||||
|
||||
set_cursor(term, 0, 0); /* move cursor to home */
|
||||
}
|
||||
|
||||
void clear_tabstop(struct terminal_t *term, struct parm_t *parm)
|
||||
{
|
||||
int i, j, num;
|
||||
|
||||
if (parm->argc <= 0) {
|
||||
term->tabstop[term->cursor.x] = false;
|
||||
} else {
|
||||
for (i = 0; i < parm->argc; i++) {
|
||||
num = dec2num(parm->argv[i]);
|
||||
if (num == 0) {
|
||||
term->tabstop[term->cursor.x] = false;
|
||||
} else if (num == 3) {
|
||||
for (j = 0; j < term->cols; j++)
|
||||
term->tabstop[j] = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,587 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* function for dcs sequence */
|
||||
#error must no longer be included
|
||||
enum {
|
||||
RGBMAX = 255,
|
||||
HUEMAX = 360,
|
||||
LSMAX = 100,
|
||||
};
|
||||
|
||||
/*
|
||||
static inline void split_rgb(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b)
|
||||
{
|
||||
*r = bit_mask[8] & (color >> 16);
|
||||
*g = bit_mask[8] & (color >> 8);
|
||||
*b = bit_mask[8] & (color >> 0);
|
||||
}
|
||||
*/
|
||||
|
||||
static inline int sixel_bitmap(struct terminal_t *term, struct sixel_canvas_t *sc, uint8_t bitmap)
|
||||
{
|
||||
int i, offset;
|
||||
//uint8_t r, g, b;
|
||||
|
||||
logging(DEBUG, "sixel_bitmap()\nbitmap:%.2X point(%d, %d)\n",
|
||||
bitmap, sc->point.x, sc->point.y);
|
||||
|
||||
if (sc->point.x >= term->width || sc->point.y >= term->height)
|
||||
return 1;
|
||||
|
||||
offset = sc->point.x * BYTES_PER_PIXEL + sc->point.y * sc->line_length;
|
||||
|
||||
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
||||
if (offset >= BYTES_PER_PIXEL * term->width * term->height)
|
||||
break;
|
||||
|
||||
if (bitmap & (0x01 << i)) {
|
||||
memcpy(sc->pixmap + offset, &sc->color_table[sc->color_index], BYTES_PER_PIXEL);
|
||||
/*
|
||||
split_rgb(sc->color_table[sc->color_index], &r, &g, &b);
|
||||
*(sc->pixmap + offset + 0) = b;
|
||||
*(sc->pixmap + offset + 1) = g;
|
||||
*(sc->pixmap + offset + 2) = r;
|
||||
*/
|
||||
}
|
||||
|
||||
offset += sc->line_length;
|
||||
}
|
||||
sc->point.x++;
|
||||
|
||||
if (sc->point.x > sc->width)
|
||||
sc->width = sc->point.x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sixel_repeat(struct terminal_t *term, struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
int i, count;
|
||||
size_t length;
|
||||
char *cp, tmp[BUFSIZE];
|
||||
uint8_t bitmap;
|
||||
|
||||
cp = buf + 1; /* skip '!' itself */
|
||||
while (isdigit(*cp)) /* skip non sixel bitmap character */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1);
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
count = dec2num(tmp);
|
||||
|
||||
logging(DEBUG, "sixel_repeat()\nbuf:%s length:%u\ncount:%d repeat:0x%.2X\n",
|
||||
tmp, (unsigned) length, count, *cp);
|
||||
|
||||
if ('?' <= *cp && *cp <= '~') {
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
for (i = 0; i < count; i++)
|
||||
sixel_bitmap(term, sc, bitmap);
|
||||
}
|
||||
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
static inline int sixel_attr(struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
char *cp, tmp[BUFSIZE];
|
||||
size_t length;
|
||||
struct parm_t parm;
|
||||
|
||||
cp = buf + 1;
|
||||
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1);
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(tmp, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc >= 4) {
|
||||
sc->width = dec2num(parm.argv[2]);
|
||||
sc->height = dec2num(parm.argv[3]);
|
||||
}
|
||||
|
||||
logging(DEBUG, "sixel_attr()\nbuf:%s\nwidth:%d height:%d\n",
|
||||
tmp, sc->width, sc->height);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static inline uint32_t hue2rgb(int n1, int n2, int hue)
|
||||
{
|
||||
if (hue < 0)
|
||||
hue += HUEMAX;
|
||||
|
||||
if (hue > HUEMAX)
|
||||
hue -= HUEMAX;
|
||||
|
||||
if (hue < (HUEMAX / 6))
|
||||
return (n1 + (((n2 - n1) * hue + (HUEMAX / 12)) / (HUEMAX / 6)));
|
||||
if (hue < (HUEMAX / 2))
|
||||
return n2;
|
||||
if (hue < ((HUEMAX * 2) / 3))
|
||||
return (n1 + (((n2 - n1) * (((HUEMAX * 2) / 3) - hue) + (HUEMAX / 12)) / (HUEMAX / 6)));
|
||||
else
|
||||
return n1;
|
||||
}
|
||||
|
||||
static inline uint32_t hls2rgb(int hue, int lum, int sat)
|
||||
{
|
||||
uint32_t r, g, b;
|
||||
int magic1, magic2;
|
||||
|
||||
if (sat == 0) {
|
||||
r = g = b = (lum * RGBMAX) / LSMAX;
|
||||
} else {
|
||||
if (lum <= (LSMAX / 2) )
|
||||
magic2 = (lum * (LSMAX + sat) + (LSMAX / 2)) / LSMAX;
|
||||
else
|
||||
magic2 = lum + sat - ((lum * sat) + (LSMAX / 2)) / LSMAX;
|
||||
magic1 = 2 * lum - magic2;
|
||||
|
||||
r = (hue2rgb(magic1, magic2, hue + (HUEMAX / 3)) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
||||
g = (hue2rgb(magic1, magic2, hue) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
||||
b = (hue2rgb(magic1, magic2, hue - (HUEMAX / 3)) * RGBMAX + (LSMAX/2)) / LSMAX;
|
||||
}
|
||||
return (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
static inline int sixel_color(struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
char *cp, tmp[BUFSIZE];
|
||||
int index, type;
|
||||
size_t length;
|
||||
uint16_t v1, v2, v3, r, g, b;
|
||||
uint32_t color;
|
||||
struct parm_t parm;
|
||||
|
||||
cp = buf + 1;
|
||||
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1); /* skip '#' */
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(tmp, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc < 1)
|
||||
return length;
|
||||
|
||||
index = dec2num(parm.argv[0]);
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
else if (index >= COLORS)
|
||||
index = COLORS - 1;
|
||||
|
||||
logging(DEBUG, "sixel_color()\nbuf:%s length:%u\nindex:%d\n",
|
||||
tmp, (unsigned) length, index);
|
||||
|
||||
if (parm.argc == 1) { /* select color */
|
||||
sc->color_index = index;
|
||||
return length;
|
||||
}
|
||||
|
||||
if (parm.argc != 5)
|
||||
return length;
|
||||
|
||||
type = dec2num(parm.argv[1]);
|
||||
v1 = dec2num(parm.argv[2]);
|
||||
v2 = dec2num(parm.argv[3]);
|
||||
v3 = dec2num(parm.argv[4]);
|
||||
|
||||
if (type == 1) { /* HLS */
|
||||
color = hls2rgb(v1, v2, v3);
|
||||
} else {
|
||||
r = bit_mask[8] & (0xFF * v1 / 100);
|
||||
g = bit_mask[8] & (0xFF * v2 / 100);
|
||||
b = bit_mask[8] & (0xFF * v3 / 100);
|
||||
color = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
logging(DEBUG, "type:%d v1:%u v2:%u v3:%u color:0x%.8X\n",
|
||||
type, v1, v2, v3, color);
|
||||
|
||||
sc->color_table[index] = color;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static inline int sixel_cr(struct sixel_canvas_t *sc)
|
||||
{
|
||||
logging(DEBUG, "sixel_cr()\n");
|
||||
|
||||
sc->point.x = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sixel_nl(struct sixel_canvas_t *sc)
|
||||
{
|
||||
logging(DEBUG, "sixel_nl()\n");
|
||||
|
||||
/* DECGNL moves active position to left margin
|
||||
and down one line of sixels:
|
||||
http://odl.sysworks.biz/disk$vaxdocdec963/decw$book/d3qsaaa1.p67.decw$book */
|
||||
sc->point.y += BITS_PER_SIXEL;
|
||||
sc->point.x = 0;
|
||||
|
||||
if (sc->point.y > sc->height)
|
||||
sc->height = sc->point.y;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sixel_parse_data(struct terminal_t *term, struct sixel_canvas_t *sc, char *start_buf)
|
||||
{
|
||||
/*
|
||||
DECDLD sixel data
|
||||
'$': carriage return
|
||||
'-': new line
|
||||
'#': color
|
||||
# Pc: select color
|
||||
# Pc; Pu; Px; Py; Pz
|
||||
Pc : color index (0 to 255)
|
||||
Pu : color coordinate system
|
||||
1: HLS (0 to 360 for Hue, 0 to 100 for others)
|
||||
2: RGB (0 to 100 percent) (default)
|
||||
Px : Hue / Red
|
||||
Py : Lightness / Green
|
||||
Pz : Saturation / Blue
|
||||
'"': attr
|
||||
" Pan; Pad; Ph; Pv
|
||||
Pan, Pad: defines aspect ratio (Pan / Pad) (ignored)
|
||||
Ph, Pv : defines vertical/horizontal size of the image
|
||||
'!': repeat
|
||||
! Pn ch
|
||||
Pn : repeat count ([0-9]+)
|
||||
ch : character to repeat ('?' to '~')
|
||||
sixel bitmap:
|
||||
range of ? (hex 3F) to ~ (hex 7E)
|
||||
? (hex 3F) represents the binary value 00 0000.
|
||||
t (hex 74) represents the binary value 11 0101.
|
||||
~ (hex 7E) represents the binary value 11 1111.
|
||||
*/
|
||||
int size = 0;
|
||||
char *cp, *end_buf;
|
||||
uint8_t bitmap;
|
||||
|
||||
cp = start_buf;
|
||||
end_buf = cp + strlen(start_buf);
|
||||
|
||||
while (cp < end_buf) {
|
||||
if (*cp == '!') {
|
||||
size = sixel_repeat(term, sc, cp);
|
||||
} else if (*cp == '"') {
|
||||
size = sixel_attr(sc, cp);
|
||||
} else if (*cp == '#') {
|
||||
size = sixel_color(sc, cp);
|
||||
} else if (*cp == '$') {
|
||||
size = sixel_cr(sc);
|
||||
} else if (*cp == '-') {
|
||||
size = sixel_nl(sc);
|
||||
} else if ('?' <= *cp && *cp <= '~') {
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
size = sixel_bitmap(term, sc, bitmap);
|
||||
} else if (*cp == '\0') { /* end of sixel data */
|
||||
break;
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
cp += size;
|
||||
}
|
||||
|
||||
logging(DEBUG, "sixel_parse_data()\nwidth:%d height:%d\n", sc->width, sc->height);
|
||||
}
|
||||
|
||||
void reset_sixel(struct sixel_canvas_t *sc, struct color_pair_t color_pair, int width, int height)
|
||||
{
|
||||
extern const uint32_t color_list[]; /* global */
|
||||
int i;
|
||||
|
||||
memset(sc->pixmap, 0, BYTES_PER_PIXEL * width * height);
|
||||
|
||||
sc->width = 1;
|
||||
sc->height = 6;
|
||||
sc->point.x = 0;
|
||||
sc->point.y = 0;
|
||||
sc->line_length = BYTES_PER_PIXEL * width;
|
||||
sc->color_index = 0;
|
||||
|
||||
/* 0 - 15: use vt340 or ansi color map */
|
||||
/* VT340 VT340 Default Color Map
|
||||
ref: http://www.vt100.net/docs/vt3xx-gp/chapter2.html#T2-3
|
||||
*/
|
||||
sc->color_table[0] = 0x000000; sc->color_table[8] = 0x424242;
|
||||
sc->color_table[1] = 0x3333CC; sc->color_table[9] = 0x545499;
|
||||
sc->color_table[2] = 0xCC2121; sc->color_table[10] = 0x994242;
|
||||
sc->color_table[3] = 0x33CC33; sc->color_table[11] = 0x549954;
|
||||
sc->color_table[4] = 0xCC33CC; sc->color_table[12] = 0x995499;
|
||||
sc->color_table[5] = 0x33CCCC; sc->color_table[13] = 0x549999;
|
||||
sc->color_table[6] = 0xCCCC33; sc->color_table[14] = 0x999954;
|
||||
sc->color_table[7] = 0x878787; sc->color_table[15] = 0xCCCCCC;
|
||||
|
||||
/* ANSI 16color table (but unusual order corresponding vt340 color map)
|
||||
sc->color_table[0] = color_list[0]; sc->color_table[8] = color_list[8];
|
||||
sc->color_table[1] = color_list[4]; sc->color_table[9] = color_list[12];
|
||||
sc->color_table[2] = color_list[1]; sc->color_table[10] = color_list[9];
|
||||
sc->color_table[3] = color_list[2]; sc->color_table[11] = color_list[10];
|
||||
sc->color_table[4] = color_list[5]; sc->color_table[12] = color_list[13];
|
||||
sc->color_table[5] = color_list[6]; sc->color_table[13] = color_list[14];
|
||||
sc->color_table[6] = color_list[3]; sc->color_table[14] = color_list[11];
|
||||
sc->color_table[7] = color_list[7]; sc->color_table[15] = color_list[15];
|
||||
*/
|
||||
/* change palette 0, because its often the same color as terminal background */
|
||||
sc->color_table[0] = color_list[color_pair.fg];
|
||||
|
||||
/* 16 - 255: use xterm 256 color palette */
|
||||
/* copy 256 color map */
|
||||
for (i = 16; i < COLORS; i++)
|
||||
sc->color_table[i] = color_list[i];
|
||||
}
|
||||
|
||||
void sixel_copy2cell(struct terminal_t *term, struct sixel_canvas_t *sc)
|
||||
{
|
||||
int y, x, h, cols, lines;
|
||||
int src_offset, dst_offset;
|
||||
struct cell_t *cellp;
|
||||
|
||||
if (sc->height > term->height)
|
||||
sc->height = term->height;
|
||||
|
||||
cols = my_ceil(sc->width, CELL_WIDTH);
|
||||
lines = my_ceil(sc->height, CELL_HEIGHT);
|
||||
|
||||
if (cols + term->cursor.x > term->cols)
|
||||
cols -= (cols + term->cursor.x - term->cols);
|
||||
|
||||
for (y = 0; y < lines; y++) {
|
||||
for (x = 0; x < cols; x++) {
|
||||
erase_cell(term, term->cursor.y, term->cursor.x + x);
|
||||
cellp = &term->cells[term->cursor.y][term->cursor.x + x];
|
||||
cellp->has_pixmap = true;
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
src_offset = (y * CELL_HEIGHT + h) * sc->line_length + (CELL_WIDTH * x) * BYTES_PER_PIXEL;
|
||||
dst_offset = h * CELL_WIDTH * BYTES_PER_PIXEL;
|
||||
if (src_offset >= BYTES_PER_PIXEL * term->width * term->height)
|
||||
break;
|
||||
memcpy(cellp->pixmap + dst_offset, sc->pixmap + src_offset, CELL_WIDTH * BYTES_PER_PIXEL);
|
||||
}
|
||||
}
|
||||
move_cursor(term, 1, 0);
|
||||
//set_cursor(term, term->cursor.y + 1, term->cursor.x);
|
||||
}
|
||||
cr(term);
|
||||
}
|
||||
|
||||
void sixel_parse_header(struct terminal_t *term, char *start_buf)
|
||||
{
|
||||
/*
|
||||
sixel format
|
||||
DSC P1; P2; P3; q; s...s; ST
|
||||
parameters
|
||||
DCS: ESC(0x1B) P (0x50) (8bit C1 character not recognized)
|
||||
P1 : pixel aspect ratio (force 0, 2:1) (ignored)
|
||||
P2 : background mode (ignored)
|
||||
0 or 2: 0 stdands for current background color (default)
|
||||
1 : 0 stands for remaining current color
|
||||
P3 : horizontal grid parameter (ignored)
|
||||
q : final character of sixel sequence
|
||||
s : see parse_sixel_data()
|
||||
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
||||
*/
|
||||
char *cp;
|
||||
struct parm_t parm;
|
||||
|
||||
/* replace final char of sixel header by NUL '\0' */
|
||||
cp = strchr(start_buf, 'q');
|
||||
*cp = '\0';
|
||||
|
||||
logging(DEBUG, "sixel_parse_header()\nbuf:%s\n", start_buf);
|
||||
|
||||
/* split header by semicolon ';' */
|
||||
reset_parm(&parm);
|
||||
parse_arg(start_buf, &parm, ';', isdigit);
|
||||
|
||||
/* set canvas parameters */
|
||||
reset_sixel(&term->sixel, term->color_pair, term->width, term->height);
|
||||
sixel_parse_data(term, &term->sixel, cp + 1); /* skip 'q' */
|
||||
sixel_copy2cell(term, &term->sixel);
|
||||
}
|
||||
|
||||
static inline void decdld_bitmap(struct glyph_t *glyph, uint8_t bitmap, uint8_t row, uint8_t column)
|
||||
{
|
||||
/*
|
||||
MSB LSB (glyph_t bitmap order, padding at LSB side)
|
||||
-> column
|
||||
sixel bit0 ->........
|
||||
sixel bit1 ->........
|
||||
sixel bit2 ->....@@..
|
||||
sixel bit3 ->...@..@.
|
||||
sixel bit4 ->...@....
|
||||
sixel bit5 ->...@....
|
||||
.@@@@@..
|
||||
...@....
|
||||
|...@....
|
||||
row |...@....
|
||||
v...@....
|
||||
...@....
|
||||
...@....
|
||||
...@....
|
||||
........
|
||||
........
|
||||
*/
|
||||
int i, height_shift, width_shift;
|
||||
|
||||
logging(DEBUG, "bit pattern:0x%.2X\n", bitmap);
|
||||
|
||||
width_shift = CELL_WIDTH - 1 - column;
|
||||
if (width_shift < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
||||
if((bitmap >> i) & 0x01) {
|
||||
height_shift = row * BITS_PER_SIXEL + i;
|
||||
|
||||
if (height_shift < CELL_HEIGHT) {
|
||||
logging(DEBUG, "height_shift:%d width_shift:%d\n", height_shift, width_shift);
|
||||
glyph->bitmap[height_shift] |= bit_mask[CELL_WIDTH] & (0x01 << width_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void init_glyph(struct glyph_t *glyph)
|
||||
{
|
||||
int i;
|
||||
|
||||
glyph->width = 1; /* drcs glyph must be HALF */
|
||||
glyph->code = 0; /* this value not used: drcs call by DRCSMMv1 */
|
||||
|
||||
for (i = 0; i < CELL_HEIGHT; i++)
|
||||
glyph->bitmap[i] = 0;
|
||||
}
|
||||
|
||||
void decdld_parse_data(char *start_buf, int start_char, struct glyph_t *chars)
|
||||
{
|
||||
/*
|
||||
DECDLD sixel data
|
||||
';': glyph separator
|
||||
'/': line feed
|
||||
sixel bitmap:
|
||||
range of ? (hex 3F) to ~ (hex 7E)
|
||||
? (hex 3F) represents the binary value 00 0000.
|
||||
t (hex 74) represents the binary value 11 0101.
|
||||
~ (hex 7E) represents the binary value 11 1111.
|
||||
*/
|
||||
char *cp, *end_buf;
|
||||
uint8_t char_num = start_char; /* start_char == 0 means SPACE(0x20) */
|
||||
uint8_t bitmap, row = 0, column = 0;
|
||||
|
||||
init_glyph(&chars[char_num]);
|
||||
cp = start_buf;
|
||||
end_buf = cp + strlen(cp);
|
||||
|
||||
while (cp < end_buf) {
|
||||
if ('?' <= *cp && *cp <= '~') { /* sixel bitmap */
|
||||
logging(DEBUG, "char_num(ten):0x%.2X\n", char_num);
|
||||
/* remove offset '?' and use only 6bit */
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
decdld_bitmap(&chars[char_num], bitmap, row, column);
|
||||
column++;
|
||||
} else if (*cp == ';') { /* next char */
|
||||
row = column = 0;
|
||||
char_num++;
|
||||
init_glyph(&chars[char_num]);
|
||||
} else if (*cp == '/') { /* sixel nl+cr */
|
||||
row++;
|
||||
column = 0;
|
||||
} else if (*cp == '\0') { /* end of DECDLD sequence */
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
void decdld_parse_header(struct terminal_t *term, char *start_buf)
|
||||
{
|
||||
/*
|
||||
DECDLD format
|
||||
DCS Pfn; Pcn; Pe; Pcmw; Pss; Pt; Pcmh; Pcss; f Dscs Sxbp1 ; Sxbp2 ; .. .; Sxbpn ST
|
||||
parameters
|
||||
DCS : ESC (0x1B) 'P' (0x50) (DCS(8bit C1 code) is not supported)
|
||||
Pfn : fontset (ignored)
|
||||
Pcn : start char (0 means SPACE 0x20)
|
||||
Pe : erase mode
|
||||
0: clear selectet charset
|
||||
1: clear only redefined glyph
|
||||
2: clear all drcs charset
|
||||
Pcmw: max cellwidth (force CELL_WEDTH defined in glyph.h)
|
||||
Pss : screen size (ignored)
|
||||
Pt : defines the glyph as text or full cell or sixel (force full cell mode)
|
||||
(TODO: implement sixel/text mode)
|
||||
Pcmh: max cellheight (force CELL_HEIGHT defined in glyph.h)
|
||||
Pcss: character set size (force: 96)
|
||||
0: 94 gylphs charset
|
||||
1: 96 gylphs charset
|
||||
f : '{' (0x7B)
|
||||
Dscs: define character set
|
||||
Intermediate char: SPACE (0x20) to '/' (0x2F)
|
||||
final char : '0' (0x30) to '~' (0x7E)
|
||||
but allow chars between '@' (0x40) and '~' (0x7E) for DRCSMMv1
|
||||
(ref: https://github.com/saitoha/drcsterm/blob/master/README.rst)
|
||||
Sxbp: see parse_decdld_sixel()
|
||||
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
||||
*/
|
||||
char *cp;
|
||||
int start_char, erase_mode, charset;
|
||||
struct parm_t parm;
|
||||
|
||||
/* replace final char of DECDLD header by NUL '\0' */
|
||||
cp = strchr(start_buf, '{');
|
||||
*cp = '\0';
|
||||
|
||||
logging(DEBUG, "decdld_parse_header()\nbuf:%s\n", start_buf);
|
||||
|
||||
/* split header by semicolon ';' */
|
||||
reset_parm(&parm);
|
||||
parse_arg(start_buf, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc != 8) /* DECDLD header must have 8 params */
|
||||
return;
|
||||
|
||||
/* set params */
|
||||
start_char = dec2num(parm.argv[1]);
|
||||
erase_mode = dec2num(parm.argv[2]);
|
||||
|
||||
/* parse Dscs */
|
||||
cp++; /* skip final char (NUL) of DECDLD header */
|
||||
while (SPACE <= *cp && *cp <= '/') /* skip intermediate char */
|
||||
cp++;
|
||||
|
||||
if (0x40 <= *cp && *cp <= 0x7E) /* final char of Dscs must be between 0x40 to 0x7E (DRCSMMv1) */
|
||||
charset = *cp - 0x40;
|
||||
else
|
||||
charset = 0;
|
||||
|
||||
logging(DEBUG, "charset(ku):0x%.2X start_char:%d erase_mode:%d\n",
|
||||
charset, start_char, erase_mode);
|
||||
|
||||
/* reset previous glyph data */
|
||||
if (erase_mode < 0 || erase_mode > 2)
|
||||
erase_mode = 0;
|
||||
|
||||
if (erase_mode == 2) /* reset all drcs charset */
|
||||
memset(term->drcs, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
||||
else if (erase_mode == 0) /* reset selected drcs charset */
|
||||
memset(term->drcs + GLYPHS_PER_CHARSET * charset, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
||||
|
||||
//if (term->drcs[charset] == NULL) /* always allcate 96 chars buffer */
|
||||
//term->drcs[charset] = ecalloc(GLYPH_PER_CHARSET, sizeof(struct glyph_t));
|
||||
|
||||
decdld_parse_data(cp + 1, start_char, term->drcs + GLYPHS_PER_CHARSET * charset); /* skip final char */
|
||||
}
|
@@ -1,103 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* function for control character */
|
||||
void bs(struct terminal_t *term)
|
||||
{
|
||||
if (term->mode & MODE_VWBS
|
||||
&& term->cursor.x - 1 >= 0
|
||||
&& term->cells[term->cursor.y][term->cursor.x - 1].width == NEXT_TO_WIDE)
|
||||
move_cursor(term, 0, -2);
|
||||
else
|
||||
move_cursor(term, 0, -1);
|
||||
}
|
||||
|
||||
void tab(struct terminal_t *term)
|
||||
{
|
||||
int i;
|
||||
const char *c = " ";
|
||||
term->txt.back().append(c, 1);
|
||||
for (i = term->cursor.x + 1; i < term->cols; i++) {
|
||||
if (term->tabstop[i]) {
|
||||
set_cursor(term, term->cursor.y, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_cursor(term, term->cursor.y, term->cols - 1);
|
||||
}
|
||||
|
||||
void nl(struct terminal_t *term)
|
||||
{
|
||||
term->nlseen = true;
|
||||
term->txt.push("");
|
||||
term->lines_available++;
|
||||
move_cursor(term, 1, 0);
|
||||
}
|
||||
|
||||
void cr(struct terminal_t *term)
|
||||
{
|
||||
set_cursor(term, term->cursor.y, 0);
|
||||
}
|
||||
|
||||
void enter_esc(struct terminal_t *term)
|
||||
{
|
||||
term->esc.state = STATE_ESC;
|
||||
}
|
||||
|
||||
/* function for escape sequence */
|
||||
void save_state(struct terminal_t *term)
|
||||
{
|
||||
term->state.mode = term->mode & MODE_ORIGIN;
|
||||
term->state.cursor = term->cursor;
|
||||
term->state.attribute = term->attribute;
|
||||
}
|
||||
|
||||
void restore_state(struct terminal_t *term)
|
||||
{
|
||||
/* restore state */
|
||||
if (term->state.mode & MODE_ORIGIN)
|
||||
term->mode |= MODE_ORIGIN;
|
||||
else
|
||||
term->mode &= ~MODE_ORIGIN;
|
||||
term->cursor = term->state.cursor;
|
||||
term->attribute = term->state.attribute;
|
||||
}
|
||||
|
||||
void crnl(struct terminal_t *term)
|
||||
{
|
||||
cr(term);
|
||||
nl(term);
|
||||
}
|
||||
|
||||
void set_tabstop(struct terminal_t *term)
|
||||
{
|
||||
term->tabstop[term->cursor.x] = true;
|
||||
}
|
||||
|
||||
void reverse_nl(struct terminal_t *term)
|
||||
{
|
||||
move_cursor(term, -1, 0);
|
||||
}
|
||||
|
||||
void identify(struct terminal_t *term)
|
||||
{
|
||||
ewrite(term->fd, "\033[?6c", 5); /* "I am a VT102" */
|
||||
}
|
||||
|
||||
void enter_csi(struct terminal_t *term)
|
||||
{
|
||||
term->esc.state = STATE_CSI;
|
||||
}
|
||||
|
||||
void enter_osc(struct terminal_t *term)
|
||||
{
|
||||
term->esc.state = STATE_OSC;
|
||||
}
|
||||
|
||||
void enter_dcs(struct terminal_t *term)
|
||||
{
|
||||
term->esc.state = STATE_DCS;
|
||||
}
|
||||
|
||||
void ris(struct terminal_t *term)
|
||||
{
|
||||
reset(term);
|
||||
}
|
@@ -1,287 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* function for osc sequence */
|
||||
int32_t parse_color1(char *seq)
|
||||
{
|
||||
/*
|
||||
format
|
||||
rgb:r/g/b
|
||||
rgb:rr/gg/bb
|
||||
rgb:rrr/ggg/bbb
|
||||
rgb:rrrr/gggg/bbbb
|
||||
*/
|
||||
int i, length, value;
|
||||
int32_t color;
|
||||
uint32_t rgb[3];
|
||||
struct parm_t parm;
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(seq, &parm, '/', isalnum);
|
||||
|
||||
for (i = 0; i < parm.argc; i++)
|
||||
logging(DEBUG, "parm.argv[%d]: %s\n", i, parm.argv[i]);
|
||||
|
||||
if (parm.argc != 3)
|
||||
return -1;
|
||||
|
||||
length = strlen(parm.argv[0]);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
value = hex2num(parm.argv[i]);
|
||||
logging(DEBUG, "value:%d\n", value);
|
||||
|
||||
if (length == 1) /* r/g/b/ */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0x0F);
|
||||
else if (length == 2) /* rr/gg/bb */
|
||||
rgb[i] = bit_mask[8] & value;
|
||||
else if (length == 3) /* rrr/ggg/bbb */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0xFFF);
|
||||
else if (length == 4) /* rrrr/gggg/bbbb */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0xFFFF);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
logging(DEBUG, "color:0x%.6X\n", color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
int32_t parse_color2(char *seq)
|
||||
{
|
||||
/*
|
||||
format
|
||||
#rgb
|
||||
#rrggbb
|
||||
#rrrgggbbb
|
||||
#rrrrggggbbbb
|
||||
*/
|
||||
int i, length;
|
||||
uint32_t rgb[3];
|
||||
int32_t color;
|
||||
char buf[BUFSIZE];
|
||||
|
||||
length = strlen(seq);
|
||||
memset(buf, '\0', BUFSIZE);
|
||||
|
||||
if (length == 3) { /* rgb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i, 1);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0x0F;
|
||||
}
|
||||
} else if (length == 6) { /* rrggbb */
|
||||
for (i = 0; i < 3; i++) { /* rrggbb */
|
||||
strncpy(buf, seq + i * 2, 2);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf);
|
||||
}
|
||||
} else if (length == 9) { /* rrrgggbbb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i * 3, 3);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0xFFF;
|
||||
}
|
||||
} else if (length == 12) { /* rrrrggggbbbb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i * 4, 4);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
logging(DEBUG, "color:0x%.6X\n", color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void set_palette(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
OSC Ps ; Pt ST
|
||||
ref: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
ref: http://ttssh2.sourceforge.jp/manual/ja/about/ctrlseq.html#OSC
|
||||
|
||||
only recognize change color palette:
|
||||
Ps: 4
|
||||
Pt: c ; spec
|
||||
c: color index (from 0 to 255)
|
||||
spec:
|
||||
rgb:r/g/b
|
||||
rgb:rr/gg/bb
|
||||
rgb:rrr/ggg/bbb
|
||||
rgb:rrrr/gggg/bbbb
|
||||
#rgb
|
||||
#rrggbb
|
||||
#rrrgggbbb
|
||||
#rrrrggggbbbb
|
||||
this rgb format is "RGB Device String Specification"
|
||||
see http://xjman.dsl.gr.jp/X11R6/X11/CH06.html
|
||||
Pt: c ; ?
|
||||
response rgb color
|
||||
OSC 4 ; c ; rgb:rr/gg/bb ST
|
||||
|
||||
TODO: this function only works in 32bpp mode
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg;
|
||||
int i, argc = pt->argc, index;
|
||||
int32_t color;
|
||||
uint8_t rgb[3];
|
||||
char **argv = pt->argv;
|
||||
char buf[BUFSIZE];
|
||||
|
||||
if (argc != 3)
|
||||
return;
|
||||
|
||||
index = dec2num(argv[1]);
|
||||
if (index < 0 || index >= COLORS)
|
||||
return;
|
||||
|
||||
if (strncmp(argv[2], "rgb:", 4) == 0) {
|
||||
if ((color = parse_color1(argv[2] + 4)) != -1) { /* skip "rgb:" */
|
||||
term->virtual_palette[index] = (uint32_t) color;
|
||||
term->palette_modified = true;
|
||||
}
|
||||
} else if (strncmp(argv[2], "#", 1) == 0) {
|
||||
if ((color = parse_color2(argv[2] + 1)) != -1) { /* skip "#" */
|
||||
term->virtual_palette[index] = (uint32_t) color;
|
||||
term->palette_modified = true;
|
||||
}
|
||||
} else if (strncmp(argv[2], "?", 1) == 0) {
|
||||
for (i = 0; i < 3; i++)
|
||||
rgb[i] = bit_mask[8] & (term->virtual_palette[index] >> (8 * (2 - i)));
|
||||
|
||||
snprintf(buf, BUFSIZE, "\033]4;%d;rgb:%.2X/%.2X/%.2X\033\\",
|
||||
index, rgb[0], rgb[1], rgb[2]);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
|
||||
void reset_palette(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
reset color c
|
||||
OSC 104 ; c ST
|
||||
c: index of color
|
||||
ST: BEL or ESC \
|
||||
reset all color
|
||||
OSC 104 ST
|
||||
ST: BEL or ESC \
|
||||
|
||||
terminfo: oc=\E]104\E\\
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg;
|
||||
int i, argc = pt->argc, c;
|
||||
char **argv = pt->argv;
|
||||
|
||||
if (argc < 2) { /* reset all color palette */
|
||||
for (i = 0; i < COLORS; i++)
|
||||
term->virtual_palette[i] = color_list[i];
|
||||
term->palette_modified = true;
|
||||
} else if (argc == 2) { /* reset color_palette[c] */
|
||||
c = dec2num(argv[1]);
|
||||
if (0 <= c && c < COLORS) {
|
||||
term->virtual_palette[c] = color_list[c];
|
||||
term->palette_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int isdigit_or_questionmark(int c)
|
||||
{
|
||||
if (isdigit(c) || c == '?')
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void glyph_width_report(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
glyph width report
|
||||
* request *
|
||||
OSC 8900 ; Ps ; Pw ; ? : Pf : Pt ST
|
||||
Ps: reserved
|
||||
Pw: width (0 or 1 or 2)
|
||||
Pfrom: beginning of unicode code point
|
||||
Pto: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
* answer *
|
||||
OSC 8900 ; Ps ; Pv ; Pw ; Pf : Pt ; Pf : Pt ; ... ST
|
||||
Ps: responce code
|
||||
0: ok (default)
|
||||
1: recognized but not supported
|
||||
2: not recognized
|
||||
Pv: reserved (maybe East Asian Width Version)
|
||||
Pw: width (0 or 1 or 2)
|
||||
Pfrom: beginning of unicode code point
|
||||
Pto: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
ref
|
||||
http://uobikiemukot.github.io/yaft/glyph_width_report.html
|
||||
https://gist.github.com/saitoha/8767268
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg, sub_parm;
|
||||
int i, argc = pt->argc, width, from, to, left, right, w, wcw; //reserved
|
||||
char **argv = pt->argv, buf[BUFSIZE];
|
||||
|
||||
if (argc < 4)
|
||||
return;
|
||||
|
||||
reset_parm(&sub_parm);
|
||||
parse_arg(argv[3], &sub_parm, ':', isdigit_or_questionmark);
|
||||
|
||||
if (sub_parm.argc != 3 || *sub_parm.argv[0] != '?')
|
||||
return;
|
||||
|
||||
//reserved = dec2num(argv[1]);
|
||||
width = dec2num(argv[2]);
|
||||
from = dec2num(sub_parm.argv[1]);
|
||||
to = dec2num(sub_parm.argv[2]);
|
||||
|
||||
if ((width < 0) || (width > 2))
|
||||
return;
|
||||
|
||||
/* unicode private area: plane 16 (DRCSMMv1) is always half */
|
||||
if ((from < 0) || (to >= UCS2_CHARS))
|
||||
return;
|
||||
|
||||
snprintf(buf, BUFSIZE, "\033]8900;0;0;%d;", width); /* OSC 8900 ; Ps; Pv ; Pw ; */
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
|
||||
left = right = -1;
|
||||
for (i = from; i <= to; i++) {
|
||||
wcw = wcwidth(i);
|
||||
if (wcw <= 0) /* zero width */
|
||||
w = 0;
|
||||
else if (term->glyph[i] == NULL) /* missing glyph */
|
||||
w = wcw;
|
||||
else
|
||||
w = term->glyph[i]->width;
|
||||
|
||||
if (w != width) {
|
||||
if (right != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, right);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
} else if (left != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, left);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
left = right = -1;
|
||||
} else {
|
||||
if (left == -1)
|
||||
left = i;
|
||||
else
|
||||
right = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (right != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, right);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
} else if (left != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, left);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
|
||||
ewrite(term->fd, "\033\\", 2); /* ST (ESC BACKSLASH) */
|
||||
}
|
@@ -1,532 +0,0 @@
|
||||
/*
|
||||
* common framebuffer struct/enum
|
||||
* for yaft framebuffer terminal
|
||||
* (C) 2018 Stefan Seyfried
|
||||
* License: GPL-2.0
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* original yaft code
|
||||
* Copyright (c) 2012 haru <uobikiemukot at gmail dot com>
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
enum fb_type_t {
|
||||
YAFT_FB_TYPE_PACKED_PIXELS = 0,
|
||||
YAFT_FB_TYPE_PLANES,
|
||||
YAFT_FB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
enum fb_visual_t {
|
||||
YAFT_FB_VISUAL_TRUECOLOR = 0,
|
||||
YAFT_FB_VISUAL_DIRECTCOLOR,
|
||||
YAFT_FB_VISUAL_PSEUDOCOLOR,
|
||||
YAFT_FB_VISUAL_UNKNOWN,
|
||||
};
|
||||
|
||||
struct bitfield_t {
|
||||
int length;
|
||||
int offset;
|
||||
};
|
||||
class CFrameBuffer;
|
||||
struct fb_info_t {
|
||||
struct bitfield_t red, green, blue;
|
||||
int width, height; /* display resolution */
|
||||
int xstart, ystart; /* position of the window in the framebuffer */
|
||||
long screen_size; /* screen data size (byte) */
|
||||
int line_length; /* line length (byte) */
|
||||
int bytes_per_pixel;
|
||||
int bits_per_pixel;
|
||||
enum fb_type_t type;
|
||||
enum fb_visual_t visual;
|
||||
int reserved; /* os specific data */
|
||||
CFrameBuffer *cfb;
|
||||
};
|
||||
|
||||
/* os dependent typedef/include */
|
||||
#if 1
|
||||
#include "neutrinofb.h"
|
||||
#elif defined(__linux__)
|
||||
#include "linux.h"
|
||||
#elif defined(__FreeBSD__)
|
||||
#include "freebsd.h"
|
||||
#elif defined(__NetBSD__)
|
||||
#include "netbsd.h"
|
||||
#elif defined(__OpenBSD__)
|
||||
#include "openbsd.h"
|
||||
#endif
|
||||
|
||||
struct framebuffer_t {
|
||||
int fd; /* file descriptor of framebuffer */
|
||||
uint32_t *buf; /* copy of framebuffer */
|
||||
#if 0
|
||||
uint8_t *fp; /* pointer of framebuffer */
|
||||
uint8_t *wall; /* buffer for wallpaper */
|
||||
#endif
|
||||
uint32_t real_palette[COLORS]; /* hardware specific color palette */
|
||||
struct fb_info_t info;
|
||||
#if 0
|
||||
cmap_t *cmap, *cmap_orig;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* common framebuffer functions */
|
||||
uint8_t *load_wallpaper(uint8_t *fp, long screen_size)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if ((ptr = (uint8_t *) ecalloc(1, screen_size)) == NULL) {
|
||||
logging(ERROR, "couldn't allocate wallpaper buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(ptr, fp, screen_size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void cmap_die(cmap_t *cmap)
|
||||
{
|
||||
if (cmap) {
|
||||
free(cmap->red);
|
||||
free(cmap->green);
|
||||
free(cmap->blue);
|
||||
//free(cmap->transp);
|
||||
free(cmap);
|
||||
}
|
||||
}
|
||||
|
||||
cmap_t *cmap_create(int colors)
|
||||
{
|
||||
cmap_t *cmap;
|
||||
|
||||
if ((cmap = (cmap_t *) ecalloc(1, sizeof(cmap_t))) == NULL) {
|
||||
logging(ERROR, "couldn't allocate cmap buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* init os specific */
|
||||
alloc_cmap(cmap, colors);
|
||||
|
||||
if (!cmap->red || !cmap->green || !cmap->blue) {
|
||||
logging(ERROR, "couldn't allocate red/green/blue buffer of cmap\n");
|
||||
cmap_die(cmap);
|
||||
return NULL;
|
||||
}
|
||||
return cmap;
|
||||
}
|
||||
|
||||
bool cmap_update(int fd, cmap_t *cmap)
|
||||
{
|
||||
if (cmap) {
|
||||
if (put_cmap(fd, cmap)) {
|
||||
logging(ERROR, "put_cmap failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmap_save(int fd, cmap_t *cmap)
|
||||
{
|
||||
if (get_cmap(fd, cmap)) {
|
||||
logging(WARN, "get_cmap failed\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmap_init(int fd, struct fb_info_t *info, cmap_t *cmap, int colors, int length)
|
||||
{
|
||||
uint16_t r, g, b, r_index, g_index, b_index;
|
||||
|
||||
for (int i = 0; i < colors; i++) {
|
||||
if (info->visual == YAFT_FB_VISUAL_DIRECTCOLOR) {
|
||||
r_index = (i >> (length - info->red.length)) & bit_mask[info->red.length];
|
||||
g_index = (i >> (length - info->green.length)) & bit_mask[info->green.length];
|
||||
b_index = (i >> (length - info->blue.length)) & bit_mask[info->blue.length];
|
||||
|
||||
/* XXX: maybe only upper order byte is used */
|
||||
r = r_index << (CMAP_COLOR_LENGTH - info->red.length);
|
||||
g = g_index << (CMAP_COLOR_LENGTH - info->green.length);
|
||||
b = b_index << (CMAP_COLOR_LENGTH - info->blue.length);
|
||||
|
||||
*(cmap->red + r_index) = r;
|
||||
*(cmap->green + g_index) = g;
|
||||
*(cmap->blue + b_index) = b;
|
||||
} else { /* YAFT_FB_VISUAL_PSEUDOCOLOR */
|
||||
r_index = (i >> info->red.offset) & bit_mask[info->red.length];
|
||||
g_index = (i >> info->green.offset) & bit_mask[info->green.length];
|
||||
b_index = (i >> info->blue.offset) & bit_mask[info->blue.length];
|
||||
|
||||
r = r_index << (CMAP_COLOR_LENGTH - info->red.length);
|
||||
g = g_index << (CMAP_COLOR_LENGTH - info->green.length);
|
||||
b = b_index << (CMAP_COLOR_LENGTH - info->blue.length);
|
||||
|
||||
*(cmap->red + i) = r;
|
||||
*(cmap->green + i) = g;
|
||||
*(cmap->blue + i) = b;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmap_update(fd, cmap))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t color2pixel(struct fb_info_t *info, uint32_t color)
|
||||
{
|
||||
uint32_t r, g, b;
|
||||
|
||||
r = bit_mask[BITS_PER_RGB] & (color >> (BITS_PER_RGB * 2));
|
||||
g = bit_mask[BITS_PER_RGB] & (color >> BITS_PER_RGB);
|
||||
b = bit_mask[BITS_PER_RGB] & (color >> 0);
|
||||
|
||||
r = r >> (BITS_PER_RGB - info->red.length);
|
||||
g = g >> (BITS_PER_RGB - info->green.length);
|
||||
b = b >> (BITS_PER_RGB - info->blue.length);
|
||||
|
||||
return (r << info->red.offset)
|
||||
+ (0xff << 24) /* transparency */
|
||||
+ (g << info->green.offset)
|
||||
+ (b << info->blue.offset);
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool init_truecolor(struct fb_info_t *info, cmap_t **cmap, cmap_t **cmap_orig)
|
||||
{
|
||||
switch(info->bits_per_pixel) {
|
||||
case 15: /* XXX: 15 bpp is not tested */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
logging(ERROR, "truecolor %d bpp not supported\n", info->bits_per_pixel);
|
||||
return false;
|
||||
}
|
||||
/* we don't use cmap in truecolor */
|
||||
*cmap = *cmap_orig = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init_indexcolor(int fd, struct fb_info_t *info, cmap_t **cmap, cmap_t **cmap_orig)
|
||||
{
|
||||
int colors, max_length;
|
||||
|
||||
if (info->visual == YAFT_FB_VISUAL_DIRECTCOLOR) {
|
||||
switch(info->bits_per_pixel) {
|
||||
case 15: /* XXX: 15 bpp is not tested */
|
||||
case 16:
|
||||
case 24: /* XXX: 24 bpp is not tested */
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
logging(ERROR, "directcolor %d bpp not supported\n", info->bits_per_pixel);
|
||||
return false;
|
||||
}
|
||||
logging(DEBUG, "red.length:%d gree.length:%d blue.length:%d\n",
|
||||
info->red.length, info->green.length, info->blue.length);
|
||||
|
||||
max_length = (info->red.length > info->green.length) ? info->red.length: info->green.length;
|
||||
max_length = (max_length > info->blue.length) ? max_length: info->blue.length;
|
||||
} else { /* YAFT_FB_VISUAL_PSEUDOCOLOR */
|
||||
switch(info->bits_per_pixel) {
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
logging(ERROR, "pseudocolor %d bpp not supported\n", info->bits_per_pixel);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* in pseudo color, we use fixed palette (red/green: 3bit, blue: 2bit).
|
||||
this palette is not compatible with xterm 256 colors,
|
||||
but we can convert 24bit color into palette number easily. */
|
||||
info->red.length = 3;
|
||||
info->green.length = 3;
|
||||
info->blue.length = 2;
|
||||
|
||||
info->red.offset = 5;
|
||||
info->green.offset = 2;
|
||||
info->blue.offset = 0;
|
||||
|
||||
/* XXX: not 3 but 8, each color has 256 colors palette */
|
||||
max_length = 8;
|
||||
}
|
||||
|
||||
colors = 1 << max_length;
|
||||
logging(DEBUG, "colors:%d max_length:%d\n", colors, max_length);
|
||||
|
||||
*cmap = cmap_create(colors);
|
||||
*cmap_orig = cmap_create(colors);
|
||||
|
||||
if (!(*cmap) || !(*cmap_orig))
|
||||
goto cmap_init_err;
|
||||
|
||||
if (!cmap_save(fd, *cmap_orig)) {
|
||||
logging(WARN, "couldn't save original cmap\n");
|
||||
cmap_die(*cmap_orig);
|
||||
*cmap_orig = NULL;
|
||||
}
|
||||
|
||||
if (!cmap_init(fd, info, *cmap, colors, max_length))
|
||||
goto cmap_init_err;
|
||||
|
||||
return true;
|
||||
|
||||
cmap_init_err:
|
||||
cmap_die(*cmap);
|
||||
cmap_die(*cmap_orig);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void fb_print_info(struct fb_info_t *info)
|
||||
{
|
||||
const char *type_str[] = {
|
||||
[YAFT_FB_TYPE_PACKED_PIXELS] = "YAFT_FB_TYPE_PACKED_PIXELS",
|
||||
[YAFT_FB_TYPE_PLANES] = "YAFT_FB_TYPE_PLANES",
|
||||
[YAFT_FB_TYPE_UNKNOWN] = "YAFT_FB_TYPE_UNKNOWN",
|
||||
};
|
||||
|
||||
const char *visual_str[] = {
|
||||
[YAFT_FB_VISUAL_TRUECOLOR] = "YAFT_FB_VISUAL_TRUECOLOR",
|
||||
[YAFT_FB_VISUAL_DIRECTCOLOR] = "YAFT_FB_VISUAL_DIRECTCOLOR",
|
||||
[YAFT_FB_VISUAL_PSEUDOCOLOR] = "YAFT_FB_VISUAL_PSEUDOCOLOR",
|
||||
[YAFT_FB_VISUAL_UNKNOWN] = "YAFT_FB_VISUAL_UNKNOWN",
|
||||
};
|
||||
|
||||
logging(DEBUG, "framebuffer info:\n");
|
||||
logging(DEBUG, "\tred(off:%d len:%d) green(off:%d len:%d) blue(off:%d len:%d)\n",
|
||||
info->red.offset, info->red.length, info->green.offset, info->green.length, info->blue.offset, info->blue.length);
|
||||
logging(DEBUG, "\tresolution %dx%d\n", info->width, info->height);
|
||||
logging(DEBUG, "\tscreen size:%ld line length:%d\n", info->screen_size, info->line_length);
|
||||
logging(DEBUG, "\tbits_per_pixel:%d bytes_per_pixel:%d\n", info->bits_per_pixel, info->bytes_per_pixel);
|
||||
logging(DEBUG, "\ttype:%s\n", type_str[info->type]);
|
||||
logging(DEBUG, "\tvisual:%s\n", visual_str[info->visual]);
|
||||
}
|
||||
|
||||
bool fb_init(struct framebuffer_t *fb)
|
||||
{
|
||||
extern const uint32_t color_list[COLORS]; /* defined in color.h */
|
||||
#if 0
|
||||
extern const char *fb_path; /* defined in conf.h */
|
||||
const char *path;
|
||||
char *env;
|
||||
/* open framebuffer device: check FRAMEBUFFER env at first */
|
||||
path = ((env = getenv("FRAMEBUFFER")) == NULL) ? fb_path: env;
|
||||
if ((fb->fd = eopen(path, O_RDWR)) < 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
fb->buf = (uint32_t *)fb->info.cfb->getBackBufferPointer();
|
||||
/* os dependent initialize */
|
||||
if (!set_fbinfo(fb->fd, &fb->info))
|
||||
return false; //goto set_fbinfo_failed;
|
||||
|
||||
if (VERBOSE)
|
||||
fb_print_info(&fb->info);
|
||||
|
||||
#if 0
|
||||
/* allocate memory */
|
||||
fb->fp = (uint8_t *) emmap(0, fb->info.screen_size,
|
||||
PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0);
|
||||
fb->buf = (uint8_t *) ecalloc(1, fb->info.screen_size);
|
||||
fb->wall = ((env = getenv("YAFT")) && strstr(env, "wall")) ?
|
||||
load_wallpaper(fb->fp, fb->info.screen_size): NULL;
|
||||
|
||||
/* error check */
|
||||
if (fb->fp == MAP_FAILED || !fb->buf)
|
||||
goto allocate_failed;
|
||||
#endif
|
||||
|
||||
if (fb->info.type != YAFT_FB_TYPE_PACKED_PIXELS) {
|
||||
/* TODO: support planes type */
|
||||
logging(ERROR, "unsupport framebuffer type\n");
|
||||
goto fb_init_failed;
|
||||
}
|
||||
|
||||
if (fb->info.visual == YAFT_FB_VISUAL_TRUECOLOR) {
|
||||
#if 0
|
||||
if (!init_truecolor(&fb->info, &fb->cmap, &fb->cmap_orig))
|
||||
goto fb_init_failed;
|
||||
} else if (fb->info.visual == YAFT_FB_VISUAL_DIRECTCOLOR
|
||||
|| fb->info.visual == YAFT_FB_VISUAL_PSEUDOCOLOR) {
|
||||
if (!init_indexcolor(fb->fd, &fb->info, &fb->cmap, &fb->cmap_orig))
|
||||
goto fb_init_failed;
|
||||
#endif
|
||||
} else {
|
||||
/* TODO: support mono visual */
|
||||
logging(ERROR, "unsupport framebuffer visual\n");
|
||||
goto fb_init_failed;
|
||||
}
|
||||
|
||||
/* init color palette */
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
fb->real_palette[i] = color2pixel(&fb->info, color_list[i]);
|
||||
|
||||
return true;
|
||||
|
||||
fb_init_failed:
|
||||
#if 0
|
||||
allocate_failed:
|
||||
free(fb->buf);
|
||||
free(fb->wall);
|
||||
if (fb->fp != MAP_FAILED)
|
||||
emunmap(fb->fp, fb->info.screen_size);
|
||||
set_fbinfo_failed:
|
||||
eclose(fb->fd);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void fb_die(struct framebuffer_t *fb)
|
||||
{
|
||||
cmap_die(fb->cmap);
|
||||
if (fb->cmap_orig) {
|
||||
put_cmap(fb->fd, fb->cmap_orig);
|
||||
cmap_die(fb->cmap_orig);
|
||||
}
|
||||
free(fb->wall);
|
||||
free(fb->buf);
|
||||
emunmap(fb->fp, fb->info.screen_size);
|
||||
eclose(fb->fd);
|
||||
//fb_release(fb->fd, &fb->info); /* os specific */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static inline void draw_sixel(struct framebuffer_t *fb, int line, int col, uint8_t *pixmap)
|
||||
{
|
||||
int h, w, src_offset, dst_offset;
|
||||
uint32_t pixel, color = 0;
|
||||
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
for (w = 0; w < CELL_WIDTH; w++) {
|
||||
src_offset = BYTES_PER_PIXEL * (h * CELL_WIDTH + w);
|
||||
memcpy(&color, pixmap + src_offset, BYTES_PER_PIXEL);
|
||||
|
||||
dst_offset = (line * CELL_HEIGHT + h) * fb->info.line_length
|
||||
+ (col * CELL_WIDTH + w) * fb->info.bytes_per_pixel;
|
||||
pixel = color2pixel(&fb->info, color);
|
||||
memcpy(fb->buf + dst_offset, &pixel, fb->info.bytes_per_pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void draw_line(struct framebuffer_t *fb, struct terminal_t *term, int line)
|
||||
{
|
||||
int pos, /*size,*/ bdf_padding, glyph_width, margin_right;
|
||||
int col, w, h;
|
||||
uint32_t pixel;
|
||||
struct color_pair_t color_pair;
|
||||
struct cell_t *cellp;
|
||||
|
||||
for (col = term->cols - 1; col >= 0; col--) {
|
||||
margin_right = (term->cols - 1 - col) * CELL_WIDTH;
|
||||
|
||||
/* target cell */
|
||||
cellp = &term->cells[line][col];
|
||||
|
||||
#if 0
|
||||
/* draw sixel pixmap */
|
||||
if (cellp->has_pixmap) {
|
||||
draw_sixel(fb, line, col, cellp->pixmap);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy current color_pair (maybe changed) */
|
||||
color_pair = cellp->color_pair;
|
||||
|
||||
/* check wide character or not */
|
||||
glyph_width = (cellp->width == HALF) ? CELL_WIDTH: CELL_WIDTH * 2;
|
||||
bdf_padding = my_ceil(glyph_width, BITS_PER_BYTE) * BITS_PER_BYTE - glyph_width;
|
||||
if (cellp->width == WIDE)
|
||||
bdf_padding += CELL_WIDTH;
|
||||
|
||||
/* check cursor positon */
|
||||
if ((term->mode & MODE_CURSOR && line == term->cursor.y)
|
||||
&& (col == term->cursor.x
|
||||
|| (cellp->width == WIDE && (col + 1) == term->cursor.x)
|
||||
|| (cellp->width == NEXT_TO_WIDE && (col - 1) == term->cursor.x))) {
|
||||
color_pair.fg = DEFAULT_BG;
|
||||
color_pair.bg = (!vt_active && BACKGROUND_DRAW) ? PASSIVE_CURSOR_COLOR: ACTIVE_CURSOR_COLOR;
|
||||
}
|
||||
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
/* if UNDERLINE attribute on, swap bg/fg */
|
||||
if ((h == (CELL_HEIGHT - 1)) && (cellp->attribute & attr_mask[ATTR_UNDERLINE]))
|
||||
color_pair.bg = color_pair.fg;
|
||||
|
||||
for (w = 0; w < CELL_WIDTH; w++) {
|
||||
pos = (term->width - 1 - margin_right - w)
|
||||
+ (line * CELL_HEIGHT + h) * fb->info.width;
|
||||
|
||||
/* set color palette */
|
||||
if (cellp->glyphp->bitmap[h] & (0x01 << (bdf_padding + w)))
|
||||
pixel = fb->real_palette[color_pair.fg];
|
||||
#if 0
|
||||
else if (fb->wall && color_pair.bg == DEFAULT_BG) /* wallpaper */
|
||||
memcpy(&pixel, fb->wall + pos, fb->info.bytes_per_pixel);
|
||||
#endif
|
||||
else
|
||||
pixel = fb->real_palette[color_pair.bg];
|
||||
|
||||
/* update copy buffer only */
|
||||
//memcpy(fb->buf + pos, &pixel, fb->info.bytes_per_pixel);
|
||||
fb->buf[pos] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* actual display update (bit blit) */
|
||||
pos = (line * CELL_HEIGHT) * fb->info.line_length;
|
||||
size = CELL_HEIGHT * fb->info.line_length;
|
||||
memcpy(fb->fp + pos, fb->buf + pos, size);
|
||||
#endif
|
||||
/* TODO: page flip
|
||||
if fb_fix_screeninfo.ypanstep > 0, we can use hardware panning.
|
||||
set fb_fix_screeninfo.{yres_virtual,yoffset} and call ioctl(FBIOPAN_DISPLAY)
|
||||
but drivers of recent hardware (inteldrmfb, nouveaufb, radeonfb) don't support...
|
||||
(maybe we can use this by using libdrm) */
|
||||
/* TODO: vertical synchronizing */
|
||||
|
||||
term->line_dirty[line] = ((term->mode & MODE_CURSOR) && term->cursor.y == line) ? true: false;
|
||||
}
|
||||
|
||||
void refresh(struct framebuffer_t *fb, struct terminal_t *term)
|
||||
{
|
||||
if (term->palette_modified) {
|
||||
term->palette_modified = false;
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
fb->real_palette[i] = color2pixel(&fb->info, term->virtual_palette[i]);
|
||||
}
|
||||
|
||||
logging(DEBUG,"%s: mode %x cur: %x cursor.y %d\n", __func__, term->mode, MODE_CURSOR, term->cursor.y);
|
||||
if (term->mode & MODE_CURSOR)
|
||||
term->line_dirty[term->cursor.y] = true;
|
||||
|
||||
for (int line = 0; line < term->lines; line++) {
|
||||
if (term->line_dirty[line]) {
|
||||
draw_line(fb, term, line);
|
||||
}
|
||||
}
|
||||
fb->info.cfb->blit2FB(fb->buf, fb->info.width, fb->info.height, fb->info.xstart, fb->info.ystart, 0, 0);
|
||||
}
|
@@ -1,112 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* XXX: _XOPEN_SOURCE >= 600 invalidates __BSD_VISIBLE
|
||||
so define some types manually */
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short u_short;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
#include <machine/param.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/fbio.h>
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct fbcmap cmap_t;
|
||||
|
||||
enum {
|
||||
CMAP_COLOR_LENGTH = sizeof(u_char) * BITS_PER_BYTE,
|
||||
};
|
||||
|
||||
/* os specific ioctl */
|
||||
void alloc_cmap(cmap_t *cmap, int colors)
|
||||
{
|
||||
/* commond member included in struct fbcmap and video_color_palette_t */
|
||||
cmap->index = 0;
|
||||
cmap->count = colors;
|
||||
cmap->red = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->green = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->blue = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
/* not exist in struct fbcmap */
|
||||
//cmap->transparent = NULL;
|
||||
}
|
||||
|
||||
int put_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, FBIOPUTCMAP, cmap);
|
||||
}
|
||||
|
||||
int get_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, FBIOGETCMAP, cmap);
|
||||
}
|
||||
|
||||
/* initialize struct fb_info_t */
|
||||
void set_bitfield(video_info_t *vinfo,
|
||||
struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue)
|
||||
{
|
||||
red->length = vinfo->vi_pixel_fsizes[0];
|
||||
green->length = vinfo->vi_pixel_fsizes[1];
|
||||
blue->length = vinfo->vi_pixel_fsizes[2];
|
||||
|
||||
red->offset = vinfo->vi_pixel_fields[0];
|
||||
green->offset = vinfo->vi_pixel_fields[1];
|
||||
blue->offset = vinfo->vi_pixel_fields[2];
|
||||
}
|
||||
|
||||
void set_type_visual(struct fb_info_t *info, int type, int visual)
|
||||
{
|
||||
/* ref: jfbterm-FreeBSD http://www.ac.auone-net.jp/~baba/jfbterm/ */
|
||||
if (type == V_INFO_MM_PACKED || type == V_INFO_MM_DIRECT)
|
||||
info->type = YAFT_FB_TYPE_PACKED_PIXELS;
|
||||
else if (type == V_INFO_MM_PLANAR)
|
||||
info->type = YAFT_FB_TYPE_PLANES;
|
||||
else
|
||||
info->type = YAFT_FB_TYPE_UNKNOWN;
|
||||
|
||||
/* in FreeBSD, Direct Color is not exist? */
|
||||
if (type == V_INFO_MM_DIRECT && info->bits_per_pixel >= 15)
|
||||
info->visual = YAFT_FB_VISUAL_TRUECOLOR;
|
||||
else if (type == V_INFO_MM_PACKED && visual & V_ADP_PALETTE
|
||||
&& info->bits_per_pixel == 8)
|
||||
info->visual = YAFT_FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
info->visual = YAFT_FB_VISUAL_UNKNOWN;
|
||||
}
|
||||
|
||||
bool set_fbinfo(int fd, struct fb_info_t *info)
|
||||
{
|
||||
int video_mode;
|
||||
video_info_t vinfo;
|
||||
video_adapter_info_t ainfo;
|
||||
|
||||
if (ioctl(fd, FBIO_GETMODE, &video_mode)) {
|
||||
logging(ERROR, "ioctl: FBIO_GETMODE failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
vinfo.vi_mode = video_mode;
|
||||
if (ioctl(fd, FBIO_MODEINFO, &vinfo)) {
|
||||
logging(ERROR, "ioctl: FBIO_MODEINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(fd, FBIO_ADPINFO, &ainfo)) {
|
||||
logging(ERROR, "ioctl: FBIO_ADPINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
set_bitfield(&vinfo, &info->red, &info->green, &info->blue);
|
||||
|
||||
info->width = vinfo.vi_width;
|
||||
info->height = vinfo.vi_height;
|
||||
info->screen_size = ainfo.va_window_size;
|
||||
info->line_length = ainfo.va_line_width;
|
||||
|
||||
info->bits_per_pixel = vinfo.vi_depth;
|
||||
info->bytes_per_pixel = my_ceil(vinfo.vi_depth, BITS_PER_BYTE);
|
||||
|
||||
logging(DEBUG, "mem_model:%d va_flags:0x%X\n", vinfo.vi_mem_model, ainfo.va_flags);
|
||||
set_type_visual(info, vinfo.vi_mem_model, ainfo.va_flags);
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,104 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#include <linux/fb.h>
|
||||
#include <linux/vt.h>
|
||||
#include <linux/kd.h>
|
||||
|
||||
typedef struct fb_cmap cmap_t;
|
||||
|
||||
enum {
|
||||
CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE,
|
||||
};
|
||||
|
||||
/* os specific ioctl */
|
||||
void alloc_cmap(cmap_t *cmap, int colors)
|
||||
{
|
||||
cmap->start = 0;
|
||||
cmap->len = colors;
|
||||
cmap->red = (__u16 *) ecalloc(colors, sizeof(__u16));
|
||||
cmap->green = (__u16 *) ecalloc(colors, sizeof(__u16));
|
||||
cmap->blue = (__u16 *) ecalloc(colors, sizeof(__u16));
|
||||
cmap->transp = NULL;
|
||||
}
|
||||
|
||||
int put_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, FBIOPUTCMAP, cmap);
|
||||
}
|
||||
|
||||
int get_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, FBIOGETCMAP, cmap);
|
||||
}
|
||||
|
||||
/* initialize struct fb_info_t */
|
||||
void set_bitfield(struct fb_var_screeninfo *vinfo,
|
||||
struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue)
|
||||
{
|
||||
red->length = vinfo->red.length;
|
||||
green->length = vinfo->green.length;
|
||||
blue->length = vinfo->blue.length;
|
||||
|
||||
red->offset = vinfo->red.offset;
|
||||
green->offset = vinfo->green.offset;
|
||||
blue->offset = vinfo->blue.offset;
|
||||
}
|
||||
|
||||
enum fb_type_t set_type(__u32 type)
|
||||
{
|
||||
if (type == FB_TYPE_PACKED_PIXELS)
|
||||
return YAFT_FB_TYPE_PACKED_PIXELS;
|
||||
else if (type == FB_TYPE_PLANES)
|
||||
return YAFT_FB_TYPE_PLANES;
|
||||
else
|
||||
return YAFT_FB_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
enum fb_visual_t set_visual(__u32 visual)
|
||||
{
|
||||
if (visual == FB_VISUAL_TRUECOLOR)
|
||||
return YAFT_FB_VISUAL_TRUECOLOR;
|
||||
else if (visual == FB_VISUAL_DIRECTCOLOR)
|
||||
return YAFT_FB_VISUAL_DIRECTCOLOR;
|
||||
else if (visual == FB_VISUAL_PSEUDOCOLOR)
|
||||
return YAFT_FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
return YAFT_FB_VISUAL_UNKNOWN;
|
||||
}
|
||||
|
||||
bool set_fbinfo(int fd, struct fb_info_t *info)
|
||||
{
|
||||
struct fb_fix_screeninfo finfo;
|
||||
struct fb_var_screeninfo vinfo;
|
||||
|
||||
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) {
|
||||
logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||
logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
set_bitfield(&vinfo, &info->red, &info->green, &info->blue);
|
||||
|
||||
info->width = vinfo.xres;
|
||||
info->height = vinfo.yres;
|
||||
info->screen_size = finfo.smem_len;
|
||||
info->line_length = finfo.line_length;
|
||||
|
||||
info->bits_per_pixel = vinfo.bits_per_pixel;
|
||||
info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE);
|
||||
|
||||
info->type = set_type(finfo.type);
|
||||
info->visual = set_visual(finfo.visual);
|
||||
|
||||
/* check screen [xy]offset and initialize because linux console changes these values */
|
||||
if (vinfo.xoffset != 0 || vinfo.yoffset != 0) {
|
||||
vinfo.xoffset = vinfo.yoffset = 0;
|
||||
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo))
|
||||
logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* XXX: _XOPEN_SOURCE >= 600 invalidates __BSD_VISIBLE
|
||||
so define some types manually */
|
||||
typedef unsigned char unchar;
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
#include <sys/param.h>
|
||||
#include <dev/wscons/wsdisplay_usl_io.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsksymdef.h>
|
||||
|
||||
typedef struct wsdisplay_cmap cmap_t;
|
||||
|
||||
enum {
|
||||
CMAP_COLOR_LENGTH = sizeof(u_char) * BITS_PER_BYTE,
|
||||
};
|
||||
|
||||
void alloc_cmap(cmap_t *cmap, int colors)
|
||||
{
|
||||
cmap->index = 0;
|
||||
cmap->count = colors;
|
||||
cmap->red = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->green = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->blue = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
}
|
||||
|
||||
int put_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, WSDISPLAYIO_PUTCMAP, cmap);
|
||||
}
|
||||
|
||||
int get_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, WSDISPLAYIO_GETCMAP, cmap);
|
||||
}
|
||||
|
||||
void set_bitfield(int depth, struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue)
|
||||
{
|
||||
switch (depth) {
|
||||
case 15:
|
||||
red->offset = 10; green->offset = 5; blue->offset = 0;
|
||||
red->length = 5; green->length = 5; blue->length = 5;
|
||||
break;
|
||||
case 16:
|
||||
red->offset = 11; green->offset = 5; blue->offset = 0;
|
||||
red->length = 5; green->length = 6; blue->length = 5;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
red->offset = 16; green->offset = 8; blue->offset = 0;
|
||||
red->length = 8; green->length = 8; blue->length = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void set_type_visual(struct fb_info_t *info)
|
||||
{
|
||||
info->type = YAFT_FB_TYPE_PACKED_PIXELS;
|
||||
|
||||
if (info->bits_per_pixel == 8)
|
||||
info->visual = YAFT_FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
info->visual = YAFT_FB_VISUAL_TRUECOLOR;
|
||||
}
|
||||
|
||||
bool set_fbinfo(int fd, struct fb_info_t *info)
|
||||
{
|
||||
int mode;
|
||||
struct wsdisplay_fbinfo finfo;
|
||||
|
||||
mode = WSDISPLAYIO_MODE_DUMBFB;
|
||||
if (ioctl(fd, WSDISPLAYIO_SMODE, &mode)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_SMODE failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(fd, WSDISPLAYIO_GINFO, &finfo)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_GINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
logging(DEBUG, "width:%d height:%d depth:%d\n", finfo.width, finfo.height, finfo.depth);
|
||||
|
||||
info->width = finfo.width;
|
||||
info->height = finfo.height;
|
||||
|
||||
info->bits_per_pixel = finfo.depth;
|
||||
info->bytes_per_pixel = my_ceil(finfo.depth, BITS_PER_BYTE);
|
||||
|
||||
info->line_length = info->bytes_per_pixel * info->width;
|
||||
info->screen_size = info->height * info->line_length;
|
||||
|
||||
set_bitfield(info->bits_per_pixel, &info->red, &info->green, &info->blue);
|
||||
set_type_visual(info);
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* neutrino specific framebuffer stuff for yaft framebuffer terminal
|
||||
* (C) 2018 Stefan Seyfried
|
||||
* License: GPL-2.0
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* derived from yaft/fb/linux.h,
|
||||
* original code
|
||||
* Copyright (c) 2012 haru <uobikiemukot at gmail dot com>
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*/
|
||||
#include <driver/framebuffer.h>
|
||||
#ifdef DEBUG
|
||||
/* maybe on compiler command line or in neutrino config.h */
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CMAP_COLOR_LENGTH = sizeof(__u16) * BITS_PER_BYTE,
|
||||
};
|
||||
|
||||
/* initialize struct fb_info_t */
|
||||
void set_bitfield(struct fb_var_screeninfo *vinfo,
|
||||
struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue)
|
||||
{
|
||||
red->length = vinfo->red.length;
|
||||
green->length = vinfo->green.length;
|
||||
blue->length = vinfo->blue.length;
|
||||
|
||||
red->offset = vinfo->red.offset;
|
||||
green->offset = vinfo->green.offset;
|
||||
blue->offset = vinfo->blue.offset;
|
||||
}
|
||||
|
||||
enum fb_type_t set_type(__u32 type)
|
||||
{
|
||||
if (type == FB_TYPE_PACKED_PIXELS)
|
||||
return YAFT_FB_TYPE_PACKED_PIXELS;
|
||||
else if (type == FB_TYPE_PLANES)
|
||||
return YAFT_FB_TYPE_PLANES;
|
||||
else
|
||||
return YAFT_FB_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
enum fb_visual_t set_visual(__u32 visual)
|
||||
{
|
||||
if (visual == FB_VISUAL_TRUECOLOR)
|
||||
return YAFT_FB_VISUAL_TRUECOLOR;
|
||||
else if (visual == FB_VISUAL_DIRECTCOLOR)
|
||||
return YAFT_FB_VISUAL_DIRECTCOLOR;
|
||||
else if (visual == FB_VISUAL_PSEUDOCOLOR)
|
||||
return YAFT_FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
return YAFT_FB_VISUAL_UNKNOWN;
|
||||
}
|
||||
|
||||
bool set_fbinfo(int /*fd*/, struct fb_info_t *info)
|
||||
{
|
||||
struct fb_fix_screeninfo finfo;
|
||||
struct fb_var_screeninfo vinfo;
|
||||
#if 0
|
||||
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo)) {
|
||||
logging(ERROR, "ioctl: FBIOGET_FSCREENINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||
logging(ERROR, "ioctl: FBIOGET_VSCREENINFO failed\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
struct fb_var_screeninfo *var = info->cfb->getScreenInfo();
|
||||
memcpy(&vinfo, var, sizeof(struct fb_var_screeninfo));
|
||||
memset(&finfo, 0, sizeof(struct fb_fix_screeninfo));
|
||||
finfo.line_length = info->cfb->getScreenX(); // * (vinfo.bits_per_pixel / 8);
|
||||
finfo.visual = FB_VISUAL_TRUECOLOR;
|
||||
finfo.type = FB_TYPE_PACKED_PIXELS;
|
||||
strcpy(finfo.id, "neutrino FB");
|
||||
|
||||
set_bitfield(&vinfo, &info->red, &info->green, &info->blue);
|
||||
|
||||
info->bits_per_pixel = vinfo.bits_per_pixel;
|
||||
info->bytes_per_pixel = my_ceil(info->bits_per_pixel, BITS_PER_BYTE);
|
||||
info->width = info->cfb->getScreenWidth(); //vinfo.xres;
|
||||
info->height = info->cfb->getScreenHeight(); //vinfo.yres;
|
||||
info->xstart = info->cfb->getScreenX();
|
||||
info->ystart = info->cfb->getScreenY();
|
||||
info->line_length = info->width * info->bytes_per_pixel;
|
||||
info->screen_size = info->line_length * info->height; //vinfo.yres;
|
||||
|
||||
info->type = set_type(finfo.type);
|
||||
info->visual = set_visual(finfo.visual);
|
||||
|
||||
/* check screen [xy]offset and initialize because linux console changes these values */
|
||||
if (vinfo.xoffset != 0 || vinfo.yoffset != 0) {
|
||||
vinfo.xoffset = vinfo.yoffset = 0;
|
||||
#if 0
|
||||
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo))
|
||||
logging(WARN, "couldn't reset offset (x:%d y:%d)\n", vinfo.xoffset, vinfo.yoffset);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,128 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* XXX: _XOPEN_SOURCE >= 600 invalidates __BSD_VISIBLE
|
||||
so define some types manually */
|
||||
typedef unsigned char unchar;
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned long u_long;
|
||||
#include <sys/param.h>
|
||||
#include <dev/wscons/wsdisplay_usl_io.h>
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsksymdef.h>
|
||||
|
||||
typedef struct wsdisplay_cmap cmap_t;
|
||||
|
||||
enum {
|
||||
CMAP_COLOR_LENGTH = sizeof(u_char) * BITS_PER_BYTE,
|
||||
FB_WIDTH = 640,
|
||||
FB_HEIGHT = 480,
|
||||
FB_DEPTH = 8,
|
||||
};
|
||||
|
||||
void alloc_cmap(cmap_t *cmap, int colors)
|
||||
{
|
||||
cmap->index = 0;
|
||||
cmap->count = colors;
|
||||
cmap->red = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->green = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
cmap->blue = (u_char *) ecalloc(colors, sizeof(u_char));
|
||||
}
|
||||
|
||||
int put_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, WSDISPLAYIO_PUTCMAP, cmap);
|
||||
}
|
||||
|
||||
int get_cmap(int fd, cmap_t *cmap)
|
||||
{
|
||||
return ioctl(fd, WSDISPLAYIO_GETCMAP, cmap);
|
||||
}
|
||||
|
||||
void set_bitfield(int depth, struct bitfield_t *red, struct bitfield_t *green, struct bitfield_t *blue)
|
||||
{
|
||||
switch (depth) {
|
||||
case 15:
|
||||
red->offset = 10; green->offset = 5; blue->offset = 0;
|
||||
red->length = 5; green->length = 5; blue->length = 5;
|
||||
break;
|
||||
case 16:
|
||||
red->offset = 11; green->offset = 5; blue->offset = 0;
|
||||
red->length = 5; green->length = 6; blue->length = 5;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
red->offset = 16; green->offset = 8; blue->offset = 0;
|
||||
red->length = 8; green->length = 8; blue->length = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void set_type_visual(struct fb_info_t *info)
|
||||
{
|
||||
info->type = YAFT_FB_TYPE_PACKED_PIXELS;
|
||||
|
||||
if (info->bits_per_pixel == 8)
|
||||
info->visual = YAFT_FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
info->visual = YAFT_FB_VISUAL_TRUECOLOR;
|
||||
}
|
||||
|
||||
bool set_fbinfo(int fd, struct fb_info_t *info)
|
||||
{
|
||||
int mode;
|
||||
struct wsdisplay_fbinfo finfo;
|
||||
struct wsdisplay_gfx_mode gfx_mode = {.width = FB_WIDTH, .height = FB_HEIGHT, .depth = FB_DEPTH};
|
||||
|
||||
/*
|
||||
if (ioctl(fd, WSDISPLAYIO_GMODE, &info->reserved)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_GMODE failed\n");
|
||||
return false;
|
||||
}
|
||||
logging(DEBUG, "orig_mode:%d\n", info->reserved);
|
||||
*/
|
||||
|
||||
if (ioctl(fd, WSDISPLAYIO_SETGFXMODE, &gfx_mode)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_SETGFXMODE failed\n");
|
||||
goto set_fbinfo_failed;
|
||||
}
|
||||
|
||||
mode = WSDISPLAYIO_MODE_DUMBFB;
|
||||
if (ioctl(fd, WSDISPLAYIO_SMODE, &mode)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_SMODE failed\n");
|
||||
goto set_fbinfo_failed;
|
||||
}
|
||||
|
||||
if (ioctl(fd, WSDISPLAYIO_GINFO, &finfo)) {
|
||||
logging(ERROR, "ioctl: WSDISPLAYIO_GINFO failed\n");
|
||||
goto set_fbinfo_failed;
|
||||
}
|
||||
logging(DEBUG, "finfo width:%d height:%d depth:%d\n", finfo.width, finfo.height, finfo.depth);
|
||||
|
||||
info->width = FB_WIDTH;
|
||||
info->height = FB_HEIGHT;
|
||||
|
||||
info->bits_per_pixel = FB_DEPTH;
|
||||
info->bytes_per_pixel = my_ceil(FB_DEPTH, BITS_PER_BYTE);
|
||||
|
||||
info->line_length = info->bytes_per_pixel * info->width;
|
||||
info->screen_size = info->height * info->line_length;
|
||||
|
||||
set_bitfield(info->bits_per_pixel, &info->red, &info->green, &info->blue);
|
||||
set_type_visual(info);
|
||||
|
||||
return true;
|
||||
|
||||
set_fbinfo_failed:
|
||||
//ioctl(fd, WSDISPLAYIO_SMODE, &info->reserved);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
void fb_release(int fd, struct fb_info_t *info)
|
||||
{
|
||||
ioctl(fd, WSDISPLAYIO_SMODE, &info->reserved);
|
||||
}
|
||||
*/
|
@@ -1,39 +0,0 @@
|
||||
<EFBFBD><EFBFBD>X Window BDF/PCF<43><46><EFBFBD><EFBFBD> 16<31>ɥåȥե<C8A5><D5A5><EFBFBD><EFBFBD><EFBFBD>milkjf<6A><66>
|
||||
|
||||
<20><><EFBFBD><EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>ݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡ<EFBFBD>
|
||||
|
||||
X68000/X68030 <20><><EFBFBD><EFBFBD><EAA1BC><EFBFBD>Ѥˡ<D1A4><CBA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͤ<EFBFBD><CDA4><EFBFBD><EFBFBD><EFBFBD>줿<EFBFBD><ECA4BF>milkjf<6A>ե<EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><C8BE>)<29><EFBFBD><F2A1A4B5>Ĥ<EFBFBD><C4A4><EFBFBD><EFBFBD><EFBFBD> X Window<6F><77>BDF<44><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ۤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD>ˤʤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>(Public Domain<69>Ǥ<EFBFBD>)<29><><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꥸ<EFBFBD>ʥ<EFBFBD>
|
||||
<EFBFBD><EFBFBD> milkjf<6A>ˤʤ<CBA4><CAA4><EFBFBD>ʬ(<28>ä˴<C3A4><CBB4><EFBFBD><EFBFBD><EFBFBD>)<29>ȡ<EFBFBD> <20><><EFBFBD>ꥷ<EFBFBD><EAA5B7>ʸ<EFBFBD><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʸ<EFBFBD><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
|
||||
<20>ե<EFBFBD><D5A5><EFBFBD><EFBFBD>Ȥΰ<C8A4><CEB0><EFBFBD><EFBFBD>ϰʲ<CFB0><CAB2><EFBFBD><EFBFBD>̤<EFBFBD><CCA4>Ǥ<EFBFBD><C7A4><EFBFBD>bold<6C>Τ<EFBFBD>mkbold<6C>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>
|
||||
<EFBFBD>㴳<EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ä<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΤǤ<EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
milkjf_8x16.bdf(.pcf)
|
||||
-milkjf-fixed-medium-r-normal--16-150-75-75-C-80-iso8859-1
|
||||
|
||||
milkjf_8x16r.bdf(.pcf)
|
||||
-milkjf-fixed-medium-r-normal--16-150-75-75-C-80-jisx0201.1976-0
|
||||
|
||||
milkjf_k16.bdf(.pcf)
|
||||
-milkjf-fixed-medium-r-normal--16-150-75-75-C-160-jisx0208.1990-0
|
||||
|
||||
milkjf_8x16B.bdf(.pcf)
|
||||
-milkjf-fixed-bold-r-normal--16-150-75-75-C-80-iso8859-1
|
||||
|
||||
milkjf_8x16rb.bdf(.pcf)
|
||||
-milkjf-fixed-bold-r-normal--16-150-75-75-C-80-jisx0201.1976-0
|
||||
|
||||
milkjf_k16b.bdf(.pcf)
|
||||
-milkjf-fixed-bold-r-normal--16-150-75-75-C-160-jisx0208.1990-0
|
||||
|
||||
|
||||
<EFBFBD>ݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡ<EFBFBD>
|
||||
X Window<6F><77>ͭ<EFBFBD><CDAD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˴ؤ<CBB4><D8A4>Ƥϡ<C6A4><CFA1>ʲ<EFBFBD><CAB2>ˤơ<CBA4>
|
||||
http://phe.phyas.aichi-edu.ac.jp/~cyamauch/xfonts.html
|
||||
|
||||
cyamauch@hst.phyas.aichi-edu.ac.jp <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Τ Oct.1,2001
|
||||
<EFBFBD>ݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡݡ<EFBFBD>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,398 +0,0 @@
|
||||
#!/bin/bash
|
||||
# desc: bash script for creating yaft's glyph.h
|
||||
|
||||
# settings
|
||||
YAFT_DIR=`pwd`
|
||||
WORK_DIR=/tmp/glyph_builder
|
||||
ALIAS_FILE=alias
|
||||
|
||||
# infomation of each fonts
|
||||
# mplus
|
||||
MPLUS_VERSION=2.2.4
|
||||
MPLUS_NAME=mplus_bitmap_fonts-${MPLUS_VERSION}
|
||||
MPLUS_FILE=${MPLUS_NAME}.tar.gz
|
||||
MPLUS_URL=http://iij.dl.osdn.jp/mplus-fonts/5030/${MPLUS_FILE}
|
||||
|
||||
# efont
|
||||
EFONT_VERSION=0.4.2
|
||||
EFONT_NAME=efont-unicode-bdf-${EFONT_VERSION}
|
||||
EFONT_FILE=${EFONT_NAME}.tar.bz2
|
||||
EFONT_URL=http://openlab.ring.gr.jp/efont/dist/unicode-bdf/${EFONT_FILE}
|
||||
|
||||
# milkjf
|
||||
# already included in yaft
|
||||
|
||||
# unifont
|
||||
UNIFONT_VERSION=8.0.01
|
||||
UNIFONT_NAME=unifont-${UNIFONT_VERSION}
|
||||
UNIFONT_FILE=${UNIFONT_NAME}.bdf.gz
|
||||
UNIFONT_URL=http://unifoundry.com/pub/${UNIFONT_NAME}/font-builds/${UNIFONT_FILE}
|
||||
|
||||
# dina font
|
||||
DINA_VERSION=
|
||||
DINA_NAME=Dina
|
||||
DINA_FILE=${DINA_NAME}.zip
|
||||
DINA_URL=http://www.donationcoder.com/Software/Jibz/${DINA_NAME}/downloads/${DINA_FILE}
|
||||
|
||||
# terminus font
|
||||
TERMINUS_VERSION=4.39
|
||||
TERMINUS_NAME=terminus-font-${TERMINUS_VERSION}
|
||||
TERMINUS_FILE=${TERMINUS_NAME}.tar.gz
|
||||
TERMINUS_URL=http://sourceforge.net/projects/terminus-font/files/${TERMINUS_NAME}/${TERMINUS_FILE}
|
||||
|
||||
# profont (pcf format)
|
||||
PROFONT_VERSION=
|
||||
PROFONT_NAME=profont-x11
|
||||
PROFONT_FILE=${PROFONT_NAME}.zip
|
||||
PROFONT_URL=http://tobiasjung.name/downloadfile.php?file=${PROFONT_FILE}
|
||||
|
||||
# tamsyn font (pcf format)
|
||||
TAMSYN_VERSION=1.11
|
||||
TAMSYN_NAME=tamsyn-font-${TAMSYN_VERSION}
|
||||
TAMSYN_FILE=${TAMSYN_NAME}.tar.gz
|
||||
TAMSYN_URL=http://www.fial.com/~scott/tamsyn-font/download/${TAMSYN_FILE}
|
||||
|
||||
# wqy-bitmapfont (mkfont_bdf cannot handle this font...)
|
||||
WQY_VERSION=1.0.0-RC1
|
||||
WQY_NAME=wqy-bitmapsong-bdf-${WQY_VERSION}
|
||||
WQY_FILE=${WQY_NAME}.tar.gz
|
||||
WQY_URL=http://jaist.dl.sourceforge.net/project/wqy/wqy-bitmapfont/${WQY_VERSION}/${WQY_FILE}
|
||||
|
||||
# misc functions
|
||||
usage()
|
||||
{
|
||||
echo -e "usage: ./glyph_builder.sh FONTS VARIATIONS"
|
||||
echo -e "\tavalable fonts: mplus, efont, milkjf, unifont, dina, terminus, profont, tamsyn"
|
||||
echo -e "depends on: wget, pcf2bdf"
|
||||
}
|
||||
|
||||
generate()
|
||||
{
|
||||
echo "./mkfont_bdf ./table/${ALIAS_FILE} ${@} > ${YAFT_DIR}/glyph.h"
|
||||
./mkfont_bdf ./table/${ALIAS_FILE} ${@} > ${YAFT_DIR}/glyph.h
|
||||
}
|
||||
|
||||
# each font generate function
|
||||
mplus_create_bdf()
|
||||
{
|
||||
# Install M+ BITMAP FONTS E
|
||||
echo -e "\nInstall M+ BITMAP FONTS E (iso8859-1)..."
|
||||
cd fonts_e
|
||||
|
||||
awk '/^SWIDTH/{$2 += 80} /^DWIDTH/{$2 += 1} {print}' mplus_h12r.bdf \
|
||||
| sed 's/hlv/hlvw/'> mplus_h12rw.bdf
|
||||
cd -
|
||||
|
||||
# Install M+ BITMAP FONTS EURO
|
||||
echo -e "\nInstall M+ BITMAP FONTS EURO (iso8859-15)..."
|
||||
cd fonts_e/euro
|
||||
for f in mplus_*.diff
|
||||
do
|
||||
b=`basename $f .diff`
|
||||
echo "$f $b"
|
||||
cp ../$b.bdf ./
|
||||
patch $b.bdf $b.diff
|
||||
mv $b.bdf $b-euro.bdf
|
||||
done
|
||||
|
||||
awk '/^SWIDTH/{$2 += 80} /^DWIDTH/{$2 += 1} {print}' \
|
||||
mplus_h12r-euro.bdf | sed 's/hlv/hlvw/' > mplus_h12rw-euro.bdf
|
||||
cd -
|
||||
|
||||
echo -e "\nInstall M+ BITMAP FONTS J..."
|
||||
cd fonts_j
|
||||
|
||||
echo "create: mplus_j10b.bdf"
|
||||
echo -n "wait a minute..."
|
||||
../mkbold -r -R mplus_j10r.bdf | sed 's/medium/bold/' \
|
||||
> mplus_j10b.bdf &&
|
||||
echo " done"
|
||||
|
||||
echo "create: mplus_j12b.bdf"
|
||||
echo -n "wait a minute..."
|
||||
../mkbold -r -R mplus_j12r.bdf | sed 's/medium/bold/' \
|
||||
> mplus_j12b.bdf &&
|
||||
echo " done"
|
||||
|
||||
cp mplus_j10r-iso-W4 mplus_j10r-iso.bdf
|
||||
echo "select: mplus_j10r-iso.bdf [W5]"
|
||||
patch mplus_j10r-iso.bdf mplus_j10r-iso-W5.diff
|
||||
#echo "select: mplus_j10r-iso.bdf [W4]"
|
||||
|
||||
for f in mplus_[!j]*-jisx0201.diff
|
||||
do
|
||||
b=`basename $f -jisx0201.diff`
|
||||
echo "create: $b-jisx0201.bdf"
|
||||
cp ../fonts_e/$b.bdf ./
|
||||
patch $b.bdf $b-jisx0201.diff
|
||||
mv $b.bdf $b-jisx0201.bdf
|
||||
done
|
||||
|
||||
for f in mplus_j*-jisx0201.diff
|
||||
do
|
||||
b=`basename $f -jisx0201.diff`
|
||||
echo "create: $b-jisx0201.bdf"
|
||||
cp $b-iso.bdf $b-jisx0201.bdf
|
||||
patch $b-jisx0201.bdf $b-jisx0201.diff
|
||||
done
|
||||
|
||||
# some bug fix
|
||||
sed -i 's|STARTCHAR 0x2455n|STARTCHAR 0x2455|' mplus_j12r.bdf
|
||||
sed -i 's|STARTCHAR 0x2455n|STARTCHAR 0x2455|' mplus_j12b.bdf
|
||||
|
||||
cd -
|
||||
|
||||
touch created
|
||||
}
|
||||
|
||||
mplus()
|
||||
{
|
||||
echo -ne "creating glyph.h from mplus fonts...\n"
|
||||
wget -q -nc ${MPLUS_URL}
|
||||
|
||||
if test ! -d ${MPLUS_NAME}; then
|
||||
bsdtar xf ${MPLUS_FILE}
|
||||
fi
|
||||
|
||||
cd ${MPLUS_NAME}
|
||||
ln -sf ${YAFT_DIR}/mkfont_bdf .
|
||||
ln -sf ${YAFT_DIR}/table .
|
||||
|
||||
if test ! -f created; then
|
||||
mplus_create_bdf > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
j10*)
|
||||
FILES=`find fonts_j -type f -name "*${1}*.bdf" | tr "\n" " "`;;
|
||||
j12*)
|
||||
PATTERN=`echo -n $1 | tail -c3`
|
||||
FILES=`find . -type f -name "*[fj]${PATTERN}*.bdf" | tr "\n" " "`;;
|
||||
f10*|f12*)
|
||||
FILES=`find fonts_e -type f -name "*${1}*.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: [fj](10|12)[rb]\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
efont()
|
||||
{
|
||||
echo -ne "creating glyph.h from efont unicode...\n"
|
||||
wget -q -nc ${EFONT_URL}
|
||||
|
||||
if test ! -d ${EFONT_NAME}; then
|
||||
bsdtar xf ${EFONT_FILE}
|
||||
fi
|
||||
|
||||
cd ${EFONT_NAME}
|
||||
ln -sf ${YAFT_DIR}/mkfont_bdf .
|
||||
ln -sf ${YAFT_DIR}/table .
|
||||
|
||||
case "$1" in
|
||||
1[0246]*|24*)
|
||||
FILES=`find . -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: (10|12|14|16|24)(_b)?\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
milkjf()
|
||||
{
|
||||
echo -ne "creating glyph.h from milkjf font...\n"
|
||||
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
ln -sf $YAFT_DIR/fonts .
|
||||
|
||||
FILES=`find -L fonts -type f -name "*.bdf" | tr "\n" " "`
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
unifont()
|
||||
{
|
||||
echo -ne "creating glyph.h from unifont...\n"
|
||||
wget -q -nc ${UNIFONT_URL}
|
||||
|
||||
if test ! -f ${UNIFONT_NAME}.bdf; then
|
||||
gunzip ${UNIFONT_FILE}
|
||||
fi
|
||||
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
FILES="${UNIFONT_NAME}.bdf"
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
dina()
|
||||
{
|
||||
echo -ne "creating glyph.h from dina font...\n"
|
||||
wget -q -nc ${DINA_URL}
|
||||
|
||||
if test ! -d BDF; then
|
||||
bsdtar xf ${DINA_FILE}
|
||||
fi
|
||||
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
case "$1" in
|
||||
r*)
|
||||
FILES=`find BDF -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: r400-(6|8|9|10), r700-(8|9|10)\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
terminus()
|
||||
{
|
||||
echo -ne "creating glyph.h from terminus font...\n"
|
||||
wget -q -nc ${TERMINUS_URL}
|
||||
|
||||
if test ! -d ${TERMINUS_NAME}; then
|
||||
bsdtar xf ${TERMINUS_FILE}
|
||||
fi
|
||||
|
||||
cd ${TERMINUS_NAME}
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
case "$1" in
|
||||
u*)
|
||||
FILES=`find . -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: u(14|16)v, u(12|14|16|18|20|22|24|28|32)[nb]\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
profont()
|
||||
{
|
||||
echo -ne "creating glyph.h from profont...\n"
|
||||
wget -q -nc ${PROFONT_URL} -O ${PROFONT_FILE}
|
||||
|
||||
if test ! -d ${PROFONT_NAME}; then
|
||||
bsdtar xf ${PROFONT_FILE}
|
||||
fi
|
||||
|
||||
cd ${PROFONT_NAME}
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
if test ! -f created; then
|
||||
for i in *.pcf; do
|
||||
pcf2bdf -o `basename $i .pcf`.bdf $i
|
||||
done
|
||||
touch created
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
1*|2*)
|
||||
FILES=`find . -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: (10|11|12|15|17|22|29)\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
tamsyn()
|
||||
{
|
||||
echo -ne "creating glyph.h from tamsyn font...\n"
|
||||
wget -q -nc ${TAMSYN_URL}
|
||||
|
||||
if test ! -d ${TAMSYN_NAME}; then
|
||||
bsdtar xf ${TAMSYN_FILE}
|
||||
fi
|
||||
|
||||
cd ${TAMSYN_NAME}
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
if test ! -f created; then
|
||||
for i in *.pcf; do
|
||||
pcf2bdf -o `basename $i .pcf`.bdf $i
|
||||
done
|
||||
touch created
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
*[rb])
|
||||
FILES=`find . -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: (5x9|6x12|7x13|7x14|8x15|8x16|10x20)[rb]\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
wqy()
|
||||
{
|
||||
echo -ne "creating glyph.h from tamsyn font...\n"
|
||||
wget -q -nc ${WQY_URL}
|
||||
|
||||
if test ! -d ${WQY_NAME}; then
|
||||
bsdtar xf ${WQY_FILE}
|
||||
fi
|
||||
|
||||
cd wqy-bitmapsong
|
||||
ln -sf $YAFT_DIR/mkfont_bdf .
|
||||
ln -sf $YAFT_DIR/table .
|
||||
|
||||
case "$1" in
|
||||
*pt|*px)
|
||||
FILES=`find . -type f -name "*${1}.bdf" | tr "\n" " "`;;
|
||||
*)
|
||||
echo -ne "avalable font variations: (9|10|11|12)pt, 13px\n"
|
||||
exit -1;;
|
||||
esac
|
||||
|
||||
generate ${FILES}
|
||||
}
|
||||
|
||||
# main
|
||||
echo "LANG: $LANG"
|
||||
mkdir -p $WORK_DIR
|
||||
cd $WORK_DIR
|
||||
|
||||
case "$1" in
|
||||
"mplus")
|
||||
shift
|
||||
mplus $1;;
|
||||
"efont")
|
||||
shift
|
||||
efont $1;;
|
||||
"milkjf")
|
||||
milkjf;;
|
||||
"unifont")
|
||||
unifont;;
|
||||
"dina")
|
||||
shift
|
||||
dina $1;;
|
||||
"terminus")
|
||||
shift
|
||||
terminus $1;;
|
||||
"profont")
|
||||
shift
|
||||
profont $1;;
|
||||
"tamsyn")
|
||||
shift
|
||||
tamsyn $1;;
|
||||
*)
|
||||
usage;;
|
||||
esac
|
Binary file not shown.
Before Width: | Height: | Size: 91 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
Binary file not shown.
Before Width: | Height: | Size: 213 KiB |
@@ -1,21 +0,0 @@
|
||||
# (untranslatable capabilities removed to fit entry within 1023 bytes)
|
||||
yaft-256color|yet another framebuffer terminal:\
|
||||
:am:ms:ut:xn:\
|
||||
:Co#256:co#80:it#8:li#24:pa#32767:\
|
||||
:&7=^Z:@7=\E[4~:AB=\E[48;5;%dm:AF=\E[38;5;%dm:AL=\E[%dL:\
|
||||
:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[23~:F2=\E[24~:\
|
||||
:F3=\E[25~:F4=\E[26~:F5=\E[28~:F6=\E[29~:F7=\E[31~:\
|
||||
:F8=\E[32~:F9=\E[33~:FA=\E[34~:IC=\E[%d@:K2=\E[G:Km=\E[M:\
|
||||
:LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\
|
||||
:al=\E[L:cb=\E[1K:cd=\E[J:ce=\E[K:ch=\E[%i%dG:cl=\E[H\E[J:\
|
||||
:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:\
|
||||
:cv=\E[%i%dd:dc=\E[P:dl=\E[M:do=^J:ec=\E[%dX:ei=:ho=\E[H:\
|
||||
:ic=\E[@:im=:is=\Ec:\
|
||||
:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\
|
||||
:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\EOH:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:\
|
||||
:le=^H:\
|
||||
:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=\EE:\
|
||||
:op=\E[39;49m:rc=\E8:rs=\Ec:sc=\E7:se=\E[27m:sf=^J:\
|
||||
:so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[24m:up=\E[A:us=\E[4m:\
|
||||
:ve=\E[?25h:vi=\E[?25l:\
|
||||
:u6=\E[%d;%dR:u7=\E[6n:
|
@@ -1,62 +0,0 @@
|
||||
yaft-256color|yet another framebuffer terminal,
|
||||
am, bce, msgr, xenl,
|
||||
|
||||
cols#80, lines#24, it#8, colors#256, pairs#32767,
|
||||
|
||||
clear=\E[H\E[J,
|
||||
|
||||
nel=\EE, cr=^M,
|
||||
|
||||
cuf=\E[%p1%dC, cuf1=\E[C,
|
||||
cub=\E[%p1%dD, cub1=^H,
|
||||
cuu=\E[%p1%dA, cuu1=\E[A,
|
||||
cud=\E[%p1%dB, cud1=^J,
|
||||
|
||||
home=\E[H,
|
||||
cup=\E[%i%p1%d;%p2%dH,
|
||||
hpa=\E[%i%p1%dG, vpa=\E[%i%p1%dd,
|
||||
|
||||
ind=^J, ri=\EM,
|
||||
csr=\E[%i%p1%d;%p2%dr,
|
||||
|
||||
ed=\E[J,
|
||||
ech=\E[%p1%dX,
|
||||
dch=\E[%p1%dP, dch1=\E[P,
|
||||
dl=\E[%p1%dM, dl1=\E[M,
|
||||
el=\E[K, el1=\E[1K,
|
||||
|
||||
il=\E[%p1%dL, il1=\E[L,
|
||||
ich=\E[%p1%d@, ich1=\E[@,
|
||||
|
||||
civis=\E[?25l, cnorm=\E[?25h,
|
||||
|
||||
ht=^I, hts=\EH, tbc=\E[3g,
|
||||
|
||||
sc=\E7, rc=\E8,
|
||||
|
||||
is2=\Ec, rs2=\Ec,
|
||||
|
||||
op=\E[39;49m,
|
||||
|
||||
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
|
||||
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
|
||||
|
||||
sgr0=\E[m,
|
||||
sgr=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m,
|
||||
|
||||
bold=\E[1m, rev=\E[7m, blink=\E[5m,
|
||||
smso=\E[7m, rmso=\E[27m,
|
||||
smul=\E[4m, rmul=\E[24m,
|
||||
smam=\E[?7h, rmam=\E[?7l,
|
||||
|
||||
kf1=\E[[A, kf2=\E[[B, kf3=\E[[C, kf4=\E[[D, kf5=\E[[E,
|
||||
kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kf10=\E[21~,
|
||||
kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~,
|
||||
kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~, kf20=\E[34~,
|
||||
|
||||
kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A,
|
||||
kb2=\E[G, kbs=\177, kcbt=\E[Z,
|
||||
khome=\E[1~, kich1=\E[2~, kdch1=\E[3~, kend=\E[4~,
|
||||
kmous=\E[M, knp=\E[6~, kpp=\E[5~, kspd=^Z,
|
||||
|
||||
u6=\E[%i%d;%dR, u7=\E[6n,
|
@@ -1,67 +0,0 @@
|
||||
CC ?= gcc
|
||||
#CC ?= clang
|
||||
|
||||
CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe
|
||||
LDFLAGS ?=
|
||||
|
||||
XCFLAGS ?= -std=c99 -pedantic -Wall -Wextra -I/usr/include/X11/ -O3 -s -pipe
|
||||
XLDFLAGS ?= -lX11
|
||||
|
||||
HDR = glyph.h yaft.h conf.h color.h parse.h terminal.h util.h \
|
||||
ctrlseq/esc.h ctrlseq/csi.h ctrlseq/osc.h ctrlseq/dcs.h \
|
||||
fb/common.h fb/linux.h fb/freebsd.h fb/netbsd.h fb/openbsd.h \
|
||||
x/x.h
|
||||
|
||||
DESTDIR =
|
||||
PREFIX = $(DESTDIR)/usr
|
||||
MANPREFIX = $(DESTDIR)/usr/share/man
|
||||
|
||||
all: yaft
|
||||
|
||||
yaft: mkfont_bdf
|
||||
|
||||
yaftx: mkfont_bdf
|
||||
|
||||
mkfont_bdf: tools/mkfont_bdf.c tools/mkfont_bdf.h tools/bdf.h tools/util.h
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
glyph.h: mkfont_bdf
|
||||
# If you want to use your favorite fonts, please change following line
|
||||
# usage: mkfont_bdf ALIAS BDF1 BDF2 BDF3... > glyph.h
|
||||
# ALIAS: glyph substitution rule file (see table/alias for more detail)
|
||||
# BDF1 BDF2 BDF3...: monospace bdf files (must be the same size)
|
||||
# If there is more than one glyph of the same codepoint, the glyph included in the first bdf file is choosed
|
||||
./mkfont_bdf table/alias fonts/milkjf_k16.bdf fonts/milkjf_8x16r.bdf fonts/milkjf_8x16.bdf > glyph.h
|
||||
|
||||
yaft: yaft.c $(HDR)
|
||||
# If you want to change configuration, please modify conf.h before make (see conf.h for more detail)
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
yaftx: x/yaftx.c $(HDR)
|
||||
# If you want to change configuration, please modify conf.h before make (see conf.h for more detail)
|
||||
$(CC) -o $@ $< $(XCFLAGS) $(XLDFLAGS)
|
||||
|
||||
install:
|
||||
mkdir -p $(PREFIX)/share/terminfo
|
||||
tic -o $(PREFIX)/share/terminfo info/yaft.src
|
||||
mkdir -p $(PREFIX)/bin/
|
||||
install -m755 ./yaft $(PREFIX)/bin/yaft
|
||||
install -m755 ./yaft_wall $(PREFIX)/bin/yaft_wall
|
||||
mkdir -p $(MANPREFIX)/man1/
|
||||
install -m644 ./man/yaft.1 $(MANPREFIX)/man1/yaft.1
|
||||
|
||||
installx:
|
||||
mkdir -p $(PREFIX)/share/terminfo
|
||||
tic -o $(PREFIX)/share/terminfo info/yaft.src
|
||||
mkdir -p $(PREFIX)/bin/
|
||||
install -m755 ./yaftx $(PREFIX)/bin/yaftx
|
||||
|
||||
uninstall:
|
||||
rm -f $(PREFIX)/bin/yaft
|
||||
rm -f $(PREFIX)/bin/yaft_wall
|
||||
|
||||
uninstallx:
|
||||
rm -f $(PREFIX)/bin/yaftx
|
||||
|
||||
clean:
|
||||
rm -f yaft yaftx mkfont_bdf glyph.h
|
@@ -1,48 +0,0 @@
|
||||
.TH "YAFT" "1" "July 2014" "yaft 0.2.7" "yaft User Manual"
|
||||
.SH NAME
|
||||
.PP
|
||||
yaft \- yet another framebuffer terminal
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
.B yaft
|
||||
.RB [ \-h ]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.B yaft
|
||||
is simple framebuffer terminal emulator for minimalist (living without X).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-h
|
||||
Show help
|
||||
.RS
|
||||
.RE
|
||||
.SH CUSTOMIZATION
|
||||
.PP
|
||||
Rewrite conf.h before make.
|
||||
.SH CUSTOM FONTS
|
||||
.PP
|
||||
You can use tools/mkfont_bdf to create fonts file. See makefile and table/alias for detail.
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.TP
|
||||
.B FRAMEBUFFER
|
||||
Specify framebuffer device.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B YAFT
|
||||
If this variable includes "wall", yaft enables wallpaper mode. See yaft_wall script for detail.
|
||||
.RS
|
||||
.RE
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
haru <uobikiemukot at gmail dot com>
|
||||
.SH LICENSE
|
||||
.PP
|
||||
MIT LISENCE
|
||||
.SH "REPORTING BUGS"
|
||||
Please submit bug reports to <\fBhttps://github.com/uobikiemukot/yaft/issues\fR>.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
.BR console_codes (4),
|
||||
.BR console_ioctl (4),
|
||||
.BR terminfo (5)
|
@@ -1,374 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#if 0
|
||||
void (*ctrl_func[CTRL_CHARS])(struct terminal_t *term) = {
|
||||
[BS] = bs,
|
||||
[HT] = tab,
|
||||
[LF] = nl,
|
||||
[VT] = nl,
|
||||
[FF] = nl,
|
||||
[CR] = cr,
|
||||
[ESC] = enter_esc,
|
||||
};
|
||||
|
||||
void (*esc_func[ESC_CHARS])(struct terminal_t *term) = {
|
||||
['7'] = save_state,
|
||||
['8'] = restore_state,
|
||||
['D'] = nl,
|
||||
['E'] = crnl,
|
||||
['H'] = set_tabstop,
|
||||
['M'] = reverse_nl,
|
||||
['P'] = enter_dcs,
|
||||
['Z'] = identify,
|
||||
['['] = enter_csi,
|
||||
[']'] = enter_osc,
|
||||
['c'] = ris,
|
||||
};
|
||||
|
||||
void (*csi_func[ESC_CHARS])(struct terminal_t *term, struct parm_t *) = {
|
||||
['@'] = insert_blank,
|
||||
['A'] = curs_up,
|
||||
['B'] = curs_down,
|
||||
['C'] = curs_forward,
|
||||
['D'] = curs_back,
|
||||
['E'] = curs_nl,
|
||||
['F'] = curs_pl,
|
||||
['G'] = curs_col,
|
||||
['H'] = curs_pos,
|
||||
['J'] = erase_display,
|
||||
['K'] = erase_line,
|
||||
['L'] = insert_line,
|
||||
['M'] = delete_line,
|
||||
['P'] = delete_char,
|
||||
['X'] = erase_char,
|
||||
['a'] = curs_forward,
|
||||
['c'] = device_attribute,
|
||||
['d'] = curs_line,
|
||||
['e'] = curs_down,
|
||||
['f'] = curs_pos,
|
||||
['g'] = clear_tabstop,
|
||||
['h'] = set_mode,
|
||||
['l'] = reset_mode,
|
||||
['m'] = set_attr,
|
||||
['n'] = status_report,
|
||||
['r'] = set_margin,
|
||||
/* XXX: not implemented because these sequences conflict DECSLRM/DECSHTS
|
||||
['s'] = sco_save_state,
|
||||
['u'] = sco_restore_state,
|
||||
*/
|
||||
['`'] = curs_col,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ctr char/esc sequence/charset function */
|
||||
void control_character(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
static const char *ctrl_char[] = {
|
||||
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
|
||||
"BS ", "HT ", "LF ", "VT ", "FF ", "CR ", "SO ", "SI ",
|
||||
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
|
||||
"CAN", "EM ", "SUB", "ESC", "FS ", "GS ", "RS ", "US ",
|
||||
};
|
||||
|
||||
*term->esc.bp = '\0';
|
||||
|
||||
logging(DEBUG, "ctl: %s\n", ctrl_char[ch]);
|
||||
|
||||
switch(ch) {
|
||||
case BS: bs(term); break;
|
||||
case HT: tab(term); break;
|
||||
case LF: nl(term); break;
|
||||
case VT: nl(term); break;
|
||||
case FF: nl(term); break;
|
||||
case CR: cr(term); break;
|
||||
case ESC: enter_esc(term); break;
|
||||
default: break;
|
||||
}
|
||||
#if 0
|
||||
if (ctrl_func[ch])
|
||||
ctrl_func[ch](term);
|
||||
#endif
|
||||
}
|
||||
|
||||
void esc_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
*term->esc.bp = '\0';
|
||||
|
||||
logging(DEBUG, "esc: ESC %s\n", term->esc.buf);
|
||||
|
||||
#if 0
|
||||
if (strlen(term->esc.buf) == 1 && esc_func[ch])
|
||||
esc_func[ch](term);
|
||||
#endif
|
||||
if (strlen(term->esc.buf) == 1)
|
||||
{
|
||||
switch(ch) {
|
||||
case '7': save_state(term); break;
|
||||
case '8': restore_state(term); break;
|
||||
case 'D': nl(term); break;
|
||||
case 'E': crnl(term); break;
|
||||
case 'H': set_tabstop(term); break;
|
||||
case 'M': reverse_nl(term); break;
|
||||
#if 0
|
||||
case 'P': enter_dcs(term); break;
|
||||
#endif
|
||||
case 'Z': identify(term); break;
|
||||
case '[': enter_csi(term); break;
|
||||
case ']': enter_osc(term); break;
|
||||
case 'c': ris(term); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* not reset if csi/osc/dcs seqence */
|
||||
if (ch == '[' || ch == ']' || ch == 'P')
|
||||
return;
|
||||
|
||||
reset_esc(term);
|
||||
}
|
||||
|
||||
void csi_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
struct parm_t parm;
|
||||
|
||||
*(term->esc.bp - 1) = '\0'; /* omit final character */
|
||||
|
||||
logging(DEBUG, "csi: CSI %s\n", term->esc.buf + 1);
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(term->esc.buf + 1, &parm, ';', isdigit); /* skip '[' */
|
||||
|
||||
#if 0
|
||||
if (csi_func[ch])
|
||||
csi_func[ch](term, &parm);
|
||||
#endif
|
||||
switch (ch) {
|
||||
case '@': insert_blank(term, &parm); break;
|
||||
case 'A': curs_up(term, &parm); break;
|
||||
case 'B': curs_down(term, &parm); break;
|
||||
case 'C': curs_forward(term, &parm); break;
|
||||
case 'D': curs_back(term, &parm); break;
|
||||
case 'E': curs_nl(term, &parm); break;
|
||||
case 'F': curs_pl(term, &parm); break;
|
||||
case 'G': curs_col(term, &parm); break;
|
||||
case 'H': curs_pos(term, &parm); break;
|
||||
case 'J': erase_display(term, &parm); break;
|
||||
case 'K': erase_line(term, &parm); break;
|
||||
case 'L': insert_line(term, &parm); break;
|
||||
case 'M': delete_line(term, &parm); break;
|
||||
case 'P': delete_char(term, &parm); break;
|
||||
case 'X': erase_char(term, &parm); break;
|
||||
case 'a': curs_forward(term, &parm); break;
|
||||
case 'c': device_attribute(term, &parm);break;
|
||||
case 'd': curs_line(term, &parm); break;
|
||||
case 'e': curs_down(term, &parm); break;
|
||||
case 'f': curs_pos(term, &parm); break;
|
||||
case 'g': clear_tabstop(term, &parm); break;
|
||||
case 'h': set_mode(term, &parm); break;
|
||||
case 'l': reset_mode(term, &parm); break;
|
||||
case 'm': set_attr(term, &parm); break;
|
||||
case 'n': status_report(term, &parm); break;
|
||||
case 'r': set_margin(term, &parm); break;
|
||||
/* XXX: not implemented because these sequences conflict DECSLRM/DECSHTS
|
||||
case 's': sco_save_state(term, &parm); break;
|
||||
case 'u': sco_restore_state(term, &parm); break;
|
||||
*/
|
||||
case '`': curs_col(term, &parm); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
reset_esc(term);
|
||||
}
|
||||
|
||||
int is_osc_parm(int c)
|
||||
{
|
||||
if (isdigit(c) || isalpha(c) ||
|
||||
c == '?' || c == ':' || c == '/' || c == '#')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void omit_string_terminator(char *bp, uint8_t ch)
|
||||
{
|
||||
if (ch == BACKSLASH) /* ST: ESC BACKSLASH */
|
||||
*(bp - 2) = '\0';
|
||||
else /* ST: BEL */
|
||||
*(bp - 1) = '\0';
|
||||
}
|
||||
|
||||
void osc_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
int osc_mode;
|
||||
struct parm_t parm;
|
||||
|
||||
omit_string_terminator(term->esc.bp, ch);
|
||||
|
||||
logging(DEBUG, "osc: OSC %s\n", term->esc.buf);
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(term->esc.buf + 1, &parm, ';', is_osc_parm); /* skip ']' */
|
||||
|
||||
if (parm.argc > 0) {
|
||||
osc_mode = dec2num(parm.argv[0]);
|
||||
logging(DEBUG, "osc_mode:%d\n", osc_mode);
|
||||
|
||||
/* XXX: disable because this functions only work 24/32bpp
|
||||
-> support other bpp (including pseudo color) */
|
||||
if (osc_mode == 4)
|
||||
set_palette(term, &parm);
|
||||
else if (osc_mode == 104)
|
||||
reset_palette(term, &parm);
|
||||
if (osc_mode == 8900)
|
||||
glyph_width_report(term, &parm);
|
||||
}
|
||||
reset_esc(term);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void dcs_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
omit_string_terminator(term->esc.bp, ch);
|
||||
|
||||
logging(DEBUG, "dcs: DCS %s\n", term->esc.buf);
|
||||
|
||||
/* check DCS header */
|
||||
cp = term->esc.buf + 1; /* skip P */
|
||||
while (cp < term->esc.bp) {
|
||||
if (*cp == '{' || *cp == 'q') /* DECDLD or sixel */
|
||||
break;
|
||||
else if (*cp == ';' || ('0' <= *cp && *cp <= '9')) /* valid DCS header */
|
||||
;
|
||||
else /* invalid sequence */
|
||||
cp = term->esc.bp;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (cp != term->esc.bp) { /* header only or couldn't find final char */
|
||||
/* parse DCS header */
|
||||
if (*cp == 'q')
|
||||
sixel_parse_header(term, term->esc.buf + 1);
|
||||
else if (*cp == '{')
|
||||
decdld_parse_header(term, term->esc.buf + 1);
|
||||
}
|
||||
|
||||
reset_esc(term);
|
||||
}
|
||||
#endif
|
||||
|
||||
void utf8_charset(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
if (0x80 <= ch && ch <= 0xBF) {
|
||||
/* check illegal UTF-8 sequence
|
||||
* ? byte sequence: first byte must be between 0xC2 ~ 0xFD
|
||||
* 2 byte sequence: first byte must be between 0xC2 ~ 0xDF
|
||||
* 3 byte sequence: second byte following 0xE0 must be between 0xA0 ~ 0xBF
|
||||
* 4 byte sequence: second byte following 0xF0 must be between 0x90 ~ 0xBF
|
||||
* 5 byte sequence: second byte following 0xF8 must be between 0x88 ~ 0xBF
|
||||
* 6 byte sequence: second byte following 0xFC must be between 0x84 ~ 0xBF
|
||||
*/
|
||||
if ((term->charset.following_byte == 0)
|
||||
|| (term->charset.following_byte == 1 && term->charset.count == 0 && term->charset.code <= 1)
|
||||
|| (term->charset.following_byte == 2 && term->charset.count == 0 && term->charset.code == 0 && ch < 0xA0)
|
||||
|| (term->charset.following_byte == 3 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x90)
|
||||
|| (term->charset.following_byte == 4 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x88)
|
||||
|| (term->charset.following_byte == 5 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x84))
|
||||
term->charset.is_valid = false;
|
||||
|
||||
term->charset.code <<= 6;
|
||||
term->charset.code += ch & 0x3F;
|
||||
term->charset.count++;
|
||||
} else if (0xC0 <= ch && ch <= 0xDF) {
|
||||
term->charset.code = ch & 0x1F;
|
||||
term->charset.following_byte = 1;
|
||||
term->charset.count = 0;
|
||||
return;
|
||||
} else if (0xE0 <= ch && ch <= 0xEF) {
|
||||
term->charset.code = ch & 0x0F;
|
||||
term->charset.following_byte = 2;
|
||||
term->charset.count = 0;
|
||||
return;
|
||||
} else if (0xF0 <= ch && ch <= 0xF7) {
|
||||
term->charset.code = ch & 0x07;
|
||||
term->charset.following_byte = 3;
|
||||
term->charset.count = 0;
|
||||
return;
|
||||
} else if (0xF8 <= ch && ch <= 0xFB) {
|
||||
term->charset.code = ch & 0x03;
|
||||
term->charset.following_byte = 4;
|
||||
term->charset.count = 0;
|
||||
return;
|
||||
} else if (0xFC <= ch && ch <= 0xFD) {
|
||||
term->charset.code = ch & 0x01;
|
||||
term->charset.following_byte = 5;
|
||||
term->charset.count = 0;
|
||||
return;
|
||||
} else { /* 0xFE - 0xFF: not used in UTF-8 */
|
||||
addch(term, REPLACEMENT_CHAR);
|
||||
reset_charset(term);
|
||||
return;
|
||||
}
|
||||
|
||||
if (term->charset.count >= term->charset.following_byte) {
|
||||
/* illegal code point (ref: http://www.unicode.org/reports/tr27/tr27-4.html)
|
||||
0xD800 ~ 0xDFFF : surrogate pair
|
||||
0xFDD0 ~ 0xFDEF : noncharacter
|
||||
0xnFFFE ~ 0xnFFFF: noncharacter (n: 0x00 ~ 0x10)
|
||||
0x110000 ~ : invalid (unicode U+0000 ~ U+10FFFF)
|
||||
*/
|
||||
if (!term->charset.is_valid
|
||||
|| (0xD800 <= term->charset.code && term->charset.code <= 0xDFFF)
|
||||
|| (0xFDD0 <= term->charset.code && term->charset.code <= 0xFDEF)
|
||||
|| ((term->charset.code & 0xFFFF) == 0xFFFE || (term->charset.code & 0xFFFF) == 0xFFFF)
|
||||
|| (term->charset.code > 0x10FFFF))
|
||||
addch(term, REPLACEMENT_CHAR);
|
||||
else
|
||||
addch(term, term->charset.code);
|
||||
|
||||
reset_charset(term);
|
||||
}
|
||||
}
|
||||
|
||||
void parse(struct terminal_t *term, uint8_t *buf, int size)
|
||||
{
|
||||
/*
|
||||
CTRL CHARS : 0x00 ~ 0x1F
|
||||
ASCII(printable): 0x20 ~ 0x7E
|
||||
CTRL CHARS(DEL) : 0x7F
|
||||
UTF-8 : 0x80 ~ 0xFF
|
||||
*/
|
||||
uint8_t ch;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
ch = buf[i];
|
||||
if (term->esc.state == STATE_RESET) {
|
||||
/* interrupted by illegal byte */
|
||||
if (term->charset.following_byte > 0 && (ch < 0x80 || ch > 0xBF)) {
|
||||
addch(term, REPLACEMENT_CHAR);
|
||||
reset_charset(term);
|
||||
}
|
||||
|
||||
if (ch <= 0x1F)
|
||||
control_character(term, ch);
|
||||
else if (ch <= 0x7F)
|
||||
addch(term, ch);
|
||||
else
|
||||
utf8_charset(term, ch);
|
||||
} else if (term->esc.state == STATE_ESC) {
|
||||
if (push_esc(term, ch))
|
||||
esc_sequence(term, ch);
|
||||
} else if (term->esc.state == STATE_CSI) {
|
||||
if (push_esc(term, ch))
|
||||
csi_sequence(term, ch);
|
||||
} else if (term->esc.state == STATE_OSC) {
|
||||
if (push_esc(term, ch))
|
||||
osc_sequence(term, ch);
|
||||
#if 0
|
||||
} else if (term->esc.state == STATE_DCS) {
|
||||
if (push_esc(term, ch))
|
||||
dcs_sequence(term, ch);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,303 +0,0 @@
|
||||
#
|
||||
# Name: ISO/IEC 8859-1:1998 to Unicode
|
||||
# Unicode version: 3.0
|
||||
# Table version: 1.0
|
||||
# Table format: Format A
|
||||
# Date: 1999 July 27
|
||||
# Authors: Ken Whistler <kenw@sybase.com>
|
||||
#
|
||||
# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved.
|
||||
#
|
||||
# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
|
||||
# No claims are made as to fitness for any particular purpose. No
|
||||
# warranties of any kind are expressed or implied. The recipient
|
||||
# agrees to determine applicability of information provided. If this
|
||||
# file has been provided on optical media by Unicode, Inc., the sole
|
||||
# remedy for any claim will be exchange of defective media within 90
|
||||
# days of receipt.
|
||||
#
|
||||
# Unicode, Inc. hereby grants the right to freely use the information
|
||||
# supplied in this file in the creation of products supporting the
|
||||
# Unicode Standard, and to make copies of this file in any form for
|
||||
# internal or external distribution as long as this notice remains
|
||||
# attached.
|
||||
#
|
||||
# General notes:
|
||||
#
|
||||
# This table contains the data the Unicode Consortium has on how
|
||||
# ISO/IEC 8859-1:1998 characters map into Unicode.
|
||||
#
|
||||
# Format: Three tab-separated columns
|
||||
# Column #1 is the ISO/IEC 8859-1 code (in hex as 0xXX)
|
||||
# Column #2 is the Unicode (in hex as 0xXXXX)
|
||||
# Column #3 the Unicode name (follows a comment sign, '#')
|
||||
#
|
||||
# The entries are in ISO/IEC 8859-1 order.
|
||||
#
|
||||
# Version history
|
||||
# 1.0 version updates 0.1 version by adding mappings for all
|
||||
# control characters.
|
||||
#
|
||||
# Updated versions of this file may be found in:
|
||||
# <ftp://ftp.unicode.org/Public/MAPPINGS/>
|
||||
#
|
||||
# Any comments or problems, contact <errata@unicode.org>
|
||||
# Please note that <errata@unicode.org> is an archival address;
|
||||
# notices will be checked, but do not expect an immediate response.
|
||||
#
|
||||
0x00 0x0000 # NULL
|
||||
0x01 0x0001 # START OF HEADING
|
||||
0x02 0x0002 # START OF TEXT
|
||||
0x03 0x0003 # END OF TEXT
|
||||
0x04 0x0004 # END OF TRANSMISSION
|
||||
0x05 0x0005 # ENQUIRY
|
||||
0x06 0x0006 # ACKNOWLEDGE
|
||||
0x07 0x0007 # BELL
|
||||
0x08 0x0008 # BACKSPACE
|
||||
0x09 0x0009 # HORIZONTAL TABULATION
|
||||
0x0A 0x000A # LINE FEED
|
||||
0x0B 0x000B # VERTICAL TABULATION
|
||||
0x0C 0x000C # FORM FEED
|
||||
0x0D 0x000D # CARRIAGE RETURN
|
||||
0x0E 0x000E # SHIFT OUT
|
||||
0x0F 0x000F # SHIFT IN
|
||||
0x10 0x0010 # DATA LINK ESCAPE
|
||||
0x11 0x0011 # DEVICE CONTROL ONE
|
||||
0x12 0x0012 # DEVICE CONTROL TWO
|
||||
0x13 0x0013 # DEVICE CONTROL THREE
|
||||
0x14 0x0014 # DEVICE CONTROL FOUR
|
||||
0x15 0x0015 # NEGATIVE ACKNOWLEDGE
|
||||
0x16 0x0016 # SYNCHRONOUS IDLE
|
||||
0x17 0x0017 # END OF TRANSMISSION BLOCK
|
||||
0x18 0x0018 # CANCEL
|
||||
0x19 0x0019 # END OF MEDIUM
|
||||
0x1A 0x001A # SUBSTITUTE
|
||||
0x1B 0x001B # ESCAPE
|
||||
0x1C 0x001C # FILE SEPARATOR
|
||||
0x1D 0x001D # GROUP SEPARATOR
|
||||
0x1E 0x001E # RECORD SEPARATOR
|
||||
0x1F 0x001F # UNIT SEPARATOR
|
||||
0x20 0x0020 # SPACE
|
||||
0x21 0x0021 # EXCLAMATION MARK
|
||||
0x22 0x0022 # QUOTATION MARK
|
||||
0x23 0x0023 # NUMBER SIGN
|
||||
0x24 0x0024 # DOLLAR SIGN
|
||||
0x25 0x0025 # PERCENT SIGN
|
||||
0x26 0x0026 # AMPERSAND
|
||||
0x27 0x0027 # APOSTROPHE
|
||||
0x28 0x0028 # LEFT PARENTHESIS
|
||||
0x29 0x0029 # RIGHT PARENTHESIS
|
||||
0x2A 0x002A # ASTERISK
|
||||
0x2B 0x002B # PLUS SIGN
|
||||
0x2C 0x002C # COMMA
|
||||
0x2D 0x002D # HYPHEN-MINUS
|
||||
0x2E 0x002E # FULL STOP
|
||||
0x2F 0x002F # SOLIDUS
|
||||
0x30 0x0030 # DIGIT ZERO
|
||||
0x31 0x0031 # DIGIT ONE
|
||||
0x32 0x0032 # DIGIT TWO
|
||||
0x33 0x0033 # DIGIT THREE
|
||||
0x34 0x0034 # DIGIT FOUR
|
||||
0x35 0x0035 # DIGIT FIVE
|
||||
0x36 0x0036 # DIGIT SIX
|
||||
0x37 0x0037 # DIGIT SEVEN
|
||||
0x38 0x0038 # DIGIT EIGHT
|
||||
0x39 0x0039 # DIGIT NINE
|
||||
0x3A 0x003A # COLON
|
||||
0x3B 0x003B # SEMICOLON
|
||||
0x3C 0x003C # LESS-THAN SIGN
|
||||
0x3D 0x003D # EQUALS SIGN
|
||||
0x3E 0x003E # GREATER-THAN SIGN
|
||||
0x3F 0x003F # QUESTION MARK
|
||||
0x40 0x0040 # COMMERCIAL AT
|
||||
0x41 0x0041 # LATIN CAPITAL LETTER A
|
||||
0x42 0x0042 # LATIN CAPITAL LETTER B
|
||||
0x43 0x0043 # LATIN CAPITAL LETTER C
|
||||
0x44 0x0044 # LATIN CAPITAL LETTER D
|
||||
0x45 0x0045 # LATIN CAPITAL LETTER E
|
||||
0x46 0x0046 # LATIN CAPITAL LETTER F
|
||||
0x47 0x0047 # LATIN CAPITAL LETTER G
|
||||
0x48 0x0048 # LATIN CAPITAL LETTER H
|
||||
0x49 0x0049 # LATIN CAPITAL LETTER I
|
||||
0x4A 0x004A # LATIN CAPITAL LETTER J
|
||||
0x4B 0x004B # LATIN CAPITAL LETTER K
|
||||
0x4C 0x004C # LATIN CAPITAL LETTER L
|
||||
0x4D 0x004D # LATIN CAPITAL LETTER M
|
||||
0x4E 0x004E # LATIN CAPITAL LETTER N
|
||||
0x4F 0x004F # LATIN CAPITAL LETTER O
|
||||
0x50 0x0050 # LATIN CAPITAL LETTER P
|
||||
0x51 0x0051 # LATIN CAPITAL LETTER Q
|
||||
0x52 0x0052 # LATIN CAPITAL LETTER R
|
||||
0x53 0x0053 # LATIN CAPITAL LETTER S
|
||||
0x54 0x0054 # LATIN CAPITAL LETTER T
|
||||
0x55 0x0055 # LATIN CAPITAL LETTER U
|
||||
0x56 0x0056 # LATIN CAPITAL LETTER V
|
||||
0x57 0x0057 # LATIN CAPITAL LETTER W
|
||||
0x58 0x0058 # LATIN CAPITAL LETTER X
|
||||
0x59 0x0059 # LATIN CAPITAL LETTER Y
|
||||
0x5A 0x005A # LATIN CAPITAL LETTER Z
|
||||
0x5B 0x005B # LEFT SQUARE BRACKET
|
||||
0x5C 0x005C # REVERSE SOLIDUS
|
||||
0x5D 0x005D # RIGHT SQUARE BRACKET
|
||||
0x5E 0x005E # CIRCUMFLEX ACCENT
|
||||
0x5F 0x005F # LOW LINE
|
||||
0x60 0x0060 # GRAVE ACCENT
|
||||
0x61 0x0061 # LATIN SMALL LETTER A
|
||||
0x62 0x0062 # LATIN SMALL LETTER B
|
||||
0x63 0x0063 # LATIN SMALL LETTER C
|
||||
0x64 0x0064 # LATIN SMALL LETTER D
|
||||
0x65 0x0065 # LATIN SMALL LETTER E
|
||||
0x66 0x0066 # LATIN SMALL LETTER F
|
||||
0x67 0x0067 # LATIN SMALL LETTER G
|
||||
0x68 0x0068 # LATIN SMALL LETTER H
|
||||
0x69 0x0069 # LATIN SMALL LETTER I
|
||||
0x6A 0x006A # LATIN SMALL LETTER J
|
||||
0x6B 0x006B # LATIN SMALL LETTER K
|
||||
0x6C 0x006C # LATIN SMALL LETTER L
|
||||
0x6D 0x006D # LATIN SMALL LETTER M
|
||||
0x6E 0x006E # LATIN SMALL LETTER N
|
||||
0x6F 0x006F # LATIN SMALL LETTER O
|
||||
0x70 0x0070 # LATIN SMALL LETTER P
|
||||
0x71 0x0071 # LATIN SMALL LETTER Q
|
||||
0x72 0x0072 # LATIN SMALL LETTER R
|
||||
0x73 0x0073 # LATIN SMALL LETTER S
|
||||
0x74 0x0074 # LATIN SMALL LETTER T
|
||||
0x75 0x0075 # LATIN SMALL LETTER U
|
||||
0x76 0x0076 # LATIN SMALL LETTER V
|
||||
0x77 0x0077 # LATIN SMALL LETTER W
|
||||
0x78 0x0078 # LATIN SMALL LETTER X
|
||||
0x79 0x0079 # LATIN SMALL LETTER Y
|
||||
0x7A 0x007A # LATIN SMALL LETTER Z
|
||||
0x7B 0x007B # LEFT CURLY BRACKET
|
||||
0x7C 0x007C # VERTICAL LINE
|
||||
0x7D 0x007D # RIGHT CURLY BRACKET
|
||||
0x7E 0x007E # TILDE
|
||||
0x7F 0x007F # DELETE
|
||||
0x80 0x0080 # <control>
|
||||
0x81 0x0081 # <control>
|
||||
0x82 0x0082 # <control>
|
||||
0x83 0x0083 # <control>
|
||||
0x84 0x0084 # <control>
|
||||
0x85 0x0085 # <control>
|
||||
0x86 0x0086 # <control>
|
||||
0x87 0x0087 # <control>
|
||||
0x88 0x0088 # <control>
|
||||
0x89 0x0089 # <control>
|
||||
0x8A 0x008A # <control>
|
||||
0x8B 0x008B # <control>
|
||||
0x8C 0x008C # <control>
|
||||
0x8D 0x008D # <control>
|
||||
0x8E 0x008E # <control>
|
||||
0x8F 0x008F # <control>
|
||||
0x90 0x0090 # <control>
|
||||
0x91 0x0091 # <control>
|
||||
0x92 0x0092 # <control>
|
||||
0x93 0x0093 # <control>
|
||||
0x94 0x0094 # <control>
|
||||
0x95 0x0095 # <control>
|
||||
0x96 0x0096 # <control>
|
||||
0x97 0x0097 # <control>
|
||||
0x98 0x0098 # <control>
|
||||
0x99 0x0099 # <control>
|
||||
0x9A 0x009A # <control>
|
||||
0x9B 0x009B # <control>
|
||||
0x9C 0x009C # <control>
|
||||
0x9D 0x009D # <control>
|
||||
0x9E 0x009E # <control>
|
||||
0x9F 0x009F # <control>
|
||||
0xA0 0x00A0 # NO-BREAK SPACE
|
||||
0xA1 0x00A1 # INVERTED EXCLAMATION MARK
|
||||
0xA2 0x00A2 # CENT SIGN
|
||||
0xA3 0x00A3 # POUND SIGN
|
||||
0xA4 0x00A4 # CURRENCY SIGN
|
||||
0xA5 0x00A5 # YEN SIGN
|
||||
0xA6 0x00A6 # BROKEN BAR
|
||||
0xA7 0x00A7 # SECTION SIGN
|
||||
0xA8 0x00A8 # DIAERESIS
|
||||
0xA9 0x00A9 # COPYRIGHT SIGN
|
||||
0xAA 0x00AA # FEMININE ORDINAL INDICATOR
|
||||
0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xAC 0x00AC # NOT SIGN
|
||||
0xAD 0x00AD # SOFT HYPHEN
|
||||
0xAE 0x00AE # REGISTERED SIGN
|
||||
0xAF 0x00AF # MACRON
|
||||
0xB0 0x00B0 # DEGREE SIGN
|
||||
0xB1 0x00B1 # PLUS-MINUS SIGN
|
||||
0xB2 0x00B2 # SUPERSCRIPT TWO
|
||||
0xB3 0x00B3 # SUPERSCRIPT THREE
|
||||
0xB4 0x00B4 # ACUTE ACCENT
|
||||
0xB5 0x00B5 # MICRO SIGN
|
||||
0xB6 0x00B6 # PILCROW SIGN
|
||||
0xB7 0x00B7 # MIDDLE DOT
|
||||
0xB8 0x00B8 # CEDILLA
|
||||
0xB9 0x00B9 # SUPERSCRIPT ONE
|
||||
0xBA 0x00BA # MASCULINE ORDINAL INDICATOR
|
||||
0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xBC 0x00BC # VULGAR FRACTION ONE QUARTER
|
||||
0xBD 0x00BD # VULGAR FRACTION ONE HALF
|
||||
0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS
|
||||
0xBF 0x00BF # INVERTED QUESTION MARK
|
||||
0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE
|
||||
0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE
|
||||
0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE
|
||||
0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
0xC6 0x00C6 # LATIN CAPITAL LETTER AE
|
||||
0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE
|
||||
0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE
|
||||
0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE
|
||||
0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE
|
||||
0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic)
|
||||
0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE
|
||||
0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE
|
||||
0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE
|
||||
0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE
|
||||
0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
0xD7 0x00D7 # MULTIPLICATION SIGN
|
||||
0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE
|
||||
0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE
|
||||
0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE
|
||||
0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic)
|
||||
0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German)
|
||||
0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE
|
||||
0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE
|
||||
0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE
|
||||
0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS
|
||||
0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE
|
||||
0xE6 0x00E6 # LATIN SMALL LETTER AE
|
||||
0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA
|
||||
0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE
|
||||
0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE
|
||||
0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS
|
||||
0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE
|
||||
0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE
|
||||
0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS
|
||||
0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic)
|
||||
0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE
|
||||
0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE
|
||||
0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE
|
||||
0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE
|
||||
0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS
|
||||
0xF7 0x00F7 # DIVISION SIGN
|
||||
0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE
|
||||
0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE
|
||||
0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE
|
||||
0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS
|
||||
0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE
|
||||
0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic)
|
||||
0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
# use WAVE DASH for FULLWIDTH TILDE
|
||||
0xFF5E 0x301C
|
||||
# use TILDE for SMALL TILDE
|
||||
0x02DC 0x007E
|
||||
# use HYPHEN-MINUS for MINUS SIGN
|
||||
0x2212 0x002D
|
@@ -1,440 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
void erase_cell(struct terminal_t *term, int y, int x)
|
||||
{
|
||||
struct cell_t *cellp;
|
||||
|
||||
cellp = &term->cells[y][x];
|
||||
cellp->glyphp = term->glyph[DEFAULT_CHAR];
|
||||
cellp->color_pair = term->color_pair; /* bce */
|
||||
cellp->attribute = ATTR_RESET;
|
||||
cellp->width = HALF;
|
||||
#if 0
|
||||
cellp->has_pixmap = false;
|
||||
#endif
|
||||
|
||||
term->line_dirty[y] = true;
|
||||
}
|
||||
|
||||
void copy_cell(struct terminal_t *term, int dst_y, int dst_x, int src_y, int src_x)
|
||||
{
|
||||
struct cell_t *dst, *src;
|
||||
|
||||
dst = &term->cells[dst_y][dst_x];
|
||||
src = &term->cells[src_y][src_x];
|
||||
|
||||
if (src->width == NEXT_TO_WIDE) {
|
||||
return;
|
||||
} else if (src->width == WIDE && dst_x == (term->cols - 1)) {
|
||||
erase_cell(term, dst_y, dst_x);
|
||||
} else {
|
||||
*dst = *src;
|
||||
if (src->width == WIDE) {
|
||||
*(dst + 1) = *src;
|
||||
(dst + 1)->width = NEXT_TO_WIDE;
|
||||
}
|
||||
term->line_dirty[dst_y] = true;
|
||||
}
|
||||
}
|
||||
|
||||
int set_cell(struct terminal_t *term, int y, int x, const struct glyph_t *glyphp)
|
||||
{
|
||||
struct cell_t cell, *cellp;
|
||||
uint8_t color_tmp;
|
||||
|
||||
cell.glyphp = glyphp;
|
||||
|
||||
cell.color_pair.fg = (term->attribute & attr_mask[ATTR_BOLD] && term->color_pair.fg <= 7) ?
|
||||
term->color_pair.fg + BRIGHT_INC: term->color_pair.fg;
|
||||
cell.color_pair.bg = (term->attribute & attr_mask[ATTR_BLINK] && term->color_pair.bg <= 7) ?
|
||||
term->color_pair.bg + BRIGHT_INC: term->color_pair.bg;
|
||||
|
||||
if (term->attribute & attr_mask[ATTR_REVERSE]) {
|
||||
color_tmp = cell.color_pair.fg;
|
||||
cell.color_pair.fg = cell.color_pair.bg;
|
||||
cell.color_pair.bg = color_tmp;
|
||||
}
|
||||
|
||||
cell.attribute = term->attribute;
|
||||
cell.width = (glyph_width)glyphp->width;
|
||||
#if 0
|
||||
cell.has_pixmap = false;
|
||||
#endif
|
||||
|
||||
cellp = &term->cells[y][x];
|
||||
*cellp = cell;
|
||||
term->line_dirty[y] = true;
|
||||
|
||||
if (cell.width == WIDE && x + 1 < term->cols) {
|
||||
cellp = &term->cells[y][x + 1];
|
||||
*cellp = cell;
|
||||
cellp->width = NEXT_TO_WIDE;
|
||||
return WIDE;
|
||||
}
|
||||
|
||||
if (cell.width == HALF /* isolated NEXT_TO_WIDE cell */
|
||||
&& x + 1 < term->cols
|
||||
&& term->cells[y][x + 1].width == NEXT_TO_WIDE) {
|
||||
erase_cell(term, y, x + 1);
|
||||
}
|
||||
return HALF;
|
||||
}
|
||||
|
||||
static inline void swap_lines(struct terminal_t *term, int i, int j)
|
||||
{
|
||||
struct cell_t *tmp;
|
||||
|
||||
tmp = term->cells[i];
|
||||
term->cells[i] = term->cells[j];
|
||||
term->cells[j] = tmp;
|
||||
}
|
||||
|
||||
void scroll(struct terminal_t *term, int from, int to, int offset)
|
||||
{
|
||||
int abs_offset, scroll_lines;
|
||||
|
||||
if (offset == 0 || from >= to)
|
||||
return;
|
||||
|
||||
logging(DEBUG, "scroll from:%d to:%d offset:%d\n", from, to, offset);
|
||||
|
||||
for (int y = from; y <= to; y++)
|
||||
term->line_dirty[y] = true;
|
||||
|
||||
abs_offset = abs(offset);
|
||||
scroll_lines = (to - from + 1) - abs_offset;
|
||||
|
||||
if (offset > 0) { /* scroll down */
|
||||
for (int y = from; y < from + scroll_lines; y++)
|
||||
swap_lines(term, y, y + offset);
|
||||
for (int y = (to - offset + 1); y <= to; y++)
|
||||
for (int x = 0; x < term->cols; x++)
|
||||
erase_cell(term, y, x);
|
||||
}
|
||||
else { /* scroll up */
|
||||
for (int y = to; y >= from + abs_offset; y--)
|
||||
swap_lines(term, y, y - abs_offset);
|
||||
for (int y = from; y < from + abs_offset; y++)
|
||||
for (int x = 0; x < term->cols; x++)
|
||||
erase_cell(term, y, x);
|
||||
}
|
||||
}
|
||||
|
||||
/* relative movement: cause scrolling */
|
||||
void move_cursor(struct terminal_t *term, int y_offset, int x_offset)
|
||||
{
|
||||
int x, y, top, bottom;
|
||||
|
||||
x = term->cursor.x + x_offset;
|
||||
y = term->cursor.y + y_offset;
|
||||
|
||||
top = term->scroll.top;
|
||||
bottom = term->scroll.bottom;
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
} else if (x >= term->cols) {
|
||||
if (term->mode & MODE_AMRIGHT)
|
||||
term->wrap_occured = true;
|
||||
x = term->cols - 1;
|
||||
}
|
||||
term->cursor.x = x;
|
||||
|
||||
y = (y < 0) ? 0:
|
||||
(y >= term->lines) ? term->lines - 1: y;
|
||||
|
||||
if (term->cursor.y == top && y_offset < 0) {
|
||||
y = top;
|
||||
scroll(term, top, bottom, y_offset);
|
||||
} else if (term->cursor.y == bottom && y_offset > 0) {
|
||||
y = bottom;
|
||||
scroll(term, top, bottom, y_offset);
|
||||
}
|
||||
term->cursor.y = y;
|
||||
|
||||
if (y_offset > 0 && !term->nlseen) {
|
||||
term->txt.push("");
|
||||
term->lines_available++;
|
||||
}
|
||||
}
|
||||
|
||||
/* absolute movement: never scroll */
|
||||
void set_cursor(struct terminal_t *term, int y, int x)
|
||||
{
|
||||
int top, bottom;
|
||||
|
||||
if (term->mode & MODE_ORIGIN) {
|
||||
top = term->scroll.top;
|
||||
bottom = term->scroll.bottom;
|
||||
y += term->scroll.top;
|
||||
} else {
|
||||
top = 0;
|
||||
bottom = term->lines - 1;
|
||||
}
|
||||
|
||||
x = (x < 0) ? 0: (x >= term->cols) ? term->cols - 1: x;
|
||||
y = (y < top) ? top: (y > bottom) ? bottom: y;
|
||||
|
||||
if (term->cursor.y != y && !term->nlseen) {
|
||||
term->txt.push("");
|
||||
term->lines_available++;
|
||||
}
|
||||
|
||||
term->cursor.x = x;
|
||||
term->cursor.y = y;
|
||||
term->wrap_occured = false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
const struct glyph_t *drcs_glyph(struct terminal_t *term, uint32_t code)
|
||||
{
|
||||
/* DRCSMMv1
|
||||
ESC ( SP <\xXX> <\xYY> ESC ( B
|
||||
<===> U+10XXYY ( 0x40 <= 0xXX <=0x7E, 0x20 <= 0xYY <= 0x7F )
|
||||
*/
|
||||
int row, cell; /* = ku, ten */
|
||||
|
||||
row = (0xFF00 & code) >> 8;
|
||||
cell = 0xFF & code;
|
||||
|
||||
logging(DEBUG, "drcs row:0x%.2X cell:0x%.2X\n", row, cell);
|
||||
|
||||
if ((0x40 <= row && row <= 0x7E) && (0x20 <= cell && cell <= 0x7F))
|
||||
return &term->drcs[(row - 0x40) * GLYPHS_PER_CHARSET + (cell - 0x20)];
|
||||
else
|
||||
return term->glyph[SUBSTITUTE_HALF];
|
||||
}
|
||||
#endif
|
||||
|
||||
void addch(struct terminal_t *term, uint32_t code)
|
||||
{
|
||||
int width;
|
||||
const struct glyph_t *glyphp;
|
||||
|
||||
logging(DEBUG, "addch: U+%.4X\n", code);
|
||||
|
||||
width = wcwidth(code);
|
||||
|
||||
if (code <= 0xff) { /* non-ascii not supported */
|
||||
char c = (char)code;
|
||||
term->txt.back().append(&c, 1);
|
||||
}
|
||||
if (width <= 0) /* zero width: not support comibining character */
|
||||
return;
|
||||
else if (0x100000 <= code && code <= 0x10FFFD) /* unicode private area: plane 16 (DRCSMMv1) */
|
||||
#if 0
|
||||
glyphp = drcs_glyph(term, code);
|
||||
#endif
|
||||
glyphp = term->glyph[SUBSTITUTE_HALF];
|
||||
else if (code >= UCS2_CHARS /* yaft support only UCS2 */
|
||||
|| term->glyph[code] == NULL /* missing glyph */
|
||||
|| term->glyph[code]->width != width) /* width unmatch */
|
||||
glyphp = (width == 1) ? term->glyph[SUBSTITUTE_HALF]: term->glyph[SUBSTITUTE_WIDE];
|
||||
else
|
||||
glyphp = term->glyph[code];
|
||||
|
||||
if ((term->wrap_occured && term->cursor.x == term->cols - 1) /* folding */
|
||||
|| (glyphp->width == WIDE && term->cursor.x == term->cols - 1)) {
|
||||
set_cursor(term, term->cursor.y, 0);
|
||||
move_cursor(term, 1, 0);
|
||||
}
|
||||
term->wrap_occured = false;
|
||||
|
||||
move_cursor(term, 0, set_cell(term, term->cursor.y, term->cursor.x, glyphp));
|
||||
}
|
||||
|
||||
void reset_esc(struct terminal_t *term)
|
||||
{
|
||||
logging(DEBUG, "*esc reset*\n");
|
||||
|
||||
term->esc.bp = term->esc.buf;
|
||||
term->esc.state = STATE_RESET;
|
||||
}
|
||||
|
||||
bool push_esc(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
long offset;
|
||||
|
||||
if ((term->esc.bp - term->esc.buf) >= term->esc.size) { /* buffer limit */
|
||||
logging(DEBUG, "escape sequence length >= %d, term.esc.buf reallocated\n", term->esc.size);
|
||||
offset = term->esc.bp - term->esc.buf;
|
||||
term->esc.buf = (char *)erealloc(term->esc.buf, term->esc.size * 2);
|
||||
term->esc.bp = term->esc.buf + offset;
|
||||
term->esc.size *= 2;
|
||||
}
|
||||
|
||||
/* ref: http://www.vt100.net/docs/vt102-ug/appendixd.html */
|
||||
*term->esc.bp++ = ch;
|
||||
if (term->esc.state == STATE_ESC) {
|
||||
/* format:
|
||||
ESC I.......I F
|
||||
' ' '/' '0' '~'
|
||||
0x1B 0x20-0x2F 0x30-0x7E
|
||||
*/
|
||||
if ('0' <= ch && ch <= '~') /* final char */
|
||||
return true;
|
||||
else if (SPACE <= ch && ch <= '/') /* intermediate char */
|
||||
return false;
|
||||
} else if (term->esc.state == STATE_CSI) {
|
||||
/* format:
|
||||
CSI P.......P I.......I F
|
||||
ESC '[' '0' '?' ' ' '/' '@' '~'
|
||||
0x1B 0x5B 0x30-0x3F 0x20-0x2F 0x40-0x7E
|
||||
*/
|
||||
if ('@' <= ch && ch <= '~')
|
||||
return true;
|
||||
else if (SPACE <= ch && ch <= '?')
|
||||
return false;
|
||||
} else {
|
||||
/* format:
|
||||
OSC I.....I F
|
||||
ESC ']' BEL or ESC '\'
|
||||
0x1B 0x5D unknown 0x07 or 0x1B 0x5C
|
||||
DCS I....I F
|
||||
ESC 'P' BEL or ESC '\'
|
||||
0x1B 0x50 unknown 0x07 or 0x1B 0x5C
|
||||
*/
|
||||
if (ch == BEL || (ch == BACKSLASH
|
||||
&& (term->esc.bp - term->esc.buf) >= 2 && *(term->esc.bp - 2) == ESC))
|
||||
return true;
|
||||
else if ((ch == ESC || ch == CR || ch == LF || ch == BS || ch == HT)
|
||||
|| (SPACE <= ch && ch <= '~'))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* invalid sequence */
|
||||
reset_esc(term);
|
||||
return false;
|
||||
}
|
||||
|
||||
void reset_charset(struct terminal_t *term)
|
||||
{
|
||||
term->charset.code = term->charset.count = term->charset.following_byte = 0;
|
||||
term->charset.is_valid = true;
|
||||
}
|
||||
|
||||
void reset(struct terminal_t *term)
|
||||
{
|
||||
term->mode = MODE_RESET;
|
||||
term->mode |= (MODE_CURSOR | MODE_AMRIGHT);
|
||||
term->wrap_occured = false;
|
||||
|
||||
term->scroll.top = 0;
|
||||
term->scroll.bottom = term->lines - 1;
|
||||
|
||||
term->cursor.x = term->cursor.y = 0;
|
||||
|
||||
term->state.mode = term->mode;
|
||||
term->state.cursor = term->cursor;
|
||||
term->state.attribute = ATTR_RESET;
|
||||
|
||||
term->color_pair.fg = DEFAULT_FG;
|
||||
term->color_pair.bg = DEFAULT_BG;
|
||||
|
||||
term->attribute = ATTR_RESET;
|
||||
|
||||
for (int line = 0; line < term->lines; line++) {
|
||||
for (int col = 0; col < term->cols; col++) {
|
||||
erase_cell(term, line, col);
|
||||
if ((col % TABSTOP) == 0)
|
||||
term->tabstop[col] = true;
|
||||
else
|
||||
term->tabstop[col] = false;
|
||||
}
|
||||
term->line_dirty[line] = true;
|
||||
}
|
||||
|
||||
reset_esc(term);
|
||||
reset_charset(term);
|
||||
}
|
||||
|
||||
void redraw(struct terminal_t *term)
|
||||
{
|
||||
for (int i = 0; i < term->lines; i++)
|
||||
term->line_dirty[i] = true;
|
||||
}
|
||||
|
||||
void term_die(struct terminal_t *term)
|
||||
{
|
||||
free(term->line_dirty);
|
||||
free(term->tabstop);
|
||||
free(term->esc.buf);
|
||||
#if 0
|
||||
free(term->sixel.pixmap);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < term->lines; i++)
|
||||
free(term->cells[i]);
|
||||
free(term->cells);
|
||||
}
|
||||
|
||||
bool term_init(struct terminal_t *term, int width, int height)
|
||||
{
|
||||
extern const uint32_t color_list[COLORS]; /* global */
|
||||
const glyph_t *_glyphs;
|
||||
|
||||
term->width = width;
|
||||
term->height = height;
|
||||
|
||||
int j = 0;
|
||||
do {
|
||||
_glyphs = glyphs[j];
|
||||
CELL_WIDTH = _glyphs[0].code;
|
||||
CELL_HEIGHT = _glyphs[0].width;
|
||||
term->cols = term->width / CELL_WIDTH;
|
||||
if (term->cols > 79)
|
||||
break;
|
||||
j++;
|
||||
} while (glyphs[j]);
|
||||
|
||||
term->lines = term->height / CELL_HEIGHT;
|
||||
|
||||
term->esc.size = ESCSEQ_SIZE;
|
||||
|
||||
logging(DEBUG, "terminal cols:%d lines:%d\n", term->cols, term->lines);
|
||||
|
||||
/* allocate memory */
|
||||
term->line_dirty = (bool *) ecalloc(term->lines, sizeof(bool));
|
||||
term->tabstop = (bool *) ecalloc(term->cols, sizeof(bool));
|
||||
term->esc.buf = (char *) ecalloc(1, term->esc.size);
|
||||
#if 0
|
||||
term->sixel.pixmap = (uint8_t *) ecalloc(width * height, BYTES_PER_PIXEL);
|
||||
#endif
|
||||
|
||||
term->cells = (struct cell_t **) ecalloc(term->lines, sizeof(struct cell_t *));
|
||||
for (int i = 0; i < term->lines; i++)
|
||||
term->cells[i] = (struct cell_t *) ecalloc(term->cols, sizeof(struct cell_t));
|
||||
|
||||
if (!term->line_dirty || !term->tabstop || !term->cells
|
||||
|| !term->esc.buf /*|| !term->sixel.pixmap*/) {
|
||||
term_die(term);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* initialize palette */
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
term->virtual_palette[i] = color_list[i];
|
||||
term->palette_modified = false;
|
||||
|
||||
/* initialize glyph map */
|
||||
for (uint32_t code = 0; code < UCS2_CHARS; code++)
|
||||
term->glyph[code] = NULL;
|
||||
|
||||
for (uint32_t gi = 1; _glyphs[gi].code > 0; gi++)
|
||||
term->glyph[_glyphs[gi].code] = &_glyphs[gi];
|
||||
|
||||
if (!term->glyph[DEFAULT_CHAR]
|
||||
|| !term->glyph[SUBSTITUTE_HALF]
|
||||
|| !term->glyph[SUBSTITUTE_WIDE]) {
|
||||
logging(ERROR, "couldn't find essential glyph:\
|
||||
DEFAULT_CHAR(U+%.4X):%p SUBSTITUTE_HALF(U+%.4X):%p SUBSTITUTE_WIDE(U+%.4X):%p\n",
|
||||
DEFAULT_CHAR, term->glyph[DEFAULT_CHAR],
|
||||
SUBSTITUTE_HALF, term->glyph[SUBSTITUTE_HALF],
|
||||
SUBSTITUTE_WIDE, term->glyph[SUBSTITUTE_WIDE]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* reset terminal */
|
||||
reset(term);
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,216 +0,0 @@
|
||||
int pre_match(const char *buf, const char *str) {
|
||||
return !strncmp(buf, str, strlen(str));
|
||||
}
|
||||
|
||||
int bit2byte(int bits)
|
||||
{
|
||||
return (bits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
|
||||
}
|
||||
|
||||
void shift_glyph(struct bdf_header_t *bdf_header, struct bdf_char_t *bdf_char)
|
||||
{
|
||||
int i, byte, shift;
|
||||
bitmap_width_t bitmap;
|
||||
|
||||
for (i = 0; i < bdf_char->bbh; i++) {
|
||||
bitmap = bdf_char->bitmap[i];
|
||||
byte = bit2byte(bdf_char->bbw);
|
||||
bitmap <<= (bit2byte(bdf_char->dwidth) - byte) * BITS_PER_BYTE;
|
||||
if (bdf_char->bbx >= 0)
|
||||
bitmap >>= bdf_char->bbx;
|
||||
else {
|
||||
logging(ERROR, "maybe overlapping (glpyh:%X bbx:%d)\n", bdf_char->encoding, bdf_char->bbx);
|
||||
bitmap <<= abs(bdf_char->bbx);
|
||||
}
|
||||
bdf_char->bitmap[i] = bitmap;
|
||||
}
|
||||
|
||||
shift = bdf_header->ascent - (bdf_char->bbh + bdf_char->bby);
|
||||
if (shift >= 0) {
|
||||
memmove(bdf_char->bitmap + shift, bdf_char->bitmap, sizeof(bitmap_width_t) * bdf_char->bbh);
|
||||
memset(bdf_char->bitmap, 0, sizeof(bitmap_width_t) * shift);
|
||||
}
|
||||
else {
|
||||
logging(ERROR, "maybe overlapping (glpyh:%X vertical shift:%d)\n", bdf_char->encoding, shift);
|
||||
memmove(bdf_char->bitmap, bdf_char->bitmap + abs(shift), sizeof(bitmap_width_t) * bdf_char->bbh);
|
||||
}
|
||||
}
|
||||
|
||||
void load_table(char *path, enum encode_t encode)
|
||||
{
|
||||
int i;
|
||||
char buf[BUFSIZE], *cp;
|
||||
FILE *fp;
|
||||
uint32_t from, to;
|
||||
|
||||
fp = efopen(path, "r");
|
||||
|
||||
for (i = 0; i < UCS2_CHARS; i++) {
|
||||
if (encode == ISO10646)
|
||||
convert_table[i] = i;
|
||||
else
|
||||
convert_table[i] = -1;
|
||||
}
|
||||
|
||||
while (fgets(buf, BUFSIZE, fp) != NULL) {
|
||||
if (strlen(buf) == 0 || buf[0] == '#')
|
||||
continue;
|
||||
|
||||
if ((cp = strchr(buf, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
sscanf(buf, "%X %X", (unsigned int *) &from, (unsigned int *) &to);
|
||||
convert_table[from] = to;
|
||||
}
|
||||
if(fp)
|
||||
efclose(fp);
|
||||
}
|
||||
|
||||
int read_header(char *buf, struct bdf_header_t *bdf_header)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (pre_match(buf, "FONTBOUNDINGBOX "))
|
||||
sscanf(buf + strlen("FONTBOUNDINGBOX "), "%d %d %d %d",
|
||||
&bdf_header->bbw, &bdf_header->bbh, &bdf_header->bbx, &bdf_header->bby);
|
||||
else if (pre_match(buf, "FONT_ASCENT "))
|
||||
bdf_header->ascent = atoi(buf + strlen("FONT_ASCENT "));
|
||||
else if (pre_match(buf, "FONT_DESCENT "))
|
||||
bdf_header->descent = atoi(buf + strlen("FONT_DESCENT "));
|
||||
else if (pre_match(buf, "DEFAULT_CHAR "))
|
||||
bdf_header->default_char = atoi(buf + strlen("DEFAULT_CHAR "));
|
||||
else if (pre_match(buf, "PIXEL_SIZE "))
|
||||
bdf_header->pixel_size = atoi(buf + strlen("PIXEL_SIZE "));
|
||||
else if (pre_match(buf, "CHARSET_REGISTRY ")) {
|
||||
strncpy(bdf_header->charset, buf + strlen("CHARSET_REGISTRY "), BUFSIZE - 1);
|
||||
logging(DEBUG, "%s\n", bdf_header->charset);
|
||||
|
||||
for (cp = bdf_header->charset; *cp != '\0'; cp++)
|
||||
*cp = (char) toupper((int) *cp);
|
||||
|
||||
if (strstr(bdf_header->charset, "X68000") != NULL
|
||||
|| strstr(bdf_header->charset, "x68000") != NULL)
|
||||
load_table("./table/X68000", X68000);
|
||||
else if (strstr(bdf_header->charset, "JISX0201") != NULL
|
||||
|| strstr(bdf_header->charset, "jisx0201") != NULL)
|
||||
load_table("./table/JISX0201", JISX0201);
|
||||
else if (strstr(bdf_header->charset, "JISX0208") != NULL
|
||||
|| strstr(bdf_header->charset, "jisx0208") != NULL)
|
||||
load_table("./table/JISX0208", JISX0208);
|
||||
else if (strstr(bdf_header->charset, "ISO8859") != NULL
|
||||
|| strstr(bdf_header->charset, "iso8859") != NULL)
|
||||
load_table("./table/ISO8859", ISO8859);
|
||||
else /* assume "ISO10646" */
|
||||
load_table("./table/ISO10646", ISO10646);
|
||||
}
|
||||
else if (pre_match(buf, "CHARS ")) {
|
||||
bdf_header->chars = atoi(buf + strlen("CHARS "));
|
||||
return BDF_CHAR;
|
||||
}
|
||||
|
||||
return BDF_HEADER;
|
||||
}
|
||||
|
||||
int read_char(char *buf, struct bdf_char_t *bdf_char)
|
||||
{
|
||||
if (pre_match(buf, "BBX "))
|
||||
sscanf(buf + strlen("BBX "), "%d %d %d %d",
|
||||
&bdf_char->bbw, &bdf_char->bbh, &bdf_char->bbx, &bdf_char->bby);
|
||||
else if (pre_match(buf, "DWIDTH "))
|
||||
bdf_char->dwidth = atoi(buf + strlen("DWIDTH "));
|
||||
else if (pre_match(buf, "ENCODING ")) {
|
||||
bdf_char->encoding = atoi(buf + strlen("ENCODING "));
|
||||
//logging(DEBUG, "reading char:%d\n", bdf_char->encoding);
|
||||
}
|
||||
else if (pre_match(buf, "BITMAP")) {
|
||||
return BDF_BITMAP;
|
||||
}
|
||||
|
||||
return BDF_CHAR;
|
||||
}
|
||||
|
||||
int read_bitmap(struct glyph_list_t **glist_head, struct glyph_t *default_glyph,
|
||||
char *buf, struct bdf_header_t *bdf_header, struct bdf_char_t *bdf_char)
|
||||
{
|
||||
static int count = 0;
|
||||
uint32_t code;
|
||||
uint8_t width, height;
|
||||
struct glyph_list_t *listp;
|
||||
struct glyph_t *glyph;
|
||||
|
||||
if (pre_match(buf, "ENDCHAR")) {
|
||||
count = 0;
|
||||
|
||||
shift_glyph(bdf_header, bdf_char);
|
||||
|
||||
if (bdf_char->encoding < 0 || bdf_char->encoding >= UCS2_CHARS)
|
||||
return BDF_CHAR;
|
||||
|
||||
code = convert_table[bdf_char->encoding];
|
||||
width = bdf_char->dwidth;
|
||||
height = bdf_header->ascent + bdf_header->descent;
|
||||
|
||||
//logging(DEBUG, "code:%d width:%d height:%d\n", code, width, height);
|
||||
|
||||
if (code < UCS2_CHARS && width <= 64) {
|
||||
listp = ecalloc(1, sizeof(struct glyph_list_t));
|
||||
glyph = ecalloc(1, sizeof(struct glyph_t));
|
||||
|
||||
glyph->width = width;
|
||||
glyph->height = height;
|
||||
/* XXX: max width 64 pixels (wide char) */
|
||||
glyph->bitmap = (bitmap_width_t *) ecalloc(glyph->height, sizeof(bitmap_width_t));
|
||||
|
||||
for (int i = 0; i < glyph->height; i++)
|
||||
glyph->bitmap[i] = bdf_char->bitmap[i];
|
||||
|
||||
/* add new element to glyph list */
|
||||
listp->code = code;
|
||||
listp->glyph = glyph;
|
||||
listp->next = *glist_head;
|
||||
*glist_head = listp;
|
||||
|
||||
if (code == DEFAULT_CHAR)
|
||||
*default_glyph = *glyph;
|
||||
}
|
||||
memset(bdf_char, 0, sizeof(struct bdf_char_t));
|
||||
return BDF_CHAR;
|
||||
}
|
||||
else
|
||||
sscanf(buf, "%X", (unsigned int *) &bdf_char->bitmap[count++]);
|
||||
|
||||
return BDF_BITMAP;
|
||||
}
|
||||
|
||||
bool load_bdf_glyph(struct glyph_list_t **glist_head, struct glyph_t *default_glyph, char *path)
|
||||
{
|
||||
int mode = BDF_HEADER;
|
||||
char lbuf[BUFSIZE], *cp;
|
||||
FILE *fp;
|
||||
struct bdf_header_t bdf_header;
|
||||
struct bdf_char_t bdf_char;
|
||||
|
||||
if ((fp = efopen(path, "r")) == NULL)
|
||||
return false;
|
||||
|
||||
memset(&bdf_header, 0, sizeof(struct bdf_header_t));
|
||||
memset(&bdf_char, 0, sizeof(struct bdf_char_t));
|
||||
|
||||
logging(DEBUG, "read bdf: %s\n", path);
|
||||
|
||||
while (fgets(lbuf, BUFSIZE, fp) != NULL) {
|
||||
if ((cp = strchr(lbuf, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
//fprintf(stderr, "%s\n", lbuf);
|
||||
|
||||
if (mode == BDF_HEADER)
|
||||
mode = read_header(lbuf, &bdf_header);
|
||||
else if (mode == BDF_CHAR)
|
||||
mode = read_char(lbuf, &bdf_char);
|
||||
else if (mode == BDF_BITMAP)
|
||||
mode = read_bitmap(glist_head, default_glyph, lbuf, &bdf_header, &bdf_char);
|
||||
}
|
||||
efclose(fp);
|
||||
return true;
|
||||
}
|
@@ -1,205 +0,0 @@
|
||||
#include "mkfont_bdf.h"
|
||||
#include "../conf.h"
|
||||
#include "util.h"
|
||||
#include "bdf.h"
|
||||
|
||||
/* mkfont_bdf functions */
|
||||
bool map_glyph(struct glyph_t *font[],
|
||||
struct glyph_list_t *glist_head, struct glyph_t *default_glyph)
|
||||
{
|
||||
int width, cell_width = 0, cell_height = 0;
|
||||
struct glyph_t *glyph;
|
||||
struct glyph_list_t *listp;
|
||||
|
||||
if (default_glyph->width == 0 || default_glyph->height == 0) {
|
||||
logging(ERROR, "default glyph(U+%.4X) not found\n", DEFAULT_CHAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
cell_width = default_glyph->width;
|
||||
cell_height = default_glyph->height;
|
||||
logging(DEBUG, "default glyph width:%d height:%d\n",
|
||||
default_glyph->width, default_glyph->height);
|
||||
|
||||
for (listp = glist_head; listp != NULL; listp = listp->next) {
|
||||
if (listp->code >= UCS2_CHARS)
|
||||
continue;
|
||||
|
||||
width = wcwidth(listp->code);
|
||||
glyph = listp->glyph;
|
||||
if ((width <= 0) /* not printable */
|
||||
|| (glyph->height != cell_height) /* invalid font height */
|
||||
|| (glyph->width != (cell_width * width))) /* invalid font width */
|
||||
continue;
|
||||
|
||||
font[listp->code] = glyph;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load_alias(struct glyph_t *font[], char *alias)
|
||||
{
|
||||
unsigned int dst, src;
|
||||
char buf[BUFSIZE];
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = efopen(alias, "r")) == NULL)
|
||||
return false;
|
||||
|
||||
while (fgets(buf, BUFSIZE, fp) != NULL) {
|
||||
if (strlen(buf) == 0 || buf[0] == '#')
|
||||
continue;
|
||||
|
||||
sscanf(buf, "%X %X", &dst, &src);
|
||||
if ((dst >= UCS2_CHARS) || (src >= UCS2_CHARS))
|
||||
continue;
|
||||
|
||||
//if (font[src] != NULL && font[dst] != NULL) {
|
||||
if (font[src] != NULL) {
|
||||
logging(DEBUG, "swapped: use U+%.4X for U+%.4X\n", src, dst);
|
||||
font[dst] = font[src];
|
||||
|
||||
//free(font[dst]->bitmap);
|
||||
//font[dst]->width = font[src]->width;
|
||||
//font[dst]->height = font[src]->height;
|
||||
//font[dst]->bitmap = font[src]->bitmap;
|
||||
//memcpy(font[dst]->bitmap, font[src]->bitmap, sizeof(bitmap_width_t) * font[src]->height);
|
||||
}
|
||||
}
|
||||
efclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_font(struct glyph_t **font, struct glyph_t *empty_half, struct glyph_t *empty_wide)
|
||||
{
|
||||
empty_half->bitmap = (bitmap_width_t *) ecalloc(font[DEFAULT_CHAR]->height, sizeof(bitmap_width_t));
|
||||
empty_wide->bitmap = (bitmap_width_t *) ecalloc(font[DEFAULT_CHAR]->height, sizeof(bitmap_width_t));
|
||||
|
||||
if (!empty_half->bitmap || !empty_wide->bitmap)
|
||||
return false;
|
||||
|
||||
empty_half->width = font[DEFAULT_CHAR]->width;
|
||||
empty_wide->width = font[DEFAULT_CHAR]->width * WIDE;
|
||||
empty_half->height = font[DEFAULT_CHAR]->height;
|
||||
empty_wide->height = font[DEFAULT_CHAR]->height;
|
||||
|
||||
if (font[SUBSTITUTE_HALF] == NULL) {
|
||||
logging(WARN, "half substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_HALF);
|
||||
font[SUBSTITUTE_HALF] = empty_half;
|
||||
}
|
||||
if (font[SUBSTITUTE_WIDE] == NULL) {
|
||||
logging(WARN, "wide substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_WIDE);
|
||||
font[SUBSTITUTE_WIDE] = empty_wide;
|
||||
}
|
||||
if (font[REPLACEMENT_CHAR] == NULL) {
|
||||
logging(WARN, "replacement glyph(U+%.4X) not found, use empty glyph\n", REPLACEMENT_CHAR);
|
||||
font[REPLACEMENT_CHAR] = empty_half;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dump_font(struct glyph_t *font[])
|
||||
{
|
||||
int i, j, width, int_type;
|
||||
uint8_t cell_width, cell_height;
|
||||
|
||||
cell_width = font[DEFAULT_CHAR]->width;
|
||||
cell_height = font[DEFAULT_CHAR]->height;
|
||||
|
||||
int_type = my_ceil(cell_width, BITS_PER_BYTE) /* minimum byte for containing half glyph */
|
||||
* 2 /* minimum byte for containing wide glyph */
|
||||
* BITS_PER_BYTE; /* minimum bits for containing wide glyph */
|
||||
|
||||
/* int_type: 16, 32, 48, 64, 80... */
|
||||
if (int_type == 48) { /* uint48_t does not exist */
|
||||
int_type = 64;
|
||||
} else if (int_type >= 80) {
|
||||
logging(ERROR, "BDF width too large (uint%d_t does not exist)\n", int_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(stdout,
|
||||
"struct glyph_t {\n"
|
||||
"\tuint32_t code;\n"
|
||||
"\tuint8_t width;\n"
|
||||
"\tuint%d_t bitmap[%d];\n"
|
||||
"};\n\n", int_type, cell_height);
|
||||
|
||||
fprintf(stdout, "enum {\n\tCELL_WIDTH = %d,\n\tCELL_HEIGHT = %d\n};\n\n",
|
||||
cell_width, cell_height);
|
||||
|
||||
fprintf(stdout, "static const struct glyph_t glyphs[] = {\n");
|
||||
for (i = 0; i < UCS2_CHARS; i++) {
|
||||
width = wcwidth(i);
|
||||
|
||||
if (font[i] == NULL) /* glyph not found */
|
||||
continue;
|
||||
|
||||
fprintf(stdout, "\t{%d, %d, {", i, width);
|
||||
for (j = 0; j < cell_height; j++)
|
||||
fprintf(stdout, "0x%X%s", (unsigned int) font[i]->bitmap[j], (j == (cell_height - 1)) ? "": ", ");
|
||||
fprintf(stdout, "}},\n");
|
||||
}
|
||||
fprintf(stdout, "};\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void cleanup(struct glyph_list_t *glist_head, struct glyph_t *empty_half, struct glyph_t *empty_wide)
|
||||
{
|
||||
struct glyph_list_t *listp, *next;
|
||||
|
||||
for (listp = glist_head; listp != NULL; listp = next) {
|
||||
next = listp->next;
|
||||
|
||||
free(listp->glyph->bitmap);
|
||||
free(listp->glyph);
|
||||
free(listp);
|
||||
}
|
||||
free(empty_half->bitmap);
|
||||
free(empty_wide->bitmap);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct glyph_list_t *glist_head = NULL;
|
||||
struct glyph_t *font[UCS2_CHARS], default_glyph, empty_wide, empty_half;
|
||||
|
||||
if (!setlocale(LC_ALL, "")) /* set current locale for wcwidth() */
|
||||
logging(WARN, "setlocale() failed\n");
|
||||
|
||||
if (argc < 3) {
|
||||
logging(FATAL, "usage: ./mkfont ALIAS BDF1 [BDF2] [BDF3] ...\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < UCS2_CHARS; i++)
|
||||
font[i] = NULL;
|
||||
|
||||
for (int i = 2; i < argc; i++)
|
||||
load_bdf_glyph(&glist_head, &default_glyph, argv[i]);
|
||||
|
||||
if (!map_glyph(font, glist_head, &default_glyph)) {
|
||||
logging(FATAL, "map_glyph() failed\n");
|
||||
goto err_occured;
|
||||
}
|
||||
|
||||
if (!load_alias(font, argv[1]))
|
||||
logging(WARN, "font alias does not work\n");
|
||||
|
||||
if (!check_font(font, &empty_half, &empty_wide)) {
|
||||
logging(FATAL, "check_font() failed\n");
|
||||
goto err_occured;
|
||||
}
|
||||
|
||||
if (!dump_font(font)) {
|
||||
logging(FATAL, "dump_font() failed\n");
|
||||
goto err_occured;
|
||||
}
|
||||
|
||||
cleanup(glist_head, &empty_half, &empty_wide);
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
err_occured:
|
||||
cleanup(glist_head, &empty_half, &empty_wide);
|
||||
return EXIT_FAILURE;
|
||||
}
|
@@ -1,82 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef uint64_t bitmap_width_t;
|
||||
|
||||
enum char_code {
|
||||
/* 7 bit control char */
|
||||
BEL = 0x07, BS = 0x08, HT = 0x09,
|
||||
LF = 0x0A, VT = 0x0B, FF = 0x0C,
|
||||
CR = 0x0D, ESC = 0x1B, DEL = 0x7F,
|
||||
/* others */
|
||||
SPACE = 0x20,
|
||||
BACKSLASH = 0x5C,
|
||||
};
|
||||
|
||||
enum misc {
|
||||
BITS_PER_BYTE = 8,
|
||||
BUFSIZE = 1024, /* read, esc, various buffer size */
|
||||
UCS2_CHARS = 0x10000, /* number of UCS2 glyph */
|
||||
DEFAULT_CHAR = SPACE, /* used for erase char, cell_size */
|
||||
MAX_HEIGHT = 64,
|
||||
BDF_HEADER = 0,
|
||||
BDF_CHAR = 1,
|
||||
BDF_BITMAP = 2,
|
||||
};
|
||||
|
||||
enum encode_t {
|
||||
X68000,
|
||||
JISX0208,
|
||||
JISX0201,
|
||||
/*
|
||||
JISX0212,
|
||||
JISX0213,
|
||||
*/
|
||||
ISO8859,
|
||||
ISO10646
|
||||
};
|
||||
|
||||
enum glyph_width_t {
|
||||
NEXT_TO_WIDE = 0,
|
||||
HALF,
|
||||
WIDE,
|
||||
};
|
||||
|
||||
struct glyph_t {
|
||||
uint8_t width, height;
|
||||
bitmap_width_t *bitmap;
|
||||
};
|
||||
|
||||
struct glyph_list_t {
|
||||
uint32_t code;
|
||||
struct glyph_t *glyph;
|
||||
struct glyph_list_t *next;
|
||||
};
|
||||
|
||||
struct bdf_header_t {
|
||||
int bbw, bbh, bbx, bby;
|
||||
int ascent, descent;
|
||||
int default_char;
|
||||
int chars;
|
||||
int pixel_size;
|
||||
char charset[BUFSIZE];
|
||||
};
|
||||
|
||||
struct bdf_char_t {
|
||||
int bbw, bbh, bbx, bby;
|
||||
int dwidth;
|
||||
int encoding;
|
||||
bitmap_width_t bitmap[MAX_HEIGHT];
|
||||
};
|
||||
|
||||
int convert_table[UCS2_CHARS];
|
@@ -1,71 +0,0 @@
|
||||
/* wrapper of C functions */
|
||||
enum loglevel_t {
|
||||
DEBUG = 0,
|
||||
WARN,
|
||||
ERROR,
|
||||
FATAL,
|
||||
};
|
||||
|
||||
void logging(enum loglevel_t loglevel, char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
static const char *loglevel2str[] = {
|
||||
[DEBUG] = "DEBUG",
|
||||
[WARN] = "WARN",
|
||||
[ERROR] = "ERROR",
|
||||
[FATAL] = "FATAL",
|
||||
};
|
||||
|
||||
/* debug message is available on verbose mode */
|
||||
if ((loglevel == DEBUG) && (VERBOSE == false))
|
||||
return;
|
||||
|
||||
fprintf(stderr, ">>%s<<\t", loglevel2str[loglevel]);
|
||||
|
||||
va_start(arg, format);
|
||||
vfprintf(stderr, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
FILE *efopen(const char *path, char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
errno = 0;
|
||||
|
||||
if ((fp = fopen(path, mode)) == NULL) {
|
||||
logging(ERROR, "couldn't open \"%s\"\n", path);
|
||||
logging(ERROR, "fopen: %s\n", strerror(errno));
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
int efclose(FILE *fp)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = fclose(fp)) < 0)
|
||||
logging(ERROR, "fclose: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
errno = 0;
|
||||
|
||||
if ((ptr = calloc(nmemb, size)) == NULL)
|
||||
logging(ERROR, "calloc: %s\n", strerror(errno));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int my_ceil(int val, int div)
|
||||
{
|
||||
if (div == 0)
|
||||
//return 0;
|
||||
return -1;
|
||||
else
|
||||
return (val + div - 1) / div;
|
||||
}
|
@@ -1,398 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* error functions */
|
||||
enum loglevel_t {
|
||||
DEBUG = 0,
|
||||
WARN,
|
||||
ERROR,
|
||||
FATAL,
|
||||
};
|
||||
|
||||
void logging(int loglevel, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
static const char *loglevel2str[] = {
|
||||
[DEBUG] = "DEBUG",
|
||||
[WARN] = "WARN",
|
||||
[ERROR] = "ERROR",
|
||||
[FATAL] = "FATAL",
|
||||
};
|
||||
|
||||
/* debug message is available on verbose mode */
|
||||
if ((loglevel == DEBUG) && (VERBOSE == false))
|
||||
return;
|
||||
|
||||
fprintf(stderr, ">>%s<<\t", loglevel2str[loglevel]);
|
||||
|
||||
va_start(arg, format);
|
||||
vfprintf(stderr, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
/* wrapper of C functions */
|
||||
int eopen(const char *path, int flag)
|
||||
{
|
||||
int fd;
|
||||
errno = 0;
|
||||
|
||||
if ((fd = open(path, flag)) < 0) {
|
||||
logging(ERROR, "couldn't open \"%s\"\n", path);
|
||||
logging(ERROR, "open: %s\n", strerror(errno));
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int eclose(int fd)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = close(fd)) < 0)
|
||||
logging(ERROR, "close: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE *efopen(const char *path, char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
errno = 0;
|
||||
|
||||
if ((fp = fopen(path, mode)) == NULL) {
|
||||
logging(ERROR, "couldn't open \"%s\"\n", path);
|
||||
logging(ERROR, "fopen: %s\n", strerror(errno));
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
int efclose(FILE *fp)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = fclose(fp)) < 0)
|
||||
logging(ERROR, "fclose: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void *emmap(void *addr, size_t len, int prot, int flag, int fd, off_t offset)
|
||||
{
|
||||
void *fp;
|
||||
errno = 0;
|
||||
|
||||
if ((fp = mmap(addr, len, prot, flag, fd, offset)) == MAP_FAILED)
|
||||
logging(ERROR, "mmap: %s\n", strerror(errno));
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
int emunmap(void *ptr, size_t len)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = munmap(ptr, len)) < 0)
|
||||
logging(ERROR, "munmap: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
errno = 0;
|
||||
|
||||
if ((ptr = calloc(nmemb, size)) == NULL)
|
||||
logging(ERROR, "calloc: %s\n", strerror(errno));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *erealloc(void *ptr, size_t size)
|
||||
{
|
||||
void *p;
|
||||
errno = 0;
|
||||
|
||||
if ((p = realloc(ptr, size)) == NULL)
|
||||
logging(ERROR, "realloc: %s\n", strerror(errno));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int eselect(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tv)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = select(maxfd, readfds, writefds, errorfds, tv)) < 0) {
|
||||
if (errno == EINTR)
|
||||
return eselect(maxfd, readfds, writefds, errorfds, tv);
|
||||
else
|
||||
logging(ERROR, "select: %s\n", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t ewrite(int fd, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = write(fd, buf, size)) < 0) {
|
||||
if (errno == EINTR) {
|
||||
logging(ERROR, "write: EINTR occurred\n");
|
||||
return ewrite(fd, buf, size);
|
||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
logging(ERROR, "write: EAGAIN or EWOULDBLOCK occurred, sleep %d usec\n", SLEEP_TIME);
|
||||
usleep(SLEEP_TIME);
|
||||
return ewrite(fd, buf, size);
|
||||
} else {
|
||||
logging(ERROR, "write: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
} else if (ret < (ssize_t) size) {
|
||||
logging(ERROR, "data size:%zu write size:%zd\n", size, ret);
|
||||
return ewrite(fd, (char *) buf + ret, size - ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int esigaction(int signo, struct sigaction *act, struct sigaction *oact)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = sigaction(signo, act, oact)) < 0)
|
||||
logging(ERROR, "sigaction: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int etcgetattr(int fd, struct termios *tm)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = tcgetattr(fd, tm)) < 0)
|
||||
logging(ERROR, "tcgetattr: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int etcsetattr(int fd, int action, const struct termios *tm)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = tcsetattr(fd, action, tm)) < 0)
|
||||
logging(ERROR, "tcgetattr: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eopenpty(int *amaster, int *aslave, char *aname,
|
||||
const struct termios *termp, const struct winsize *winsize)
|
||||
{
|
||||
int master;
|
||||
char *name = NULL;
|
||||
errno = 0;
|
||||
|
||||
if ((master = posix_openpt(O_RDWR | O_NOCTTY)) < 0
|
||||
|| grantpt(master) < 0
|
||||
|| unlockpt(master) < 0
|
||||
|| (name = ptsname(master)) == NULL) {
|
||||
logging(ERROR, "openpty: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
*amaster = master;
|
||||
*aslave = eopen(name, O_RDWR | O_NOCTTY);
|
||||
|
||||
if (aname)
|
||||
/* XXX: we don't use the slave's name, do nothing */
|
||||
(void) aname;
|
||||
//strncpy(aname, name, _POSIX_TTY_NAME_MAX - 1);
|
||||
//snprintf(aname, _POSIX_TTY_NAME_MAX, "%s", name);
|
||||
if (termp)
|
||||
etcsetattr(*aslave, TCSAFLUSH, termp);
|
||||
if (winsize)
|
||||
ioctl(*aslave, TIOCSWINSZ, winsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t eforkpty(int *amaster, char *name,
|
||||
const struct termios *termp, const struct winsize *winsize)
|
||||
{
|
||||
int master, slave;
|
||||
pid_t pid;
|
||||
|
||||
if (eopenpty(&master, &slave, name, termp, winsize) < 0)
|
||||
return -1;
|
||||
|
||||
errno = 0;
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
logging(ERROR, "fork: %s\n", strerror(errno));
|
||||
return pid;
|
||||
} else if (pid == 0) { /* child */
|
||||
close(master);
|
||||
setsid();
|
||||
|
||||
dup2(slave, STDIN_FILENO);
|
||||
dup2(slave, STDOUT_FILENO);
|
||||
dup2(slave, STDERR_FILENO);
|
||||
|
||||
/* XXX: this ioctl may fail in Mac OS X
|
||||
ref http://www.opensource.apple.com/source/Libc/Libc-825.25/util/pty.c?txt */
|
||||
if (ioctl(slave, TIOCSCTTY, NULL))
|
||||
logging(WARN, "ioctl: TIOCSCTTY faild\n");
|
||||
close(slave);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* parent */
|
||||
close(slave);
|
||||
*amaster = master;
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
int esetenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = setenv(name, value, overwrite)) < 0)
|
||||
logging(ERROR, "setenv: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eexecvp(const char *file, const char *argv[])
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
if ((ret = execvp(file, (char * const *) argv)) < 0)
|
||||
logging(ERROR, "execvp: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eexecl(const char *path)
|
||||
{
|
||||
int ret;
|
||||
errno = 0;
|
||||
|
||||
/* XXX: assume only one argument is given */
|
||||
if ((ret = execl(path, path, NULL)) < 0)
|
||||
logging(ERROR, "execl: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long estrtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
long int ret;
|
||||
errno = 0;
|
||||
|
||||
ret = strtol(nptr, endptr, base);
|
||||
if (ret == LONG_MIN || ret == LONG_MAX) {
|
||||
logging(ERROR, "strtol: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* parse_arg functions */
|
||||
void reset_parm(struct parm_t *pt)
|
||||
{
|
||||
pt->argc = 0;
|
||||
for (int i = 0; i < MAX_ARGS; i++)
|
||||
pt->argv[i] = NULL;
|
||||
}
|
||||
|
||||
void add_parm(struct parm_t *pt, char *cp)
|
||||
{
|
||||
if (pt->argc >= MAX_ARGS)
|
||||
return;
|
||||
|
||||
logging(DEBUG, "argv[%d]: %s\n", pt->argc, (cp == NULL) ? "NULL": cp);
|
||||
|
||||
pt->argv[pt->argc] = cp;
|
||||
pt->argc++;
|
||||
}
|
||||
|
||||
void parse_arg(char *buf, struct parm_t *pt, int delim, int (is_valid)(int c))
|
||||
{
|
||||
/*
|
||||
v..........v d v.....v d v.....v ... d
|
||||
(valid char) (delimiter)
|
||||
argv[0] argv[1] argv[2] ... argv[argc - 1]
|
||||
*/
|
||||
size_t length;
|
||||
char *cp, *vp;
|
||||
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
length = strlen(buf);
|
||||
logging(DEBUG, "parse_arg() length:%u\n", (unsigned) length);
|
||||
|
||||
vp = NULL;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
cp = buf + i;
|
||||
|
||||
if (vp == NULL && is_valid(*cp))
|
||||
vp = cp;
|
||||
|
||||
if (*cp == delim) {
|
||||
*cp = '\0';
|
||||
add_parm(pt, vp);
|
||||
vp = NULL;
|
||||
}
|
||||
|
||||
if (i == (length - 1) && (vp != NULL || *cp == '\0'))
|
||||
add_parm(pt, vp);
|
||||
}
|
||||
|
||||
logging(DEBUG, "argc:%d\n", pt->argc);
|
||||
}
|
||||
|
||||
/* other functions */
|
||||
int my_ceil(int val, int div)
|
||||
{
|
||||
if (div == 0)
|
||||
return 0;
|
||||
else
|
||||
return (val + div - 1) / div;
|
||||
}
|
||||
|
||||
int dec2num(char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
return estrtol(str, NULL, 10);
|
||||
}
|
||||
|
||||
int hex2num(char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
return estrtol(str, NULL, 16);
|
||||
}
|
||||
|
||||
int sum(struct parm_t *parm)
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < parm->argc; i++)
|
||||
sum += dec2num(parm->argv[i]);
|
||||
|
||||
return sum;
|
||||
}
|
@@ -1,241 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#define XK_NO_MOD UINT_MAX
|
||||
|
||||
enum { /* default terminal size 80x24 (8x16 dot font) */
|
||||
TERM_WIDTH = 640,
|
||||
TERM_HEIGHT = 384,
|
||||
};
|
||||
|
||||
struct keymap_t {
|
||||
KeySym keysym;
|
||||
unsigned int mask;
|
||||
char str[BUFSIZE];
|
||||
};
|
||||
|
||||
const struct keymap_t keymap[] = {
|
||||
{XK_BackSpace, XK_NO_MOD, "\177" },
|
||||
{XK_Up, Mod1Mask, "\033\033[A"},
|
||||
{XK_Up, XK_NO_MOD, "\033[A" },
|
||||
{XK_Down, Mod1Mask, "\033\033[B"},
|
||||
{XK_Down, XK_NO_MOD, "\033[B" },
|
||||
{XK_Right, Mod1Mask, "\033\033[C"},
|
||||
{XK_Right, XK_NO_MOD, "\033[C" },
|
||||
{XK_Left, Mod1Mask, "\033\033[D"},
|
||||
{XK_Left, XK_NO_MOD, "\033[D" },
|
||||
{XK_Begin, XK_NO_MOD, "\033[G" },
|
||||
{XK_Home, XK_NO_MOD, "\033[1~" },
|
||||
{XK_Insert, XK_NO_MOD, "\033[2~" },
|
||||
{XK_Delete, XK_NO_MOD, "\033[3~" },
|
||||
{XK_End, XK_NO_MOD, "\033[4~" },
|
||||
{XK_Prior, XK_NO_MOD, "\033[5~" },
|
||||
{XK_Next, XK_NO_MOD, "\033[6~" },
|
||||
{XK_F1, XK_NO_MOD, "\033[[A" },
|
||||
{XK_F2, XK_NO_MOD, "\033[[B" },
|
||||
{XK_F3, XK_NO_MOD, "\033[[C" },
|
||||
{XK_F4, XK_NO_MOD, "\033[[D" },
|
||||
{XK_F5, XK_NO_MOD, "\033[[E" },
|
||||
{XK_F6, XK_NO_MOD, "\033[17~" },
|
||||
{XK_F7, XK_NO_MOD, "\033[18~" },
|
||||
{XK_F8, XK_NO_MOD, "\033[19~" },
|
||||
{XK_F9, XK_NO_MOD, "\033[20~" },
|
||||
{XK_F10, XK_NO_MOD, "\033[21~" },
|
||||
{XK_F11, XK_NO_MOD, "\033[23~" },
|
||||
{XK_F12, XK_NO_MOD, "\033[24~" },
|
||||
{XK_F13, XK_NO_MOD, "\033[25~" },
|
||||
{XK_F14, XK_NO_MOD, "\033[26~" },
|
||||
{XK_F15, XK_NO_MOD, "\033[28~" },
|
||||
{XK_F16, XK_NO_MOD, "\033[29~" },
|
||||
{XK_F17, XK_NO_MOD, "\033[31~" },
|
||||
{XK_F18, XK_NO_MOD, "\033[32~" },
|
||||
{XK_F19, XK_NO_MOD, "\033[33~" },
|
||||
{XK_F20, XK_NO_MOD, "\033[34~" },
|
||||
};
|
||||
|
||||
/* not assigned:
|
||||
kcbt=\E[Z,kmous=\E[M,kspd=^Z,
|
||||
*/
|
||||
|
||||
struct xwindow_t {
|
||||
Display *display;
|
||||
Window window;
|
||||
Pixmap pixbuf;
|
||||
Colormap cmap;
|
||||
GC gc;
|
||||
int width, height;
|
||||
int screen;
|
||||
unsigned long color_palette[COLORS];
|
||||
};
|
||||
|
||||
unsigned long color2pixel(struct xwindow_t *xw, uint32_t color)
|
||||
{
|
||||
XColor xc;
|
||||
|
||||
xc.red = ((color >> 16) & bit_mask[8]) << 8;
|
||||
xc.green = ((color >> 8) & bit_mask[8]) << 8;
|
||||
xc.blue = ((color >> 0) & bit_mask[8]) << 8;
|
||||
|
||||
XAllocColor(xw->display, xw->cmap, &xc);
|
||||
return xc.pixel;
|
||||
}
|
||||
|
||||
bool xw_init(struct xwindow_t *xw)
|
||||
{
|
||||
XTextProperty xtext = {.value = (unsigned char *) "yaftx",
|
||||
.encoding = XA_STRING, .format = 8, .nitems = 5};
|
||||
|
||||
if ((xw->display = XOpenDisplay(NULL)) == NULL) {
|
||||
logging(ERROR, "XOpenDisplay() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!XSupportsLocale())
|
||||
logging(WARN, "X does not support locale\n");
|
||||
|
||||
if (XSetLocaleModifiers("") == NULL)
|
||||
logging(WARN, "cannot set locale modifiers\n");
|
||||
|
||||
xw->cmap = DefaultColormap(xw->display, xw->screen);
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
xw->color_palette[i] = color2pixel(xw, color_list[i]);
|
||||
|
||||
xw->screen = DefaultScreen(xw->display);
|
||||
xw->window = XCreateSimpleWindow(xw->display, DefaultRootWindow(xw->display),
|
||||
0, 0, TERM_WIDTH, TERM_HEIGHT, 0, xw->color_palette[DEFAULT_FG], xw->color_palette[DEFAULT_BG]);
|
||||
XSetWMProperties(xw->display, xw->window, &xtext, NULL, NULL, 0, NULL, NULL, NULL); /* return void */
|
||||
|
||||
xw->gc = XCreateGC(xw->display, xw->window, 0, NULL);
|
||||
XSetGraphicsExposures(xw->display, xw->gc, False);
|
||||
|
||||
xw->width = DisplayWidth(xw->display, xw->screen);
|
||||
xw->height = DisplayHeight(xw->display, xw->screen);
|
||||
xw->pixbuf = XCreatePixmap(xw->display, xw->window,
|
||||
xw->width, xw->height, XDefaultDepth(xw->display, xw->screen));
|
||||
|
||||
XSelectInput(xw->display, xw->window,
|
||||
ExposureMask | KeyPressMask | StructureNotifyMask);
|
||||
|
||||
XMapWindow(xw->display, xw->window);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void xw_die(struct xwindow_t *xw)
|
||||
{
|
||||
XFreeGC(xw->display, xw->gc);
|
||||
XFreePixmap(xw->display, xw->pixbuf);
|
||||
XDestroyWindow(xw->display, xw->window);
|
||||
XCloseDisplay(xw->display);
|
||||
}
|
||||
|
||||
static inline void draw_sixel(struct xwindow_t *xw, int line, int col, struct cell_t *cellp)
|
||||
{
|
||||
int w, h;
|
||||
uint32_t color = 0;
|
||||
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
for (w = 0; w < CELL_WIDTH; w++) {
|
||||
memcpy(&color, cellp->pixmap + BYTES_PER_PIXEL * (h * CELL_WIDTH + w), BYTES_PER_PIXEL);
|
||||
|
||||
if (color_list[DEFAULT_BG] != color) {
|
||||
XSetForeground(xw->display, xw->gc, color2pixel(xw, color));
|
||||
XDrawPoint(xw->display, xw->pixbuf, xw->gc,
|
||||
col * CELL_WIDTH + w, line * CELL_HEIGHT + h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void draw_line(struct xwindow_t *xw, struct terminal_t *term, int line)
|
||||
{
|
||||
int bdf_padding, glyph_width, margin_right;
|
||||
int col, w, h;
|
||||
struct color_pair_t color_pair;
|
||||
struct cell_t *cellp;
|
||||
const struct glyph_t *glyphp;
|
||||
|
||||
/* at first, fill all pixels of line in backgournd color */
|
||||
XSetForeground(xw->display, xw->gc, xw->color_palette[DEFAULT_BG]);
|
||||
XFillRectangle(xw->display, xw->pixbuf, xw->gc, 0, line * CELL_HEIGHT, term->width, CELL_HEIGHT);
|
||||
|
||||
for (col = term->cols - 1; col >= 0; col--) {
|
||||
margin_right = (term->cols - 1 - col) * CELL_WIDTH;
|
||||
|
||||
/* draw sixel pixmap */
|
||||
cellp = &term->cells[line][col];
|
||||
if (cellp->has_pixmap) {
|
||||
draw_sixel(xw, line, col, cellp);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get color and glyph */
|
||||
color_pair = cellp->color_pair;
|
||||
glyphp = cellp->glyphp;
|
||||
|
||||
/* check wide character or not */
|
||||
glyph_width = (cellp->width == HALF) ? CELL_WIDTH: CELL_WIDTH * 2;
|
||||
bdf_padding = my_ceil(glyph_width, BITS_PER_BYTE) * BITS_PER_BYTE - glyph_width;
|
||||
if (cellp->width == WIDE)
|
||||
bdf_padding += CELL_WIDTH;
|
||||
|
||||
/* check cursor positon */
|
||||
if ((term->mode & MODE_CURSOR && line == term->cursor.y)
|
||||
&& (col == term->cursor.x
|
||||
|| (cellp->width == WIDE && (col + 1) == term->cursor.x)
|
||||
|| (cellp->width == NEXT_TO_WIDE && (col - 1) == term->cursor.x))) {
|
||||
color_pair.fg = DEFAULT_BG;
|
||||
color_pair.bg = (!vt_active && BACKGROUND_DRAW) ? PASSIVE_CURSOR_COLOR: ACTIVE_CURSOR_COLOR;
|
||||
}
|
||||
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
/* if UNDERLINE attribute on, swap bg/fg */
|
||||
if ((h == (CELL_HEIGHT - 1)) && (cellp->attribute & attr_mask[ATTR_UNDERLINE]))
|
||||
color_pair.bg = color_pair.fg;
|
||||
|
||||
for (w = 0; w < CELL_WIDTH; w++) {
|
||||
/* set color palette */
|
||||
if (glyphp->bitmap[h] & (0x01 << (bdf_padding + w)))
|
||||
XSetForeground(xw->display, xw->gc, xw->color_palette[color_pair.fg]);
|
||||
else if (color_pair.bg != DEFAULT_BG)
|
||||
XSetForeground(xw->display, xw->gc, xw->color_palette[color_pair.bg]);
|
||||
else /* already draw */
|
||||
continue;
|
||||
|
||||
/* update copy buffer */
|
||||
XDrawPoint(xw->display, xw->pixbuf, xw->gc,
|
||||
term->width - 1 - margin_right - w, line * CELL_HEIGHT + h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
term->line_dirty[line] = ((term->mode & MODE_CURSOR) && term->cursor.y == line) ? true: false;
|
||||
}
|
||||
|
||||
void refresh(struct xwindow_t *xw, struct terminal_t *term)
|
||||
{
|
||||
int line, update_from, update_to;
|
||||
|
||||
if (term->mode & MODE_CURSOR)
|
||||
term->line_dirty[term->cursor.y] = true;
|
||||
|
||||
update_from = update_to = -1;
|
||||
for (line = 0; line < term->lines; line++) {
|
||||
if (term->line_dirty[line]) {
|
||||
draw_line(xw, term, line);
|
||||
|
||||
if (update_from == -1)
|
||||
update_from = update_to = line;
|
||||
else
|
||||
update_to = line;
|
||||
}
|
||||
}
|
||||
|
||||
/* actual display update: vertical synchronizing */
|
||||
if (update_from != -1)
|
||||
XCopyArea(xw->display, xw->pixbuf, xw->window, xw->gc, 0, update_from * CELL_HEIGHT,
|
||||
term->width, (update_to - update_from + 1) * CELL_HEIGHT, 0, update_from * CELL_HEIGHT);
|
||||
}
|
@@ -1,241 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#include "../yaft.h"
|
||||
#include "../conf.h"
|
||||
#include "../util.h"
|
||||
#include "x.h"
|
||||
#include "../terminal.h"
|
||||
#include "../ctrlseq/esc.h"
|
||||
#include "../ctrlseq/csi.h"
|
||||
#include "../ctrlseq/osc.h"
|
||||
#include "../ctrlseq/dcs.h"
|
||||
#include "../parse.h"
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
extern volatile sig_atomic_t child_alive;
|
||||
|
||||
if (signo == SIGCHLD) {
|
||||
child_alive = false;
|
||||
wait(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool sig_set(int signo, void (*handler)(int signo), int flags)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
|
||||
memset(&sigact, 0, sizeof(struct sigaction));
|
||||
sigact.sa_handler = handler;
|
||||
sigact.sa_flags = flags;
|
||||
|
||||
if (esigaction(signo, &sigact, NULL) == -1) {
|
||||
logging(WARN, "sigaction: signo %d failed\n", signo);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void check_fds(fd_set *fds, struct timeval *tv, int master)
|
||||
{
|
||||
FD_ZERO(fds);
|
||||
FD_SET(master, fds);
|
||||
tv->tv_sec = 0;
|
||||
tv->tv_usec = SELECT_TIMEOUT;
|
||||
eselect(master + 1, fds, NULL, NULL, tv);
|
||||
}
|
||||
|
||||
char *keyremap(KeySym keysym, unsigned int state)
|
||||
{
|
||||
int length;
|
||||
unsigned int mask;
|
||||
|
||||
length = sizeof(keymap) / sizeof(keymap[0]);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
mask = keymap[i].mask;
|
||||
if (keymap[i].keysym == keysym &&
|
||||
((state & mask) == mask || (mask == XK_NO_MOD && !state)))
|
||||
return (char *) keymap[i].str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xkeypress(struct xwindow_t *xw, struct terminal_t *term, XEvent *ev)
|
||||
{
|
||||
int size;
|
||||
char buf[BUFSIZE], *customkey;
|
||||
XKeyEvent *e = &ev->xkey;
|
||||
KeySym keysym;
|
||||
|
||||
//size = XmbLookupString(xw->ic, e, buf, BUFSIZE, &keysym, NULL);
|
||||
(void) xw;
|
||||
|
||||
size = XLookupString(e, buf, BUFSIZE, &keysym, NULL);
|
||||
if ((customkey = keyremap(keysym, e->state))) {
|
||||
ewrite(term->fd, customkey, strlen(customkey));
|
||||
} else {
|
||||
if (size == 1 && (e->state & Mod1Mask)) {
|
||||
buf[1] = buf[0];
|
||||
buf[0] = '\033';
|
||||
size = 2;
|
||||
}
|
||||
ewrite(term->fd, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
void xresize(struct xwindow_t *xw, struct terminal_t *term, XEvent *ev)
|
||||
{
|
||||
XConfigureEvent *e = &ev->xconfigure;
|
||||
struct winsize ws;
|
||||
|
||||
logging(DEBUG, "xresize() term.width:%d term.height:%d width:%d height:%d\n",
|
||||
term->width, term->height, e->width, e->height);
|
||||
|
||||
(void ) xw; /* unused */
|
||||
|
||||
if (e->width == term->width && e->height == term->height)
|
||||
return;
|
||||
|
||||
term->width = e->width;
|
||||
term->height = e->height;
|
||||
|
||||
term->cols = term->width / CELL_WIDTH;
|
||||
term->lines = term->height / CELL_HEIGHT;
|
||||
|
||||
term->scroll.top = 0;
|
||||
term->scroll.bottom = term->lines - 1;
|
||||
|
||||
ws.ws_col = term->cols;
|
||||
ws.ws_row = term->lines;
|
||||
ws.ws_xpixel = CELL_WIDTH * term->cols;
|
||||
ws.ws_ypixel = CELL_HEIGHT * term->lines;
|
||||
ioctl(term->fd, TIOCSWINSZ, &ws);
|
||||
}
|
||||
|
||||
void xredraw(struct xwindow_t *xw, struct terminal_t *term, XEvent *ev)
|
||||
{
|
||||
XExposeEvent *e = &ev->xexpose;
|
||||
int i, lines, update_from;
|
||||
|
||||
logging(DEBUG, "xredraw() count:%d x:%d y:%d width:%d height:%d\n",
|
||||
e->count, e->x, e->y, e->width, e->height);
|
||||
|
||||
update_from = e->y / CELL_HEIGHT;
|
||||
lines = my_ceil(e->height, CELL_HEIGHT);
|
||||
|
||||
for (i = 0; i < lines; i++) {
|
||||
if ((update_from + i) < term->lines)
|
||||
term->line_dirty[update_from + i] = true;
|
||||
}
|
||||
|
||||
if (e->count == 0)
|
||||
refresh(xw, term);
|
||||
}
|
||||
|
||||
void (*event_func[LASTEvent])(struct xwindow_t *xw, struct terminal_t *term, XEvent *ev) = {
|
||||
[KeyPress] = xkeypress,
|
||||
[ConfigureNotify] = xresize,
|
||||
[Expose] = xredraw,
|
||||
};
|
||||
|
||||
bool fork_and_exec(int *master, int lines, int cols)
|
||||
{
|
||||
extern const char *shell_cmd; /* defined in conf.h */
|
||||
char *shell_env;
|
||||
pid_t pid;
|
||||
struct winsize ws = {.ws_row = lines, .ws_col = cols,
|
||||
/* XXX: this variables are UNUSED (man tty_ioctl),
|
||||
but useful for calculating terminal cell size */
|
||||
.ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols};
|
||||
|
||||
pid = eforkpty(master, NULL, NULL, &ws);
|
||||
if (pid < 0)
|
||||
return false;
|
||||
else if (pid == 0) { /* child */
|
||||
esetenv("TERM", term_name, 1);
|
||||
if ((shell_env = getenv("SHELL")) != NULL)
|
||||
eexecl(shell_env);
|
||||
else
|
||||
eexecl(shell_cmd);
|
||||
/* never reach here */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
uint8_t buf[BUFSIZE];
|
||||
ssize_t size;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct xwindow_t xw;
|
||||
struct terminal_t term;
|
||||
XEvent ev;
|
||||
XConfigureEvent confev;
|
||||
extern volatile sig_atomic_t child_alive;
|
||||
|
||||
/* init */
|
||||
if (!setlocale(LC_ALL, ""))
|
||||
logging(WARN, "setlocale falied\n");
|
||||
|
||||
if (!sig_set(SIGCHLD, sig_handler, SA_RESTART))
|
||||
logging(ERROR, "signal initialize failed\n");
|
||||
|
||||
if (!xw_init(&xw)) {
|
||||
logging(FATAL, "xwindow initialize failed\n");
|
||||
goto xw_init_failed;
|
||||
}
|
||||
|
||||
if (!term_init(&term, xw.width, xw.height)) {
|
||||
logging(FATAL, "terminal initialize failed\n");
|
||||
goto term_init_failed;
|
||||
}
|
||||
|
||||
/* fork and exec shell */
|
||||
if (!fork_and_exec(&term.fd, term.lines, term.cols)) {
|
||||
logging(FATAL, "forkpty failed\n");
|
||||
goto fork_failed;
|
||||
}
|
||||
child_alive = true;
|
||||
|
||||
/* initial terminal size defined in x.h */
|
||||
confev.width = TERM_WIDTH;
|
||||
confev.height = TERM_HEIGHT;
|
||||
xresize(&xw, &term, (XEvent *) &confev);
|
||||
|
||||
/* main loop */
|
||||
while (child_alive) {
|
||||
while(XPending(xw.display)) {
|
||||
XNextEvent(xw.display, &ev);
|
||||
if (XFilterEvent(&ev, None))
|
||||
continue;
|
||||
if (event_func[ev.type])
|
||||
event_func[ev.type](&xw, &term, &ev);
|
||||
}
|
||||
|
||||
check_fds(&fds, &tv, term.fd);
|
||||
if (FD_ISSET(term.fd, &fds)) {
|
||||
size = read(term.fd, buf, BUFSIZE);
|
||||
if (size > 0) {
|
||||
if (DEBUG)
|
||||
ewrite(STDOUT_FILENO, buf, size);
|
||||
parse(&term, buf, size);
|
||||
refresh(&xw, &term);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* die */
|
||||
term_die(&term);
|
||||
xw_die(&xw);
|
||||
sig_set(SIGCHLD, SIG_DFL, 0);
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
fork_failed:
|
||||
term_die(&term);
|
||||
term_init_failed:
|
||||
xw_die(&xw);
|
||||
xw_init_failed:
|
||||
return EXIT_FAILURE;
|
||||
}
|
@@ -1,239 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
/* yaft.c: include main function */
|
||||
#include "yaft.h"
|
||||
#include "conf.h"
|
||||
#include "util.h"
|
||||
#include "fb/common.h"
|
||||
#include "terminal.h"
|
||||
#include "ctrlseq/esc.h"
|
||||
#include "ctrlseq/csi.h"
|
||||
#include "ctrlseq/osc.h"
|
||||
#include "ctrlseq/dcs.h"
|
||||
#include "parse.h"
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
sigset_t sigset;
|
||||
/* global */
|
||||
extern volatile sig_atomic_t vt_active;
|
||||
extern volatile sig_atomic_t child_alive;
|
||||
extern volatile sig_atomic_t need_redraw;
|
||||
|
||||
logging(DEBUG, "caught signal! no:%d\n", signo);
|
||||
|
||||
if (signo == SIGCHLD) {
|
||||
child_alive = false;
|
||||
wait(NULL);
|
||||
} else if (signo == SIGUSR1) { /* vt activate */
|
||||
vt_active = true;
|
||||
need_redraw = true;
|
||||
ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
|
||||
} else if (signo == SIGUSR2) { /* vt deactivate */
|
||||
vt_active = false;
|
||||
ioctl(STDIN_FILENO, VT_RELDISP, 1);
|
||||
|
||||
if (BACKGROUND_DRAW) { /* update passive cursor */
|
||||
need_redraw = true;
|
||||
} else { /* sleep until next vt switching */
|
||||
sigfillset(&sigset);
|
||||
sigdelset(&sigset, SIGUSR1);
|
||||
sigsuspend(&sigset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_rawmode(int fd, struct termios *save_tm)
|
||||
{
|
||||
struct termios tm;
|
||||
|
||||
tm = *save_tm;
|
||||
tm.c_iflag = tm.c_oflag = 0;
|
||||
tm.c_cflag &= ~CSIZE;
|
||||
tm.c_cflag |= CS8;
|
||||
tm.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||
tm.c_cc[VMIN] = 1; /* min data size (byte) */
|
||||
tm.c_cc[VTIME] = 0; /* time out */
|
||||
etcsetattr(fd, TCSAFLUSH, &tm);
|
||||
}
|
||||
|
||||
bool tty_init(struct termios *termios_orig)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
|
||||
memset(&sigact, 0, sizeof(struct sigaction));
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
esigaction(SIGCHLD, &sigact, NULL);
|
||||
|
||||
if (VT_CONTROL) {
|
||||
esigaction(SIGUSR1, &sigact, NULL);
|
||||
esigaction(SIGUSR2, &sigact, NULL);
|
||||
|
||||
struct vt_mode vtm;
|
||||
vtm.mode = VT_PROCESS;
|
||||
vtm.waitv = 0;
|
||||
vtm.acqsig = SIGUSR1;
|
||||
vtm.relsig = SIGUSR2;
|
||||
vtm.frsig = 0;
|
||||
|
||||
if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm))
|
||||
logging(WARN, "ioctl: VT_SETMODE failed (maybe here is not console)\n");
|
||||
|
||||
if (FORCE_TEXT_MODE == false) {
|
||||
if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS))
|
||||
logging(WARN, "ioctl: KDSETMODE failed (maybe here is not console)\n");
|
||||
}
|
||||
}
|
||||
|
||||
etcgetattr(STDIN_FILENO, termios_orig);
|
||||
set_rawmode(STDIN_FILENO, termios_orig);
|
||||
ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tty_die(struct termios *termios_orig)
|
||||
{
|
||||
/* no error handling */
|
||||
struct sigaction sigact;
|
||||
struct vt_mode vtm;
|
||||
|
||||
memset(&sigact, 0, sizeof(struct sigaction));
|
||||
sigact.sa_handler = SIG_DFL;
|
||||
sigaction(SIGCHLD, &sigact, NULL);
|
||||
|
||||
if (VT_CONTROL) {
|
||||
sigaction(SIGUSR1, &sigact, NULL);
|
||||
sigaction(SIGUSR2, &sigact, NULL);
|
||||
|
||||
vtm.mode = VT_AUTO;
|
||||
vtm.waitv = 0;
|
||||
vtm.relsig = vtm.acqsig = vtm.frsig = 0;
|
||||
|
||||
ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
|
||||
|
||||
if (FORCE_TEXT_MODE == false)
|
||||
ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT);
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig);
|
||||
fflush(stdout);
|
||||
ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */
|
||||
}
|
||||
|
||||
bool fork_and_exec(int *master, int lines, int cols)
|
||||
{
|
||||
extern const char *shell_cmd; /* defined in conf.h */
|
||||
char *shell_env;
|
||||
pid_t pid;
|
||||
struct winsize ws = {.ws_row = lines, .ws_col = cols,
|
||||
/* XXX: this variables are UNUSED (man tty_ioctl),
|
||||
but useful for calculating terminal cell size */
|
||||
.ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols};
|
||||
|
||||
pid = eforkpty(master, NULL, NULL, &ws);
|
||||
if (pid < 0)
|
||||
return false;
|
||||
else if (pid == 0) { /* child */
|
||||
esetenv("TERM", term_name, 1);
|
||||
if ((shell_env = getenv("SHELL")) != NULL)
|
||||
eexecl(shell_env);
|
||||
else
|
||||
eexecl(shell_cmd);
|
||||
/* never reach here */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int check_fds(fd_set *fds, struct timeval *tv, int input, int master)
|
||||
{
|
||||
FD_ZERO(fds);
|
||||
FD_SET(input, fds);
|
||||
FD_SET(master, fds);
|
||||
tv->tv_sec = 0;
|
||||
tv->tv_usec = SELECT_TIMEOUT;
|
||||
return eselect(master + 1, fds, NULL, NULL, tv);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
uint8_t buf[BUFSIZE];
|
||||
ssize_t size;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct framebuffer_t fb;
|
||||
struct terminal_t term;
|
||||
/* global */
|
||||
extern volatile sig_atomic_t need_redraw;
|
||||
extern volatile sig_atomic_t child_alive;
|
||||
extern struct termios termios_orig;
|
||||
|
||||
/* init */
|
||||
if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */
|
||||
logging(WARN, "setlocale falied\n");
|
||||
|
||||
if (!fb_init(&fb)) {
|
||||
logging(FATAL, "framebuffer initialize failed\n");
|
||||
goto fb_init_failed;
|
||||
}
|
||||
|
||||
if (!term_init(&term, fb.info.width, fb.info.height)) {
|
||||
logging(FATAL, "terminal initialize failed\n");
|
||||
goto term_init_failed;
|
||||
}
|
||||
|
||||
if (!tty_init(&termios_orig)) {
|
||||
logging(FATAL, "tty initialize failed\n");
|
||||
goto tty_init_failed;
|
||||
}
|
||||
|
||||
/* fork and exec shell */
|
||||
if (!fork_and_exec(&term.fd, term.lines, term.cols)) {
|
||||
logging(FATAL, "forkpty failed\n");
|
||||
goto tty_init_failed;
|
||||
}
|
||||
child_alive = true;
|
||||
|
||||
/* main loop */
|
||||
while (child_alive) {
|
||||
if (need_redraw) {
|
||||
need_redraw = false;
|
||||
cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */
|
||||
redraw(&term);
|
||||
refresh(&fb, &term);
|
||||
}
|
||||
|
||||
if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1)
|
||||
continue;
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0)
|
||||
ewrite(term.fd, buf, size);
|
||||
}
|
||||
if (FD_ISSET(term.fd, &fds)) {
|
||||
if ((size = read(term.fd, buf, BUFSIZE)) > 0) {
|
||||
if (VERBOSE)
|
||||
ewrite(STDOUT_FILENO, buf, size);
|
||||
parse(&term, buf, size);
|
||||
if (LAZY_DRAW && size == BUFSIZE)
|
||||
continue; /* maybe more data arrives soon */
|
||||
refresh(&fb, &term);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* normal exit */
|
||||
tty_die(&termios_orig);
|
||||
term_die(&term);
|
||||
fb_die(&fb);
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
/* error exit */
|
||||
tty_init_failed:
|
||||
term_die(&term);
|
||||
term_init_failed:
|
||||
fb_die(&fb);
|
||||
fb_init_failed:
|
||||
return EXIT_FAILURE;
|
||||
}
|
@@ -1,194 +0,0 @@
|
||||
/* See LICENSE for licence details. */
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if 0
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include <sys/select.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#include "glyph.h"
|
||||
#include "color.h"
|
||||
|
||||
enum char_code {
|
||||
/* 7 bit */
|
||||
BEL = 0x07, BS = 0x08, HT = 0x09,
|
||||
LF = 0x0A, VT = 0x0B, FF = 0x0C,
|
||||
CR = 0x0D, ESC = 0x1B, DEL = 0x7F,
|
||||
/* others */
|
||||
SPACE = 0x20,
|
||||
BACKSLASH = 0x5C,
|
||||
};
|
||||
|
||||
enum misc {
|
||||
BUFSIZE = 1024, /* read, esc, various buffer size */
|
||||
BITS_PER_BYTE = 8, /* bits per byte */
|
||||
BYTES_PER_PIXEL = sizeof(uint32_t), /* pixel size of sixel pixmap data */
|
||||
BITS_PER_SIXEL = 6, /* number of bits of a sixel */
|
||||
ESCSEQ_SIZE = 1024, /* limit size of terminal escape sequence */
|
||||
SELECT_TIMEOUT = 15000, /* used by select() */
|
||||
SLEEP_TIME = 30000, /* sleep time at EAGAIN, EWOULDBLOCK (usec) */
|
||||
MAX_ARGS = 16, /* max parameters of csi/osc sequence */
|
||||
UCS2_CHARS = 0x10000, /* number of UCS2 glyphs */
|
||||
CTRL_CHARS = 0x20, /* number of ctrl_func */
|
||||
ESC_CHARS = 0x80, /* number of esc_func */
|
||||
DRCS_CHARSETS = 63, /* number of charset of DRCS (according to DRCSMMv1) */
|
||||
GLYPHS_PER_CHARSET = 96, /* number of glyph of each DRCS charset */
|
||||
DRCS_CHARS = DRCS_CHARSETS * GLYPHS_PER_CHARSET,
|
||||
DEFAULT_CHAR = SPACE, /* used for erase char */
|
||||
BRIGHT_INC = 8, /* value used for brightening color */
|
||||
};
|
||||
|
||||
enum char_attr {
|
||||
ATTR_RESET = 0,
|
||||
ATTR_BOLD = 1, /* brighten foreground */
|
||||
ATTR_UNDERLINE = 4,
|
||||
ATTR_BLINK = 5, /* brighten background */
|
||||
ATTR_REVERSE = 7,
|
||||
};
|
||||
|
||||
const uint8_t attr_mask[] = {
|
||||
0x00, 0x01, 0x00, 0x00, /* 0:none 1:bold 2:none 3:none */
|
||||
0x02, 0x04, 0x00, 0x08, /* 4:underline 5:blink 6:none 7:reverse */
|
||||
};
|
||||
|
||||
const uint32_t bit_mask[] = {
|
||||
0x00,
|
||||
0x01, 0x03, 0x07, 0x0F,
|
||||
0x1F, 0x3F, 0x7F, 0xFF,
|
||||
0x1FF, 0x3FF, 0x7FF, 0xFFF,
|
||||
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
|
||||
0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
|
||||
0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
|
||||
0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
|
||||
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
enum osc {
|
||||
OSC_GWREPT = 8900, /* OSC Ps: mode number of yaft GWREPT */
|
||||
};
|
||||
|
||||
enum term_mode {
|
||||
MODE_RESET = 0x00,
|
||||
MODE_ORIGIN = 0x01, /* origin mode: DECOM */
|
||||
MODE_CURSOR = 0x02, /* cursor visible: DECTCEM */
|
||||
MODE_AMRIGHT = 0x04, /* auto wrap: DECAWM */
|
||||
MODE_VWBS = 0x08, /* variable-width backspace */
|
||||
};
|
||||
|
||||
enum esc_state {
|
||||
STATE_RESET = 0x00,
|
||||
STATE_ESC = 0x01, /* 0x1B, \033, ESC */
|
||||
STATE_CSI = 0x02, /* ESC [ */
|
||||
STATE_OSC = 0x04, /* ESC ] */
|
||||
STATE_DCS = 0x08, /* ESC P */
|
||||
};
|
||||
|
||||
enum glyph_width {
|
||||
NEXT_TO_WIDE = 0,
|
||||
HALF,
|
||||
WIDE,
|
||||
};
|
||||
|
||||
struct margin_t { uint16_t top, bottom; };
|
||||
struct point_t { uint16_t x, y; };
|
||||
struct color_pair_t { uint8_t fg, bg; };
|
||||
|
||||
struct cell_t {
|
||||
const struct glyph_t *glyphp; /* pointer to glyph */
|
||||
struct color_pair_t color_pair; /* color (fg, bg) */
|
||||
/*enum char_attr*/ int attribute; /* bold, underscore, etc... */
|
||||
enum glyph_width width; /* wide char flag: WIDE, NEXT_TO_WIDE, HALF */
|
||||
#if 0
|
||||
bool has_pixmap; /* has sixel pixmap data or not */
|
||||
/* sixel pixmap data:
|
||||
must be statically allocated for copy_cell() */
|
||||
uint8_t pixmap[BYTES_PER_PIXEL * CELL_WIDTH * CELL_HEIGHT];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct esc_t {
|
||||
char *buf;
|
||||
char *bp;
|
||||
int size;
|
||||
enum esc_state state;
|
||||
};
|
||||
|
||||
struct charset_t {
|
||||
uint32_t code; /* UCS4 code point: yaft only prints UCS2 and DRCSMMv1 */
|
||||
int following_byte, count;
|
||||
bool is_valid;
|
||||
};
|
||||
|
||||
struct state_t { /* for save, restore state */
|
||||
struct point_t cursor;
|
||||
/*enum term_mode*/ int mode;
|
||||
/*enum char_attr*/ int attribute;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct sixel_canvas_t {
|
||||
uint8_t *pixmap;
|
||||
struct point_t point;
|
||||
int width, height;
|
||||
int line_length;
|
||||
uint8_t color_index;
|
||||
uint32_t color_table[COLORS];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct terminal_t {
|
||||
int fd; /* master of pseudo terminal */
|
||||
int width, height; /* terminal size (pixel) */
|
||||
int cols, lines; /* terminal size (cell) */
|
||||
struct cell_t **cells; /* pointer to each cell: cells[y * lines + x] */
|
||||
struct margin_t scroll; /* scroll margin */
|
||||
struct point_t cursor; /* cursor pos (x, y) */
|
||||
bool *line_dirty; /* dirty flag */
|
||||
bool *tabstop; /* tabstop flag */
|
||||
/*enum term_mode*/ int mode; /* for set/reset mode */
|
||||
bool wrap_occured; /* whether auto wrap occured or not */
|
||||
struct state_t state; /* for restore */
|
||||
struct color_pair_t color_pair; /* color (fg, bg) */
|
||||
/*enum char_attr*/int attribute; /* bold, underscore, etc... */
|
||||
struct charset_t charset; /* store UTF-8 byte stream */
|
||||
struct esc_t esc; /* store escape sequence */
|
||||
uint32_t virtual_palette[COLORS]; /* virtual color palette: always 32bpp */
|
||||
bool palette_modified; /* true if palette changed by OSC 4/104 */
|
||||
const struct glyph_t *glyph[UCS2_CHARS]; /* array of pointer to glyphs[] */
|
||||
#if 0
|
||||
struct glyph_t drcs[DRCS_CHARS]; /* DRCS chars */
|
||||
struct sixel_canvas_t sixel;
|
||||
#endif
|
||||
std::queue<std::string> txt; /* contains "sanitized" (without control chars) output text */
|
||||
int lines_available; /* lines available in txt */
|
||||
bool nlseen;
|
||||
};
|
||||
|
||||
struct parm_t { /* for parse_arg() */
|
||||
int argc;
|
||||
char *argv[MAX_ARGS];
|
||||
};
|
||||
|
||||
volatile sig_atomic_t vt_active = true; /* SIGUSR1: vt is active or not */
|
||||
volatile sig_atomic_t need_redraw = false; /* SIGUSR1: vt activated */
|
||||
volatile sig_atomic_t child_alive = false; /* SIGCHLD: child process (shell) is alive or not */
|
||||
struct termios termios_orig;
|
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
# usage: yaft_wall /path/to/image
|
||||
# you can use fbv or idump
|
||||
|
||||
# fbv (http://www.eclis.ch/fbv/)
|
||||
echo -ne "\e[?25l" # hide cursor
|
||||
fbv -ciuker "$1" << EOF
|
||||
q
|
||||
EOF
|
||||
|
||||
# idump (https://github.com/uobikiemukot/idump)
|
||||
#idump "$1"
|
||||
|
||||
export YAFT="wall"
|
||||
exec yaft
|
Reference in New Issue
Block a user