├── .default ├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── Makefile ├── Makefile.am ├── NEWS ├── README ├── TODO ├── autogen.sh ├── configure ├── configure.ac ├── data ├── Makefile ├── Makefile.am ├── lilyterm.1 ├── lilyterm.conf ├── lilyterm.desktop ├── lilyterm.png ├── lilyterm.xml └── lilyterm.xpm ├── po ├── Makefile ├── POTFILES.in ├── de.po ├── es.po ├── fr.po ├── it.po ├── lilyterm.pot ├── nl.po ├── pl.po ├── pt_BR.po ├── ru.po ├── sk.po ├── tr.po ├── uk.po ├── zh_CN.po └── zh_TW.po └── src ├── Makefile ├── Makefile.am ├── console.c ├── console.h ├── data.h ├── dialog.c ├── dialog.h ├── font.c ├── font.h ├── lilyterm.h ├── main.c ├── main.h ├── menu.c ├── menu.h ├── misc.c ├── misc.h ├── notebook.c ├── notebook.h ├── pagename.c ├── pagename.h ├── profile.c ├── profile.h ├── property.c ├── property.h ├── socket.c ├── socket.h ├── unit_test.sh ├── window.c └── window.h /.default: -------------------------------------------------------------------------------- 1 | PACKAGE = LilyTerm 2 | BINARY = lilyterm 3 | VERSION = 0.9.9.4 4 | 5 | AUTHOR = Lu, Chao-Ming (Tetralet) 6 | BUGREPORT = tetrlet@gmail.com 7 | MAINSITE = http://lilyterm.luna.com.tw/ 8 | GITHUBURL = https://github.com/Tetralet/LilyTerm 9 | BLOG = http://tetralet.luna.com.tw 10 | WIKI = https://github.com/Tetralet/LilyTerm/wiki 11 | ISSUES = https://github.com/Tetralet/LilyTerm/issues 12 | IRC = \#hime@freenode.net 13 | 14 | LANG_LIST = de fr es it nl pl pt_BR ru sk tr uk zh_CN zh_TW 15 | 16 | YEAR = $(shell date +%Y) 17 | ECHO = $(shell whereis "echo" | tr -s ' ' '\n' | grep "bin/""echo""$$" | head -n 1) 18 | PRINTF = $(shell whereis "printf" | tr -s ' ' '\n' | grep "bin/""printf""$$" | head -n 1) 19 | 20 | PREFIX = /usr/local 21 | ETCDIR = $(PREFIX)/etc/xdg 22 | BINDIR = $(PREFIX)/bin 23 | DATADIR = $(PREFIX)/share 24 | MANDIR = $(DATADIR)/man/man1 25 | DOCDIR = $(DATADIR)/doc/$(BINARY) 26 | EXAMPLES_DIR = $(DATADIR)/doc/$(BINARY)/examples 27 | LOCALEDIR = $(DATADIR)/locale 28 | ICONDIR = $(DATADIR)/pixmaps 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .config 2 | *.swp 3 | src/*.o 4 | src/*.swp 5 | src/lilyterm 6 | src/lilyterm_dbg 7 | src/lilyterm_dev 8 | src/unit_test 9 | src/unit_test.c 10 | src/unit_test.o 11 | src/gdb_batch 12 | src/gdb.log 13 | src/valgrind.log 14 | src/vgcore.* 15 | po/*.mo 16 | po/*.swp 17 | data/lilyterm.1.gz 18 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Authors: 2 | Lu, Chao-Ming (Tetralet) 3 | 4 | Homepage: 5 | http://lilyterm.luna.com.tw/ (Main site) 6 | https://github.com/Tetralet/LilyTerm (Github site) 7 | 8 | Blog: 9 | http://tetralet.luna.com.tw 10 | 11 | Wiki: 12 | https://github.com/Tetralet/LilyTerm/wiki 13 | 14 | Issues: 15 | https://github.com/Tetralet/LilyTerm/issues 16 | 17 | IRC: 18 | #hime@freenode.net 19 | 20 | Translators: 21 | 22 | Adrian Buyssens: Flemish/Dutch translation 23 | Bogusz Kowalski: Polish translation 24 | GoGoNKT: Simplified Chinese translation 25 | Marco Paolome: Italian translation 26 | Mario Blättermann: German translation 27 | Niels Martignène: French translation 28 | P.L. Francisco: Spanish translation 29 | Rafael Ferreira: Portuguese translation 30 | Samed Beyribey: Turkish translation 31 | Slavko: Slovak translation 32 | Vladimir: Russian and Ukrainian translation 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include .default 2 | -include .config 3 | 4 | DIR = src data 5 | 6 | ifeq ($(NLS), Y) 7 | DIR += po 8 | endif 9 | 10 | .PHONY: all 11 | all: $(DIR) 12 | 13 | .PHONY: src 14 | src: 15 | @ $(MAKE) -C src 16 | 17 | .PHONY: data 18 | data: 19 | @ $(MAKE) -C data 20 | 21 | .PHONY: po 22 | po: 23 | @ $(MAKE) -C po 24 | 25 | clean: 26 | @ $(MAKE) -C src clean 27 | @ $(MAKE) -C data clean 28 | @ $(MAKE) -C po clean 29 | 30 | install: all 31 | @ $(MAKE) -C src install 32 | @ $(MAKE) -C data install 33 | ifeq ($(NLS), Y) 34 | @ $(MAKE) -C po install 35 | endif 36 | 37 | uninstall: 38 | @ $(MAKE) -C src uninstall 39 | @ $(MAKE) -C data uninstall 40 | ifeq ($(NLS), Y) 41 | @ $(MAKE) -C po uninstall 42 | endif 43 | @ if [ -z "`ls -A "$(DESTDIR)/$(PREFIX)"`" ]; then \ 44 | $(ECHO) "===========================================" ; \ 45 | $(PRINTF) "\033[1;31m** WARNING: \"\033[1;34m$(DESTDIR)/$(PREFIX)\033[1;31m\" is empty. Please remove it manually if necessary.\033[0m\n" ; \ 46 | $(ECHO) "===========================================" ; \ 47 | fi 48 | distclean: clean 49 | @ if [ -f .config ]; then \ 50 | $(PRINTF) "\033[1;35m** deleting \033[1;32m.config\033[1;35m ...\033[0m\n" ; \ 51 | rm .config ; \ 52 | fi 53 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src po data 2 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tetralet/LilyTerm/faf1254f46049edfb1fd6e9191e78b1b23b9c51d/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | NAME 2 | LilyTerm - A light and easy-to-use terminal emulator for X. 3 | 4 | SYNOPSIS 5 | lilyterm [-? | -h | --help] [-T TITLE | --title TITLE] [-t NUMBER | 6 | --tab NUMBER] [-n TAB NAMES | --tab_names TAB NAMES] [-d 7 | DIRECTORY | --directory DIRECTORY] [-g GEOMETRY | --geometry 8 | GEOMETRY] [-l | -ls | --login] [-ut] [-H | --hold] [-s | 9 | --separate] [-j | --join] [-p | --profile] [-u PROFILE | 10 | --user_profile PROFILE] [-v | --version] [-e COMMAND | -x COM 11 | MAND | --execute COMMAND] 12 | 13 | DESCRIPTION 14 | LilyTerm is a terminal emulator for the X Window System, based on the 15 | libvte library, and aims to be fast and lightweight. 16 | 17 | OPTIONS 18 | -? | -h | --help 19 | Display a brief help message. 20 | 21 | -T TITLE | --title TITLE 22 | Specify the window title. 23 | 24 | -t NUMBER | --tab NUMBER 25 | Open multi tabs when starting up. 26 | 27 | -n TAB NAMES | --tab_names TAB NAMES 28 | Specify the tab names, separate with . 29 | 30 | -d DIRECTORY | --directory DIRECTORY 31 | Specify the init directory when starting up. 32 | 33 | -g GEOMETRY | --geometry GEOMETRY 34 | Specify the geometry of window when starting. 35 | A reasonable example value is "80x24+0+0", witch means "width x 36 | height {+-} xoffset {+-} yoffset" (without space). 37 | 38 | -l | -ls | --login 39 | Make the shell invoked as a login shell. 40 | 41 | -ut 42 | Disable recording the session in lastlog, utmp and wtmp. 43 | 44 | -H | --hold 45 | Hold the terminal window open when the command following -e/-x ter 46 | minated. 47 | 48 | -s | --separate 49 | Run in separate process. 50 | 51 | -j | --join 52 | Integrate new created tabs to the last accessed window. 53 | It may be useful for launching multi commands with LilyTerm in a 54 | shell script. 55 | 56 | -p | --profile 57 | Got a profile sample. 58 | 59 | -u PROFILE | --user_profile PROFILE 60 | Use a specified profile. 61 | 62 | -v | --version 63 | Show the version information. 64 | 65 | -e COMMAND | -x COMMAND | --execute COMMAND 66 | Run a command when starting up. Must be the final option. 67 | 68 | 69 | KEYBOARD CONTROL 70 | The following key bindings may custom or disable by the right click 71 | menu [Set key binding]. 72 | 73 | <> Disable/Enable hyperlinks, function keys and right 74 | click menu for temporary. 75 | 76 | Add a New tab with current directory. 77 | 78 | Switch to Prev/Next tab. 79 | 80 | Switch to First/Last tab. 81 | 82 | <[/]> Move current tab Forward/Backward. 83 | 84 | Move current tab to First/Last. 85 | 86 | Switch to 1st ~ 12th tab. 87 | 88 | Select all the text in the Vte Terminal box. 89 | 90 | <+/-/Enter> Increase/Decrease/Reset the font size of current 91 | tab. 92 | 93 | Switch between fullwindow/unfullwindow and 94 | fullscreen/unfullscreen state. 95 | 96 | Emulate a mouse Scroll Up/Down event on Vte Termi 97 | nal box. 98 | 99 | Asks to scroll Up/Down 1 line on Vte Terminal box. 100 | 101 | Asks to scroll Up/Down on Vte Terminal box. 102 | 103 | 104 | Copy the text to clipboard / Paste the text in 105 | clipboard. 106 | 107 | 108 | Copy the text to primary clipboard / Paste the text 109 | in primary clipboard. 110 | i.e. Emulate a middle button mouse click to 111 | copy/paste the text. 112 | 113 | Some key bindings that disabled by default but maybe useful: 114 | 115 | 116 | Close current tab. 117 | Using or exit to close tabs is recommended. 118 | 119 | 120 | Open a new window with current directory. 121 | 122 | 123 | Rename the current tab. 124 | 125 | FILE 126 | /etc/xdg/lilyterm.conf System configure file 127 | 128 | ~/.config/lilyterm/default.conf Users profile. 129 | 130 | Use [Save settings] in the right click menu to save the current tabs 131 | settings as default to the specified profile. 132 | 133 | TIPS 134 | Display UTF-8 character under C locale 135 | 136 | Execute the following command under LilyTerm: 137 | 138 | bind "set convert-meta off" 139 | bind "set output-meta on" 140 | 141 | And use the right click menu to set the text encoding to "UTF-8". 142 | 143 | Launch LilyTerm under a chroot jail 144 | 145 | Extract xauth info to a file (under X): 146 | 147 | xauth extract /PathToChroot/tmp/display $DISPLAY 148 | 149 | Mount the devpts device and /tmp (may not necessary) before chroot 150 | into a chroot jail: 151 | 152 | mount /dev/pts /PathToChroot/dev/pts -t devpts 153 | mount -o bind /tmp /PathToChroot/tmp (may not necessary) 154 | 155 | Merge the extracted xauth info and set the DISPLAY environ after 156 | chroot into the chroot jail: 157 | 158 | xauth merge /tmp/display 159 | export DISPLAY=:0 160 | 161 | Launch LilyTerm directly, or run it under Xnest/Xephyr: 162 | 163 | xinit ~/.xinitrc -- /usr/bin/Xnest :1 -ac -geometry 800x600 164 | 165 | or 166 | 167 | xinit ~/.xinitrc -- /usr/bin/Xephyr :1 -ac -screen 800x600 168 | 169 | and dont work under VIM: 170 | 171 | Use the following command to turn off flow-Control under 172 | LilyTerm: 173 | 174 | stty raw 175 | 176 | or 177 | 178 | stty -ixon 179 | 180 | 181 | BSD Users: 182 | 183 | Please mount the procfs before launch LilyTerm: 184 | 185 | mount -t procfs procfs /proc 186 | 187 | ENVIRONMENT 188 | TERM Sets what type of terminal attempts to emulate. Please 189 | always set to "xterm" under LilyTerm. 190 | 191 | VTE_CJK_WIDTH Controls the width of some ideographs should be "single 192 | width (narrow)" or "double width (wide)" in a vte temi 193 | nal. 194 | This environment should be set before creating a vte 195 | widget. 196 | In LilyTerm, you may set the VTE_CJK_WIDTH of a new tab 197 | to wide with right click menu New tab with specified 198 | locale -> xx_XX.UTF-8 (Wide) or UTF-8 (Wide). 199 | 200 | PROMPT_COMMAND Customs the "Window Title" for shell. 201 | The following is a reasonable example ~/.bashrc for 202 | bash: 203 | 204 | case $TERM in 205 | xterm*) 206 | PROMPT_COMMAND=echo -ne "\033]0;${HOST 207 | NAME}: ${PWD}\007" 208 | ;; 209 | *) 210 | ;; 211 | esac 212 | 213 | The following is a reasonable example ~/.cshrc for 214 | csh/tcsh: 215 | 216 | switch ($TERM) 217 | case "xterm*": 218 | setenv TITLE "%{\033]0;%m: %~\007%}" 219 | breaksw 220 | endsw 221 | 222 | set prompt = "${TITLE}%# " 223 | 224 | Please visit http://tldp.org/HOWTO/Xterm-Title.html for 225 | more details. 226 | 227 | AUTHOR 228 | Lu, Chao-Ming (Tetralet) 229 | 230 | SEE ALSO 231 | xterm(1) 232 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | BUG: 2 | 3 | the dialog of find text behavior strange. 4 | recheck the geometry of gtk2. 5 | the text of running command is wrapped? 6 | 7 | GtkWidget in unit test... 8 | 9 | [Open new tab with locale] -> [Set as default locale] 10 | 11 | check window_resizable 12 | 13 | add a new tab, and increase the font size of 1st tab, close 2nd tab, the window size is incorrect. 14 | check every externs... 15 | the environ won't copy from last tab <- very hard to fix it. 16 | * antialias don't work in new libvte 17 | ** [LilyTerm Default & System Default] don't behave the same? 18 | 19 | TODO: 20 | 21 | * reload settings (Window Title may cause problems) 22 | * apply to every window 23 | * response from unix sockets 24 | check vte_data->column 25 | ** confirm to save settings before exit 26 | * double click to select more... 27 | add programs to 'whitelist' when warning dialog appeared. 28 | sort menu via profile 29 | a scroll bar menu 30 | Save settings that diff and full 31 | ** check the focus of dialogs 32 | * replace sleep with time_out 33 | ** check the pagename if page_shows_cmdline = 0 34 | ** fullscreen and fullwindow in profile. 35 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CONF_FILE='.default' 4 | AC_FILE='configure.ac' 5 | 6 | Replace_Parameter() 7 | { 8 | # Find the parameter from CONF_FILE 9 | Parameter=`grep "^$* = " $CONF_FILE | sed -e "s|$* = ||g" | tr -d '\\\\'` 10 | if [ $? != 0 ]; then 11 | echo "Can Not find the string for "$*" from $CONF_FILE. exit..." >&2 12 | exit 1 13 | fi 14 | if [ -n "`echo $Parameter | grep '^\$(shell .*)$'`" ]; then 15 | Parameter=`$(echo $Parameter | sed -e 's/^\$(shell \(.*\))$/\1/g')` 16 | fi 17 | 18 | echo "$AC_FILE: Replacing variable '$*' with '$Parameter'..." >&2 19 | 20 | # Replace the parameter in AC_FILE 21 | sed -i "s|\$_$*|$Parameter|g" $AC_FILE 22 | if [ $? != 0 ]; then 23 | echo "Something goes wrong when replace '$*' with '$Parameter' for $AC_FILE. exit..." >&2 24 | exit 1 25 | fi 26 | } 27 | 28 | echo "" 29 | Replace_Parameter BINARY 30 | Replace_Parameter PACKAGE 31 | Replace_Parameter VERSION 32 | Replace_Parameter BUGREPORT 33 | Replace_Parameter ISSUES 34 | Replace_Parameter YEAR 35 | Replace_Parameter AUTHOR 36 | Replace_Parameter MAINSITE 37 | Replace_Parameter GITHUBURL 38 | Replace_Parameter BLOG 39 | Replace_Parameter WIKI 40 | Replace_Parameter IRC 41 | Replace_Parameter LANG_LIST 42 | 43 | AC_FILE='src/Makefile.am' 44 | Replace_Parameter BINARY 45 | echo "" 46 | 47 | # for GTK3+ 48 | pkg-config --cflags gtk+-2.0 > /dev/null 2>&1 49 | if [ $? != 0 ]; then 50 | sed -i 's/^AM_PATH_GTK_2_0.*/PKG_CHECK_MODULES([GTK], [gtk+-3.0])/g' configure.ac 51 | pkg-config --cflags vte-2.91 > /dev/null 2>&1 52 | if [ $? = 0 ]; then 53 | sed -i 's/^PKG_CHECK_MODULES(vte, \[vte >= .*/PKG_CHECK_MODULES(vte, [vte-2.91 >= 0.38.0],, AC_MSG_ERROR([You need libvte-2.91 >= 0.38.0 to build $_PACKAGE]))/g' configure.ac 54 | sed -i 's/^lilyterm_LDADD\(.*\)$/lilyterm_LDADD\1 -lX11/g' src/Makefile.am 55 | else 56 | sed -i 's/^PKG_CHECK_MODULES(vte, \[vte >= .*/PKG_CHECK_MODULES(vte, [vte-2.90 >= 0.30.0],, AC_MSG_ERROR([You need libvte-2.90 >= 0.30.0 to build $_PACKAGE]))/g' configure.ac 57 | fi 58 | fi 59 | 60 | set -x 61 | 62 | aclocal 63 | autoheader 64 | intltoolize --automake --copy --force 65 | automake --add-missing --copy 66 | autoconf 67 | 68 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GLIB_MIN_VERSION="2.4.7" 4 | GTK_MIN_VERSION="2.4.10" 5 | GTK_COMMEND_VERSION="2.11" 6 | VTE_MIN_VERSION="0.11.11" 7 | 8 | PACKAGE=`grep "^PACKAGE = " .default | awk -F ' = ' '{print $2}'` 9 | PREFIX=`grep "^PREFIX = " .default | awk -F ' = ' '{print $2}'` 10 | DATADIR=`grep "^DATADIR = " .default | awk -F ' = ' '{print $2}'` 11 | ETCDIR=`grep "^ETCDIR = " .default | awk -F ' = ' '{print $2}'` 12 | 13 | BSD=0 14 | UNAME="`uname`" 15 | if [ "$UNAME" = "FreeBSD" -o "$UNAME" = "OpenBSD" -o "$UNAME" = "NetBSD" ]; then 16 | BSD=1 17 | fi 18 | 19 | GTK=gtk+-2.0 20 | 21 | VERBOSITY=N 22 | DEBUG=N 23 | NLS=Y 24 | SAFEMODE=Y 25 | BACKGROUND=N 26 | STRIP=N 27 | GNOME_CONTROL_CENTER=Y 28 | 29 | GTK_SPC=1 30 | NLS_SPC=0 31 | GNOME_CONTROL_CENTER_SPC=0 32 | 33 | if [ -z "$CC" ]; then 34 | CC=gcc 35 | fi 36 | 37 | if [ -z "$CFLAGS" ]; then 38 | CFLAGS="-Wall -O -g" 39 | fi 40 | 41 | MAKE=`whereis "gmake" | tr -s ' ' '\n' | grep "bin/""gmake""$" | head -n 1` 42 | if [ -z "$MAKE" ]; then 43 | MAKE=`whereis "make" | tr -s ' ' '\n' | grep "bin/""make""$" | head -n 1` 44 | else 45 | GMAKE="$MAKE" 46 | fi 47 | ECHO=`whereis "echo" | tr -s ' ' '\n' | grep "bin/""echo""$" | head -n 1` 48 | PRINTF=`whereis "printf" | tr -s ' ' '\n' | grep "bin/""printf""$" | head -n 1` 49 | WC=`whereis "wc" | tr -s ' ' '\n' | grep "bin/""wc""$" | head -n 1` 50 | 51 | ERR() 52 | { 53 | $PRINTF "\033[1;31m$*\033[0m" >&2 54 | } 55 | 56 | WARN() 57 | { 58 | $PRINTF "\033[1;35m$*\033[0m" 59 | } 60 | 61 | INFO() 62 | { 63 | $PRINTF "\033[1;36m$*\033[0m" 64 | } 65 | 66 | IMPORTANT() 67 | { 68 | $PRINTF "\033[1;33m$*\033[0m" 69 | } 70 | 71 | NORMAL() 72 | { 73 | $PRINTF "\033[1;32m$*\033[0m" 74 | } 75 | 76 | CHECK_MESSAGE() 77 | { 78 | DOTS=30 79 | $ECHO -n " Checking " 80 | NORMAL "$*" 81 | $ECHO -n " " 82 | total=$(($DOTS-`$ECHO "$*" | $WC -m`)) 83 | while [ $total -ge 0 ]; do 84 | $ECHO -n "." 85 | total=$(($total-1)) 86 | done 87 | $ECHO -n " " 88 | } 89 | 90 | PACKAGE_MESSAGE() 91 | { 92 | ERR "\n\n Please install " 93 | COUNT_PKG=1 94 | for PKG in $*; do 95 | if [ $COUNT_PKG -ge 2 ]; then 96 | if [ $COUNT_PKG -eq $# ]; then 97 | ERR " or " 98 | else 99 | ERR ", " 100 | fi 101 | fi 102 | ERR "\"" 103 | WARN "$PKG" 104 | ERR "\"" 105 | COUNT_PKG=$(($COUNT_PKG+1)) 106 | done 107 | ERR " package. ABORT!\n\n" 108 | } 109 | 110 | VERSION_MESSAGE() 111 | { 112 | ERR "$1 ERROR: " 113 | WARN "$2" 114 | ERR " > " 115 | WARN "$3" 116 | ERR " is needed to build $PACKAGE. ABORT!\n\n" 117 | } 118 | 119 | if [ "$1" = "-h" -o "$1" = "--help" -o "$1" = "-help" ]; then 120 | $ECHO "" 121 | WARN "Usage: $0 [OPTION]... [VAR=VALUE]...\n" 122 | $ECHO "" 123 | $ECHO "Installation directories:" 124 | $ECHO " `INFO '--prefix=PREFIX'` : install in PREFIX (e.g. /usr) `NORMAL '[default: /usr/local]'`" 125 | $ECHO " `INFO '--sysconfdir=ETCDIR'` : system conf file install dir `NORMAL '[default: $PREFIX/etc/xdg]'`" 126 | $ECHO "" 127 | # $ECHO "Optional Packages:" 128 | # $ECHO " `INFO '--with-gtk=2.0|3.0'` : which gtk+ version to compile against `NORMAL '[default: 2.0]'`" 129 | # $ECHO "" 130 | $ECHO "Optional Features:" 131 | $ECHO " `INFO '--enable-verbosity'` : enable verbosity output `NORMAL '[default: disable]'`" 132 | $ECHO " `INFO '--enable-debug'` : enable debug mode `NORMAL '[default: disable]'`" 133 | $ECHO " `INFO '--disable-nls'` : disable Native Language Support `NORMAL '[default: enable]'`" 134 | $ECHO " `INFO '--disable-safe-mode'` : disable run in safe mode `NORMAL '[default: enable]'`" 135 | $ECHO " `INFO '--enable-background'` : enable background for vte > 0.34.8 `NORMAL '[default: disable]'`" 136 | $ECHO "" 137 | $ECHO "run \``IMPORTANT 'make clean'`' to clean $PACKAGE builded files." 138 | $ECHO "run \``IMPORTANT 'make distclean'`' to clean $PACKAGE builded and configure files." 139 | $ECHO "run \``IMPORTANT 'make'`' to build $PACKAGE, include binary, data and translations." 140 | $ECHO "run \``IMPORTANT 'make install'`' to install $PACKAGE to your system." 141 | $ECHO "run \``IMPORTANT 'make uninstall'`' to unstall $PACKAGE in `NORMAL "$PREFIX"` from your system." 142 | $ECHO "" 143 | exit 0 144 | fi 145 | 146 | PKGCONFIG=`whereis "pkg-config" | tr -s ' ' '\n' | grep "bin/""pkg-config""$" | head -n 1` 147 | if [ -z "$PKGCONFIG" ]; then 148 | ERR "\n ERROR: \`" 149 | WARN "pkg-config" 150 | ERR "' package is needed to run this configure script. ABORT!\n\n" 151 | exit 1 152 | fi 153 | 154 | for opt do 155 | case "$opt" in 156 | --enable-verbosity) 157 | VERBOSITY=Y 158 | ;; 159 | --disable-verbosity) 160 | VERBOSITY=N 161 | ;; 162 | --enable-debug) 163 | DEBUG=Y 164 | ;; 165 | --disable-debug) 166 | DEBUG=N 167 | ;; 168 | --prefix=*) 169 | PREFIX=`$ECHO $opt | cut -d '=' -f 2` 170 | ;; 171 | --sysconfdir=*) 172 | ETCDIR=`$ECHO $opt | cut -d '=' -f 2` 173 | ;; 174 | --with-gtk=2.0) 175 | GTK_SPC=1 176 | ;; 177 | # --with-gtk=3.0) 178 | # GTK=gtk+-3.0 179 | # GTK_SPC=1 180 | # ;; 181 | --enable-nls) 182 | NLS_SPC=1 183 | ;; 184 | --disable-nls) 185 | NLS=N 186 | ;; 187 | --disable-safe-mode) 188 | SAFEMODE=N 189 | ;; 190 | --enable-background) 191 | BACKGROUND=Y 192 | ;; 193 | --enable-strip) 194 | STRIP=Y 195 | ;; 196 | --enable-gnome-control-center) 197 | GNOME_CONTROL_CENTER_SPC=1 198 | ;; 199 | --disable-gnome-control-center) 200 | GNOME_CONTROL_CENTER=N 201 | ;; 202 | *) 203 | WARN "\n WARN: invalid option \"" 204 | IMPORTANT "$opt" 205 | WARN "\" !!\n" 206 | ;; 207 | esac 208 | done 209 | 210 | $ECHO "" 211 | 212 | # ---- Build Requirement ---- # 213 | 214 | $PKGCONFIG --exists "glib-2.0 >= $GLIB_MIN_VERSION" > /dev/null 2>&1 215 | if [ $? != 0 ]; then 216 | VERSION_MESSAGE "" "Glib" "$GLIB_MIN_VERSION" 217 | exit 1 218 | fi 219 | 220 | # ---- GTK ---- # 221 | 222 | if [ "$GTK" = "gtk+-2.0" ]; then 223 | CHECK_MESSAGE 'GTK+2' 224 | else 225 | CHECK_MESSAGE 'GTK+3' 226 | fi 227 | 228 | $PKGCONFIG --cflags $GTK > /dev/null 2>&1 229 | if [ $? != 0 ]; then 230 | if [ "$GTK" = "gtk+-2.0" -a $GTK_SPC -eq 0 ]; then 231 | $ECHO "[NO]. Trying GTK+3 ..." 232 | GTK=gtk+-3.0 233 | CHECK_MESSAGE 'GTK+3' 234 | $PKGCONFIG --cflags $GTK > /dev/null 2>&1 235 | if [ $? != 0 ]; then 236 | ERR "[NG]" 237 | PACKAGE_MESSAGE "libgtk2.0-dev/libgtk-3-dev" 238 | exit 1 239 | else 240 | INFO "[OK] " 241 | WARN "(NOT RECOMMEND)\n" 242 | fi 243 | else 244 | if [ "$GTK" = "gtk+-2.0" ]; then 245 | ERR "[NG]" 246 | PACKAGE_MESSAGE "libgtk2.0-dev" 247 | else 248 | ERR "[NG]" 249 | PACKAGE_MESSAGE "libgtk-3-dev" 250 | fi 251 | exit 1 252 | fi 253 | else 254 | if [ "$GTK" = gtk+-2.0 ]; then 255 | $PKGCONFIG --exists "gtk+-2.0 >= $GTK_MIN_VERSION" > /dev/null 2>&1 256 | if [ $? != 0 ]; then 257 | ERR "[NG]" 258 | VERSION_MESSAGE "\n\n" "Gtk+2" "$GTK_MIN_VERSION" 259 | exit 1 260 | fi 261 | 262 | $PKGCONFIG --exists "gtk+-2.0 < $GTK_COMMEND_VERSION" > /dev/null 2>&1 263 | if [ $? != 0 ]; then 264 | INFO "[OK]\n" 265 | else 266 | WARN "[OK]. But using Gtk+2 > $GTK_COMMEND_VERSION is recommended to build $PACKAGE.\n" 267 | fi 268 | else 269 | INFO "[OK].\n" 270 | fi 271 | fi 272 | 273 | 274 | # ---- VTE ---- # 275 | 276 | if [ "$GTK" = 'gtk+-2.0' ]; then 277 | CHECK_MESSAGE 'VTE' 278 | VTE=vte 279 | else 280 | CHECK_MESSAGE 'VTE 0.38' 281 | VTE=vte-2.91 282 | fi 283 | 284 | $PKGCONFIG --cflags $VTE > /dev/null 2>&1 285 | if [ $? != 0 ]; then 286 | if [ "$GTK" = 'gtk+-2.0' ]; then 287 | ERR "[NG]" 288 | PACKAGE_MESSAGE "libvte-dev" 289 | exit 1 290 | else 291 | $ECHO "[NO]. Trying VTE 0.29 ..." 292 | VTE=vte-2.90 293 | CHECK_MESSAGE 'VTE 0.29' 294 | $PKGCONFIG --cflags $VTE > /dev/null 2>&1 295 | if [ $? != 0 ]; then 296 | ERR "[NG]" 297 | PACKAGE_MESSAGE "libvte-2.90-dev" "libvte-2.91-dev" 298 | exit 1 299 | else 300 | INFO "[OK]\n" 301 | fi 302 | fi 303 | else 304 | if [ "$VTE" = 'vte' ]; then 305 | $PKGCONFIG --exists "vte >= $VTE_MIN_VERSION" > /dev/null 2>&1 306 | if [ $? != 0 ]; then 307 | ERR "[NG]" 308 | VERSION_MESSAGE "\n\n" "VTE" "$VTE_MIN_VERSION" 309 | exit 1 310 | fi 311 | fi 312 | 313 | INFO "[OK]\n" 314 | fi 315 | 316 | $PKGCONFIG --exists "$VTE < 0.34.8" > /dev/null 2>&1 317 | if [ $? = 0 ]; then 318 | BACKGROUND=N 319 | fi 320 | 321 | $PKGCONFIG --exists "$VTE >= 0.38.0" > /dev/null 2>&1 322 | if [ $? = 0 ]; then 323 | BACKGROUND=N 324 | fi 325 | 326 | # ---- NLS ---- # 327 | 328 | if [ "$NLS" = 'Y' ]; then 329 | CHECK_MESSAGE 'Native Language Support' 330 | GETTEXT=`whereis "msgfmt" | tr -s ' ' '\n' | grep "bin/""msgfmt""$" | head -n 1` 331 | if [ -z "$GETTEXT" ]; then 332 | if [ $NLS_SPC -eq 1 ]; then 333 | ERR "[NG]" 334 | PACKAGE_MESSAGE "gettext" 335 | exit 1 336 | fi 337 | WARN "[NO]\n" 338 | NLS=N 339 | else 340 | INFO "[OK]\n" 341 | fi 342 | fi 343 | 344 | 345 | # ---- GNOME_CONTROL_CENTER ---- # 346 | 347 | if [ "$GNOME_CONTROL_CENTER" = 'Y' ]; then 348 | GNOME_CONTROL_CENTER_DIR=`pkg-config --variable=defappsdir --define-variable=datadir='$(DATADIR)' gnome-default-applications 2>&1` 349 | if [ $? != 0 ]; then 350 | if [ $GNOME_CONTROL_CENTER_SPC -eq 1 ]; then 351 | CHECK_MESSAGE 'Gnome Control Center' 352 | ERR "[NG]" 353 | PACKAGE_MESSAGE "gnome-control-center-dev" 354 | exit 1 355 | fi 356 | GNOME_CONTROL_CENTER_DIR= 357 | GNOME_CONTROL_CENTER=N 358 | else 359 | CHECK_MESSAGE 'Gnome Control Center' 360 | INFO "[OK]\n" 361 | fi 362 | fi 363 | 364 | $ECHO "" 365 | 366 | # ---- REPORT ---- # 367 | 368 | INFO "=================================================\n" 369 | IMPORTANT " PREFIX = $PREFIX\n" 370 | IMPORTANT " ETCDIR = $ETCDIR\n" 371 | if [ "$VERBOSITY" = 'Y' ]; then 372 | IMPORTANT " VERBOSITY = $VERBOSITY\n" 373 | fi 374 | if [ "$DEBUG" = 'Y' ]; then 375 | IMPORTANT " DEBUG = $DEBUG\n" 376 | else 377 | $ECHO " DEBUG = $DEBUG" 378 | fi 379 | if [ "$NLS" = 'N' ]; then 380 | IMPORTANT " NLS = $NLS\n" 381 | else 382 | $ECHO " NLS = $NLS" 383 | fi 384 | if [ "$SAFEMODE" = 'N' ]; then 385 | IMPORTANT " SAFEMODE = $SAFEMODE\n" 386 | else 387 | $ECHO " SAFEMODE = $SAFEMODE" 388 | fi 389 | if [ "$BACKGROUND" = 'Y' ]; then 390 | IMPORTANT " BACKGROUND = $BACKGROUND\n" 391 | fi 392 | if [ "$STRIP" = 'Y' ]; then 393 | IMPORTANT " STRIP = $STRIP\n" 394 | fi 395 | CHECK_CC=`whereis "$CC" | tr -s ' ' '\n' | grep "bin/""$CC""$" | head -n 1` 396 | if [ -n "$CHECK_CC" ]; then 397 | if [ "$CC" != 'gcc' ]; then 398 | IMPORTANT " CC = $CC\n" 399 | fi 400 | else 401 | ERR " CC = $CC\n" 402 | fi 403 | if [ -n "$CPPFLAGS" ]; then 404 | IMPORTANT " CPPFLAGS = $CPPFLAGS\n" 405 | fi 406 | if [ "$CFLAGS" != '-Wall -O -g' ]; then 407 | IMPORTANT " CFLAGS = $CFLAGS\n" 408 | else 409 | $ECHO " CFLAGS = $CFLAGS" 410 | fi 411 | if [ -n "$LDFLAGS" ]; then 412 | IMPORTANT " LDFLAGS = $LDFLAGS\n" 413 | fi 414 | 415 | if [ -n "$GMAKE" ]; then 416 | IMPORTANT " MAKE = $MAKE\n" 417 | else 418 | if [ -z "$MAKE" ]; then 419 | ERR " MAKE = $MAKE\n" 420 | fi 421 | fi 422 | $ECHO " GTK = $GTK" 423 | $ECHO " VTE = $VTE" 424 | if [ $BSD -eq 1 ]; then 425 | IMPORTANT " MANDIR = \$(PREFIX)/man/man1\n" 426 | IMPORTANT " EXAMPLES_DIR = \$(DATADIR)/examples/\$(BINARY)\n" 427 | fi 428 | if [ "$GNOME_CONTROL_CENTER" = 'Y' ]; then 429 | IMPORTANT " GNOME_CONTROL_CENTER = $GNOME_CONTROL_CENTER\n" 430 | IMPORTANT " GNOME_CONTROL_CENTER_DIR = $GNOME_CONTROL_CENTER_DIR\n" 431 | fi 432 | INFO "=================================================\n" 433 | $ECHO "" 434 | if [ -n "$GMAKE" ]; then 435 | WARN "Please be sure to use \`" 436 | IMPORTANT "gmake" 437 | WARN "' instead of \`" 438 | IMPORTANT "make" 439 | WARN "' to compile $PACKAGE\!\!\n\n" 440 | fi 441 | 442 | $ECHO "BSD = $BSD" > .config 443 | $ECHO "PREFIX = $PREFIX" >> .config 444 | $ECHO "ETCDIR = $ETCDIR" >> .config 445 | if [ $BSD -eq 1 ]; then 446 | $ECHO "MANDIR = \$(PREFIX)/man/man1" >> .config 447 | $ECHO "EXAMPLES_DIR = \$(DATADIR)/examples/\$(BINARY)" >> .config 448 | fi 449 | $ECHO "NLS = $NLS" >> .config 450 | $ECHO "VERBOSITY = $VERBOSITY" >> .config 451 | $ECHO "DEBUG = $DEBUG" >> .config 452 | $ECHO "NLS = $NLS" >> .config 453 | $ECHO "SAFEMODE = $SAFEMODE" >> .config 454 | $ECHO "FORCE_ENABLE_VTE_BACKGROUND = $BACKGROUND" >> .config 455 | $ECHO "STRIP = $STRIP" >> .config 456 | $ECHO "CC = $CC" >> .config 457 | $ECHO "CPPFLAGS = $CPPFLAGS" >> .config 458 | $ECHO "CFLAGS = $CFLAGS" >> .config 459 | $ECHO "LDFLAGS = $LDFLAGS" >> .config 460 | $ECHO "MAKE = $MAKE" >> .config 461 | $ECHO "GTK = $GTK" >> .config 462 | $ECHO "VTE = $VTE" >> .config 463 | $ECHO "GNOME_CONTROL_CENTER = $GNOME_CONTROL_CENTER" >> .config 464 | $ECHO "GNOME_CONTROL_CENTER_DIR = $GNOME_CONTROL_CENTER_DIR" >> .config 465 | 466 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ(2.61) 5 | AC_INIT($_PACKAGE, $_VERSION, $_BUGREPORT) 6 | AM_INIT_AUTOMAKE 7 | AC_CONFIG_SRCDIR([src/main.c]) 8 | AC_CONFIG_HEADERS([config.h]) 9 | 10 | # Checks for programs. 11 | AC_PROG_CC 12 | AM_PROG_CC_C_O 13 | 14 | # Checks for libraries. 15 | AM_PATH_GLIB_2_0(2.5.4,,AC_MSG_ERROR([You need Glib >= 2.5.4 to build $_PACKAGE])) 16 | AM_PATH_GTK_2_0(2.4.10,,AC_MSG_ERROR([You need Gtk+ >= 2.4.10 to build $_PACKAGE])) 17 | PKG_CHECK_MODULES(vte, [vte >= 0.11.11],, AC_MSG_ERROR([You need libvte >= 0.11.11 to build $_PACKAGE])) 18 | 19 | AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable debug mode]), 20 | CFLAGS="$CFLAGS -g" 21 | AC_DEFINE(DEBUG,, [enable debug mode])) 22 | 23 | AC_ARG_ENABLE(safe-mode, AC_HELP_STRING([--disable-safe-mode], [disable run in safe mode]), 24 | CFLAGS="$CFLAGS -g" 25 | AC_DEFINE(REALMODE,, [disable run in safe mode])) 26 | 27 | PKG_CHECK_EXISTS(gtk+-2.0 < 2.11, 28 | AC_MSG_WARN([Using Gtk+ >= 2.11.0 to build $_PACKAGE is recommended])) 29 | 30 | AC_MSG_CHECKING([whether to install GNOME control-center default application definition]) 31 | if $PKG_CONFIG --variable=keysdir gnome-default-applications >/dev/null ; then 32 | AC_MSG_RESULT([yes]) 33 | DEFAULTAPPS_DIR="`$PKG_CONFIG --variable=defappsdir gnome-default-applications`" 34 | AC_SUBST(DEFAULTAPPS_DIR) 35 | else 36 | AC_MSG_RESULT([no]) 37 | DEFAULTAPPS_DIR="" 38 | fi 39 | AM_CONDITIONAL([DEFAULT_APPS_DEFINITION],[test -n "$DEFAULTAPPS_DIR"]) 40 | 41 | AC_DEFINE([BINARY], ["$_BINARY"], "The binary file name of LilyTerm.") 42 | AC_DEFINE([ISSUES], ["$_ISSUES"], "The web site for reporting issues.") 43 | AC_DEFINE([YEAR], ["$_YEAR"], "The current year.") 44 | AC_DEFINE([AUTHOR], ["$_AUTHOR"], "The author's name.") 45 | AC_DEFINE([MAINSITE], ["$_MAINSITE"], "The main site.") 46 | AC_DEFINE([GITHUBURL], ["$_GITHUBURL"], "The github site.") 47 | AC_DEFINE([BLOG], ["$_BLOG"], "The blog site.") 48 | AC_DEFINE([WIKI], ["$_WIKI"], "The wiki site.") 49 | AC_DEFINE([IRC], ["$_IRC"], "The irc channel.") 50 | AC_DEFINE([BUGREPORT], ["$_BUGREPORT"], "The author's email address.") 51 | 52 | AC_PROG_INTLTOOL 53 | ALL_LINGUAS="$_LANG_LIST" 54 | GETTEXT_PACKAGE="$_BINARY" 55 | AC_SUBST(GETTEXT_PACKAGE) 56 | AM_GLIB_GNU_GETTEXT 57 | AM_GLIB_DEFINE_LOCALEDIR(LOCALEDIR) 58 | 59 | # Checks for header files. 60 | AC_HEADER_STDC 61 | AC_CHECK_HEADERS([locale.h stdlib.h string.h]) 62 | 63 | # Checks for typedefs, structures, and compiler characteristics. 64 | AC_C_CONST 65 | AC_TYPE_PID_T 66 | 67 | # Checks for library functions. 68 | AC_CHECK_FUNCS([setlocale]) 69 | 70 | AC_CONFIG_FILES([ 71 | Makefile 72 | src/Makefile 73 | po/Makefile.in 74 | data/Makefile 75 | ]) 76 | AC_OUTPUT 77 | -------------------------------------------------------------------------------- /data/Makefile: -------------------------------------------------------------------------------- 1 | include ../.default 2 | -include ../.config 3 | 4 | ifeq ($(VERBOSITY), Y) 5 | VERBOSITY_OUTPUT = 6 | else 7 | VERBOSITY_OUTPUT = @ 8 | endif 9 | 10 | DESKTOP_DIR ?= $(DATADIR)/applications 11 | GNOME_CONTROL_CENTER ?= Y 12 | GNOME_CONTROL_CENTER_DIR ?= $(DATADIR)/gnome-control-center/default-apps 13 | 14 | MAIN_BINARY := $(shell if [ -f ../src/$(BINARY)_dev ]; then echo $(BINARY)_dev; fi) 15 | MAIN_BINARY := $(shell if [ -f ../src/$(BINARY)_dbg ]; then echo $(BINARY)_dbg; fi) 16 | ifeq ($(MAIN_BINARY), ) 17 | MAIN_BINARY = $(BINARY) 18 | endif 19 | 20 | RomveFileList = $(DESTDIR)/$(ETCDIR)/$(BINARY).conf \ 21 | $(DESTDIR)/$(DOCDIR)/AUTHORS \ 22 | $(DESTDIR)/$(DOCDIR)/COPYING \ 23 | $(DESTDIR)/$(DOCDIR)/ChangeLog \ 24 | $(DESTDIR)/$(MANDIR)/$(BINARY).1.gz \ 25 | $(DESTDIR)/$(DESKTOP_DIR)/$(BINARY).desktop \ 26 | $(DESTDIR)/$(ICONDIR)/$(BINARY).png \ 27 | $(DESTDIR)/$(ICONDIR)/$(BINARY).xpm \ 28 | $(DESTDIR)/$(EXAMPLES_DIR)/$(BINARY).conf 29 | ifeq ($(GNOME_CONTROL_CENTER), Y) 30 | ifneq ($(GNOME_CONTROL_CENTER_DIR), ) 31 | RomveFileList += $(DESTDIR)/$(GNOME_CONTROL_CENTER_DIR)/$(BINARY).xml 32 | endif 33 | endif 34 | 35 | .PHONY: all 36 | all: $(BINARY).conf $(BINARY).1.gz 37 | 38 | $(BINARY).conf: 39 | # @ if [ ! -f ../src/$(BINARY) -a \ 40 | # ! -f ../src/$(BINARY)_dbg -a \ 41 | # ! -f ../src/$(BINARY)_dev ]; then \ 42 | # cd ../src ; \ 43 | # $(MAKE) ; \ 44 | # fi 45 | # @ $(PRINTF) "\033[1;33m** creating $(BINARY).conf...\033[0m\n" 46 | # @ ../src/$(MAIN_BINARY) -p > $(BINARY).conf 47 | 48 | $(BINARY).1.gz: 49 | @ if [ -f $(BINARY).1 ]; then \ 50 | $(PRINTF) "\033[1;33m** adding \033[1;32m$(BINARY).1\033[1;33m ...\033[0m\n" ; \ 51 | gzip $(BINARY).1 ; \ 52 | fi 53 | 54 | .PHONY: clean 55 | clean: 56 | @ # @ if [ -f $(BINARY).conf ]; then \ 57 | # $(PRINTF) "\033[1;35m** deleteing $(BINARY).conf...\033[0m\n" ; \ 58 | # rm $(BINARY).conf ; \ 59 | # fi 60 | @ if [ -f $(BINARY).1.gz ]; then \ 61 | $(PRINTF) "\033[1;35m** unziping \033[1;32m$(BINARY).1\033[1;35m ...\033[0m\n" ; \ 62 | gzip -d $(BINARY).1.gz ; \ 63 | fi 64 | 65 | .PHONY: install 66 | install: all 67 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).conf\033[1;33m to \033[1;34m$(DESTDIR)/$(ETCDIR)\033[1;33m ...\033[0m\n" 68 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(ETCDIR) 69 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).conf $(DESTDIR)/$(ETCDIR) 70 | 71 | @ $(PRINTF) "\033[1;33m** installing \033[1;32mAUTHORS COPYING ChangeLog\033[1;33m to \033[1;34m$(DESTDIR)/$(DOCDIR)\033[1;33m ...\033[0m\n" 72 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(DOCDIR) 73 | $(VERBOSITY_OUTPUT) install -m 644 ../AUTHORS ../COPYING ../ChangeLog $(DESTDIR)/$(DOCDIR) 74 | 75 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).1.gz\033[1;33m to \033[1;34m$(DESTDIR)/$(MANDIR)\033[1;33m ...\033[0m\n" 76 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(MANDIR) 77 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).1.gz $(DESTDIR)/$(MANDIR) 78 | 79 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).desktop\033[1;33m to \033[1;34m$(DESTDIR)/$(DESKTOP_DIR)\033[1;33m ...\033[0m\n" 80 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(DESKTOP_DIR) 81 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).desktop $(DESTDIR)/$(DESKTOP_DIR) 82 | 83 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).png $(BINARY).xpm\033[1;33m to \033[1;34m$(DESTDIR)/$(ICONDIR)\033[1;33m ...\033[0m\n" 84 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(ICONDIR) 85 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).png $(BINARY).xpm $(DESTDIR)/$(ICONDIR) 86 | 87 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).conf\033[1;33m to \033[1;34m$(DESTDIR)/$(EXAMPLES_DIR)\033[1;33m ...\033[0m\n" 88 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(EXAMPLES_DIR) 89 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).conf $(DESTDIR)/$(EXAMPLES_DIR) 90 | 91 | ifeq ($(GNOME_CONTROL_CENTER), Y) 92 | ifneq ($(GNOME_CONTROL_CENTER_DIR), ) 93 | @ $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY).xml\033[1;33m to \033[1;34m$(DESTDIR)/$(GNOME_CONTROL_CENTER_DIR)\033[1;33m ...\033[0m\n" 94 | $(VERBOSITY_OUTPUT) install -d $(DESTDIR)/$(GNOME_CONTROL_CENTER_DIR) 95 | $(VERBOSITY_OUTPUT) install -m 644 $(BINARY).xml $(DESTDIR)/$(GNOME_CONTROL_CENTER_DIR) 96 | endif 97 | endif 98 | 99 | .PHONY: uninstall 100 | uninstall: 101 | @ - for FileName in $(RomveFileList) ; do \ 102 | if [ -f "$$FileName" ]; then \ 103 | $(PRINTF) "\033[1;35m** deleting \033[1;32m$$FileName\033[1;35m ...\033[0m\n" ; \ 104 | rm -f "$$FileName" ; \ 105 | DirName=`dirname $$FileName` ; \ 106 | until [ -n "`ls -A $$DirName`" -o "$$DirName" = "$(DESTDIR)/$(PREFIX)" ]; do \ 107 | $(PRINTF) "\033[1;35m** deleting directory \033[1;34m$$DirName\033[1;35m ...\033[0m\n" ; \ 108 | rmdir "$$DirName" ; \ 109 | DirName=`dirname $$DirName` ; \ 110 | done \ 111 | else \ 112 | $(PRINTF) "\033[1;31m** \033[1;32m$$FileName\033[1;31m is NOT exist!\033[0m\n"; \ 113 | fi ; \ 114 | done 115 | -------------------------------------------------------------------------------- /data/Makefile.am: -------------------------------------------------------------------------------- 1 | authordir = $(datadir)/doc/$(PACKAGE) 2 | author_DATA = ../AUTHORS 3 | 4 | copyingdir = $(datadir)/doc/$(PACKAGE) 5 | copying_DATA = ../COPYING 6 | 7 | changlogdir = $(datadir)/doc/$(PACKAGE) 8 | changlog_DATA = ../ChangeLog 9 | 10 | man_MANS=$(PACKAGE).1 11 | 12 | etcdir = $(sysconfdir)/xdg 13 | etc_DATA = $(PACKAGE).conf 14 | 15 | desktopdir = $(datadir)/applications 16 | desktop_DATA = $(PACKAGE).desktop 17 | 18 | pixmapsdir = $(datadir)/pixmaps 19 | pixmaps_DATA = $(PACKAGE).png $(PACKAGE).xpm 20 | 21 | examplesdir = $(datadir)/doc/$(PACKAGE)/examples 22 | examples_DATA = $(PACKAGE).conf 23 | 24 | EXTRA_DIST = $(author_DATA) $(copying_DATA) $(changlog_DATA) $(etc_DATA) $(desktop_DATA) $(pixmaps_DATA) $(examples_DATA) 25 | 26 | 27 | xml_in_files = $(PACKAGE).xml.in 28 | 29 | if DEFAULT_APPS_DEFINITION 30 | xmldir = $(DEFAULTAPPS_DIR) 31 | xml_DATA = $(xml_in_files:.xml.in=.xml) 32 | endif 33 | 34 | @INTLTOOL_XML_RULE@ 35 | -------------------------------------------------------------------------------- /data/lilyterm.1: -------------------------------------------------------------------------------- 1 | .\" Process this file with 2 | .\" groff -man -Tascii lilyterm.1 3 | .\" 4 | .TH LilyTerm 1 "March 2013" "LilyTerm 0.9.9.5" "A light and eazy\-to\-use terminal emulator" 5 | .SH NAME 6 | LilyTerm \- A light and eazy\-to\-use terminal emulator for X. 7 | .\" Disable justification (adjust text to left margin only) 8 | .ad l 9 | .SH SYNOPSIS 10 | .HP 9 11 | \fBlilyterm\fR 12 | [\fB\-?\fR | \fB\-h\fR | \fB\-\-help\fR] 13 | [\fB\-T\fR \fITITLE\fR | \fB\-\-title\fR \fITITLE\fR] 14 | [\fB\-R\fR \fIROLE\fR | \fB\-\-role\fR \fIROLE\fR] 15 | [\fB\-t\fR \fINUMBER\fR | \fB\-\-tab\fR \fINUMBER\fR] 16 | [\fB\-n\fR \fITAB NAMES\fR | \fB\-\-tab_names\fR \fITAB NAMES\fR] 17 | [\fB\-d\fR \fIDIRECTORY\fR | \fB\-\-directory\fR \fIDIRECTORY\fR] 18 | [\fB\-g\fR \fIGEOMETRY\fR | \fB\-\-geometry\fR \fIGEOMETRY\fR] 19 | [\fB\-l\fR | \fB\-ls\fR | \fB\-\-login\fR] 20 | [\fB\-ut\fR] 21 | [\fB\-H\fR | \fB\-\-hold\fR] 22 | [\fB\-s\fR | \fB\-\-separate\fR] 23 | [\fB\-j\fR | \fB\-\-join\fR] 24 | [\fB\-p\fR | \fB\-\-profile\fR] 25 | [\fB\-u\fR \fIPROFILE\fR | \fB\-\-user_profile\fR \fIPROFILE\fR] 26 | [\fB\-v\fR | \fB\-\-version\fR] 27 | [\fB\-e\fR \fICOMMAND\fR | \fB\-x\fR \fICOMMAND\fR | \fB\-\-execute\fR \fICOMMAND\fR] 28 | .SH DESCRIPTION 29 | LilyTerm is a terminal emulator for the X Window System, based on the \fBlibvte\fR library, and aims to be fast and lightweight. 30 | .SH OPTIONS 31 | .PP 32 | \fB\-?\fR | \fB\-h\fR | \fB\-\-help\fR 33 | .RS 4 34 | Display a brief help message. 35 | .RE 36 | .PP 37 | \fB\-T\fR \fITITLE\fR | \fB\-\-title\fR \fITITLE\fR 38 | .RS 4 39 | Specify the window title. 40 | .RE 41 | .PP 42 | \fB\-R\fR \fIROLE\fR | \fB\-\-role\fR \fIROLE\fR 43 | .RS 4 44 | Specify the WM_WINDOW_ROLE string of window. 45 | .RE 46 | .PP 47 | \fB\-t\fR \fINUMBER\fR | \fB\-\-tab\fR \fINUMBER\fR 48 | .RS 4 49 | Open multi tabs when starting up. 50 | .RE 51 | .PP 52 | \fB\-n\fR \fITAB NAMES\fR | \fB\-\-tab_names\fR \fITAB NAMES\fR 53 | .RS 4 54 | Specify the tab names, separate with . 55 | .RE 56 | .PP 57 | \fB\-d\fR \fIDIRECTORY\fR | \fB\-\-directory\fR \fIDIRECTORY\fR 58 | .RS 4 59 | Specify the init directory when starting up. 60 | .RE 61 | .PP 62 | \fB\-g\fR \fIGEOMETRY\fR | \fB\-\-geometry\fR \fIGEOMETRY\fR 63 | .RS 4 64 | Specify the geometry of window when starting. 65 | .br 66 | A reasonable example value is "80x24+0+0", witch means "width x height {+\-} xoffset {+\-} yoffset" (without space). 67 | .RE 68 | .PP 69 | \fB\-l\fR | \fB\-ls\fR | \fB\-\-login\fR 70 | .RS 4 71 | Make the shell invoked as a login shell. 72 | .RE 73 | .PP 74 | \fB\-ut\fR 75 | .RS 4 76 | Disable recording the session in lastlog, utmp and wtmp. 77 | .RE 78 | .PP 79 | \fB\-H\fR | \fB\-\-hold\fR 80 | .RS 4 81 | Hold the terminal window open when the command following \-e/\-x terminated. 82 | .RE 83 | .PP 84 | \fB\-s\fR | \fB\-\-separate\fR 85 | .RS 4 86 | Run in separate process. 87 | .RE 88 | .PP 89 | \fB\-j\fR | \fB\-\-join\fR 90 | .RS 4 91 | Integrate new created tabs to the last accessed window. 92 | .br 93 | It may be useful for launching multi commands with LilyTerm in a shell script. 94 | .RE 95 | .PP 96 | \fB\-J\fR 97 | .RS 4 98 | Disable integrating new created tabs to the last accessed window. 99 | .RE 100 | .PP 101 | \fB\-p\fR | \fB\-\-profile\fR 102 | .RS 4 103 | Got a profile sample. 104 | .RE 105 | .PP 106 | \fB\-u\fR \fIPROFILE\fR | \fB\-\-user_profile\fR \fIPROFILE\fR 107 | .RS 4 108 | Use a specified profile. 109 | .RE 110 | .PP 111 | \fB\-v\fR | \fB\-\-version\fR 112 | .RS 4 113 | Show the version information. 114 | .RE 115 | .PP 116 | \fB\-e\fR \fICOMMAND\fR | \fB\-x\fR \fICOMMAND\fR | \fB\-\-execute\fR \fICOMMAND\fR 117 | .RS 4 118 | Run a command when starting up. Must be the final option. 119 | .RE 120 | .PP 121 | \fB\-E\fR \fICOMMAND\fR | \fB\-X\fR \fICOMMAND\fR 122 | .RS 4 123 | Same as -e/-x option, but will not show a comfirm dialog window. 124 | .RE 125 | 126 | .SH KEYBOARD CONTROL 127 | The following key bindings may custom or disable by the right click menu \fB[Set key binding]\fR. 128 | .PP 129 | .PD 0 130 | .TP 20 131 | .BI <`> 132 | Disable/Enable hyperlinks, function keys and right click menu for temporary. 133 | 134 | .TP 135 | .BI 136 | Add a New tab with current directory. 137 | 138 | .TP 139 | .BI 140 | Switch to Prev/Next tab. 141 | 142 | .TP 143 | .BI 144 | Switch to First/Last tab. 145 | 146 | .TP 147 | .BI <[/]> 148 | Move current tab Forward/Backward. 149 | 150 | .TP 151 | .BI 152 | Move current tab to First/Last. 153 | 154 | .TP 155 | .BI 156 | Switch to 1st ~ 12th tab. 157 | 158 | .TP 159 | .BI 160 | Select all the text in the Vte Terminal box. 161 | 162 | .TP 163 | .BI <+/\-/Enter> 164 | Increase/Decrease/Reset the font size of current tab. 165 | 166 | .TP 167 | .BI 168 | Switch between fullwindow/unfullwindow and fullscreen/unfullscreen state. 169 | 170 | .TP 171 | .BI 172 | Emulate a mouse Scroll Up/Down event on Vte Terminal box. 173 | 174 | .TP 175 | .BI 176 | Asks to scroll Up/Down 1 line on Vte Terminal box. 177 | 178 | .TP 179 | .BI 180 | Asks to scroll Up/Down on Vte Terminal box. 181 | 182 | .TP 183 | .BI 184 | Copy the text to clipboard / Paste the text in clipboard. 185 | 186 | .TP 187 | .BI 188 | Copy the text to primary clipboard / Paste the text in primary clipboard. 189 | .br 190 | i.e. Emulate a middle button mouse click to copy/paste the text. 191 | .RE 192 | 193 | Some key bindings that disabled by default but maybe useful: 194 | 195 | .TP 196 | .BI 197 | Close current tab. 198 | .br 199 | \fIUsing \fR\fB\fR\fI or '\fR\fBexit\fR\fI' to close tabs is recommended.\fR 200 | 201 | .TP 202 | .BI 203 | Open a new window with current directory. 204 | 205 | .TP 206 | .BI 207 | Rename the current tab. 208 | 209 | .SH FILE 210 | .PP 211 | .PD 0 212 | .TP 32 213 | .BI /etc/xdg/lilyterm.conf 214 | System configure file 215 | 216 | .TP 217 | .BI ~/.config/lilyterm/default.conf 218 | User's profile. 219 | .RE 220 | 221 | Use \fB[Save settings]\fR in the right click menu to save the current tab's settings as default to the specified profile. 222 | 223 | .SH TIPS 224 | .PP 225 | \fBDisplay UTF\-8 character under C locale\fR 226 | 227 | .RS 4 228 | Execute the following command under LilyTerm: 229 | 230 | .RS 4 231 | bind "set convert\-meta off" 232 | .br 233 | bind "set output\-meta on" 234 | .RE 235 | 236 | And use the right click menu to set the text encoding to "\fBUTF\-8\fR". 237 | .RE 238 | 239 | .PP 240 | \fBLaunch LilyTerm under a chroot jail\fR 241 | 242 | .RS 4 243 | Extract \fBxauth info\fR to a file (under X): 244 | 245 | .RS 4 246 | xauth extract /PathToChroot/tmp/display $DISPLAY 247 | .RE 248 | 249 | Mount the \fBdevpts\fR device and \fB/tmp\fR (may not necessary) before chroot into a chroot jail: 250 | 251 | .RS 4 252 | mount /dev/pts /PathToChroot/dev/pts \-t devpts 253 | .br 254 | mount \-o bind /tmp /PathToChroot/tmp (may not necessary) 255 | .RE 256 | 257 | Merge the extracted \fBxauth info\fR and set the \fBDISPLAY\fR environ after chroot into the chroot jail: 258 | 259 | .RS 4 260 | xauth merge /tmp/display 261 | .br 262 | export DISPLAY=:0 263 | .RE 264 | 265 | Launch LilyTerm directly, or run it under \fBXnest\fR/\fBXephyr\fR: 266 | 267 | .RS 4 268 | xinit ~/.xinitrc \-\- /usr/bin/Xnest :1 \-ac \-geometry 800x600 269 | .RE 270 | 271 | or 272 | 273 | .RS 4 274 | xinit ~/.xinitrc \-\- /usr/bin/Xephyr :1 \-ac \-screen 800x600 275 | .RE 276 | .RE 277 | 278 | .PP 279 | \fB and don't work under VIM:\fR 280 | 281 | .RS 4 282 | Use the following command to turn off '\fBflow\-Control\fR' under LilyTerm: 283 | 284 | .RS 4 285 | stty raw 286 | .RE 287 | 288 | or 289 | 290 | .RS 4 291 | stty \-ixon 292 | .RE 293 | 294 | .RE 295 | 296 | .PP 297 | \fBBSD Users:\fR 298 | 299 | .RS 4 300 | Please mount the procfs before launch LilyTerm: 301 | 302 | .RS 4 303 | mount \-t procfs procfs /proc 304 | .RE 305 | 306 | .SH ENVIRONMENT 307 | .PP 308 | .PD 0 309 | .TP 15 310 | .BI TERM 311 | Sets what type of terminal attempts to emulate. Please always set to "\fBxterm\fR" under LilyTerm. 312 | 313 | .TP 314 | .BI VTE_CJK_WIDTH 315 | Controls the width of some ideographs should be "single width (narrow)" or "double width (wide)" in a vte teminal. 316 | .br 317 | This environment should be set \fBbefore\fR creating a vte widget. 318 | .br 319 | In LilyTerm, you may set the VTE_CJK_WIDTH of a new tab to 'wide' with right click menu 'New tab with specified locale' \-> 'xx_XX.UTF\-8 (Wide)' or 'UTF\-8 (Wide)'. 320 | 321 | .TP 322 | .BI PROMPT_COMMAND 323 | Customs the "Window Title" for shell. 324 | .br 325 | The following is a reasonable example ~/.bashrc for bash: 326 | .RS 19 327 | .br 328 | 329 | case $TERM in 330 | .br 331 | xterm*) 332 | PROMPT_COMMAND='echo \-ne "\\033]0;${HOSTNAME}: ${PWD}\\007"' 333 | ;; 334 | .br 335 | *) 336 | ;; 337 | .br 338 | esac 339 | 340 | .br 341 | .RE 342 | .RS 15 343 | The following is a reasonable example ~/.cshrc for csh/tcsh: 344 | .RS 4 345 | .br 346 | 347 | switch ($TERM) 348 | case "xterm*": 349 | setenv TITLE "%{\\033]0;%m: %~\\007%}" 350 | breaksw 351 | .br 352 | endsw 353 | 354 | set prompt = "${TITLE}%# " 355 | 356 | .br 357 | .RE 358 | .RE 359 | .RS 15 360 | Please visit \fIhttp://tldp.org/HOWTO/Xterm\-Title.html\fR for more details. 361 | .RE 362 | 363 | .SH AUTHOR 364 | Lu, Chao\-Ming (Tetralet) 365 | 366 | .SH SEE ALSO 367 | xterm(1) 368 | -------------------------------------------------------------------------------- /data/lilyterm.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | 3 | # Auto save settings when closing window. 4 | auto_save = 0 5 | 6 | # The version of this profile's format. DO NOT EDIT IT! 7 | version = 0.9.9 8 | 9 | # The default font name of vte terminal. 10 | font_name = Monospace 12 11 | 12 | # The default column of vte terminal. 13 | column = 80 14 | 15 | # The default row of vte terminal. 16 | row = 24 17 | 18 | # Use true opacity in vte box. 19 | # 0: do NOT use rgba, 1: force to use rgba. 20 | # Left it blank will enable it automatically 21 | # if the window manager were composited. 22 | # Disable it will disable transparent_window, too. 23 | use_rgba = 24 | 25 | # Start up with fullscreen. 26 | fullscreen = 0 27 | 28 | # Transparent window. Only enabled when the window manager were composited. 29 | transparent_window = 0 30 | 31 | # The opacity of transparent window. 32 | window_opacity = 0.050 33 | 34 | # The opacity of transparent window when inactive. 35 | # Left it blank to disable this feature. 36 | window_opacity_inactive = 0.200 37 | 38 | # Use transparent background. 39 | # It will use true transparent if the window manager were composited. 40 | transparent_background = 0 41 | 42 | # The saturation of transparent background. 43 | background_saturation = 0.150 44 | 45 | # Scroll the background image along with the text. 46 | scroll_background = 0 47 | 48 | # Sets a background image. 49 | background_image = 50 | 51 | # Confirm to execute command with -e/-x/--execute option. 52 | confirm_to_execute_command = 1 53 | 54 | # Don't need to confirm for executing a program if it's in the whitelist, 55 | # separate with . 56 | execute_command_whitelist = 57 | 58 | # Launching executed command in a new tab instead of opening a new window. 59 | execute_command_in_new_tab = 1 60 | 61 | # If a program is running on foreground, 62 | # Don't need to confirm for terminating it if it's in the whitelist, 63 | # separate with . 64 | foreground_program_whitelist = bash dash csh ksh tcsh zsh screen 65 | 66 | # If a program is running in background, 67 | # Don't need to confirm for terminating it if it's in the whitelist, 68 | # separate with . 69 | background_program_whitelist = bash dash csh ksh tcsh zsh su 70 | 71 | # Confirm before pasting texts to vte terminal. 72 | confirm_to_paste = 1 73 | 74 | # If the program is running on foreground,, 75 | # Don't need to confirm for pasting texts to it if it's in the whitelist, 76 | # separate with . 77 | paste_texts_whitelist = editor vi vim elvis nano emacs emacs23 nano joe ne mg ssh 78 | 79 | # Confirm to close multi tabs. 80 | confirm_to_close_multi_tabs = 0 81 | 82 | # Shows [Transparent Background], [Background Saturation] 83 | # [Transparent Window] and [Window Opacity] on right click menu. 84 | show_background_menu = 1 85 | 86 | # Shows [Change the foreground color] 87 | # and [Change the background color] on right click menu. 88 | show_color_selection_menu = 1 89 | 90 | # The normal text color used in vte terminal. 91 | # You may use black, #000000 or #000000000000 here. 92 | foreground_color = white 93 | 94 | # Sets the background color for text which is under the cursor. 95 | # You may use black, #000000 or #000000000000 here. 96 | cursor_color = #55B5E7 97 | 98 | # The background color used in vte terminal. 99 | # You may use black, #000000 or #000000000000 here. 100 | background_color = black 101 | 102 | # Shows [Increase window size], [Decrease window size], 103 | # [Reset to default font/size] and [Reset to system font/size] 104 | # on right click menu. 105 | show_resize_menu = 1 106 | 107 | # The ratio when resizing font via function key <+> and <->. 108 | # 0: the font size is +/- 1 when resizing. 109 | font_resize_ratio = 0.000 110 | 111 | # The ratio when resizing window via right click menu. 112 | # 0: the font size is +/- 1 when resizing window. 113 | window_resize_ratio = 1.120 114 | 115 | # When user double clicks on a text, which character will be selected. 116 | word_chars = -A-Za-z0-9_.+!@&=/~% 117 | 118 | # The lines of scrollback history. -1 means unlimited (vte >= 0.22.3). 119 | scrollback_lines = 1024 120 | 121 | # Shows scroll_bar or not. 122 | # 0: Never shows the scroll_bar; 1: Always shows the scroll_bar. 123 | # Left it blank: Hide when fullscreen, or scrollback_lines = 0. 124 | show_scroll_bar = 125 | 126 | # The position of scroll_bar. 127 | # 0: scroll_bar is on left; 1: scroll_bar is on right. 128 | scroll_bar_position = 1 129 | 130 | # Shows input method menu on right click menu. 131 | show_input_method_menu = 0 132 | 133 | # Shows change page name menu on right click menu. 134 | show_change_page_name_menu = 1 135 | 136 | # Shows exit menu on right click menu. 137 | show_exit_menu = 1 138 | 139 | # Enable hyperlink in vte terminal. 140 | enable_hyperlink = 1 141 | 142 | # Sets whether or not the cursor will blink in vte terminal. 143 | # 0: Follow GTK+ settings for cursor blinking. 144 | # 1: Cursor blinks. 145 | # 2: Cursor does not blink. 146 | cursor_blinks = 0 147 | 148 | # Shows copy/paste menu on right click menu. 149 | show_copy_paste_menu = 1 150 | 151 | # Embed the copy/paste menu to the main menu. 152 | embedded_copy_paste_menu = 1 153 | 154 | # Sets whether or not the terminal will beep 155 | # when the child outputs the "bl" sequence. 156 | audible_bell = 1 157 | 158 | # Sets whether or not the terminal will flash 159 | # when the child outputs the "bl" sequence. 160 | visible_bell = 0 161 | 162 | # Sets whether or not the window's urgent tag will be set 163 | # when the child outputs the "bl" sequence. 164 | urgent_bell = 1 165 | 166 | # Which string the terminal should send to an application 167 | # when the user presses the Delete or Backspace keys. 168 | # 0: VTE_ERASE_AUTO 169 | # 1: VTE_ERASE_ASCII_BACKSPACE 170 | # 2: VTE_ERASE_ASCII_DELETE 171 | # 3: VTE_ERASE_DELETE_SEQUENCE 172 | # 4: VTE_ERASE_TTY 173 | erase_binding = 2 174 | 175 | # Sets the shape of the cursor drawn. 176 | # 0: VTE_CURSOR_SHAPE_BLOCK 177 | # 1: VTE_CURSOR_SHAPE_IBEAM 178 | # 2: VTE_CURSOR_SHAPE_UNDERLINE 179 | cursor_shape = 0 180 | 181 | # The default locale used when initing a vte terminal. 182 | # You may use "zh_TW", "zh_TW.Big5", or "zh_TW.UTF-8" here. 183 | default_locale = 184 | 185 | # The locales list on right click menu, separate with . 186 | # You may use "ja_JP", "ja_JP.EUC-JP", or "ja_JP.UTF-8" here. 187 | # You may want to use "UTF-8" here if you have no locale data installed. 188 | # Left it blank will disable locale and encoding select menu items. 189 | locales_list = UTF-8 190 | 191 | # Sets what type of terminal attempts to emulate. 192 | # It will also set the TERM environment. 193 | # Unless you are interested in this feature, always use "xterm". 194 | emulate_term = xterm 195 | 196 | # The environment 'VTE_CJK_WIDTH' used when initing a vte terminal. 197 | # 0: get via environment; 1: use narrow ideograph; 2: use wide ideograph. 198 | VTE_CJK_WIDTH = 1 199 | 200 | # The geometry of window when starting. 201 | # A reasonable example value is "80x24+0+0", 202 | # witch means "WIDTH x HEIGHT {+-} XOFFSET {+-} YOFFSET", and NO SPACE in it. 203 | # Notice that it will overwrite the default column and row settings above. 204 | geometry = 205 | 206 | 207 | [page] 208 | 209 | # The max character width of page name. 210 | page_width = 16 211 | 212 | # Show the tabs bar or not. 213 | # 0: Never shows the tabs ; 1: Always shows the tabs bar. 214 | # Left it blank: Hide when fullscreen, or tabs number = 1. 215 | show_tabs_bar = 216 | 217 | # Placement of new tabs on the tab bar. 218 | # 0: New tabs are placed as the last tab on the tab bar. 219 | # 1: New tabs are placed next to the current tab. 220 | new_tab_next_to_current = 1 221 | 222 | # The position of tabs bar. 223 | # 0: Top, 1: bottom. 224 | tabs_bar_position = 0 225 | 226 | # The label of tabs will fill the tab bar. 227 | fill_tabs_bar = 0 228 | 229 | # The page name used for a new page. 230 | page_name = Terminal 231 | 232 | # The page names list used for new pages, separate with . 233 | page_names = Terminal 234 | 235 | # Reuse the page name in the page names list. 236 | reuse_page_names = 1 237 | 238 | # Shows a (number no) on the page name. 239 | page_shows_number = 1 240 | 241 | # Shows the foreground running command on the page name. 242 | page_shows_current_cmdline = 1 243 | 244 | # Shows the terminal's idea of what the window's title should be. 245 | page_shows_window_title = 1 246 | 247 | # Shows current directory on the page name. 248 | page_shows_current_dir = 1 249 | 250 | # Check if the running command is root privileges. 251 | check_root_privileges = 1 252 | 253 | # Shows current encoding on the page name. 254 | page_shows_encoding = 1 255 | 256 | # Bold the text of current page name. 257 | bold_current_page_name = 1 258 | 259 | # Bold the text of action page name. 260 | bold_action_page_name = 1 261 | 262 | # Shows the page name of current page on window title. 263 | window_title_shows_current_page = 1 264 | 265 | # Append a package name (- LilyTerm) to the window title. 266 | window_title_append_package_name = 1 267 | 268 | # Shows a close button [X] on current tab. 269 | show_close_button_on_tab = 1 270 | 271 | # Shows a close button [X] on all tabs. 272 | show_close_button_on_all_tabs = 0 273 | 274 | # Use colorful text on page. 275 | use_color_page = 1 276 | 277 | # The color used for showing Window Title on page name. 278 | # You may use black, #000000 or #000000000000 here. 279 | page_win_title_color = #9A6401 280 | 281 | # The color used for showing Running Command on page name. 282 | # You may use black, #000000 or #000000000000 here. 283 | page_cmdline_color = #1C1CDC 284 | 285 | # The color used for showing Current Dir on page name. 286 | # You may use black, #000000 or #000000000000 here. 287 | page_dir_color = #215E3E 288 | 289 | # The color used for showing Custom Tab Name on page name. 290 | # You may use black, #000000 or #000000000000 here. 291 | page_custom_color = #9C0A81 292 | 293 | # The color used for showing Root Privileges on page name. 294 | # You may use black, #000000 or #000000000000 here. 295 | page_root_color = #BE0020 296 | 297 | # The color used for showing Normal Text on page name. 298 | # You may use black, #000000 or #000000000000 here. 299 | page_normal_color = #333333 300 | 301 | 302 | [key] 303 | 304 | # Disable/Enable hyperlinks, function keys and right click menu. 305 | # Left it blank to disable this function key. 306 | disable_key_binding = Ctrl grave 307 | 308 | # Add a new tab. 309 | # Left it blank to disable this function key. 310 | new_tab_key = Ctrl T 311 | 312 | # Close current tab. 313 | # Left it blank to disable this function key. 314 | close_tab_key = 315 | 316 | # Rename the page name of current tab. 317 | # Left it blank to disable this function key. 318 | edit_label_key = 319 | 320 | # Find the strings matching the search regex. 321 | # Left it blank to disable this function key. 322 | find_key = Ctrl F 323 | 324 | # Find the previous string matching the search regex. 325 | # Left it blank to disable this function key. 326 | find_key_prev = Shift F3 327 | 328 | # Find the next string matching the search regex. 329 | # Left it blank to disable this function key. 330 | find_key_next = F3 331 | 332 | # Switch to prev tab. 333 | # Left it blank to disable this function key. 334 | prev_tab_key = Ctrl Page_Up 335 | 336 | # Switch to next tab. 337 | # Left it blank to disable this function key. 338 | next_tab_key = Ctrl Page_Down 339 | 340 | # Switch to first tab. 341 | # Left it blank to disable this function key. 342 | first_tab_key = Ctrl Home 343 | 344 | # Switch to last tab. 345 | # Left it blank to disable this function key. 346 | last_tab_key = Ctrl End 347 | 348 | # Move current page forward. 349 | # Left it blank to disable this function key. 350 | move_tab_forward = Ctrl bracketleft 351 | 352 | # Move current page backward. 353 | # Left it blank to disable this function key. 354 | move_tab_backward = Ctrl bracketright 355 | 356 | # Move current page to first. 357 | # Left it blank to disable this function key. 358 | move_tab_first = Ctrl Up 359 | 360 | # Move current page to last. 361 | # Left it blank to disable this function key. 362 | move_tab_last = Ctrl Down 363 | 364 | # Switch to #1 tab directly. 365 | # Left it blank to disable this function key. 366 | switch_to_tab_1 = Ctrl F1 367 | 368 | # Switch to #2 tab directly. 369 | # Left it blank to disable this function key. 370 | switch_to_tab_2 = Ctrl F2 371 | 372 | # Switch to #3 tab directly. 373 | # Left it blank to disable this function key. 374 | switch_to_tab_3 = Ctrl F3 375 | 376 | # Switch to #4 tab directly. 377 | # Left it blank to disable this function key. 378 | switch_to_tab_4 = Ctrl F4 379 | 380 | # Switch to #5 tab directly. 381 | # Left it blank to disable this function key. 382 | switch_to_tab_5 = Ctrl F5 383 | 384 | # Switch to #6 tab directly. 385 | # Left it blank to disable this function key. 386 | switch_to_tab_6 = Ctrl F6 387 | 388 | # Switch to #7 tab directly. 389 | # Left it blank to disable this function key. 390 | switch_to_tab_7 = Ctrl F7 391 | 392 | # Switch to #8 tab directly. 393 | # Left it blank to disable this function key. 394 | switch_to_tab_8 = Ctrl F8 395 | 396 | # Switch to #9 tab directly. 397 | # Left it blank to disable this function key. 398 | switch_to_tab_9 = Ctrl F9 399 | 400 | # Switch to #10 tab directly. 401 | # Left it blank to disable this function key. 402 | switch_to_tab_10 = Ctrl F10 403 | 404 | # Switch to #11 tab directly. 405 | # Left it blank to disable this function key. 406 | switch_to_tab_11 = Ctrl F11 407 | 408 | # Switch to #12 tab directly. 409 | # Left it blank to disable this function key. 410 | switch_to_tab_12 = Ctrl F12 411 | 412 | # Open a new window with current dir. 413 | # Left it blank to disable this function key. 414 | new_window = 415 | 416 | # Select all the text in the Vte Terminal box. 417 | # Left it blank to disable this function key. 418 | select_all = Ctrl O 419 | 420 | # Copy the text to clipboard. 421 | # Left it blank to disable this function key. 422 | copy_clipboard = Ctrl Delete 423 | 424 | # Paste the text in clipboard. 425 | # Left it blank to disable this function key. 426 | paste_clipboard = Ctrl Insert 427 | 428 | # Paste the text in the primary clipboard. 429 | # Left it blank to disable this function key. 430 | paste_clipboard in primary = Shift Insert 431 | 432 | # Increase the font size of current tab. 433 | # Left it blank to disable this function key. 434 | increase_font_size = Ctrl equal 435 | 436 | # Decrease the font size of current tab. 437 | # Left it blank to disable this function key. 438 | decrease_font_size = Ctrl minus 439 | 440 | # Reset the font of current tab to original size. 441 | # Left it blank to disable this function key. 442 | reset_font_size = Ctrl Return 443 | 444 | # Try to maximize the window to use all available space on your display. 445 | # Left it blank to disable this function key. 446 | max_window = Alt F11 447 | 448 | # Asks to place window in the fullscreen/unfullscreen state. 449 | # Left it blank to disable this function key. 450 | full_screen = Alt Return 451 | 452 | # Emulate a mouse scroll up event on Vte Terminal box. 453 | # Left it blank to disable this function key. 454 | scroll_up = Shift Left 455 | 456 | # Emulate a mouse scroll down event on Vte Terminal box. 457 | # Left it blank to disable this function key. 458 | scroll_down = Shift Right 459 | 460 | # Asks to scroll up 1 line on Vte Terminal box. 461 | # Left it blank to disable this function key. 462 | scroll_up_1_line = Shift Up 463 | 464 | # Asks to scroll down 1 line on Vte Terminal box. 465 | # Left it blank to disable this function key. 466 | scroll_down_1_line = Shift Down 467 | 468 | 469 | [color] 470 | 471 | # The main ansi color theme used in vte. 472 | # Possible values are linux, xterm, rxvt, tango, grayscale or solarized. 473 | # or left it blank to use the default settings form libvte. 474 | theme = 475 | 476 | # Invert the ansi colors, like invert the darkred to red, darkblue to blue. 477 | invert_color = 0 478 | 479 | # The brightness for ansi colors used in terminal. 480 | brightness = 0.200 481 | 482 | # The brightness for ansi colors used in terminal when inactive. 483 | # Left it blank to disable this feature. 484 | inactive_brightness = -2.000 485 | 486 | # The ANSI color code for Normal Black 487 | # You may use black, #000000 or #000000000000 here. 488 | Color0 = 489 | 490 | # The ANSI color code for Normal Red 491 | # You may use black, #000000 or #000000000000 here. 492 | Color1 = 493 | 494 | # The ANSI color code for Normal Green 495 | # You may use black, #000000 or #000000000000 here. 496 | Color2 = 497 | 498 | # The ANSI color code for Normal Yellow 499 | # You may use black, #000000 or #000000000000 here. 500 | Color3 = 501 | 502 | # The ANSI color code for Normal Blue 503 | # You may use black, #000000 or #000000000000 here. 504 | Color4 = 505 | 506 | # The ANSI color code for Normal Magenta 507 | # You may use black, #000000 or #000000000000 here. 508 | Color5 = 509 | 510 | # The ANSI color code for Normal Cyan 511 | # You may use black, #000000 or #000000000000 here. 512 | Color6 = 513 | 514 | # The ANSI color code for Normal White 515 | # You may use black, #000000 or #000000000000 here. 516 | Color7 = 517 | 518 | # The ANSI color code for Bright Black 519 | # You may use black, #000000 or #000000000000 here. 520 | Color8 = 521 | 522 | # The ANSI color code for Bright Red 523 | # You may use black, #000000 or #000000000000 here. 524 | Color9 = 525 | 526 | # The ANSI color code for Bright Green 527 | # You may use black, #000000 or #000000000000 here. 528 | Color10 = 529 | 530 | # The ANSI color code for Bright Yellow 531 | # You may use black, #000000 or #000000000000 here. 532 | Color11 = 533 | 534 | # The ANSI color code for Bright Blue 535 | # You may use black, #000000 or #000000000000 here. 536 | Color12 = 537 | 538 | # The ANSI color code for Bright Magenta 539 | # You may use black, #000000 or #000000000000 here. 540 | Color13 = 541 | 542 | # The ANSI color code for Bright Cyan 543 | # You may use black, #000000 or #000000000000 here. 544 | Color14 = 545 | 546 | # The ANSI color code for Bright White 547 | # You may use black, #000000 or #000000000000 here. 548 | Color15 = 549 | 550 | 551 | [command] 552 | 553 | # The parameters of the APPLICATION should be separated with , if any. 554 | # 555 | # method = {0,1,2} 556 | # 0: Open the hyperlink in new tab. 557 | # Use it if the command were using CLI, like w3m. 558 | # 1: Open the hyperlink with gdk_spawn_on_screen_with_pipes(). 559 | # Use it if the command were using GUI, like chromium. 560 | # 2: Open the hyperlink in new window, 561 | # Use it if you not sure. 562 | # 563 | # VTE_CJK_WIDTH = {0,1,2} 564 | # 0: get via environment 565 | # 1: use narrow ideograph 566 | # 2: use wide ideograph. 567 | # 568 | # The ENVIRONS will apply to the application, separated with , too. 569 | # 570 | # The LOCALE will apply to the application as locale environs. 571 | # You may use "zh_TW", "zh_TW.Big5", or "zh_TW.UTF-8" here. 572 | # Left it blank to use the locale environs from current page. 573 | 574 | # The web browser using for http(s):// 575 | web_browser = xdg-open 576 | web_method = 1 577 | web_VTE_CJK_WIDTH = 0 578 | web_environ = 579 | web_locale = 580 | 581 | # The ftp client using for ftp(s):// 582 | ftp_client = xdg-open 583 | ftp_method = 1 584 | ftp_VTE_CJK_WIDTH = 0 585 | ftp_environ = 586 | ftp_locale = 587 | 588 | # The file manager using for file:// and [Open current directory with file manager] 589 | file_manager = xdg-open 590 | file_method = 1 591 | file_VTE_CJK_WIDTH = 0 592 | file_environ = 593 | file_locale = 594 | 595 | # The email client using for user@host 596 | email_client = xdg-open 597 | email_method = 1 598 | email_VTE_CJK_WIDTH = 0 599 | email_environ = 600 | email_locale = 601 | 602 | -------------------------------------------------------------------------------- /data/lilyterm.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=LilyTerm 3 | GenericName=Terminal 4 | Comment=A light and easy to use libvte based X Terminal Emulator 5 | Comment[zh_TW]=輕巧人性化、基於 libvte 的 X 終端機模擬程式 6 | Comment[de]=Leichtgewichtiger und benutzerfreundlicher, libvte-basierter Terminal emulator 7 | Comment[it]=Un emulatore di terminale per X basato su libvte, leggero e facile da usare 8 | Comment[ru]=Лёгкий и простой эмулятор терминала, основанный на libvte 9 | Comment[uk]=Легкий та простий емулятор терміналу, заснований на libvte 10 | Comment[nl]=Een lichte, eenvoudige en makkelijk te gebruiken X Terminal Emulator met als basis libvte 11 | Comment[tr]=libvte tabanlı hafif ve kolay kullanımlı bir X Terminal Öykünücüsü 12 | Comment[sk]=Odľahčený a ľahko použiteľný emulátor terminálu pre X, založený na libvte 13 | 14 | TryExec=lilyterm 15 | Exec=lilyterm 16 | Icon=lilyterm 17 | Type=Application 18 | Terminal=false 19 | Categories=GTK;Utility;System;TerminalEmulator; 20 | -------------------------------------------------------------------------------- /data/lilyterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tetralet/LilyTerm/faf1254f46049edfb1fd6e9191e78b1b23b9c51d/data/lilyterm.png -------------------------------------------------------------------------------- /data/lilyterm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LilyTerm 7 | lilyterm 8 | lilyterm %s 9 | terminal 10 | -e 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/lilyterm.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * favicon_xpm[] = { 3 | "32 32 109 2", 4 | " c None", 5 | ". c #A1A7B0", 6 | "+ c #9FA5AD", 7 | "@ c #A0A5AD", 8 | "# c #9FA4AD", 9 | "$ c #A0A4AD", 10 | "% c #A9ADB5", 11 | "& c #ADB1B8", 12 | "* c #ABAFB6", 13 | "= c #A1A5AC", 14 | "- c #9CA0A6", 15 | "; c #91959B", 16 | "> c #7A7E84", 17 | ", c #29292A", 18 | "' c #2F2F31", 19 | ") c #343435", 20 | "! c #353536", 21 | "~ c #2F2F30", 22 | "{ c #2A2A2A", 23 | "] c #252525", 24 | "^ c #212122", 25 | "/ c #1E1E1F", 26 | "( c #19191A", 27 | "_ c #989DA4", 28 | ": c #141414", 29 | "< c #797D84", 30 | "[ c #3A3A3B", 31 | "} c #474748", 32 | "| c #555556", 33 | "1 c #585859", 34 | "2 c #4B4B4D", 35 | "3 c #3E3E3F", 36 | "4 c #2A2A2C", 37 | "5 c #1F2021", 38 | "6 c #131313", 39 | "7 c #404041", 40 | "8 c #79797A", 41 | "9 c #808081", 42 | "0 c #636364", 43 | "a c #464647", 44 | "b c #383839", 45 | "c c #303031", 46 | "d c #2B2B2C", 47 | "e c #202021", 48 | "f c #7A7E85", 49 | "g c #424243", 50 | "h c #5E5E5F", 51 | "i c #868687", 52 | "j c #8D8D8E", 53 | "k c #6C6C6D", 54 | "l c #49494A", 55 | "m c #39393A", 56 | "n c #303032", 57 | "o c #2B2B2D", 58 | "p c #979CA3", 59 | "q c #121212", 60 | "r c #797E84", 61 | "s c #474749", 62 | "t c #515152", 63 | "u c #6B6B6C", 64 | "v c #717172", 65 | "w c #59595A", 66 | "x c #434344", 67 | "y c #373738", 68 | "z c #9A9FA7", 69 | "A c #181818", 70 | "B c #464648", 71 | "C c #4A4A4B", 72 | "D c #4C4C4D", 73 | "E c #444445", 74 | "F c #3A3A3C", 75 | "G c #333335", 76 | "H c #2E2E2F", 77 | "I c #2A2A2B", 78 | "J c #1F1F20", 79 | "K c #989CA4", 80 | "L c #7B7F85", 81 | "M c #434345", 82 | "N c #545456", 83 | "O c #373739", 84 | "P c #2E2E30", 85 | "Q c #282829", 86 | "R c #1E1E20", 87 | "S c #111111", 88 | "T c #83868D", 89 | "U c #393A3C", 90 | "V c #3A3B3D", 91 | "W c #494A4C", 92 | "X c #3D3E40", 93 | "Y c #38393B", 94 | "Z c #363739", 95 | "` c #343537", 96 | " . c #333436", 97 | ".. c #313234", 98 | "+. c #2E2F31", 99 | "@. c #979CA4", 100 | "#. c #8D9197", 101 | "$. c #909499", 102 | "%. c #8E9197", 103 | "&. c #8B8F94", 104 | "*. c #878C91", 105 | "=. c #8A8E94", 106 | "-. c #888C91", 107 | ";. c #86898E", 108 | ">. c #82868B", 109 | ",. c #7E8288", 110 | "'. c #81848A", 111 | "). c #7C7F84", 112 | "!. c #101010", 113 | " ", 114 | " ", 115 | " ", 116 | " ", 117 | " ", 118 | " ", 119 | " . . + + @ @ # # # # $ $ % % & & * * = = - - ; ; ", 120 | " . . + + @ @ # # # # $ $ % % & & * * = = - - ; ; ", 121 | " > > , , ' ' ) ) ! ! ~ ~ { { ] ] ^ ^ / / ( ( _ _ : : ", 122 | " > > , , ' ' ) ) ! ! ~ ~ { { ] ] ^ ^ / / ( ( _ _ : : ", 123 | " < < [ [ } } | | 1 1 2 2 3 3 ! ! ~ ~ 4 4 5 5 _ _ 6 6 ", 124 | " < < [ [ } } | | 1 1 2 2 3 3 ! ! ~ ~ 4 4 5 5 _ _ 6 6 ", 125 | " < < 7 7 1 1 8 8 9 9 0 0 a a b b c c d d e e _ _ 6 6 ", 126 | " < < 7 7 1 1 8 8 9 9 0 0 a a b b c c d d e e _ _ 6 6 ", 127 | " f f g g h h i i j j k k l l m m n n o o e e p p q q ", 128 | " f f g g h h i i j j k k l l m m n n o o e e p p q q ", 129 | " r r s s t t u u v v w w x x y y ' ' d d e e z z A A ", 130 | " r r s s t t u u v v w w x x y y ' ' d d e e z z A A ", 131 | " < < B B v v C C D D E E F F G G H H I I J J K K 6 6 ", 132 | " < < B B v v C C D D E E F F G G H H I I J J K K 6 6 ", 133 | " L L D D M M N N g g O O G G P P d d Q Q R R p p S S ", 134 | " L L D D M M N N g g O O G G P P d d Q Q R R p p S S ", 135 | " T T U U V V W W X X Y Y Z Z ` ` . .....+.+.@.@.q q ", 136 | " T T U U V V W W X X Y Y Z Z ` ` . .....+.+.@.@.q q ", 137 | " #.#.$.$.%.%.&.&.*.*.=.=.-.-.;.;.>.>.,.,.'.'.).).!.!. ", 138 | " #.#.$.$.%.%.&.&.*.*.=.=.-.-.;.;.>.>.,.,.'.'.).).!.!. ", 139 | " ", 140 | " ", 141 | " ", 142 | " ", 143 | " ", 144 | " "}; 145 | -------------------------------------------------------------------------------- /po/Makefile: -------------------------------------------------------------------------------- 1 | include ../.default 2 | -include ../.config 3 | 4 | ifeq ($(VERBOSITY), Y) 5 | VERBOSITY_OUTPUT = 6 | else 7 | VERBOSITY_OUTPUT = @ 8 | endif 9 | 10 | 11 | PO_LIST ?= $(LANG_LIST:=.po) 12 | MO_LIST ?= $(LANG_LIST:=.mo) 13 | 14 | XGETTEXT := $(shell whereis "xgettext" | tr -s ' ' '\n' | grep "bin/""xgettext""$$" | head -n 1) 15 | ifneq ($(XGETTEXT), ) 16 | 17 | XGETTEXT_PARAMETER = -k_ 18 | 19 | SUPPORT_FROM_CODE = $(shell $(XGETTEXT) --help | grep -q -- '--from-code' && echo Y) 20 | ifeq ($(SUPPORT_FROM_CODE), Y) 21 | XGETTEXT_PARAMETER += --from-code=UTF-8 22 | endif 23 | 24 | SUPPORT_COPYRIGHT_HOLDER = $(shell $(XGETTEXT) --help | grep -q -- '--copyright-holder' && echo Y) 25 | ifeq ($(SUPPORT_COPYRIGHT_HOLDER), Y) 26 | XGETTEXT_PARAMETER += --copyright-holder="$(YEAR) FULL NAME " 27 | endif 28 | 29 | SUPPORT_PACKAGE_NAME = $(shell $(XGETTEXT) --help | grep -q -- '--package-name' && echo Y) 30 | ifeq ($(SUPPORT_PACKAGE_NAME), Y) 31 | XGETTEXT_PARAMETER += --package-name=$(PACKAGE) 32 | endif 33 | 34 | SUPPORT_PACKAGE_VERSION = $(shell $(XGETTEXT) --help | grep -q -- '--package-version' && echo Y) 35 | ifeq ($(SUPPORT_PACKAGE_VERSION), Y) 36 | XGETTEXT_PARAMETER += --package-version="$(VER)" 37 | endif 38 | 39 | endif 40 | 41 | MSGCMP := $(shell whereis "msgcmp" | tr -s ' ' '\n' | grep "bin/""msgcmp""$$" | head -n 1) 42 | ifneq ($(MSGCMP), ) 43 | 44 | SUPPORT_USE_UNTRANSLATED = $(shell $(MSGCMP) --help | grep -q -- '--use-untranslated' && echo Y) 45 | ifeq ($(SUPPORT_USE_UNTRANSLATED), Y) 46 | MSGCMP_PARAMETER += --use-untranslated 47 | endif 48 | 49 | endif 50 | 51 | MSGMERGE := $(shell whereis "msgmerge" | tr -s ' ' '\n' | grep "bin/""msgmerge""$$" | head -n 1) 52 | ifneq ($(MSGMERGE), ) 53 | 54 | SUPPORT_PREVIOUS = $(shell $(MSGMERGE) --help | grep -q -- '--previous' && echo Y) 55 | ifeq ($(SUPPORT_PREVIOUS), Y) 56 | MSGMERGE_PARAMETER += --previous 57 | endif 58 | 59 | endif 60 | 61 | MSGFMT := $(shell whereis "msgfmt" | tr -s ' ' '\n' | grep "bin/""msgfmt""$$" | head -n 1) 62 | TOUCH := $(shell whereis "touch" | tr -s ' ' '\n' | grep "bin/""touch""$$" | head -n 1) 63 | 64 | .PHONY: all 65 | all: $(MO_LIST) 66 | 67 | .PHONY: update-po 68 | update-po: pot $(PO_LIST) 69 | 70 | .PHONY: pot 71 | pot: 72 | ifeq ($(XGETTEXT), ) 73 | @ $(PRINTF) "\033[1;31mERROR: '\033[1;32mxgettext\033[1;31m' command can NOT found!\033[0m\n" 74 | @ $(PRINTF) "\033[1;31mERROR: \033[1;32mgettext\033[1;31m package is needed to make pot. ABORT!\033[0m\n" 75 | @ exit 1 76 | endif 77 | ifeq ($(MSGCMP), ) 78 | @ $(PRINTF) "\033[1;31mERROR: '\033[1;32mmsgcmp\033[1;31m' command can NOT found!\033[0m\n" 79 | @ $(PRINTF) "\033[1;31mERROR: \033[1;32mgettext\033[1;31m package is needed to make pot. ABORT!\033[0m\n" 80 | @ exit 1 81 | endif 82 | @ cd ../src ; \ 83 | $(XGETTEXT) $(XGETTEXT_PARAMETER) --add-comments='TRANSLATE NOTE:' -o ../po/$(BINARY).po *.c 84 | @# echo '' >> $(BINARY).po 85 | @# echo 'msgid "A light and easy to use libvte based X Terminal Emulator"' >> $(BINARY).po 86 | @# echo 'msgstr ""' >> $(BINARY).po 87 | @ if ($(MSGCMP) $(MSGCMP_PARAMETER) $(BINARY).pot $(BINARY).po > /dev/null 2>&1) then \ 88 | rm $(BINARY).po ; \ 89 | else \ 90 | $(PRINTF) "\033[1;36m** creating \033[1;32m$(BINARY).pot\033[1;36m ...\033[0m\n" ; \ 91 | mv $(BINARY).po $(BINARY).pot ; \ 92 | echo "" ; \ 93 | fi 94 | 95 | $(BINARY).pot: pot 96 | 97 | .PHONY: reset 98 | reset: 99 | @ $(TOUCH) $(BINARY).pot 100 | 101 | .PHONY: po 102 | po: $(PO_LIST) 103 | 104 | %.po: $(BINARY).pot 105 | ifeq ($(MSGMERGE), ) 106 | @ $(PRINTF) "\033[1;31mERROR: '\033[1;32mmsgmerge\033[1;31m' command can NOT found!\033[0m\n" 107 | @ $(PRINTF) "\033[1;31mERROR: \033[1;32mgettext\033[1;31m package is needed to make po files. ABORT!\033[0m\n" 108 | @ exit 1 109 | endif 110 | @ $(PRINTF) "\033[1;33m** msgmerge \033[1;32m$@\033[1;33m ...\033[0m\n" 111 | -$(VERBOSITY_OUTPUT) $(MSGMERGE) $(MSGMERGE_PARAMETER) $@ $< -o $@ 112 | 113 | %.mo: %.po $(BINARY).pot 114 | ifeq ($(MSGFMT), ) 115 | @ $(PRINTF) "\033[1;31mERROR: '\033[1;32mmsgfmt\033[1;31m' command can NOT found!\033[0m\n" 116 | @ $(PRINTF) "\033[1;31mERROR: \033[1;32mgettext\033[1;31m package is needed to make mo files. ABORT!\033[0m\n" 117 | @ exit 1 118 | endif 119 | @ $(PRINTF) "\033[1;33m** creating \033[1;32m$@\033[1;33m ...\033[0m\n" 120 | -$(VERBOSITY_OUTPUT) $(MSGFMT) --check --statistics $< -o $@ 121 | 122 | .PHONY: clean 123 | clean: 124 | @ for FILE in $(MO_LIST); do \ 125 | if [ -f $$FILE ]; then \ 126 | $(PRINTF) "\033[1;35m** deleting \033[1;32m$$FILE\033[1;35m...\033[0m\n" ; \ 127 | rm $$FILE ; \ 128 | fi ; \ 129 | done 130 | 131 | .PHONY: install 132 | install: all 133 | @ for FILE in $(LANG_LIST); do \ 134 | if [ -f $$FILE.mo ]; then \ 135 | install -d $(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/ ; \ 136 | $(PRINTF) "\033[1;33m** installing \033[1;32m$$FILE.mo\033[1;33m to \033[1;34m$(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/\033[1;32m ...\033[0m\n" ; \ 137 | install -m 644 $$FILE.mo $(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/$(BINARY).mo ; \ 138 | fi ; \ 139 | done 140 | 141 | .PHONY: uninstall 142 | uninstall: 143 | @ - for FILE in $(LANG_LIST); do \ 144 | if [ -f $(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/$(BINARY).mo ]; then \ 145 | $(PRINTF) "\033[1;35m** \033[1;32mdeleting $(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/$(BINARY).mo\033[1;35m ...\033[0m\n" ; \ 146 | rm "$(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/$(BINARY).mo" ; \ 147 | DirName="$(DESTDIR)/$(LOCALEDIR)/$$FILE/LC_MESSAGES/" ; \ 148 | until [ -n "`ls -A $$DirName`" -o "$$DirName" = "$(DESTDIR)/$(PREFIX)" ]; do \ 149 | $(PRINTF) "\033[1;35m** deleting directory \033[1;34m$$DirName\033[1;35m ...\033[0m\n" ; \ 150 | rmdir "$$DirName" ; \ 151 | DirName=`dirname $$DirName` ; \ 152 | done \ 153 | else \ 154 | $(PRINTF) "\033[1;31m** \033[1;32m$(DESTDIR)/$(LOCALEDIR)/$$FILE\033[1;31m is NOT exist!\033[0m\n" ; \ 155 | fi ; \ 156 | done 157 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | src/console.c 2 | src/window.c 3 | src/profile.c 4 | src/dialog.c 5 | src/main.c 6 | src/menu.c 7 | src/notebook.c 8 | src/misc.c 9 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # This is a sample Makefile for debuging LilyTerm. 2 | # 3 | # Usage: 4 | # make clean: delete lilyterm binary files. 5 | # make debug: compile lilyeterm_dbg with CLAGS -g. 6 | # make dev: compile lilyeterm_dev with CLAGS -g. 7 | # make vdev: compile lilyeterm_dev with full compiling command message. 8 | # make ddev: compile lilyeterm_dev with -DSAFEMODE compile option. 9 | # make ut: run a tiny unit testing script with gdb debug information. 10 | # make uto: build *.o binary files for using in the unit testing programs. 11 | # make utb: build the the unit testing programs only. 12 | # make utd: run a tiny unit testing script with full runtime debug information. 13 | # make utf: run a tiny unit testing script with glib, gtk, gdb and valgrind debug information. 14 | # make geometry: compile lilyeterm_dev with geometry debug information. 15 | # make pagename: compile lilyeterm_dev with pagename debug information. 16 | # make detail: compile lilyeterm_dev with detail runtime debug information. 17 | # make full: compile lilyeterm_dev with full runtime debug information. 18 | # make memory: compile lilyeterm_dev for memory lack testing. 19 | # make data: compile po and $(BINARY).conf files. 20 | # 21 | # grep 'g_debug *( *" *[^\!@+\?-]' * | grep -v '\/\/' 22 | # (\(console\|dialog\|font\|main\|menu\|misc\|notebook\|pagename\|profile\|property\|window\|socket\).c:[0-9]*) 23 | # MANWIDTH=80 man data/lilyterm.1 | col -b > README 24 | 25 | include ../.default 26 | -include ../.config 27 | 28 | PKGCONFIG := $(shell whereis "pkg-config" | tr -s ' ' '\n' | grep "bin/""pkg-config""$$" | head -n 1) 29 | STRIP := $(shell whereis "strip" | tr -s ' ' '\n' | grep "bin/""strip""$$" | head -n 1) 30 | 31 | VTE ?= 32 | 33 | ifneq ($(PKGCONFIG), ) 34 | 35 | ifeq ($(VTE), vte) 36 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-2.0' && $(ECHO) 'gtk+-2.0') 37 | endif 38 | ifeq ($(VTE), vte-2.91) 39 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-3.0' && $(ECHO) 'gtk+-3.0') 40 | endif 41 | ifeq ($(VTE), vte-2.90) 42 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-3.0' && $(ECHO) 'gtk+-3.0') 43 | endif 44 | ifeq ($(VTE), ) 45 | VTE := $(shell $(PKGCONFIG) --exists 'vte' && $(ECHO) 'vte') 46 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-2.0' && $(ECHO) 'gtk+-2.0') 47 | endif 48 | ifeq ($(VTE), ) 49 | VTE := $(shell $(PKGCONFIG) --exists 'vte-2.91' && $(ECHO) 'vte-2.91') 50 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-3.0' && $(ECHO) 'gtk+-3.0') 51 | endif 52 | ifeq ($(VTE), ) 53 | VTE := $(shell $(PKGCONFIG) --exists 'vte-2.90' && $(ECHO) 'vte-2.90') 54 | GTK := $(shell $(PKGCONFIG) --exists 'gtk+-3.0' && $(ECHO) 'gtk+-3.0') 55 | endif 56 | 57 | endif 58 | 59 | BINDIR = $(PREFIX)/bin 60 | date = `date +%Y-%m-%d` 61 | CC ?= gcc 62 | CFLAGS ?= -Wall -Werror -Os 63 | #CFLAGS = $$CFLAGS -Wall -Wextra -Os -std=c99 \ 64 | # -DG_DISABLE_DEPRECATED \ 65 | # -DG_DISABLE_SINGLE_INCLUDES -DGDK_DISABLE_DEPRECATED \ 66 | # -DGDK_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED \ 67 | # -DGTK_DISABLE_SINGLE_INCLUDES -DGSEAL_ENABLE 68 | LDFLAGS += -L$(prefix)/local/lib 69 | ifeq ($(VTE), vte-2.91) 70 | LDFLAGS += -lX11 71 | endif 72 | OBJ_PKG_CMD = $(PKGCONFIG) --cflags $(GTK) $(VTE) 73 | BINARY_PKG_CMD = $(PKGCONFIG) --cflags --libs $(GTK) $(VTE) 74 | SOURCE_FILES = socket.c menu.c profile.c dialog.c pagename.c notebook.c font.c \ 75 | property.c window.c misc.c console.c main.c 76 | OBJ = $(SOURCE_FILES:.c=.o) 77 | 78 | AUTHOR_CONVERT = $(shell echo "$(AUTHOR)" | sed -e 's/\([ ()]\)/\\\1/g') 79 | 80 | INCLUDES = -DBINARY=\"$(BINARY)\" \ 81 | -DPACKAGE=\"$(PACKAGE)\" \ 82 | -DBUGREPORT=\"$(BUGREPORT)\" \ 83 | -DMAINSITE=\"$(MAINSITE)\" \ 84 | -DGITHUBURL=\"$(GITHUBURL)\" \ 85 | -DBLOG=\"$(BLOG)\" \ 86 | -DWIKI=\"$(WIKI)\" \ 87 | -DISSUES=\"$(ISSUES)\" \ 88 | -DIRC=\"$(IRC)\" \ 89 | -DYEAR=\"$(YEAR)\" \ 90 | -DETCDIR=\"$(ETCDIR)\" \ 91 | -DLOCALEDIR=\"$(LOCALEDIR)\" \ 92 | -DICONDIR=\"$(ICONDIR)\" 93 | 94 | ifeq ($(BSD), 1) 95 | INCLUDES += -DBSD 96 | endif 97 | ifeq ($(VERBOSITY), Y) 98 | VERBOSITY_OUTPUT = 99 | else 100 | VERBOSITY_OUTPUT = @ 101 | endif 102 | 103 | .PHONY: all 104 | all: default 105 | ifeq ($(DEBUG), N) 106 | @ $(PRINTF) "\033[1;36m** striping \033[1;32m$(BINARY)\033[1;36m ...\033[0m\n" 107 | $(VERBOSITY_OUTPUT) $(STRIP) --remove-section=.comment --remove-section=.note $(BINARY) 108 | endif 109 | 110 | .PHONY: default 111 | ifneq ($(SAFEMODE), N) 112 | default: CFLAGS += -DSAFEMODE 113 | else 114 | default: CFLAGS += -DREALMODE 115 | endif 116 | default: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DVERSION=\"$(VERSION)\ \($(date)\)\" 117 | ifeq ($(DEBUG), Y) 118 | default: INCLUDES += -DDEBUG -DFATAL 119 | endif 120 | default: $(BINARY) 121 | 122 | .PHONY: debug 123 | debug: CFLAGS := $(CFLAGS) -g 124 | debug: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DREALMODE -DDEBUG -DFATAL -DFORCE_ENABLE_VTE_BACKGROUND -DVERSION=\"$(VERSION)\ Debug\ Version\ \($(date)\)\" 125 | debug: BINARY := $(BINARY)_dbg 126 | debug: $(BINARY) 127 | 128 | .PHONY: dev 129 | dev: develop 130 | .PHONY: develop 131 | # develop: CFLAGS := -pedantic -pipe -fno-common -W -Wall -Wcast-align -Wformat=2 -Wpointer-arith -Wundef -Waggregate-return -Wcast-qual -Wmissing-declarations -Wnested-externs -Wstrict-prototypes -O3 -g 132 | develop: CFLAGS := $(CFLAGS) -g 133 | develop: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DREALMODE -DDEBUG -DFATAL -DFORCE_ENABLE_VTE_BACKGROUND -DDEVELOP -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 134 | develop: BINARY := $(BINARY)_dev 135 | develop: $(BINARY) 136 | 137 | .PHONY: vdev 138 | vdev: verbosity-output 139 | .PHONY: verbosity-output 140 | verbosity-output: VERBOSITY_OUTPUT := 141 | verbosity-output: develop 142 | 143 | .PHONY: ddev 144 | ddev: defensive-develop 145 | .PHONY: defensive-develop 146 | defensive-develop: CFLAGS := $(CFLAGS) -g 147 | defensive-develop: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 148 | defensive-develop: BINARY := $(BINARY)_dev 149 | defensive-develop: $(BINARY) 150 | 151 | .PHONY: detail 152 | detail: CFLAGS := $(CFLAGS) -g 153 | detail: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DGEOMETRY -DPAGENAME -DREALMODE -DDEBUG -DFATAL -DDEVELOP -DDETAIL -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 154 | detail: BINARY := $(BINARY)_dev 155 | detail: $(BINARY) 156 | 157 | .PHONY: full 158 | full: CFLAGS = -Wall -Werror -Wformat -Wformat-security -Werror=format-security -Os -g 159 | full: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DGEOMETRY -DPAGENAME -DREALMODE -DDEBUG -DFATAL -DDEVELOP -DDETAIL -DFULL -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 160 | full: BINARY := $(BINARY)_dev 161 | full: $(BINARY) 162 | 163 | .PHONY: geometry 164 | geometry: CFLAGS := $(CFLAGS) -g 165 | geometry: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DGEOMETRY -DREALMODE -DDEBUG -DFATAL -DDEVELOP -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 166 | geometry: BINARY := $(BINARY)_dev 167 | geometry: $(BINARY) 168 | 169 | .PHONY: pagename 170 | pagename: CFLAGS := $(CFLAGS) -g 171 | pagename: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DPAGENAME -DREALMODE -DDEBUG -DFATAL -DDEVELOP -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 172 | pagename: BINARY := $(BINARY)_dev 173 | pagename: $(BINARY) 174 | 175 | .PHONY: ut 176 | ut: unit_test 177 | .PHONY: unit_test 178 | unit_test: CFLAGS := $(CFLAGS) -g 179 | unit_test: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(PACKAGE)\" -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DUNIT_TEST -DVERSION=\"$(VERSION)_UNIT_TEST_$(date)\" 180 | unit_test: $(OBJ) 181 | @ sh unit_test.sh "$(INCLUDES)" --enable-gdb --test_all 182 | 183 | .PHONY: uto 184 | uto: unit_test_object 185 | .PHONY: unit_test_object 186 | unit_test_object: CFLAGS := $(CFLAGS) -g 187 | unit_test_object: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(PACKAGE)\" -DGEOMETRY -DPAGENAME -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DDETAIL -DFULL -DUNIT_TEST -DVERSION=\"$(VERSION)_UNIT_TEST_$(date)\" 188 | unit_test_object: $(OBJ) 189 | 190 | .PHONY: utb 191 | utb: unit_test_build 192 | .PHONY: unit_test_build 193 | unit_test_build: CFLAGS := $(CFLAGS) -g 194 | unit_test_build: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(PACKAGE)\" -DGEOMETRY -DPAGENAME -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DDETAIL -DFULL -DUNIT_TEST -DVERSION=\"$(VERSION)_UNIT_TEST_$(date)\" 195 | unit_test_build: $(OBJ) 196 | @ sh unit_test.sh "$(INCLUDES)" --build_program_only 197 | 198 | .PHONY: utd 199 | utd: unit_test_debug 200 | .PHONY: unit_test_debug 201 | unit_test_debug: CFLAGS := $(CFLAGS) -g 202 | unit_test_debug: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(PACKAGE)\" -DGEOMETRY -DPAGENAME -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DDETAIL -DFULL -DUNIT_TEST -DVERSION=\"$(VERSION)_UNIT_TEST_$(date)\" 203 | unit_test_debug: $(OBJ) 204 | @ sh unit_test.sh "$(INCLUDES)" --enable-glib-debugger --enable-gtk-debugger --enable-gdb 205 | 206 | .PHONY: utf 207 | utf: unit_test_full 208 | .PHONY: unit_test_full 209 | unit_test_full: CFLAGS := $(CFLAGS) -g 210 | unit_test_full: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(PACKAGE)\" -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DUNIT_TEST -DVERSION=\"$(VERSION)_UNIT_TEST_$(date)\" 211 | unit_test_full: $(OBJ) 212 | @ sh unit_test.sh "$(INCLUDES)" --enable-glib-debugger --enable-gtk-debugger --enable-gdb --enable-valgrind 213 | 214 | .PHONY: memory 215 | memory: CFLAGS = -Wall -Wformat -Wformat-security -Werror=format-security -O2 216 | memory: INCLUDES := $(INCLUDES) -DAUTHOR=\"$(AUTHOR_CONVERT)\" -DSAFEMODE -DDEBUG -DFATAL -DDEVELOP -DOUT_OF_MEMORY -DVERSION=\"$(VERSION)\ Develop\ Version\ \($(date)\)\" 217 | memory: BINARY := $(BINARY)_dev 218 | memory: $(BINARY) 219 | 220 | .PHONY: clean 221 | clean: 222 | -@ for FileName in $(BINARY) $(BINARY)_dev $(BINARY)_dbg $(OBJ) unit_test unit_test.[co] gdb_batch gdb.log valgrind.log vgcore.*; \ 223 | do \ 224 | if [ -f "$$FileName" ]; then \ 225 | $(PRINTF) "\033[1;35m** deleting \033[1;32m$$FileName\033[1;35m ...\033[0m\n"; \ 226 | rm "$$FileName"; \ 227 | fi; \ 228 | done 229 | 230 | %.o: %.c %.h data.h $(BINARY).h 231 | @ $(PRINTF) "\033[1;33m** compiling \033[1;32m$@\033[1;33m ...\033[0m\n" 232 | $(VERBOSITY_OUTPUT) $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c $< `$(OBJ_PKG_CMD)` 233 | 234 | $(BINARY): $(OBJ) 235 | @ $(PRINTF) "\033[1;36m** compiling \033[1;32m$(BINARY)\033[1;36m ...\033[0m\n" 236 | $(VERBOSITY_OUTPUT) $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -o $(BINARY) $(OBJ) `$(BINARY_PKG_CMD)` 237 | 238 | .PHONY: data 239 | data: debug 240 | @ $(MAKE) -C ../po po 241 | 242 | .PHONY: install 243 | install: $(BINARY) 244 | @ install -d $(DESTDIR)/$(BINDIR) 245 | @ if [ -f $(BINARY) ]; then \ 246 | $(PRINTF) "\033[1;33m** installing \033[1;32m$(BINARY)\033[1;33m to \033[1;34m$(DESTDIR)/$(BINDIR)\033[1;33m ...\033[0m\n" ; \ 247 | install -m 755 $(BINARY) $(DESTDIR)/$(BINDIR) ; \ 248 | fi ; \ 249 | 250 | .PHONY: uninstall 251 | uninstall: 252 | @ - if [ -f $(DESTDIR)/$(BINDIR)/$(BINARY) ]; then \ 253 | $(PRINTF) "\033[1;35m** deleting \033[1;32m$(DESTDIR)/$(BINDIR)/$(BINARY)\033[1;35m ...\033[0m\n" ; \ 254 | rm "$(DESTDIR)/$(BINDIR)/$(BINARY)" ; \ 255 | DirName="$(DESTDIR)/$(BINDIR)" ; \ 256 | until [ -n "`ls -A $$DirName`" -o "$$DirName" = "$(DESTDIR)/$(PREFIX)" ]; do \ 257 | $(PRINTF) "\033[1;35m** deleting directory \033[1;34m$$DirName\033[1;35m ...\033[0m\n" ; \ 258 | rmdir "$$DirName" ; \ 259 | DirName=`dirname $$DirName` ; \ 260 | done \ 261 | else \ 262 | $(PRINTF) "\033[1;31m** \033[1;32m$(DESTDIR)/$(BINDIR)/$(BINARY)\033[1;31m is NOT exist!\033[0m\n" ; \ 263 | fi 264 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = -DICONDIR=\"$(datadir)/pixmaps\" -DETCDIR=\"$(sysconfdir)/xdg\" 2 | 3 | bin_PROGRAMS = $_BINARY 4 | lilyterm_CFLAGS = $(GTK_CFLAGS) $(vte_CFLAGS) 5 | lilyterm_LDADD = $(GTK_LIBS) $(vte_LIBS) $(INTLLIBS) 6 | lilyterm_SOURCES = data.h lilyterm.h \ 7 | socket.h socket.c \ 8 | misc.h misc.c \ 9 | console.h console.c \ 10 | menu.h menu.c \ 11 | profile.h profile.c \ 12 | property.h property.c \ 13 | dialog.h dialog.c \ 14 | pagename.h pagename.c \ 15 | notebook.h notebook.c \ 16 | font.h font.c \ 17 | window.h window.c \ 18 | main.h main.c 19 | 20 | -------------------------------------------------------------------------------- /src/console.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include "console.h" 21 | 22 | extern gboolean single_process; 23 | extern gchar *profile_dir; 24 | 25 | void command_option(int argc, 26 | char *argv[]) 27 | { 28 | #ifdef DETAIL 29 | g_debug("! Launch command_option()!"); 30 | #endif 31 | 32 | #ifdef SAFEMODE 33 | if (argv==NULL) return; 34 | #endif 35 | gint i; 36 | for (i=0; istr); 55 | // g_string_free (help_msg, TRUE); 56 | 57 | exit (0); 58 | } 59 | else if ((!strcmp(argv[i], "-p")) || (!strcmp(argv[i], "--profile"))) 60 | { 61 | #ifdef ENABLE_PROFILE 62 | GString *settings = save_user_settings(NULL, NULL); 63 | # ifdef SAFEMODE 64 | if (settings) 65 | # endif 66 | g_print("%s", settings->str); 67 | g_string_free(settings, TRUE); 68 | #else 69 | g_critical(_("You should upgrade to %s and recompile %s to support this feature."), ENABLE_PROFILE_VER, PACKAGE); 70 | #endif 71 | exit (0); 72 | } 73 | else if ((!strcmp(argv[i], "-s")) || (!strcmp(argv[i], "--separate"))) 74 | { 75 | single_process = FALSE; 76 | } 77 | else if ((!strcmp(argv[i], "-e")) || (!strcmp(argv[i], "-x")) || 78 | (!strcmp(argv[i], "-E")) || (!strcmp(argv[i], "-X")) || (!strcmp(argv[i], "--execute"))) 79 | { 80 | // If -e or -x options specified then ignore anything beyond them 81 | break; 82 | } 83 | else if (!strcmp(argv[i], "--name")) 84 | { 85 | if (++i==argc) 86 | g_critical("missing program name after --name!\n"); 87 | else 88 | { 89 | extern gchar *wmclass_name; 90 | wmclass_name = argv[i]; 91 | } 92 | } 93 | else if (!strcmp(argv[i], "--class")) 94 | { 95 | if (++i==argc) 96 | g_critical("missing program class after --class!\n"); 97 | else 98 | { 99 | extern gchar *wmclass_class; 100 | wmclass_class = argv[i]; 101 | } 102 | } 103 | } 104 | } 105 | 106 | // It will be ok if profile=NULL here. 107 | gchar *get_help_message(gchar *profile) 108 | { 109 | #ifdef DETAIL 110 | g_debug("! Launch get_help_message()!"); 111 | #endif 112 | GString *help_message = g_string_new(NULL); 113 | gchar *usage = get_help_message_usage(profile, FALSE); 114 | #ifdef SAFEMODE 115 | if (usage) 116 | #endif 117 | g_string_append(help_message, usage); 118 | 119 | gchar *key_binding = get_help_message_key_binding(FALSE); 120 | #ifdef SAFEMODE 121 | if (key_binding) 122 | #endif 123 | g_string_append(help_message, key_binding); 124 | 125 | g_string_append(help_message, "\n"); 126 | g_string_append_printf(help_message, _("Please report bug at <%s>.\n"), ISSUES); 127 | g_string_append_printf(help_message, _("Thank you for using %s!"), PACKAGE); 128 | g_string_append(help_message, "\n"); 129 | g_free(usage); 130 | g_free(key_binding); 131 | return g_string_free(help_message, FALSE); 132 | } 133 | 134 | // It will be ok if profile=NULL here. 135 | gchar *get_help_message_usage(gchar *profile, gboolean convert_to_html) 136 | { 137 | #ifdef DETAIL 138 | g_debug("! Launch get_help_message_usage() with profile = %s, convert_to_html = %d!", 139 | profile, convert_to_html); 140 | #endif 141 | GString *help_message = g_string_new(NULL); 142 | 143 | // TRANSLATE NOTE: Please be care of the length of the following usage translation, 144 | // TRANSLATE NOTE: It should be shorter than 80 columns. 145 | g_string_append_printf(help_message, _("%s is a libvte based X Terminal Emulator.\n\n"), PACKAGE); 146 | g_string_append(help_message, _("Use -T/--title {title} to specify the window title.\n")); 147 | g_string_append(help_message, _("Use -R/--role {role} to specify the WM_WINDOW_ROLE string of window.\n")); 148 | g_string_append(help_message, _("Use -t/--tab {number} to open multi tabs when starting up.\n")); 149 | g_string_append(help_message, _("Use -n/--tab_names {tab names} to specify tab names, separate with .\n")); 150 | g_string_append(help_message, _("Use -d/--directory {directory} to specify the init directory when starting up.\n")); 151 | g_string_append(help_message, _("Use -g/--geometry {WIDTHxHEIGHT[+-]XOFFSET[+-]YOFFSET} to specify the geometry.\n")); 152 | g_string_append(help_message, _("Use -l/-ls/--login to make the shell invoked as a login shell.\n")); 153 | g_string_append(help_message, _("Use -ut to disable recording the session in lastlog, utmp and wtmp.\n")); 154 | g_string_append(help_message, _("Use -H/--hold to hold the terminal window open when -e/-x command terminated.\n")); 155 | // g_string_append(help_message, _("\t\t\tThis option will be ignored when using with -e/-x/--execute option.\n")); 156 | g_string_append(help_message, _("Use -s/--separate to run in separate process.\n")); 157 | g_string_append(help_message, _("Use -j/--join to integrate new created tabs to the last accessed window.\n")); 158 | g_string_append(help_message, _("Use -J to disable integrating new created tabs to the last accessed window.\n")); 159 | g_string_append(help_message, _("Use -p/--profile to get a profile sample.\n")); 160 | g_string_append_printf(help_message, 161 | _("Use -u/--user_profile {%s} to use a specified profile.\n"), PROFILE); 162 | g_string_append(help_message, _("Use -v/--version to show the version information.\n")); 163 | g_string_append(help_message, _("Use -e/-x/--execute {Command} to run a command. (Must be the final option).\n")); 164 | g_string_append(help_message, _("Use -E/-X {Command} to run a command without showing a comfirm dialog window.\n\n")); 165 | g_string_append_printf(help_message, 166 | _("The %s system configure file is: %s\n"), PACKAGE, SYS_PROFILE); 167 | 168 | gchar *current_profile = NULL; 169 | // g_debug("get_help_message_usage(): profile = %s", profile); 170 | if (profile) 171 | current_profile = g_strdup(profile); 172 | else 173 | current_profile = g_strdup_printf("%s/%s", profile_dir, USER_PROFILE); 174 | #ifdef SAFEMODE 175 | if (current_profile) 176 | { 177 | #endif 178 | if (convert_to_html) 179 | { 180 | gchar *msg_str = g_string_free(help_message, FALSE); 181 | gchar *new_help_message = convert_text_to_html (&msg_str, TRUE, NULL, "tt", NULL); 182 | #ifdef SAFEMODE 183 | if (new_help_message) 184 | #endif 185 | help_message = g_string_new(new_help_message); 186 | #ifdef SAFEMODE 187 | else 188 | help_message = g_string_new(""); 189 | #endif 190 | g_free(new_help_message); 191 | current_profile = convert_text_to_html (¤t_profile, TRUE, "darkgreen", "tt", NULL); 192 | } 193 | else 194 | { 195 | gchar *new_current_profile = g_strdup_printf("%s\n\n", current_profile); 196 | g_free(current_profile); 197 | current_profile = new_current_profile; 198 | } 199 | 200 | gchar *profile_message = g_strdup_printf(_("And your %s profile is: "), PACKAGE); 201 | #ifdef SAFEMODE 202 | if (profile_message) 203 | #endif 204 | if (convert_to_html) 205 | profile_message = convert_text_to_html(&profile_message, TRUE, NULL, "tt", NULL); 206 | 207 | // g_debug("FINAL: profile_message = %s", profile_message); 208 | 209 | #ifdef SAFEMODE 210 | if (profile_message) 211 | #endif 212 | g_string_append(help_message, profile_message); 213 | #ifdef SAFEMODE 214 | if (current_profile) 215 | #endif 216 | g_string_append(help_message, current_profile); 217 | g_free(profile_message); 218 | #ifdef SAFEMODE 219 | } 220 | #endif 221 | 222 | g_free(current_profile); 223 | return g_string_free(help_message, FALSE); 224 | } 225 | 226 | gchar *get_help_message_key_binding(gboolean convert_to_html) 227 | { 228 | #ifdef DETAIL 229 | g_debug("! Launch get_help_message_key_binding() with convert_to_html = %d!", convert_to_html); 230 | #endif 231 | gchar *msg_head = _("Default key binding:"); 232 | // TRANSLATE NOTE: Please be care of the spacing when translating the following key binding description. 233 | // TRANSLATE NOTE: Please check it in [Right Click Menu] -> [Usage] -> [Key binding] page after translating. 234 | gchar *disable_key_binding = _(" * <`> Disable/Enable hyperlinks, function keys and menu."); 235 | GString *message = g_string_new(NULL); 236 | g_string_append(message, _(" * Add a New tab with current directory.\n")); 237 | g_string_append(message, _(" * Switch to Prev/Next tab.\n")); 238 | g_string_append(message, _(" * Switch to First/Last tab.\n")); 239 | g_string_append(message, _(" * <[/]> Move current tab Forward/Backward.\n")); 240 | g_string_append(message, _(" * Move current tab to First/Last.\n")); 241 | g_string_append(message, _(" * Switch to 1st ~ 12th tab.\n")); 242 | g_string_append(message, _(" * <+/-/Enter> Increase/Decrease/Reset the font size of current tab.\n")); 243 | g_string_append(message, _(" * Emulate a mouse Scroll Up/Down event on terminal.\n")); 244 | g_string_append(message, _(" * Asks to Scroll Up/Down 1 line on terminal.\n")); 245 | g_string_append(message, _(" * Gtk+ default behavior, Scroll Up/Down on terminal.\n")); 246 | g_string_append(message, _(" * Gtk+ default behavior, Scroll terminal to Top/Bottom.\n")); 247 | g_string_append(message, _(" * Switch between full/unfullwindow and full/unfullscreen.\n")); 248 | g_string_append(message, _(" * Find text in the terminal.\n" 249 | " Use / to find Next/Prev.\n")); 250 | g_string_append(message, _(" * Select all the text in the terminal.\n")); 251 | g_string_append(message, _(" * Copy/Paste the text in clipboard.\n")); 252 | g_string_append(message, _(" * Copy/Paste the text in primary clipboard.\n")); 253 | g_string_append(message, _(" (i.e. Emulate middle button mouse click to Copy/Paste)\n")); 254 | g_string_append(message,"\n"); 255 | g_string_append(message, _("Some key bindings that disabled by default but maybe useful:\n")); 256 | g_string_append(message, _(" * Trying to close current tab.\n")); 257 | g_string_append(message, _(" (Using or 'exit' to close tabs is recommended)\n")); 258 | g_string_append(message, _(" * Open a new window with current directory.\n")); 259 | g_string_append(message, _(" * Rename the current tab.\n")); 260 | 261 | gchar *final_message = NULL; 262 | if (convert_to_html) 263 | { 264 | gchar *str[5]; 265 | 266 | str[0] = g_strdup_printf (_("TIP: These key bindings may custom or disable by right click menu [%s]."), _("Set key binding")); 267 | str[1] = convert_text_to_html(&msg_head, FALSE, NULL, "tt", NULL); 268 | str[2] = convert_text_to_html(&disable_key_binding, FALSE, "darkred", "tt", NULL); 269 | str[3] = convert_text_to_html(&(message->str), FALSE, NULL, "tt", NULL); 270 | str[4] = convert_text_to_html(&str[0], FALSE, "darkblue", "tt", "b", NULL); 271 | final_message = g_strdup_printf("%s\n%s\n%s\n%s", str[1], str[2], str[3], str[4]); 272 | gint i; 273 | for (i=0; i<5; i++) g_free(str[i]); 274 | } 275 | else 276 | final_message = g_strdup_printf("%s\n%s\n%s", msg_head, disable_key_binding, message->str); 277 | 278 | g_string_free (message, TRUE); 279 | return final_message; 280 | } 281 | -------------------------------------------------------------------------------- /src/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | // for L10n 22 | #include 23 | #include 24 | // for exit() 25 | #include 26 | // for va_start(), va_arg(), va_end() 27 | #include 28 | // for strcmp() 29 | #include 30 | 31 | #include "lilyterm.h" 32 | 33 | gchar *get_help_message(gchar *profile); 34 | -------------------------------------------------------------------------------- /src/dialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | // for L10n 23 | #include 24 | // for strlen() 25 | #include 26 | // for aoti() 27 | #include 28 | 29 | #include "lilyterm.h" 30 | 31 | typedef enum { 32 | DIALOG_OK, 33 | DIALOG_OK_CANCEL, 34 | DIALOG_QUIT, 35 | DIALOG_NONE, 36 | } Dialog_Button_Type; 37 | 38 | typedef enum { 39 | BOX_NONE, 40 | BOX_HORIZONTAL, 41 | BOX_VERTICALITY, 42 | } Box_Type; 43 | 44 | struct Dialog 45 | { 46 | GtkWidget *window; 47 | GtkWidget *operate[5]; 48 | GtkWidget *box; 49 | GtkWidget *title_label; 50 | 51 | #ifdef ENABLE_RGBA 52 | gboolean original_transparent_window; 53 | gdouble original_window_opacity; 54 | gdouble original_window_opacity_inactive; 55 | gboolean original_dim_window; 56 | #endif 57 | GtkWidget *custom_cursor_color_checkbox; 58 | gboolean original_custom_cursor_color; 59 | gboolean original_transparent_background; 60 | gboolean original_invert_color; 61 | gboolean original_have_custom_color; 62 | gboolean original_use_custom_theme; 63 | gdouble original_color_brightness; 64 | gdouble original_color_brightness_inactive; 65 | gboolean original_dim_text; 66 | gint original_update_method[PAGE_COLOR+1]; 67 | GtkWidget *ansi_table; 68 | GtkWidget *color_button[COLOR]; 69 | 70 | // For restore to original count of tabs when change the color of tab names. 71 | gint total_page; 72 | gint current_page_no; 73 | 74 | gboolean tab_1_is_bold; 75 | 76 | GtkWidget *treeview; 77 | gint KeyTree[KEYS][KEYS]; 78 | gint current_key_index; 79 | 80 | gchar *user_key_value[KEYS]; 81 | 82 | // ---- color datas ---- 83 | 84 | // the function type. 85 | gint type; 86 | gboolean recover; 87 | 88 | gchar *demo_text; 89 | GtkWidget *demo_vte; 90 | 91 | gchar *original_page_color; 92 | GdkRGBA original_color; 93 | // the color theme that will apply to current vte 94 | GdkRGBA ansi_colors_orig[COLOR]; 95 | GdkRGBA ansi_colors[COLOR]; 96 | gchar *original_custom_page_name; 97 | 98 | gboolean transparent_background; 99 | }; 100 | void init_dialog_ansi_colors_from_win_data(struct Window *win_data, struct Dialog *dialog_data); 101 | void update_fg_bg_color(struct Window *win_data, GdkRGBA color, gboolean update_fg); 102 | void clear_custom_colors_data(struct Window *win_data, gboolean update_fg); 103 | #if defined(USE_OLD_GTK_COLOR_SELECTION) || defined(UNIT_TEST) 104 | void update_custom_cursor_color(GtkWidget *menuitem, struct Window *win_data); 105 | #endif 106 | void dialog_invert_color_theme(GtkWidget *menuitem, struct Window *win_data); 107 | void update_color_buttons(struct Window *win_data, struct Dialog *dialog_data); 108 | void update_ansi_color_info(GtkWidget *button, gint color_index); 109 | GtkWidget *create_label_with_text(GtkWidget *box, gboolean set_markup, gboolean selectable, gint max_width_chars, const gchar *text); 110 | GtkWidget *add_secondary_button(GtkWidget *dialog, const gchar *text, gint response_id, const gchar *stock_id); 111 | void paste_text_to_vte_terminal(GtkWidget *widget, struct Dialog *dialog_data); 112 | void create_dialog(gchar *dialog_title_translation, gchar *dialog_title, Dialog_Button_Type type, 113 | GtkWidget *window, gboolean center, gboolean resizable, gint border_width, 114 | gint response, gchar *icon, gchar *title, gboolean selectable, gint max_width_chars, 115 | gboolean state_bottom, gint create_entry_hbox, gint entry_hbox_spacing, 116 | struct Dialog *dialog_data); 117 | void refresh_regex_settings(GtkWidget *widget, struct Window *win_data); 118 | void refresh_regex(struct Window *win_data, struct Dialog *dialog_data); 119 | void find_str(GtkWidget *widget, Dialog_Find_Type type); 120 | GtkWidget *create_entry_widget (GtkWidget *box, gchar *contents, gchar *name, gchar *default_value, gboolean activates_default); 121 | GtkWidget *create_frame_widget( struct Dialog *dialog_data, gchar *label, 122 | GtkWidget *label_widget, GtkWidget *child, guint padding); 123 | GtkWidget *create_button_with_image(gchar *label_text, const gchar *stock_id, gboolean set_tooltip_text, 124 | GSourceFunc func, gpointer func_data); 125 | void create_color_selection_widget(struct Dialog *dialog_data, GSourceFunc func, gpointer func_data); 126 | void set_color_selection_colors(GtkWidget *color_selection, GdkRGBA *color); 127 | void create_scale_widget(struct Dialog *dialog_data, gdouble min, gdouble max, gdouble step, gdouble value, 128 | GSourceFunc func, gpointer func_data); 129 | void create_SIGKILL_and_EXIT_widget(struct Dialog *dialog_data, gboolean create_entry_hbox, 130 | gboolean create_force_kill_hbox, gchar *count_str); 131 | gboolean grab_key_press (GtkWidget *window, GdkEventKey *event, struct Dialog *dialog_data); 132 | gboolean deal_dialog_key_press(GtkWidget *widget, GdkEventKey *event, struct Dialog *dialog_data); 133 | gchar *deal_dialog_key_press_join_string(StrAddr **value, gchar *separator, gchar *mask); 134 | gboolean clean_model_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer userdata); 135 | void recover_page_colors(GtkWidget *dialog, GtkWidget *window, GtkWidget *notebook); 136 | gboolean set_ansi_color(GtkRange *range, GtkScrollType scroll, gdouble value, GtkWidget *vte); 137 | #if defined(USE_GTK_COLOR_CHOOSER) || defined(UNIT_TEST) 138 | void adjust_vte_color_sample(GtkColorButton* color_button, gint color_index); 139 | #endif 140 | void adjust_vte_color(GtkColorChooser *colorselection, GdkRGBA *color, GtkWidget *vte); 141 | void set_new_ansi_color(GtkWidget *vte, GdkRGBA color_orig[COLOR], GdkRGBA color[COLOR], gdouble color_brightness, gboolean invert_color, 142 | gboolean default_vte_color, gboolean custom_cursor_color, GdkRGBA cursor_color, gboolean dim_fg_color); 143 | void hide_combo_box_capital(GtkCellLayout *cell_layout, GtkCellRenderer *cell, 144 | GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); 145 | void update_key_info (GtkTreeSelection *treeselection, struct Dialog *dialog_data); 146 | void clear_key_group(GtkButton *button, struct Dialog *dialog_data); 147 | void clear_key_group_all(GtkButton *button, struct Dialog *dialog_data); 148 | void clear_key_groups(struct Dialog *dialog_data, gboolean clear_all); 149 | GtkWidget *add_text_to_notebook(GtkWidget *notebook, const gchar *label, const gchar *stock_id, const gchar *text); 150 | void show_usage_text(GtkWidget *notebook, gpointer page, guint page_num, struct Dialog *dialog_data); 151 | // void err_page_data_is_null(gchar *function_name); 152 | -------------------------------------------------------------------------------- /src/font.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include "font.h" 21 | 22 | // extern GtkWidget *current_vte; 23 | extern GtkWidget *menu_active_window; 24 | 25 | void set_vte_font(GtkWidget *widget, Font_Set_Type type) 26 | { 27 | #ifdef DETAIL 28 | g_debug("! Launch set_vte_font() with type = %d", type); 29 | #endif 30 | #ifdef SAFEMODE 31 | if (menu_active_window==NULL) return; 32 | #endif 33 | 34 | // GtkWidget *vte = current_vte; 35 | struct Window *win_data = (struct Window *)g_object_get_data(G_OBJECT(menu_active_window), "Win_Data"); 36 | #ifdef SAFEMODE 37 | if (win_data==NULL) return; 38 | #endif 39 | GtkWidget *vte = win_data->current_vte; 40 | gchar *new_font_name = NULL; 41 | 42 | // type 0, FONT_RESET: reset current page's font size 43 | // type 1, FONT_INCREASE: increase current page's font size 44 | // type 2, FONT_DECREASE: decrease current page's font size 45 | // type 3, FONT_ZOOM_OUT: increase window size & font size for every vte 46 | // type 4, FONT_ZOOM_IN: decrease window size & font size for every vte 47 | // type 5, FONT_RESET_DEFAULT: reset window size & font size to default for every vte 48 | // type 6, FONT_RESET_SYSTEM: reset window size & font size to system for every vte 49 | // type 7, FONT_SET_TO_SELECTED: change every vte to the selected font name 50 | 51 | switch (type) 52 | { 53 | case FONT_RESET: // 0 54 | // reset current page's font size 55 | new_font_name = get_resize_font(vte, FONT_NAME_RESTORE); 56 | reset_vte_size(vte, new_font_name, RESET_CURRENT_TAB_FONT); 57 | break; 58 | case FONT_INCREASE: // 1 59 | // increase current page's font size 60 | new_font_name = get_resize_font(vte, FONT_NAME_INCREASE); 61 | reset_vte_size(vte, new_font_name, RESET_CURRENT_TAB_FONT); 62 | break; 63 | case FONT_DECREASE: // 2 64 | // decrease current page's font size 65 | new_font_name = get_resize_font(vte, FONT_NAME_DECREASE); 66 | reset_vte_size(vte, new_font_name, RESET_CURRENT_TAB_FONT); 67 | break; 68 | case FONT_ZOOM_OUT: // 3 69 | // increase window size & font size for every vte 70 | new_font_name = get_resize_font(vte, FONT_NAME_ZOOM_OUT); 71 | reset_vte_size(vte, new_font_name, RESET_ALL_TO_CURRENT_TAB); 72 | break; 73 | case FONT_ZOOM_IN: // 4 74 | // decrease window size & font size for every vte 75 | new_font_name = get_resize_font(vte, FONT_NAME_ZOOM_IN); 76 | reset_vte_size(vte, new_font_name, RESET_ALL_TO_CURRENT_TAB); 77 | break; 78 | case FONT_RESET_DEFAULT: // 5 79 | // reset window size & font size to default for every vte 80 | new_font_name = get_resize_font(vte, FONT_NAME_DEFAULT); 81 | reset_vte_size(vte, new_font_name, RESET_ALL_TO_DEFAULT); 82 | break; 83 | case FONT_RESET_SYSTEM: // 6 84 | // reset window size & font size to system for every vte 85 | new_font_name = get_resize_font(vte, FONT_NAME_SYSTEM); 86 | reset_vte_size(vte, new_font_name, RESET_ALL_TO_SYSTEM); 87 | break; 88 | case FONT_SET_TO_SELECTED: // 7 89 | // change every vte to the selected font name 90 | new_font_name = get_resize_font(vte, FONT_NAME_UPDATE); 91 | reset_vte_size(vte, new_font_name, RESET_ALL_TO_CURRENT_TAB); 92 | break; 93 | default: 94 | #ifdef FATAL 95 | print_switch_out_of_range_error_dialog("set_vte_font", "type", type); 96 | #endif 97 | break; 98 | } 99 | g_free(new_font_name); 100 | } 101 | 102 | // it will update the new_font_name and page_data->font_name 103 | gchar *get_resize_font(GtkWidget *vte, Font_Name_Type type) 104 | { 105 | #ifdef DETAIL 106 | g_debug("! Launch get_resize_font() for vte %p with type %d", vte, type); 107 | #endif 108 | #ifdef SAFEMODE 109 | if (vte==NULL) return NULL; 110 | #endif 111 | // we must insure that vte!=NULL 112 | struct Page *page_data = (struct Page *)g_object_get_data(G_OBJECT(vte), "Page_Data"); 113 | #ifdef SAFEMODE 114 | if (page_data==NULL) return NULL; 115 | #endif 116 | struct Window *win_data = (struct Window *)g_object_get_data(G_OBJECT(page_data->window), "Win_Data"); 117 | #ifdef SAFEMODE 118 | if (win_data==NULL) return NULL; 119 | #endif 120 | // g_debug("Get win_data = %d when get resize font!", win_data); 121 | // type 0, FONT_NAME_DEFAULT: restore font to default_font_name 122 | // type 1, FONT_NAME_SYSTEM: restore font to system_font_name 123 | // type 2, FONT_NAME_RESTORE: restore font to restore_font_name 124 | // type 3, FONT_NAME_UPDATE: do nothing but only update new_font_name 125 | // type 4, FONT_NAME_ZOOM_OUT: increase window by *1.1 or +1 126 | // type 5, FONT_NAME_ZOOM_IN: decrease window by /1.1 or -1 127 | // type 6, FONT_NAME_INCREASE: increase font by *1.1 or +1 128 | // type 7, FONT_NAME_DECREASE: decrease font by /1.1 or -1 129 | 130 | if (win_data->restore_font_name == NULL) 131 | { 132 | // win_data->restore_font_name = g_strdup(page_data->font_name); 133 | win_data->restore_font_name = g_strdup(win_data->default_font_name); 134 | // g_debug("Restore the font to %s!", win_data->restore_font_name); 135 | if (type==FONT_NAME_RESTORE) 136 | return g_strdup(page_data->font_name); 137 | } 138 | 139 | switch (type) 140 | { 141 | case FONT_NAME_DEFAULT: 142 | case FONT_NAME_SYSTEM: 143 | case FONT_NAME_RESTORE: 144 | g_free(page_data->font_name); 145 | break; 146 | default: 147 | break; 148 | } 149 | 150 | // we use font_size to save current font size 151 | // font_size = (the size in font_name) * PANGO_SCALE 152 | // if font_size == 0 -> use the data in font_name 153 | 154 | switch (type) 155 | { 156 | case FONT_NAME_DEFAULT: 157 | // restore font to default_font_name 158 | page_data->font_name = g_strdup(win_data->default_font_name); 159 | page_data->font_size = 0; 160 | break; 161 | case FONT_NAME_SYSTEM: 162 | // restore font to default_font_name 163 | page_data->font_name = g_strdup(SYSTEM_FONT_NAME); 164 | page_data->font_size = 0; 165 | break; 166 | case FONT_NAME_RESTORE: 167 | // restore font to default_font_name 168 | page_data->font_name = g_strdup(win_data->restore_font_name); 169 | page_data->font_size = 0; 170 | break; 171 | case FONT_NAME_UPDATE: 172 | break; 173 | case FONT_NAME_ZOOM_OUT: 174 | case FONT_NAME_ZOOM_IN: 175 | case FONT_NAME_INCREASE: 176 | case FONT_NAME_DECREASE: 177 | { 178 | #ifdef SAFEMODE 179 | if (page_data->font_name==NULL) break; 180 | #endif 181 | gint oldfontsize=0, fontsize=0; 182 | 183 | // g_debug("old font name: %s", page_data->font_name); 184 | PangoFontDescription *font_desc = pango_font_description_from_string( 185 | page_data->font_name); 186 | // increase/decrease font 187 | oldfontsize = (pango_font_description_get_size(font_desc)/PANGO_SCALE); 188 | if (page_data->font_size==0) 189 | page_data->font_size = pango_font_description_get_size(font_desc); 190 | 191 | switch (type) 192 | { 193 | // g_debug("window_resize_ratio = %f", win_data->window_resize_ratio); 194 | case FONT_NAME_ZOOM_OUT: 195 | if (win_data->window_resize_ratio) 196 | page_data->font_size = page_data->font_size * 197 | win_data->window_resize_ratio + 198 | 0.5; 199 | else 200 | page_data->font_size = page_data->font_size + PANGO_SCALE; 201 | break; 202 | case FONT_NAME_ZOOM_IN: 203 | if (win_data->window_resize_ratio) 204 | page_data->font_size = page_data->font_size / 205 | win_data->window_resize_ratio + 206 | 0.5; 207 | else 208 | page_data->font_size = page_data->font_size - PANGO_SCALE; 209 | break; 210 | case FONT_NAME_INCREASE: 211 | if (win_data->font_resize_ratio) 212 | page_data->font_size = page_data->font_size * 213 | win_data->font_resize_ratio + 214 | 0.5; 215 | else 216 | page_data->font_size = page_data->font_size + PANGO_SCALE; 217 | break; 218 | case FONT_NAME_DECREASE: 219 | if (win_data->font_resize_ratio) 220 | page_data->font_size = page_data->font_size / 221 | win_data->font_resize_ratio + 222 | 0.5; 223 | else 224 | page_data->font_size = page_data->font_size - PANGO_SCALE; 225 | break; 226 | default: 227 | break; 228 | } 229 | // g_debug("font_size = %d", page_data->font_size); 230 | fontsize = (page_data->font_size)/PANGO_SCALE; 231 | 232 | // to avoid the fontsize is unchanged or = 0 233 | switch (type) 234 | { 235 | case FONT_NAME_ZOOM_OUT: 236 | case FONT_NAME_INCREASE: 237 | if (oldfontsize==fontsize) 238 | fontsize++; 239 | break; 240 | case FONT_NAME_ZOOM_IN: 241 | case FONT_NAME_DECREASE: 242 | if (oldfontsize==fontsize) 243 | fontsize--; 244 | if (fontsize<1) 245 | fontsize=1; 246 | break; 247 | default: 248 | break; 249 | } 250 | 251 | // g_debug("Trying to change the font size to %d.", fontsize); 252 | pango_font_description_set_size(font_desc, fontsize*PANGO_SCALE); 253 | g_free(page_data->font_name); 254 | page_data->font_name = pango_font_description_to_string(font_desc); 255 | pango_font_description_free(font_desc); 256 | break; 257 | default: 258 | #ifdef FATAL 259 | print_switch_out_of_range_error_dialog("get_resize_font", "type", type); 260 | #endif 261 | return NULL; 262 | } 263 | } 264 | 265 | // g_debug("new font name: %s", page_data->font_name); 266 | 267 | switch (type) 268 | { 269 | case FONT_NAME_DEFAULT: 270 | case FONT_NAME_SYSTEM: 271 | case FONT_NAME_UPDATE: 272 | case FONT_NAME_ZOOM_OUT: 273 | case FONT_NAME_ZOOM_IN: 274 | // if not using <+ - enter> to change the font size. 275 | g_free(win_data->restore_font_name); 276 | win_data->restore_font_name = g_strdup(page_data->font_name); 277 | break; 278 | case FONT_NAME_INCREASE: 279 | case FONT_NAME_DECREASE: 280 | // Check if we can specify page_data->font_size = 0 281 | if ( ! compare_strings(page_data->font_name, win_data->restore_font_name, TRUE)) 282 | { 283 | page_data->font_size = 0; 284 | // g_debug("The font is restored to win_data->restore_font_name"); 285 | } 286 | break; 287 | default: 288 | break; 289 | } 290 | return g_strdup(page_data->font_name); 291 | } 292 | 293 | void reset_vte_size(GtkWidget *vte, gchar *new_font_name, Font_Reset_Type type) 294 | { 295 | #ifdef DETAIL 296 | g_debug("! Launch reset_vte_size() with vte = %p, new_font_name = %s, type = %d", 297 | vte, new_font_name, type); 298 | #endif 299 | #ifdef SAFEMODE 300 | if ((vte==NULL) || (new_font_name==NULL)) return; 301 | #endif 302 | 303 | // type 0, RESET_CURRENT_TAB_FONT: change current page's font 304 | // type 1, RESET_ALL_TO_CURRENT_TAB: apply current column & row to every vte 305 | // type 2, RESET_ALL_TO_DEFAULT: apply default column & row to every vte 306 | // type 3, RESET_ALL_TO_SYSTEM: apply system column & row to every vte 307 | 308 | struct Page *page_data = (struct Page *)g_object_get_data(G_OBJECT(vte), "Page_Data"); 309 | #ifdef SAFEMODE 310 | if (page_data==NULL) return; 311 | #endif 312 | struct Window *win_data = (struct Window *)g_object_get_data(G_OBJECT(page_data->window), "Win_Data"); 313 | #ifdef SAFEMODE 314 | if (win_data==NULL) return; 315 | #endif 316 | // g_debug("Get win_data = %d when reset vte size!", win_data); 317 | 318 | switch (type) 319 | { 320 | case RESET_CURRENT_TAB_FONT: 321 | // We need to apply a new font to a single vte. 322 | // so that we should insure that this won't change the size of window. 323 | // g_debug("Trying to apply font %s to vte", current_font_name); 324 | fake_vte_terminal_set_font_from_string( vte, 325 | new_font_name, 326 | win_data->font_anti_alias); 327 | // g_debug("reset_vte_size(): call window_resizable() with run_once = %d", win_data->hints_type); 328 | // g_debug("reset_vte_size(): launch update_window_hint()!"); 329 | # ifdef GEOMETRY 330 | fprintf(stderr, "\033[1;37m!! reset_vte_size(): call update_window_hint()\033[0m\n"); 331 | # endif 332 | update_window_hint(win_data, page_data); 333 | break; 334 | case RESET_ALL_TO_CURRENT_TAB: 335 | // increase/decrease window size & font size for every vte 336 | // g_debug("Trying to apply font %s to every vte", current_font_name); 337 | // struct Page *page_data = (struct Page *)g_object_get_data(G_OBJECT(current_vte), "Page_Data"); 338 | #ifdef USE_GTK2_GEOMETRY_METHOD 339 | apply_font_to_every_vte(page_data->window, new_font_name, 340 | vte_terminal_get_column_count(VTE_TERMINAL(win_data->current_vte)), 341 | vte_terminal_get_row_count(VTE_TERMINAL(win_data->current_vte))); 342 | #endif 343 | #ifdef USE_GTK3_GEOMETRY_METHOD 344 | apply_font_to_every_vte( page_data->window, new_font_name, win_data->geometry_width, win_data->geometry_height); 345 | #endif 346 | break; 347 | case RESET_ALL_TO_DEFAULT: 348 | // reset window size & font size for every vte 349 | // g_debug("Trying to apply font %s to every vte", current_font_name); 350 | apply_font_to_every_vte(page_data->window, new_font_name, 351 | win_data->default_column, win_data->default_row); 352 | break; 353 | case RESET_ALL_TO_SYSTEM: 354 | // reset window size & font size for every vte 355 | // g_debug("Trying to apply font %s to every vte", current_font_name); 356 | apply_font_to_every_vte(page_data->window, new_font_name, 357 | SYSTEM_COLUMN, SYSTEM_ROW); 358 | break; 359 | default: 360 | #ifdef FATAL 361 | print_switch_out_of_range_error_dialog("reset_vte_size", "type", type); 362 | #endif 363 | break; 364 | } 365 | } 366 | 367 | void apply_font_to_every_vte(GtkWidget *window, gchar *new_font_name, glong column, glong row) 368 | { 369 | #ifdef DETAIL 370 | g_debug("! Launch apply_font_to_every_vte() with window = %p, new_font_name = %s," 371 | " column = %ld, row = %ld", window, new_font_name, column, row); 372 | #endif 373 | #ifdef SAFEMODE 374 | if ((window==NULL) || (new_font_name==NULL) || (column<1) || (row<1)) return; 375 | #endif 376 | struct Window *win_data = (struct Window *)g_object_get_data(G_OBJECT(window), "Win_Data"); 377 | // g_debug("Get win_data = %d when apply font to every vte!", win_data); 378 | #ifdef SAFEMODE 379 | if (win_data==NULL) return; 380 | #endif 381 | 382 | struct Page *page_data = NULL; 383 | gint i; 384 | 385 | // g_debug("Trying to apply every vte to %dx%d!", column, row); 386 | // g_debug("Trying to apply font %s to every vte!", new_font_name); 387 | 388 | for (i=0; inotebook)); i++) 389 | { 390 | page_data = get_page_data_from_nth_page(win_data, i); 391 | #ifdef SAFEMODE 392 | if (page_data==NULL) continue; 393 | #endif 394 | // g_debug("The default font for %d page is: %s (%s)", i, page_data->font_name, new_font_name); 395 | fake_vte_terminal_set_font_from_string( page_data->vte, 396 | new_font_name, 397 | win_data->font_anti_alias); 398 | vte_terminal_set_size(VTE_TERMINAL(page_data->vte), column, row); 399 | g_free(page_data->font_name); 400 | page_data->font_name = g_strdup(new_font_name); 401 | // g_debug("The new font for %d page is: %s (%s)", i, page_data->font_name, new_font_name); 402 | } 403 | 404 | // g_debug("* Set hints to HINTS_FONT_BASE!, win_data->window_status = %d", win_data->window_status); 405 | win_data->hints_type = HINTS_FONT_BASE; 406 | 407 | // win_data->keep_vte_size |= 0x30; 408 | // g_debug("window_resizable in apply_font_to_every_vte!"); 409 | // window_resizable(window, page_data->vte, 2, 1); 410 | // g_debug("apply_font_to_every_vte(): launch keep_window_size()!"); 411 | 412 | // Don't need to call keep_gtk2_window_size() when fullscreen 413 | switch (win_data->window_status) 414 | { 415 | #ifdef USE_GTK2_GEOMETRY_METHOD 416 | case FULLSCREEN_NORMAL: 417 | case FULLSCREEN_UNFS_OK: 418 | # ifdef GEOMETRY 419 | g_debug("@ apply_font_to_every_vte(): Call keep_gtk2_window_size() with keep_vte_size = 0x%X", 420 | win_data->keep_vte_size); 421 | # endif 422 | keep_gtk2_window_size (win_data, page_data->vte, GEOMETRY_CHANGING_FONT); 423 | #endif 424 | #ifdef USE_GTK3_GEOMETRY_METHOD 425 | case WINDOW_NORMAL: 426 | case WINDOW_APPLY_PROFILE_NORMAL: 427 | # ifdef GEOMETRY 428 | fprintf(stderr, "\033[1;%dm!! apply_font_to_every_vte(win_data %p): Calling keep_gtk3_window_size() with hints_type = %d\n", 429 | ANSI_COLOR_MAGENTA, win_data, win_data->hints_type); 430 | # endif 431 | window_resizable(win_data->window, win_data->current_vte, win_data->hints_type); 432 | if (win_data->window_status==WINDOW_NORMAL) 433 | win_data->resize_type = GEOMETRY_AUTOMATIC; 434 | else 435 | win_data->resize_type = GEOMETRY_CUSTOM; 436 | win_data->geometry_width = column; 437 | win_data->geometry_height = row; 438 | keep_gtk3_window_size(win_data, TRUE); 439 | #endif 440 | break; 441 | default: 442 | break; 443 | } 444 | } 445 | 446 | gboolean check_if_every_vte_is_using_restore_font_name(struct Window *win_data) 447 | { 448 | #ifdef DETAIL 449 | g_debug("! Launch check_if_every_vte_is_using_restore_font_name() with win_data = %p", win_data); 450 | #endif 451 | #ifdef SAFEMODE 452 | if ((win_data==NULL) || (win_data->notebook==NULL)) return FALSE; 453 | #endif 454 | if (win_data->restore_font_name == NULL) 455 | // win_data->restore_font_name = g_strdup(page_data->font_name); 456 | win_data->restore_font_name = g_strdup(win_data->default_font_name); 457 | 458 | gint i; 459 | struct Page *page_data = NULL; 460 | gboolean return_value = TRUE; 461 | for (i=0; inotebook)); i++) 462 | { 463 | page_data = get_page_data_from_nth_page(win_data, i); 464 | #ifdef SAFEMODE 465 | if (page_data==NULL) continue; 466 | #endif 467 | if (compare_strings(page_data->font_name, win_data->restore_font_name, TRUE)) 468 | { 469 | return_value = FALSE; 470 | break; 471 | } 472 | } 473 | return return_value; 474 | } 475 | 476 | void fake_vte_terminal_set_font_from_string(GtkWidget *vte, const char *font_name, gboolean anti_alias) 477 | { 478 | #ifdef DETAIL 479 | g_debug("! Launch fake_vte_terminal_set_font_from_string() with vte = %p, font_name = %s, anti_alias = %d", vte, font_name, anti_alias); 480 | #endif 481 | #ifdef SAFEMODE 482 | if ((vte==NULL) || (font_name==NULL)) return; 483 | #endif 484 | 485 | #ifdef USE_VTE_TERMINAL_SET_FONT 486 | PangoFontDescription *font_desc = pango_font_description_from_string(font_name); 487 | vte_terminal_set_font(VTE_TERMINAL(vte), font_desc); 488 | #else 489 | vte_terminal_set_font_from_string_full( VTE_TERMINAL(vte), font_name, anti_alias); 490 | #endif 491 | } 492 | -------------------------------------------------------------------------------- /src/font.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "lilyterm.h" 24 | 25 | gchar *get_resize_font(GtkWidget *vte, Font_Name_Type type); 26 | void reset_vte_size(GtkWidget *vte, gchar *new_font_name, Font_Reset_Type type); 27 | -------------------------------------------------------------------------------- /src/lilyterm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | 21 | #ifndef LILYTERM_H 22 | #define LILYTERM_H 23 | 24 | #include "data.h" 25 | #include "socket.h" 26 | 27 | typedef gchar StrAddr; 28 | typedef gchar StrLists; 29 | 30 | // 31 | // **************************** misc.c **************************** 32 | // 33 | 34 | #ifdef USE_GTK_ALT_DIALOG_BUTTON_ORDER 35 | gboolean gtk_alt_dialog_button_order(); 36 | #endif 37 | gboolean check_if_default_proc_dir_exist(gchar *proc_dir); 38 | gchar *convert_array_to_string(gchar **array, gchar separator); 39 | gchar *convert_str_to_utf8(gchar *string, gchar *encoding_str); 40 | gchar *convert_escape_sequence_to_string(const gchar *string); 41 | gchar *convert_escape_sequence_from_string(const gchar *string); 42 | gboolean compare_strings(const gchar *string_a, const gchar *string_b, gboolean case_sensitive); 43 | void set_VTE_CJK_WIDTH_environ(gint VTE_CJK_WIDTH); 44 | gchar *get_VTE_CJK_WIDTH_str(gint VTE_CJK_WIDTH); 45 | gint get_default_VTE_CJK_WIDTH(); 46 | void restore_SYSTEM_VTE_CJK_WIDTH_STR(); 47 | void set_env(const gchar *variable, const gchar *value, gboolean overwrite); 48 | const gchar *get_default_lc_data(gint lc_type); 49 | gchar *get_encoding_from_locale(const gchar *locale); 50 | gboolean check_string_in_array(gchar *str, gchar **lists); 51 | gchar *get_proc_data(pid_t pid, gchar *file, gsize *length); 52 | gchar **split_string(const gchar *str, const gchar *split, gint max_tokens); 53 | gint count_char_in_string(const gchar *str, const gchar split); 54 | gchar **get_pid_stat(pid_t pid, gint max_tokens); 55 | gchar *convert_text_to_html(StrAddr **text, gboolean free_text, gchar *color, StrLists *tag, ...); 56 | gchar *join_strings_to_string(const gchar separator, const gint total, const StrLists *string, ...); 57 | gchar *colorful_max_new_lines(gchar *string, gint max, gint output_line); 58 | #ifdef ENABLE_RGBA 59 | GdkRGBA convert_color_to_rgba(GdkColor color); 60 | GdkColor convert_rgba_to_color(GdkRGBA rgba); 61 | gchar *dirty_gdk_rgba_to_string(GdkRGBA *rgba); 62 | gboolean dirty_gdk_color_parse(const gchar *spec, GdkRGBA *color); 63 | #endif 64 | GtkWidget *dirty_gtk_vbox_new(gboolean homogeneous, gint spacing); 65 | GtkWidget *dirty_gtk_hbox_new(gboolean homogeneous, gint spacing); 66 | #if defined(ENABLE_VTE_BACKGROUND) || defined(FORCE_ENABLE_VTE_BACKGROUND) || defined(UNIT_TEST) 67 | void dirty_vte_terminal_set_background_tint_color(VteTerminal *vte, const GdkRGBA rgba); 68 | #endif 69 | #if defined(GEOMETRY) || defined(UNIT_TEST) 70 | void widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gchar *name); 71 | #endif 72 | 73 | #if defined(OUT_OF_MEMORY) || defined(UNIT_TEST) 74 | gchar *fake_g_strdup(const gchar *gchar); 75 | gchar *fake_g_strdup_printf(const StrLists *format, ...); 76 | #endif 77 | 78 | // 79 | // **************************** main.c **************************** 80 | // 81 | 82 | gchar *convert_socket_data_to_string(char *argv[]); 83 | gboolean convert_string_to_socket_data(gchar *socket_str); 84 | void main_quit(GtkWidget *widget, struct Window *win_data); 85 | void quit_gtk(); 86 | 87 | // 88 | // **************************** console.c **************************** 89 | // 90 | 91 | void command_option(int argc, char *argv[]); 92 | gchar *get_help_message_usage(gchar *profile, gboolean convert_to_html); 93 | gchar *get_help_message_key_binding(gboolean convert_to_html); 94 | 95 | // 96 | // **************************** window.c **************************** 97 | // 98 | 99 | GtkNotebook *new_window(int argc, 100 | char *argv[], 101 | gchar *shell, 102 | gchar *environment, 103 | gchar *locale_list, 104 | gchar *PWD, 105 | gchar *HOME, 106 | const gchar *VTE_CJK_WIDTH_STR, 107 | gboolean VTE_CJK_WIDTH_STR_overwrite_profile, 108 | const gchar *wmclass_name, 109 | gchar *wmclass_class, 110 | gchar *user_environ, 111 | gchar *encoding, 112 | gboolean encoding_overwrite_profile, 113 | gchar *lc_messages, 114 | struct Window *win_data_orig, 115 | struct Page *page_data_orig); 116 | gchar *get_init_dir(pid_t pid, gchar *pwd, gchar *home); 117 | #if defined(USE_GTK2_GEOMETRY_METHOD) || defined(UNIT_TEST) 118 | void keep_gtk2_window_size (struct Window *win_data, GtkWidget *vte, Geometry_Resize_Type keep_vte_size); 119 | #endif 120 | #if defined(USE_GTK3_GEOMETRY_METHOD) || defined(UNIT_TEST) 121 | void keep_gtk3_window_size(struct Window *win_data, gboolean idle); 122 | gboolean show_or_hide_tabs_bar_and_scroll_bar(); 123 | gboolean idle_set_vte_font_to_selected(struct Window *win_data); 124 | #endif 125 | void dim_window(struct Window *win_data, gint dim_window); 126 | void clear_window(struct Window *win_data); 127 | void set_window_icon(GtkWidget *window); 128 | gboolean window_quit(GtkWidget *window, GdkEvent *event, struct Window *win_data); 129 | GString *close_multi_tabs(struct Window *win_data, int window_no); 130 | gboolean display_child_process_dialog (GString *child_process_list, struct Window *win_data, gsize style); 131 | GString *get_child_process_list(GtkWidget *window, gint window_no, gint page_no, GString *process_list, pid_t pid, struct Window *win_data, gboolean show_foreground); 132 | void clean_process_data(); 133 | gboolean deal_key_press(GtkWidget *window, Key_Bindings type, struct Window *win_data); 134 | #ifdef DISABLE_PAGE_ADDED 135 | void notebook_page_added(GtkNotebook *notebook, GtkWidget *child, guint page_num, struct Window *win_data); 136 | #endif 137 | void show_close_button_on_tab(struct Window *win_data, struct Page *page_data); 138 | void set_fill_tabs_bar(GtkNotebook *notebook, gboolean fill_tabs_bar, struct Page *page_data); 139 | void remove_notebook_page (GtkNotebook *notebook, GtkWidget *child, guint page_num, struct Window *win_data, gboolean run_quit_gtk); 140 | void update_window_hint(struct Window *win_data, struct Page *page_data); 141 | void window_resizable(GtkWidget *window, GtkWidget *vte, Hints_Type hints_type); 142 | gboolean hide_and_show_tabs_bar(struct Window *win_data , Switch_Type show_tabs_bar); 143 | void set_widget_can_not_get_focus(GtkWidget *widget); 144 | gboolean hide_scrollback_lines(GtkWidget *widget, struct Window *win_data); 145 | #if defined(FATAL) || defined(UNIT_TEST) 146 | void print_array(gchar *name, gchar **data); 147 | #endif 148 | void clear_win_data(struct Window *win_data); 149 | gboolean confirm_to_paste_form_clipboard(Clipboard_Type type, struct Window *win_data, struct Page *page_data); 150 | gboolean show_clipboard_dialog(Clipboard_Type type, struct Window *win_data, 151 | struct Page *page_data, Dialog_Type_Flags dialog_type); 152 | 153 | void print_color(gint no, gchar *name, GdkRGBA color); 154 | 155 | // 156 | // **************************** profile.c **************************** 157 | // 158 | void convert_system_color_to_rgba(); 159 | void init_page_parameters(struct Window *win_data, struct Page *page_data); 160 | void init_user_color(struct Window *win_data, gchar *theme_name); 161 | void init_locale_restrict_data(gchar *lc_messages); 162 | GString *save_user_settings(GtkWidget *widget, struct Window *win_data); 163 | gchar *get_user_profile_path(struct Window *win_data, int argc, char *argv[]); 164 | void get_user_settings(struct Window *win_data, const gchar *encoding); 165 | void init_prime_user_datas(struct Window *win_data); 166 | #ifdef ENABLE_PROFILE 167 | void get_prime_user_settings(GKeyFile *keyfile, struct Window *win_data, gchar *encoding); 168 | gboolean check_boolean_value(GKeyFile *keyfile, const gchar *group_name, const gchar *key, const gboolean default_value); 169 | void check_profile_version (GKeyFile *keyfile, struct Window *win_data); 170 | #endif 171 | void profile_is_invalid_dialog(GError *error, struct Window *win_data); 172 | void convert_string_to_user_key(gint i, gchar *value, struct Window *win_data); 173 | gchar *get_profile(); 174 | #if defined(ENABLE_RGBA) || defined(UNIT_TEST) 175 | void init_rgba(struct Window *win_data); 176 | #endif 177 | void get_row_and_column_from_geometry_str(glong *column, glong *row, glong *default_column, glong *default_row, gchar *geometry_str); 178 | 179 | // 180 | // **************************** property.c **************************** 181 | // 182 | 183 | void create_theme_color_data(GdkRGBA color[COLOR], GdkRGBA color_orig[COLOR], gdouble color_brightness, gboolean invert_color, 184 | gboolean default_vte_theme, gboolean dim_fg_color); 185 | void adjust_ansi_color(GdkRGBA *color, GdkRGBA *color_orig, gdouble color_brightness); 186 | void generate_all_color_datas(struct Window *win_data); 187 | GdkRGBA *get_current_color_theme(struct Window *win_data); 188 | void init_new_page(struct Window *win_data, struct Page *page_data, glong column, glong row); 189 | void set_cursor_blink(struct Window *win_data, struct Page *page_data); 190 | void set_hyperlink(struct Window *win_data, struct Page *page_data); 191 | void clean_hyperlink(struct Window *win_data, struct Page *page_data); 192 | void enable_custom_cursor_color(GtkWidget *vte, gboolean custom_cursor_color, GdkRGBA *cursor_color); 193 | void set_vte_color(GtkWidget *vte, gboolean default_vte_color, gboolean custom_cursor_color, GdkRGBA cursor_color, GdkRGBA color[COLOR], 194 | gboolean update_fg_only, gboolean over_16_colors); 195 | gboolean use_default_vte_theme(struct Window *win_data); 196 | void set_page_width(struct Window *win_data, struct Page *page_data); 197 | void pack_vte_and_scroll_bar_to_hbox(struct Window *win_data, struct Page *page_data); 198 | void add_remove_page_timeout_id(struct Window *win_data, struct Page *page_data); 199 | void add_remove_window_title_changed_signal(struct Page *page_data); 200 | #if defined(ENABLE_VTE_BACKGROUND) || defined(FORCE_ENABLE_VTE_BACKGROUND) || defined(UNIT_TEST) 201 | gboolean set_background_saturation(GtkRange *range, GtkScrollType scroll, gdouble value, GtkWidget *vte); 202 | #endif 203 | gboolean set_window_opacity (GtkRange *range, GtkScrollType scroll, gdouble value, struct Window *win_data); 204 | #if defined(vte_terminal_get_padding) || defined(UNIT_TEST) 205 | void fake_vte_terminal_get_padding(VteTerminal *vte, gint *width, gint *height); 206 | #endif 207 | void apply_new_win_data_to_page (struct Window *win_data_orig, struct Window *win_data, struct Page *page_data); 208 | gboolean compare_color(GdkRGBA *a, GdkRGBA *b); 209 | gboolean check_show_or_hide_scroll_bar(struct Window *win_data); 210 | void show_and_hide_scroll_bar(struct Page *page_data, gboolean show_scroll_bar); 211 | void set_widget_thickness(GtkWidget *widget, gint thickness); 212 | 213 | // 214 | // **************************** notebook.c **************************** 215 | // 216 | 217 | struct Page *add_page(struct Window *win_data, 218 | struct Page *page_data_prev, 219 | GtkWidget *menuitem_encoding, 220 | gchar *encoding, 221 | gchar *runtime_locale_encoding, 222 | gchar *locale, 223 | gchar *environments, 224 | gchar *user_environ, 225 | const gchar *VTE_CJK_WIDTH_STR, 226 | gboolean add_to_next); 227 | void dim_vte_text (struct Window *win_data, struct Page *page_data, gint dim_text); 228 | gboolean close_page(GtkWidget *vte, gint close_type); 229 | gboolean open_url_with_external_command (gchar *url, gint tag, struct Window *win_data, struct Page *page_data); 230 | struct Page *get_page_data_from_nth_page(struct Window *win_data, guint page_no); 231 | struct Page *get_page_data_from_vte(GtkWidget *vte, struct Window *win_data, gint page_no); 232 | 233 | // 234 | // **************************** font.c **************************** 235 | // 236 | 237 | void set_vte_font(GtkWidget *widget, Font_Set_Type type); 238 | void apply_font_to_every_vte(GtkWidget *window, gchar *new_font_name, glong column, glong row); 239 | gboolean check_if_every_vte_is_using_restore_font_name (struct Window *win_data); 240 | void fake_vte_terminal_set_font_from_string(GtkWidget *vte, const char *font_name, gboolean anti_alias); 241 | 242 | // 243 | // **************************** pagename.c **************************** 244 | // 245 | 246 | void update_window_title(GtkWidget *window, gchar *name, gboolean window_title_append_package_name); 247 | void init_monitor_cmdline_datas(struct Window *win_data, struct Page *page_data); 248 | gboolean monitor_cmdline(struct Page *page_data); 249 | void update_page_window_title (VteTerminal *vte, struct Page *page_data); 250 | gchar *get_cmdline(const pid_t tpgid); 251 | gboolean check_is_root(pid_t tpgid); 252 | gint get_tpgid(pid_t pid); 253 | void check_and_update_window_title(struct Window *win_data, gboolean custom_window_title, gint page_no, 254 | gchar *custom_page_name, gchar *page_name); 255 | gboolean get_and_update_page_name(struct Page *page_data, gboolean lost_focus); 256 | void reorder_page_number (GtkNotebook *notebook, GtkWidget *child, guint page_num, GtkWidget *window); 257 | gchar *get_tab_name_with_current_dir(pid_t pid); 258 | void update_page_name_wintitle(StrAddr **page_name, 259 | StrAddr **page_color, 260 | struct Window *win_data, 261 | struct Page *page_data); 262 | void update_page_name_cmdline(StrAddr **page_name, 263 | StrAddr **page_color, 264 | struct Window *win_data, 265 | struct Page *page_data); 266 | void update_page_name_pwd(StrAddr **page_name, 267 | StrAddr **page_color, 268 | struct Window *win_data, 269 | struct Page *page_data, 270 | gboolean lost_focus); 271 | gboolean update_page_name(GtkWidget *window, GtkWidget *vte, gchar *page_name, GtkWidget *label, 272 | gint page_no, gchar *custom_page_name, const gchar *tab_color, gboolean is_root, 273 | gboolean is_bold, gboolean show_encoding, gchar *encoding_str, 274 | gboolean custom_window_title, gboolean lost_focus); 275 | void update_page_name_normal(StrAddr **page_name, 276 | StrAddr **page_color, 277 | struct Window *win_data, 278 | struct Page *page_data); 279 | 280 | // 281 | // **************************** dialog.c **************************** 282 | // 283 | 284 | GtkResponseType dialog(GtkWidget *widget, gsize style); 285 | gint get_color_index(gboolean invert_color, gint index); 286 | gboolean find_str_in_vte(GtkWidget *vte, Dialog_Find_Type type); 287 | void set_markup_key_value(gboolean bold, gchar *color, gchar *key_value, GtkWidget *label); 288 | gboolean check_and_add_locale_to_warned_locale_list(struct Window *win_data, gchar *new_locale); 289 | void create_invalid_locale_error_message(gchar *locale); 290 | void error_dialog(GtkWidget *window, gchar *title_translation, gchar *title, 291 | gchar *icon, gchar *message, gchar *encoding); 292 | #if defined(FATAL) || defined(UNIT_TEST) 293 | void print_switch_out_of_range_error_dialog(gchar *function, gchar *var, gint value); 294 | #endif 295 | GdkRGBA get_inactive_color(GdkRGBA original_fg_color, gdouble new_brightness, gdouble old_brightness); 296 | gboolean upgrade_dialog(gchar *version_str); 297 | gchar *get_colorful_profile(struct Window *win_data); 298 | 299 | // 300 | // **************************** menu.c **************************** 301 | // 302 | 303 | void recreate_theme_menu_items(struct Window *win_data); 304 | gboolean refresh_locale_and_encoding_list(struct Window *win_data); 305 | void set_encoding(GtkWidget *menuitem, gpointer user_data); 306 | gboolean create_menu(struct Window *win_data); 307 | void set_urgent_bell(GtkWidget *widget, struct Window *win_data); 308 | void set_vte_urgent_bell(struct Window *win_data, struct Page *page_data); 309 | gboolean stop_urgency_hint(GtkWidget *window, GdkEvent *event, struct Window *win_data); 310 | GtkWidget *add_radio_menuitem_to_sub_menu(GSList *encoding_group, 311 | GtkWidget *sub_menu, 312 | const gchar *name, 313 | GSourceFunc func, 314 | gpointer func_data); 315 | void refresh_profile_list (struct Window *win_data); 316 | long get_profile_dir_modtime(); 317 | gboolean check_if_win_data_is_still_alive(struct Window *win_data); 318 | void clean_scrollback_lines(GtkWidget *widget, struct Window *win_data); 319 | 320 | #if defined(FATAL) || defined(UNIT_TEST) 321 | void print_active_window_is_null_error_dialog(gchar *function); 322 | #endif 323 | 324 | #endif 325 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include "main.h" 21 | 22 | // for using in socket 23 | gboolean single_process = TRUE; 24 | GtkClipboard *selection_clipboard = NULL; 25 | GtkClipboard *selection_primary = NULL; 26 | 27 | // gchar *command_line_path; 28 | // gchar **empty_environ; 29 | gchar *system_locale_list; 30 | gchar *init_LC_CTYPE; 31 | gchar *init_LANGUAGE; 32 | gchar *init_encoding; 33 | gchar *init_LC_MESSAGES; 34 | const gchar *SYSTEM_VTE_CJK_WIDTH_STR = NULL; 35 | 36 | const gchar *wmclass_name = NULL; 37 | gchar *wmclass_class = NULL; 38 | const gchar *shell = NULL; 39 | gchar *pwd = NULL; 40 | const gchar *home = NULL; 41 | 42 | GList *window_list = NULL; 43 | gchar *profile_dir = NULL; 44 | gboolean proc_exist = FALSE; 45 | gchar *proc_file_system_path = NULL; 46 | 47 | extern gboolean force_to_quit; 48 | extern gchar *restricted_locale_message; 49 | 50 | #ifdef UNIT_TEST 51 | int fake_main(int argc, 52 | char *argv[]) 53 | #else 54 | int main( int argc, 55 | char *argv[]) 56 | #endif 57 | { 58 | #if defined(USE_GTK2_GEOMETRY_METHOD) && defined (GEOMETRY) 59 | g_debug("GEOMETRY_NONE = 0x%X", GEOMETRY_NONE ); 60 | g_debug("GEOMETRY_UPDATE_PAGE_NAME = 0x%X", GEOMETRY_UPDATE_PAGE_NAME); 61 | g_debug("GEOMETRY_UPDATE_PAGE_NAME_MASK = 0x%X", GEOMETRY_UPDATE_PAGE_NAME_MASK); 62 | g_debug("GEOMETRY_CHANGING_THEME = 0x%X", GEOMETRY_CHANGING_THEME); 63 | g_debug("GEOMETRY_SHOW_HIDE_SCROLL_BAR = 0x%X", GEOMETRY_SHOW_HIDE_SCROLL_BAR); 64 | g_debug("GEOMETRY_SHOW_HIDE_TAB_BAR = 0x%X", GEOMETRY_SHOW_HIDE_TAB_BAR); 65 | g_debug("GEOMETRY_CHANGING_FONT = 0x%X", GEOMETRY_CHANGING_FONT); 66 | 67 | g_debug("GEOMETRY_NEEDS_RUN_SIZE_REQUEST_MASK = 0x%X", GEOMETRY_NEEDS_RUN_SIZE_REQUEST_MASK); 68 | g_debug("GEOMETRY_NEEDS_RUN_SIZE_REQUEST_AGAIN_MASK = 0x%X", GEOMETRY_NEEDS_RUN_SIZE_REQUEST_AGAIN_MASK); 69 | g_debug("GEOMETRY_HAD_BEEN_RESIZED_ONCE_MASK = 0x%X", GEOMETRY_HAD_BEEN_RESIZED_ONCE_MASK); 70 | #endif 71 | // command_line_path = argv[0]; 72 | 73 | // g_debug ("argc = %d", argc); 74 | // print_array ("argv", argv); 75 | // i18n support. We need to support i18n under console, too. 76 | setlocale(LC_ALL, ""); 77 | bindtextdomain(BINARY, LOCALEDIR); 78 | bind_textdomain_codeset(BINARY, "UTF-8"); 79 | textdomain(BINARY); 80 | 81 | #if ! defined(SAFEMODE) && defined(DEVELOP) 82 | g_message("Running %s without SAFE MODE!", PACKAGE); 83 | #endif 84 | 85 | #ifdef OUT_OF_MEMORY 86 | # undef g_strdup_printf 87 | #endif 88 | #ifdef ENABLE_PROFILE 89 | const gchar *user_config_dir = g_get_user_config_dir(); 90 | if (user_config_dir) profile_dir = g_strdup_printf("%s/%s", user_config_dir, BINARY); 91 | #endif 92 | #ifdef OUT_OF_MEMORY 93 | #define g_strdup_printf(...) NULL 94 | #endif 95 | // in BSD system, /proc may not exist. 96 | proc_exist = check_if_default_proc_dir_exist(NULL); 97 | // g_debug ("Get proc_exist = %d, proc_file_system_path = %s", proc_exist, proc_file_system_path); 98 | 99 | shell = g_getenv("SHELL"); 100 | if (shell==NULL) shell = ""; 101 | 102 | gboolean pwd_need_be_free = FALSE; 103 | pwd = (gchar *)g_getenv("PWD"); 104 | if (pwd==NULL) 105 | { 106 | pwd_need_be_free = TRUE; 107 | pwd = g_get_current_dir(); 108 | } 109 | if (pwd==NULL) 110 | { 111 | pwd_need_be_free = FALSE; 112 | pwd = ""; 113 | } 114 | // g_debug("Got $PWD = %s", pwd); 115 | 116 | home = g_getenv("HOME"); 117 | if (home==NULL) home = ""; 118 | // g_debug("Get $HOME = %s", home); 119 | 120 | // deal the command line options 121 | command_option(argc, argv); 122 | if (wmclass_name==NULL) wmclass_name = g_getenv("RESOURCE_NAME"); 123 | if (wmclass_name==NULL) wmclass_name = ""; 124 | if (wmclass_class==NULL) wmclass_class = ""; 125 | // g_debug("Got wmclass_name = %s, wmclass_class = %s", wmclass_name, wmclass_class); 126 | 127 | // init the gtk+2 engine 128 | 129 | // GTK3: get gtk_test_widget_click() working... 130 | // gdk_disable_multidevice(); 131 | 132 | #ifndef UNIT_TEST 133 | gtk_init(&argc, &argv); 134 | #endif 135 | // FIXME: we should get the single_process from profile. Current is command-line option only. 136 | if (single_process) 137 | { 138 | gchar *socket_str = convert_socket_data_to_string(argv); 139 | if (init_gtk_socket(SOCKET_FILE, socket_str, (GSourceFunc)convert_string_to_socket_data) == UNIX_SOCKET_DATA_SENT) 140 | { 141 | g_free(profile_dir); 142 | exit (0); 143 | } 144 | g_free(socket_str); 145 | } 146 | 147 | // start LilyTerm 148 | 149 | // empty_environ = g_strsplit("", " ", -1); 150 | extern gchar **environ; 151 | // print_array("main(): environ", environ); 152 | gchar *environ_str = convert_array_to_string(environ, '\t'); 153 | // if (window_list) g_error("CHECK: window_list = %p !!", window_list); 154 | // g_debug("Got environ_str (in main.c) = %s", environ_str); 155 | selection_clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 156 | selection_primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 157 | system_locale_list = get_locale_list(); 158 | // g_debug("Got system_locale_list = %s", system_locale_list); 159 | init_LC_CTYPE = g_strdup(get_default_lc_data(LC_CTYPE)); 160 | // g_debug("Got init_LC_CTYPE = %s", init_LC_CTYPE); 161 | init_LANGUAGE = g_strdup(get_default_lc_data(LANGUAGE)); 162 | // g_debug("Got init_LANGUAGE = %s", init_LANGUAGE); 163 | init_LC_MESSAGES = g_strdup(get_default_lc_data(LC_MESSAGES)); 164 | // g_debug("init_LC_MESSAGES = %s", init_LC_MESSAGES); 165 | init_encoding = (gchar *)get_encoding_from_locale(NULL); 166 | if (! compare_strings(init_encoding, "ANSI_X3.4-1968", TRUE)) 167 | { 168 | g_free(init_encoding); 169 | init_encoding = g_strdup("UTF-8"); 170 | } 171 | // g_debug("init_encoding = %s", init_encoding); 172 | SYSTEM_VTE_CJK_WIDTH_STR = g_getenv("VTE_CJK_WIDTH"); 173 | // g_debug ("Got SYSTEM_VTE_CJK_WIDTH_STR = %s", SYSTEM_VTE_CJK_WIDTH_STR); 174 | // FIXME: signal(SIGCHLD, SIG_IGN); 175 | // The first window of LilyTerm 176 | 177 | // Convert the GdkColor to GdkRGBA 178 | convert_system_color_to_rgba(); 179 | 180 | // g_debug("Got original encoding = %s", get_encoding_from_locale(NULL)); 181 | //GtkNotebook *new_window(int argc, 182 | // char *argv[], 183 | // gchar *shell, 184 | // gchar *environment, 185 | // gchar *locale_list, 186 | // gchar *PWD, 187 | // gchar *HOME, 188 | // gchar *VTE_CJK_WIDTH_STR, 189 | // gboolean VTE_CJK_WIDTH_STR_overwrite_profile, 190 | // gchar *wmclass_name, 191 | // gchar *wmclass_class, 192 | // gchar *user_environ, 193 | // gchar *encoding, 194 | // gboolean encoding_overwrite_profile, 195 | // gchar *lc_messages, 196 | // struct Window *win_data_orig, 197 | // struct Page *page_data_orig) 198 | 199 | // g_debug("main(1): gtk_main_level = %d, g_list_length(window_list) = %d", gtk_main_level(), g_list_length(window_list)); 200 | if ((new_window(argc, 201 | argv, 202 | (gchar *) shell, 203 | environ_str, 204 | system_locale_list, 205 | (gchar *) pwd, 206 | (gchar *) home, 207 | SYSTEM_VTE_CJK_WIDTH_STR, 208 | FALSE, 209 | wmclass_name, 210 | wmclass_class, 211 | NULL, 212 | init_encoding, 213 | FALSE, 214 | init_LC_MESSAGES, 215 | NULL, 216 | NULL)) || 217 | g_list_length(window_list)) 218 | { 219 | // The argv of "main" LilyTerm can't be free. 220 | // Set it to NULL here to avoid double_free(). 221 | argv=NULL; 222 | #ifdef ENABLE_X_STARTUP_NOTIFICATION_ID 223 | gdk_notify_startup_complete_with_id(PACKAGE); 224 | #endif 225 | // g_debug("main(2): gtk_main_level = %d, g_list_length(window_list) = %d", gtk_main_level(), g_list_length(window_list)); 226 | if (! gtk_main_level()) 227 | gtk_main(); 228 | } 229 | #ifdef DETAIL 230 | else 231 | { 232 | // g_debug("Got window_list = %p", window_list); 233 | // GList *win_list = window_list; 234 | // gint i=0; 235 | // 236 | // while (win_list) 237 | // { 238 | // g_debug("Got %d win_data = %p", ++i, win_list->data); 239 | // win_list = win_list->next; 240 | // } 241 | g_debug("??? The creation of first window is FAIL!!!"); 242 | } 243 | #endif 244 | extern struct KeyValue system_keys[KEYS]; 245 | gint i; 246 | // g_debug("Clear function key data!!"); 247 | for (i=KEY_SWITCH_TO_TAB_1; i<=KEY_SWITCH_TO_TAB_12; i++) 248 | { 249 | g_free(system_keys[i].name); 250 | g_free(system_keys[i].topic); 251 | g_free(system_keys[i].comment); 252 | g_free(system_keys[i].translation); 253 | #ifdef UNIT_TEST 254 | system_keys[i].name = NULL; 255 | system_keys[i].topic = NULL; 256 | system_keys[i].comment = NULL; 257 | system_keys[i].translation = NULL; 258 | #endif 259 | } 260 | 261 | // g_free(pwd); 262 | // g_strfreev(empty_environ); 263 | g_free(environ_str); 264 | g_free(init_encoding); 265 | g_free(system_locale_list); 266 | g_free(profile_dir); 267 | if (pwd_need_be_free) g_free(pwd); 268 | g_free(restricted_locale_message); 269 | g_list_free(window_list); 270 | g_free(init_LC_CTYPE); 271 | g_free(init_LC_MESSAGES); 272 | #ifdef UNIT_TEST 273 | // empty_environ = NULL; 274 | environ_str = NULL; 275 | init_encoding = NULL; 276 | system_locale_list = NULL; 277 | profile_dir = NULL; 278 | restricted_locale_message = NULL; 279 | window_list = NULL; 280 | init_LC_CTYPE = NULL; 281 | init_LC_MESSAGES = NULL; 282 | #endif 283 | return 0; 284 | } 285 | 286 | // it will return TRUE if scucceed 287 | gchar *convert_socket_data_to_string(char *argv[]) 288 | { 289 | #ifdef DETAIL 290 | print_array("! convert_socket_data_to_string() argv", argv); 291 | #endif 292 | extern gchar **environ; 293 | 294 | gchar *locale_list = get_locale_list(); 295 | 296 | const gchar *VTE_CJK_WIDTH_STR = g_getenv("VTE_CJK_WIDTH"); 297 | // VTE_CJK_WIDTH can't = NULL 298 | if (VTE_CJK_WIDTH_STR == NULL) VTE_CJK_WIDTH_STR = ""; 299 | 300 | // g_debug("Got LOCALE = %s in send_socket...", get_encoding_from_locale(NULL)); 301 | gchar *encoding = get_encoding_from_locale(NULL); 302 | if (! compare_strings(encoding, "ANSI_X3.4-1968", TRUE)) 303 | { 304 | g_free(encoding); 305 | encoding = g_strdup("UTF-8"); 306 | } 307 | // g_debug("Got encoding = %s in send_socket...", encoding); 308 | gchar *lc_messages = g_strdup(get_default_lc_data(LC_MESSAGES)); 309 | 310 | gchar *environ_str = convert_array_to_string(environ, '\t'); 311 | // print_array("! send_socket() environ", environ); 312 | // g_debug("environ_str = %s", environ_str); 313 | gchar *argv_str = convert_array_to_string(argv, SEPARATE_CHAR); 314 | #ifdef SAFEMODE 315 | gboolean need_free_argv_str = TRUE; 316 | if (argv_str==NULL) argv_str=g_strdup(""); 317 | if (argv_str==NULL) 318 | { 319 | need_free_argv_str = FALSE; 320 | argv_str = ""; 321 | } 322 | #endif 323 | // g_debug("argv_str = %s", argv_str); 324 | 325 | // g_debug("SEND DATA: SOCKET_DATA_VERSION = %s", SOCKET_DATA_VERSION); 326 | // g_debug("SEND DATA: locale_list = %s", locale_list); 327 | // g_debug("SEND DATA: encoding = %s", encoding); 328 | // g_debug("SEND DATA: PWD = %s", PWD); 329 | // g_debug("SEND DATA: VTE_CJK_WIDTH_STR = %s", VTE_CJK_WIDTH_STR); 330 | // g_debug("SEND DATA: wmclass_name = %s", wmclass_name); 331 | // g_debug("SEND DATA: wmclass_class = %s", wmclass_class); 332 | // g_debug("SEND DATA: environ_str = %s", environ_str); 333 | // g_debug("SEND DATA: argv_str = %s", argv_str); 334 | // 0 1 2 3 4 5 6 7 8 9 10 11 335 | // send data: SOCKET_DATA_VERSION SHELL LOCALE_LIST ENCODING LC_MESSAGES PWD HOME VTE_CJK_WIDTH_STR wmclass_name wmclass_class ENVIRON ARGV 336 | // 0 1 2 3 4 5 6 7 8 9 10 11 337 | gchar *arg_str = g_strdup_printf("%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s", 338 | SOCKET_DATA_VERSION, 339 | SEPARATE_CHAR, 340 | shell, 341 | SEPARATE_CHAR, 342 | locale_list, 343 | SEPARATE_CHAR, 344 | encoding, 345 | SEPARATE_CHAR, 346 | lc_messages, 347 | SEPARATE_CHAR, 348 | pwd, 349 | SEPARATE_CHAR, 350 | home, 351 | SEPARATE_CHAR, 352 | VTE_CJK_WIDTH_STR, 353 | SEPARATE_CHAR, 354 | wmclass_name, 355 | SEPARATE_CHAR, 356 | wmclass_class, 357 | SEPARATE_CHAR, 358 | environ_str, 359 | SEPARATE_CHAR, 360 | argv_str); 361 | // g_debug("arg_str = %s", arg_str); 362 | g_free(locale_list); 363 | g_free(encoding); 364 | g_free(lc_messages); 365 | g_free(environ_str); 366 | #ifdef SAFEMODE 367 | if (need_free_argv_str) 368 | #endif 369 | g_free(argv_str); 370 | 371 | return arg_str; 372 | } 373 | 374 | // it will return TRUE if succeed 375 | gboolean convert_string_to_socket_data(gchar *socket_str) 376 | { 377 | #ifdef DETAIL 378 | g_debug("! Launch convert_string_to_socket_data() with socket_str = %s", socket_str); 379 | #endif 380 | // 0 1 2 3 4 5 6 7 8 9 10 11 381 | // get data: SOCKET_DATA_VERSION SHELL LOCALE_LIST ENCODING LC_MESSAGES PWD HOME VTE_CJK_WIDTH_STR wmclass_name wmclass_class ENVIRON ARGV 382 | 383 | gchar **datas = split_string(socket_str, SEPARATE_STR, 12); 384 | // g_debug("The SOCKET_DATA_VERSION = %s ,and the data sent via socket is %s", 385 | // SOCKET_DATA_VERSION, datas[0]); 386 | 387 | if (datas==NULL) 388 | { 389 | // A dirty hack for sometimes the received socket datas is empty. 390 | g_warning("Got a NULL string from the socket!"); 391 | new_window(0, 392 | NULL, 393 | NULL, 394 | NULL, 395 | NULL, 396 | NULL, 397 | NULL, 398 | NULL, 399 | FALSE, 400 | NULL, 401 | NULL, 402 | NULL, 403 | NULL, 404 | FALSE, 405 | NULL, 406 | NULL, 407 | NULL); 408 | } 409 | else if (compare_strings(SOCKET_DATA_VERSION, datas[0], TRUE)) 410 | { 411 | // The SOCKET_DATA_VERSION != the data sent via socket 412 | gchar *received_socket_version = NULL; 413 | if (datas) received_socket_version = datas[0]; 414 | 415 | gchar *message = g_strdup_printf(_("The data got from socket seems incorrect.\n\n" 416 | "\tReceived socket version: %s\n" 417 | "\tExpected socket version: %s\n\n" 418 | "If you just updated %s recently,\n" 419 | "Please close all the windows of %s and try again."), 420 | received_socket_version, SOCKET_DATA_VERSION, 421 | PACKAGE, PACKAGE); 422 | error_dialog(NULL, 423 | _("The format of socket data is out of date"), 424 | "The format of socket data is out of date", 425 | GTK_FAKE_STOCK_DIALOG_ERROR, 426 | message, 427 | NULL); 428 | g_free(message); 429 | } 430 | else 431 | { 432 | // g_debug("datas[11] = %s", datas[11]); 433 | gchar **argv = split_string(datas[11], SEPARATE_STR, -1); 434 | gint argc = 0; 435 | if (argv) 436 | while (argv[argc]) 437 | argc ++; 438 | 439 | // g_debug("Final:"); 440 | // g_debug("\targc =%d", argc); 441 | // print_array("\targv", argv); 442 | // g_debug("\tSHELL = %s", datas[1]); 443 | // g_debug("\tenvironments = %s", datas[10]); 444 | // g_debug("\tlocale_list = %s", datas[2]); 445 | // g_debug("\tPWD = %s", datas[5]); 446 | // g_debug("\tHOME = %s", datas[6]); 447 | // g_debug("\tVTE_CJK_WIDTH_STR = %s", datas[7]); 448 | // g_debug("\twmclass_name = %s", datas[8]); 449 | // g_debug("\twmclass_class= %s", datas[9]); 450 | // g_debug("\tencoding = %s", datas[3]); 451 | // g_debug("\tlc_messages = %s", datas[4]); 452 | 453 | //GtkNotebook *new_window(int argc, 454 | // char *argv[], 455 | // gchar *shell, // 1 456 | // gchar *environment, // 10 457 | // gchar *locale_list, // 2 458 | // gchar *PWD, // 5 459 | // gchar *HOME, // 6 460 | // gchar *VTE_CJK_WIDTH_STR, // 7 461 | // gboolean VTE_CJK_WIDTH_STR_overwrite_profile, 462 | // gchar *wmclass_name, // 8 463 | // gchar *wmclass_class, // 9 464 | // gchar *user_environ, 465 | // gchar *encoding, // 3 466 | // gboolean encoding_overwrite_profile, 467 | // gchar *lc_messages, // 4 468 | // struct Window *win_data_orig, 469 | // struct Page *page_data_orig) 470 | 471 | if ((new_window(argc, 472 | argv, 473 | datas[1], 474 | datas[10], 475 | datas[2], 476 | datas[5], 477 | datas[6], 478 | datas[7], 479 | FALSE, 480 | datas[8], 481 | datas[9], 482 | NULL, 483 | datas[3], 484 | FALSE, 485 | datas[4], 486 | NULL, 487 | NULL) == NULL && (g_list_length(window_list) == 0))) 488 | // Sometimes, new_window() will return NULL. Therefore LilyTerm may should quit. 489 | quit_gtk(); 490 | // g_debug("main(3): gtk_main_level = %d, g_list_length(window_list) = %d", gtk_main_level(), g_list_length(window_list)); 491 | g_strfreev(argv); 492 | } 493 | g_strfreev(datas); 494 | 495 | // return FALSE means this connection is finish. 496 | return FALSE; 497 | } 498 | 499 | void main_quit(GtkWidget *widget, struct Window *win_data) 500 | { 501 | #ifdef DETAIL 502 | g_debug("! Launch main_quit() with win_data = %p!", win_data); 503 | #endif 504 | // g_debug("Total window = %d", g_list_length(window_list)); 505 | if (g_list_length(window_list)==1) 506 | { 507 | #ifdef SAFEMODE 508 | // g_debug ("main_quit(): win_data==NULL, call gtk_main_quit()"); 509 | if (win_data==NULL) return quit_gtk(); 510 | #endif 511 | window_quit(win_data->window, NULL, win_data); 512 | } 513 | else 514 | { 515 | GString *all_process_list = g_string_new(NULL); 516 | GString *child_process_list; 517 | GList *win_list = window_list; 518 | struct Window *temp_win_data; 519 | gint i = 1; 520 | while (win_list) 521 | { 522 | temp_win_data = win_list->data; 523 | child_process_list = close_multi_tabs(temp_win_data, i); 524 | #ifdef SAFEMODE 525 | if (child_process_list) 526 | #endif 527 | g_string_append (all_process_list, child_process_list->str); 528 | g_string_free(child_process_list, TRUE); 529 | win_list = win_list->next; 530 | i++; 531 | } 532 | 533 | // g_debug("Got all_process_list =%s", all_process_list->str); 534 | #ifdef SAFEMODE 535 | if ((all_process_list==NULL) || (all_process_list->len==0) || 536 | (display_child_process_dialog (all_process_list, win_data, 537 | CONFIRM_TO_EXIT_WITH_CHILD_PROCESS))) 538 | #else 539 | if ((all_process_list->len==0) || 540 | (display_child_process_dialog (all_process_list, win_data, 541 | CONFIRM_TO_EXIT_WITH_CHILD_PROCESS))) 542 | #endif 543 | { 544 | force_to_quit = TRUE; 545 | // g_debug ("main_quit(): call gtk_main_quit()"); 546 | quit_gtk(); 547 | } 548 | g_string_free(all_process_list, TRUE); 549 | } 550 | } 551 | 552 | void quit_gtk() 553 | { 554 | #ifdef DETAIL 555 | g_debug("! Launch quit_gtk()"); 556 | #endif 557 | if (gtk_main_level()) gtk_main_quit(); 558 | } 559 | 560 | gchar *get_locale_list() 561 | { 562 | #ifdef DETAIL 563 | g_debug("! Launch get_locale_list()!"); 564 | #endif 565 | #ifdef OUT_OF_MEMORY 566 | # undef g_getenv 567 | #endif 568 | return join_strings_to_string(' ', 569 | 14, 570 | g_getenv("LANG"), 571 | g_getenv("LC_CTYPE"), 572 | g_getenv("LC_NUMERIC"), 573 | g_getenv("LC_TIME"), 574 | g_getenv("LC_COLLATE"), 575 | g_getenv("LC_MONETARY"), 576 | g_getenv("LC_MESSAGES"), 577 | g_getenv("LC_PAPER"), 578 | g_getenv("LC_NAME"), 579 | g_getenv("LC_ADDRESS"), 580 | g_getenv("LC_TELEPHONE"), 581 | g_getenv("LC_MEASUREMENT"), 582 | g_getenv("LC_IDENTIFICATION"), 583 | g_getenv("LC_ALL")); 584 | #ifdef OUT_OF_MEMORY 585 | #define g_getenv(x) NULL 586 | #endif 587 | } 588 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | // for g_get_tmp_dir() 22 | #include 23 | // for L10n 24 | #include 25 | #include 26 | // for exit() 27 | #include 28 | // for socket() 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "lilyterm.h" 36 | 37 | // the max size of saddr.sun_path in Linux is 108! 38 | #define UNIX_PATH_MAX 108 39 | 40 | #ifdef UNIT_TEST 41 | int fake_main(int argc, char *argv[]); 42 | #endif 43 | 44 | gboolean set_fd_non_block(gint *fd); 45 | gboolean init_socket_server(); 46 | gboolean accept_socket(GIOChannel *source, GIOCondition condition, gpointer user_data); 47 | gboolean read_socket(GIOChannel *channel, GIOCondition condition, gpointer user_data); 48 | gboolean socket_fault(int i, GError *error, GIOChannel* channel, gboolean unref); 49 | gboolean clear_channel(GIOChannel* channel, gboolean unref); 50 | gint shutdown_socket_server(gpointer data); 51 | gchar *get_locale_list(); 52 | -------------------------------------------------------------------------------- /src/menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | // for L10n 23 | #include 24 | #include 25 | // for opendir() readdir() closedir() 26 | #include 27 | // for stat() 28 | #include 29 | // for memcpy() memset() 30 | #include 31 | // for aoti() 32 | #include 33 | // for GDK_WINDOW_XID 34 | #include 35 | 36 | #include "lilyterm.h" 37 | 38 | typedef enum { 39 | IMAGE_MENU_ITEM, 40 | CHECK_MENU_ITEM, 41 | } Menu_Itemn_Type; 42 | 43 | typedef enum { 44 | NEW_WINDOW_FROM_SYSTEM_PROFILE, 45 | NEW_WINDOW_FROM_PROFILE, 46 | LOAD_FROM_SYSTEM_PROFILE, 47 | LOAD_FROM_PROFILE, 48 | APPLY_FROM_NEW_WIN_DATA, 49 | } Apply_Profile_Type; 50 | 51 | struct Preview 52 | { 53 | gchar *default_filename; 54 | GtkWidget *mainbox; 55 | GtkWidget *frame; 56 | GtkWidget *vbox; 57 | GtkWidget *image; 58 | GtkWidget *no_image_text; 59 | GtkWidget *scroll_background; 60 | }; 61 | 62 | void new_tab_with_locale(GtkWidget *local_menuitem, gboolean VTE_CJK_WIDTH); 63 | GtkWidget *check_name_in_menuitem(GtkWidget *sub_menu, const gchar *name, gboolean case_sensitive); 64 | #if defined(ENABLE_VTE_BACKGROUND) || defined(FORCE_ENABLE_VTE_BACKGROUND) || defined(UNIT_TEST) 65 | void set_trans_bg(GtkWidget *menuitem_trans_bg, struct Window *win_data); 66 | void load_background_image_from_file(GtkWidget *widget, struct Window *win_data); 67 | void update_preview_image (GtkFileChooser *dialog, struct Preview *preview); 68 | #endif 69 | void set_trans_win(GtkWidget *widget, GtkWidget *window); 70 | void invert_color_theme(GtkWidget *menuitem, struct Window *win_data); 71 | void select_ansi_theme(GtkWidget *menuitem, gint index); 72 | void set_ansi_theme(GtkWidget *menuitem, Set_ANSI_Theme_Type type, gboolean use_custom_theme, gboolean invert_color, 73 | gint theme_index, struct Window *win_data); 74 | void set_auto_save(GtkWidget *menuitem, struct Window *win_data); 75 | void set_erase_binding (GtkWidget *menuitem, gint value); 76 | #if defined(ENABLE_CURSOR_SHAPE) || defined(UNIT_TEST) 77 | void set_cursor_shape (GtkWidget *menuitem, gint value); 78 | #endif 79 | GSList *create_theme_menu_items(struct Window *win_data, GtkWidget *sub_menu, GSList *theme_group, gint current_theme, gint custom_theme); 80 | void reset_vte(GtkWidget *widget, struct Window *win_data); 81 | void select_font(GtkWidget *widget, struct Window *win_data); 82 | void set_dim_text(GtkWidget *menuitem_dim_text, struct Window *win_data); 83 | #ifdef ENABLE_RGBA 84 | void set_dim_window(GtkWidget *menuitem_dim_text, struct Window *win_data); 85 | #endif 86 | void set_cursor_blinks(GtkWidget *widget, struct Window *win_data); 87 | void set_allow_bold_text(GtkWidget *menuitem_allow_bold_text, struct Window *win_data); 88 | void set_open_url_with_ctrl_pressed(GtkWidget *menuitem_open_url_with_ctrl_pressed, struct Window *win_data); 89 | void set_disable_url_when_ctrl_pressed(GtkWidget *menuitem_disable_url_when_ctrl_pressed, struct Window *win_data); 90 | void set_audible_bell(GtkWidget *widget, struct Window *win_data); 91 | #if defined(ENABLE_VISIBLE_BELL) || defined(UNIT_TEST) 92 | void set_visible_bell(GtkWidget *widget, struct Window *win_data); 93 | #endif 94 | void urgent_beep(GtkWidget *window, struct Page *page_data); 95 | void launch_hide_and_show_tabs_bar(GtkWidget *widget, Switch_Type show_tabs_bar); 96 | void copy_url_clipboard(GtkWidget *widget, gpointer user_data); 97 | void copy_clipboard(GtkWidget *widget, struct Window *win_data); 98 | void paste_clipboard(GtkWidget *widget, struct Window *win_data); 99 | void paste_to_every_vte(GtkWidget *widget, struct Window *win_data); 100 | void open_current_dir_with_file_manager(GtkWidget *widget, struct Window *win_data); 101 | void view_current_page_info(GtkWidget *widget, struct Window *win_data); 102 | void view_clipboard(GtkWidget *widget, struct Window *win_data); 103 | void view_primary(GtkWidget *widget, struct Window *win_data); 104 | gint add_menuitem_to_locale_sub_menu(struct Window *win_data, gint no, gchar *name); 105 | GtkWidget *recreate_profile_menu_item(GtkWidget *menuitem, GtkWidget *subitem, 106 | struct Window *win_data, Apply_Profile_Type type); 107 | void create_new_window_from_menu_items(GtkWidget *sub_menu, const gchar *stock_id); 108 | void create_load_profile_from_menu_items(GtkWidget *sub_menu, const gchar *stock_id, struct Window *win_data); 109 | gboolean create_profile_menu_list(GtkWidget *sub_menu, const gchar *stock_id, GSourceFunc func, gpointer func_data); 110 | void apply_profile_from_file_dialog(GtkWidget *menu_item, Apply_Profile_Type type); 111 | void apply_profile_from_menu_item(GtkWidget *menu_item, Apply_Profile_Type type); 112 | void apply_profile_from_file(const gchar *path, Apply_Profile_Type type); 113 | void reload_settings(GtkWidget *menu_item, struct Window *win_data); 114 | void apply_to_every_window(GtkWidget *menu_item, struct Window *win_data); 115 | void save_user_settings_as(GtkWidget *widget, struct Window *win_data); 116 | GtkWidget *create_load_file_dialog(GtkFileChooserAction action, GtkWidget *window, gchar *button_text, gchar *filename); 117 | GtkWidget *create_menu_item (Menu_Itemn_Type type, GtkWidget *sub_menu, const gchar *label, const gchar *label_name, 118 | const gchar *stock_id, GSourceFunc func, gpointer func_data); 119 | GtkWidget *create_sub_item (GtkWidget *menu, gchar *label, const gchar *stock_id); 120 | GtkWidget *create_sub_item_subitem (gchar *label, const gchar *stock_id); 121 | GtkWidget *create_sub_item_submenu (GtkWidget *menu, GtkWidget *menu_item); 122 | GtkWidget *add_separator_menu(GtkWidget *sub_menu); 123 | void set_menuitem_label(GtkWidget *menu_item, gchar *text); 124 | void enable_disable_theme_menus(struct Window *win_data, gboolean show); 125 | -------------------------------------------------------------------------------- /src/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | // for setenv() and unsetenv() 22 | #include 23 | // for usleep() 24 | #include 25 | // for strcmp() 26 | #include 27 | // for L10n 28 | #include 29 | #include 30 | 31 | #include "lilyterm.h" 32 | 33 | gboolean check_if_proc_dir_exist(gchar *proc_dir); 34 | -------------------------------------------------------------------------------- /src/notebook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | // for kill 25 | #include 26 | // for exit() and env() 27 | #include 28 | // for sockaddr_un 29 | #include 30 | // for GDK_WINDOW_XID 31 | // #include 32 | 33 | #include "lilyterm.h" 34 | 35 | gchar **get_argv(struct Window *win_data, gboolean *argv_need_be_free); 36 | void create_utf8_child_process_failed_dialog (struct Window *win_data, gchar *message, gchar *encoding); 37 | void create_child_process_failed_dialog(struct Window *win_data, gchar *message, gchar *encoding); 38 | void clear_arg(struct Window *win_data); 39 | #if defined (USE_GTK2_GEOMETRY_METHOD) || defined(UNIT_TEST) 40 | void label_size_request (GtkWidget *label, GtkRequisition *requisition, struct Page *page_data); 41 | #endif 42 | gboolean vte_button_press(GtkWidget *widget, GdkEventButton *event, struct Page *page_data); 43 | gboolean vte_button_release(GtkWidget *widget, GdkEventButton *event, struct Page *page_data); 44 | void vte_grab_focus(GtkWidget *vte, gpointer user_data); 45 | gboolean compare_win_page_encoding(GtkWidget *menu_item_encoding, gchar *encoding_str); 46 | // void vte_style_set (GtkWidget *vte, GtkStyle *previous_style, gpointer user_data); 47 | // void vte_size_request (GtkWidget *vte, GtkRequisition *requisition, gpointer user_data); 48 | // void vte_size_allocate (GtkWidget *vte, GtkAllocation *allocation, gpointer user_data); 49 | gchar *get_url (GdkEventButton *event, struct Page *page_data, gint *tag); 50 | #if defined(GEOMETRY) || defined(UNIT_TEST) 51 | void vte_size_allocate (GtkWidget *vte, GtkAllocation *allocation, struct Page *page_data); 52 | #endif 53 | void vte_size_changed(VteTerminal *vte, Font_Set_Type type); 54 | void page_data_dup(struct Page *page_data_prev, struct Page *page_data); 55 | // void vte_paste_clipboard (VteTerminal *vte, gpointer user_data); 56 | gchar *get_language_str_from_locales(const gchar *new_locale, const gchar *old_locale); 57 | gchar *get_lang_str_from_locale(const gchar *locale, const gchar *split); 58 | -------------------------------------------------------------------------------- /src/pagename.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | // for aoti() 23 | #include 24 | // for strlen() 25 | #include 26 | // for usleep() 27 | #include 28 | // for stat() 29 | #include 30 | #include "lilyterm.h" 31 | 32 | gboolean check_cmdline (struct Page *page_data, pid_t check_tpgid); 33 | gboolean check_window_title (struct Page *page_data, gboolean lost_focus); 34 | gboolean check_pwd(struct Page *page_data, gchar *pwd, gchar *new_pwd, gint page_update_method); 35 | gchar *get_tab_name_with_page_names(struct Window *win_data); 36 | gchar *get_tab_name_with_cmdline(struct Page *page_data); 37 | -------------------------------------------------------------------------------- /src/profile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #define _GNU_SOURCE 21 | 22 | #include 23 | #include 24 | // for L10n 25 | #include 26 | #include 27 | // for aoti() aotf() canonicalize_file_name() 28 | #include 29 | // for access() 30 | #include 31 | // for strcmp() 32 | #include 33 | // for XParseGeometry() 34 | #include 35 | 36 | #include "lilyterm.h" 37 | 38 | #define DEFAULT_FOREGROUND_COLOR "white" 39 | #define DEFAULT_BACKGROUND_COLOR "black" 40 | #define DEFAULT_CURSOR_COLOR "#44738B" 41 | 42 | #ifdef BSD 43 | // chars in a path name including nul 44 | // which is already defined in /usr/include/sys/syslimits.h 45 | // #define PATH_MAX 4096 46 | #endif 47 | 48 | typedef enum { 49 | DISABLE_EMPTY_STR, 50 | ENABLE_EMPTY_STR, 51 | } Check_Empty; 52 | 53 | typedef enum { 54 | DISABLE_ZERO, 55 | ENABLE_ZERO, 56 | } Check_Zero; 57 | 58 | typedef enum { 59 | NO_CHECK_MIN, 60 | CHECK_MIN, 61 | } Check_Min; 62 | 63 | typedef enum { 64 | NO_CHECK_MAX, 65 | CHECK_MAX, 66 | } Check_Max; 67 | 68 | void init_command(); 69 | void init_user_command(struct Window *win_data); 70 | void init_window_parameters(struct Window *win_data); 71 | void init_user_keys(struct Window *win_data); 72 | void init_key_bindings_name_and_group(); 73 | void init_key_bindings(); 74 | void init_page_color_data(); 75 | void init_page_color_data_comment(); 76 | void init_mod_keys(); 77 | void init_colors(); 78 | gchar *load_profile_from_dir(const gchar *dir, const gchar* profile); 79 | #ifdef ENABLE_PROFILE 80 | gdouble check_double_value(GKeyFile *keyfile, const gchar *group_name, const gchar *key, const gdouble default_value, 81 | Check_Empty enable_empty, gdouble empty_value, 82 | Check_Min check_min, gdouble min, 83 | Check_Max check_max, gdouble max); 84 | glong check_integer_value(GKeyFile *keyfile, const gchar *group_name, const gchar *key, 85 | const glong default_value, Check_Empty enable_empty, glong empty_value, 86 | Check_Zero enable_zero, Check_Min check_min, glong min, 87 | Check_Max check_max, glong max); 88 | gchar *check_string_value(GKeyFile *keyfile, const gchar *group_name, 89 | const gchar *key, gchar *original_value, gboolean free_original_value, Check_Empty enable_empty); 90 | #endif 91 | gboolean check_color_value (const gchar *key_name, const gchar *color_name, GdkRGBA *color, const GdkRGBA *default_color); 92 | gboolean accelerator_parse(const gchar *key_name, const gchar *key_value, guint *key, guint *mods); 93 | void create_save_failed_dialog(struct Window *win_data, gchar *message); 94 | -------------------------------------------------------------------------------- /src/property.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #define _GNU_SOURCE 21 | 22 | #include 23 | #include 24 | // for L10n 25 | #include 26 | #include 27 | // for strlen() 28 | #include 29 | // for aoti() aotf() canonicalize_file_name() 30 | #include 31 | // for access() 32 | #include 33 | 34 | #include "lilyterm.h" 35 | #if defined(USE_GTK3_GEOMETRY_METHOD) || defined(UNIT_TEST) 36 | void get_hint_min_size(GtkWidget *notebook, GtkWidget *scrollbar, gint *min_width, gint *min_height); 37 | #endif 38 | -------------------------------------------------------------------------------- /src/socket.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2016 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * GtkSocket is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GtkSocket is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with GtkSocket. If not, see . 16 | */ 17 | 18 | // The Main Function Usage: 19 | // 20 | // Unix_Socket_States init_gtk_socket(gchar *package_name, gchar *socket_str, GSourceFunc read_function) 21 | // 22 | // package_name: The uniq name of package. 23 | // The socket server will create an unix soket file at /tmp/.PACKAGENAME_USERNAME:DISPLAY 24 | // socket_str: A string will be sent to the socket server, if it exist. 25 | // read_function: A function that will headle the socket_str as it's the socket server. 26 | // gboolean read_function(gchar *socket_str) 27 | // 28 | // Example: 29 | // if (init_gtk_socket(PACKAGE, socket_str, (GSourceFunc)read_function) == UNIX_SOCKET_DATA_SENT) 30 | // /* Data is sent. Quiting... */ 31 | // 32 | // return: UNIX_SOCKET_SERVER_INITED: had been inited as a unix socket server. 33 | // UNIX_SOCKET_DATA_SENT: the data had been sent to an unix socket server. 34 | // UNIX_SOCKET_ERROR: error occured. 35 | 36 | // 37 | // init_gtk_socket() -----------------(N)------------------------------------> return FALSE 38 | // | ^ ^ 39 | // init_socket_data() | | 40 | // socket_fd -------------------(N)---| | 41 | // set_fd_non_block ------------(N)---/ | 42 | // | | 43 | // query_socket() | 44 | // connect ---------------------(N)-------> init_socket_server()--------------| 45 | // | ^ unlink | 46 | // send_socket() | bind -----------------------(N)-| 47 | // * g_io_channel_unix_new -------(N)---| listen ---------------------(N)-| 48 | // g_io_channel_set_encoding ---(N)---| * g_io_channel_unix_new ------(N)-| 49 | // g_io_channel_set_buffered | g_io_channel_set_encoding --(N)-| 50 | // g_io_channel_write_chars ----(N)---| g_io_add_watch -------------(N)-/ 51 | // g_io_channel_flush ----------(N)---/ | 52 | // + clear_channel() |---- accept_socket() 53 | // g_io_channel_shutdown | (condition) 54 | // (g_io_channel_unref) | accept 55 | // | | set_fd_non_block 56 | // exit() | * g_io_channel_unix_new 57 | // | g_io_channel_set_encoding 58 | // | g_io_add_watch 59 | // | | 60 | // | `-- read_socket() 61 | // | g_io_channel_read_line 62 | // | [READ_FUNC] 63 | // | + clear_channel() 64 | // | g_io_channel_shutdown 65 | // | (g_io_channel_unref) 66 | // \---- g_atexit() 67 | // shutdown_socket_server() 68 | // unlink 69 | // + clear_channel() 70 | // g_io_channel_shutdown 71 | // (g_io_channel_unref) 72 | 73 | 74 | #include 75 | 76 | // for exit() 77 | #include 78 | // for socket() 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | 85 | #include "socket.h" 86 | 87 | // the max size of saddr.sun_path in Linux is 108! 88 | #define UNIX_PATH_MAX 108 89 | # define MAX_BACKLOG 100 90 | 91 | typedef enum { 92 | GTK_SOCKET_ERROR_CREATE_SOCKET_FILE, 93 | GTK_SOCKET_ERROR_CONNECT_SOCKET, 94 | GTK_SOCKET_ERROR_BIND_SOCKET, 95 | GTK_SOCKET_ERROR_LISTEN_SOCKET, 96 | GTK_SOCKET_ERROR_WATCH_SOCKET, 97 | GTK_SOCKET_ERROR_ACCEPT_REQUEST, 98 | GTK_SOCKET_ERROR_RECEIVE_DATA, 99 | GTK_SOCKET_ERROR_FCNTL, 100 | GTK_SOCKET_ERROR_CHANNEL_ENCODING, 101 | GTK_SOCKET_ERROR_SHUTDOWN_CHANNEL, 102 | GTK_SOCKET_ERROR_WRITE_CHANNEL, 103 | GTK_SOCKET_ERROR_CREATE_CHANNEL, 104 | GTK_SOCKET_ERROR_WRITE_BUFFER, 105 | GTK_SOCKET_ERROR_GOT_NULL_STRING, 106 | GTK_SOCKET_ERROR_TMP_DIR, 107 | } Unix_Socket_Error; 108 | 109 | gboolean init_socket_fd(); 110 | gboolean init_socket_data(gchar *package_name); 111 | gboolean set_fd_non_block(gint *fd); 112 | gboolean query_socket(); 113 | gboolean send_socket(gchar *socket_str); 114 | gboolean clear_channel(GIOChannel *channel, gboolean unref); 115 | gboolean init_socket_server(GSourceFunc read_function); 116 | gboolean accept_socket(GIOChannel *source, GIOCondition condition, GSourceFunc read_function); 117 | gboolean read_socket(GIOChannel *channel, GIOCondition condition, GSourceFunc read_function); 118 | gint shutdown_socket_server(gpointer data); 119 | gboolean socket_fault(Unix_Socket_Error type, GError *error, GIOChannel *channel, gboolean unref); 120 | 121 | // for unix socket 122 | gint socket_fd = 0; 123 | struct sockaddr_un address = {0}; 124 | int address_len = -1; 125 | GIOChannel *main_channel = NULL; 126 | 127 | #if ! GLIB_CHECK_VERSION(2,5,0) 128 | // SICNE glib-2.5.0/glib/gmessages.h:g_debug() 129 | #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) 130 | #endif 131 | #if ! GTK_CHECK_VERSION(2,23,0) 132 | // END: gtk+-2.23.0/gtk/gtkmain.h: gtk_quit_add() GTK_DISABLE_DEPRECATED 133 | #define g_atexit(x) gtk_quit_add(0, (GtkFunction)x, NULL) 134 | #endif 135 | #if GLIB_CHECK_VERSION(2,31,2) 136 | // END: glib-2.31.2/glib/gutils.h: g_atexit () GLIB_DEPRECATED 137 | #define g_atexit atexit 138 | #endif 139 | 140 | // it will return UNIX_SOCKET_SERVER_INITED if succeed 141 | Unix_Socket_States init_gtk_socket(gchar *package_name, gchar *socket_str, GSourceFunc read_function) 142 | { 143 | #ifdef DETAIL 144 | g_debug("! Launch init_gtk_socket() with package_name = %s, socket_str = %s", package_name, socket_str); 145 | #endif 146 | // if Socket Server call init_gtk_socket() again... 147 | if (address_len > 0) 148 | { 149 | if (init_socket_fd() && query_socket() && (send_socket(socket_str))) 150 | return UNIX_SOCKET_DATA_SENT; 151 | } 152 | 153 | // init socket data 154 | if (init_socket_data(package_name)) 155 | { 156 | // trying to connect to an existing Socket Server 157 | if (query_socket()) 158 | { 159 | // success, sent the socket_str then quit 160 | if (send_socket(socket_str)) 161 | { 162 | exit (0); 163 | return UNIX_SOCKET_DATA_SENT; 164 | } 165 | } 166 | 167 | // no socket server exist. create a socket server 168 | if (init_socket_server(read_function)) 169 | { 170 | g_atexit((GVoidFunc)shutdown_socket_server); 171 | return UNIX_SOCKET_SERVER_INITED; 172 | } 173 | } 174 | 175 | return UNIX_SOCKET_ERROR; 176 | } 177 | 178 | gboolean init_socket_fd() 179 | { 180 | #ifdef DETAIL 181 | g_debug("! Launch init_socket_fd()"); 182 | #endif 183 | GError *error = NULL; 184 | // init socket 185 | socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); 186 | if (socket_fd < 0) 187 | // main_channel is NULL, so that we don't need to launch clear_channel() 188 | return socket_fault(GTK_SOCKET_ERROR_CREATE_SOCKET_FILE, error, NULL, FALSE); 189 | return TRUE; 190 | } 191 | 192 | // it will return TRUE if init socket data successfully 193 | gboolean init_socket_data(gchar *package_name) 194 | { 195 | #ifdef DETAIL 196 | g_debug("! Launch init_socket_data() to init %s socket!", PACKAGE); 197 | #endif 198 | GError *error = NULL; 199 | 200 | // clean data first 201 | bzero(&address, sizeof(address)); 202 | // init the address of socket 203 | address.sun_family = AF_UNIX; 204 | 205 | const gchar *tmp_dir = g_get_tmp_dir(); 206 | 207 | if (tmp_dir) 208 | g_snprintf(address.sun_path, UNIX_PATH_MAX, "%s/.%s_%s%s", 209 | tmp_dir ,package_name, g_get_user_name(), 210 | gdk_display_get_name(gdk_display_get_default())); 211 | else 212 | return socket_fault(GTK_SOCKET_ERROR_TMP_DIR, error, NULL, FALSE); 213 | 214 | address.sun_path[UNIX_PATH_MAX-1] = address.sun_path[UNIX_PATH_MAX-2] = '\0'; 215 | // g_debug("The socket file is %s", address.sun_path); 216 | address_len = sizeof(address); 217 | 218 | if (! init_socket_fd()) return FALSE; 219 | 220 | // set this socket is non-block 221 | return set_fd_non_block(&socket_fd); 222 | } 223 | 224 | 225 | // it will return TRUE if scucceed 226 | gboolean set_fd_non_block(gint *fd) 227 | { 228 | #ifdef DETAIL 229 | if (fd) 230 | g_debug("! Launch set_fd_non_block() with fd = %d!", *fd); 231 | else 232 | g_debug("! Launch set_fd_non_block() with fd = (%p)!", fd); 233 | #endif 234 | #ifdef SAFEMODE 235 | if (fd==NULL) return FALSE; 236 | #endif 237 | GError *error = NULL; 238 | gint flags = fcntl(*fd, F_GETFL, 0); 239 | if (fcntl(*fd, F_SETFL, O_NONBLOCK|flags) < 0) 240 | // main_channel is NULL, so that we don't need to launch clear_channel() 241 | return socket_fault(GTK_SOCKET_ERROR_FCNTL, error, NULL, FALSE); 242 | return TRUE; 243 | } 244 | 245 | 246 | // it will return TRUE if scucceed 247 | gboolean query_socket() 248 | { 249 | #ifdef DETAIL 250 | g_debug("! Launch query_socket() to connect to an existing %s !", PACKAGE); 251 | #endif 252 | GError *error = NULL; 253 | 254 | if (connect(socket_fd, (struct sockaddr *)&address, address_len) < 0) 255 | // main_channel is NULL, so that we don't need to launch clear_channel() 256 | return socket_fault(GTK_SOCKET_ERROR_CONNECT_SOCKET, error, NULL, FALSE); 257 | return TRUE; 258 | } 259 | 260 | 261 | // it will return TRUE if scucceed 262 | gboolean send_socket(gchar *socket_str) 263 | { 264 | #ifdef DETAIL 265 | g_debug("! Launch send_socket() to send data to the exiting %s with socket_str = \"%s\"!", PACKAGE, socket_str); 266 | #endif 267 | // write data! 268 | #ifdef SAFEMODE 269 | if (fcntl(socket_fd, F_GETFL) < 0) return FALSE; 270 | #endif 271 | GError *error = NULL; 272 | GIOChannel *channel = g_io_channel_unix_new(socket_fd); 273 | gsize len; 274 | 275 | // main_channel is NULL, so that we don't need to launch clear_channel() 276 | if (!channel) return socket_fault(GTK_SOCKET_ERROR_CREATE_CHANNEL, NULL, NULL, FALSE); 277 | 278 | // set the channel to read binary file 279 | if (g_io_channel_set_encoding(channel, NULL, &error) == G_IO_STATUS_ERROR) 280 | return socket_fault(GTK_SOCKET_ERROR_CHANNEL_ENCODING, error, channel, TRUE); 281 | 282 | g_io_channel_set_buffered (channel, FALSE); 283 | 284 | if (g_io_channel_write_chars(channel, socket_str, -1, &len, &error)==G_IO_STATUS_ERROR) 285 | // main_channel is NULL, so that we don't need to launch clear_channel() 286 | return socket_fault(GTK_SOCKET_ERROR_WRITE_CHANNEL, error, channel, TRUE); 287 | 288 | // flush writing datas 289 | // there are three results: 290 | // G_IO_STATUS_AGAIN this means temporarily anvailable, so try again 291 | // G_IO_STATUS_NORMAL 292 | // G_IO_STATUS_ERROR 293 | GIOStatus ioStatus; 294 | do ioStatus = g_io_channel_flush(channel, &error); 295 | while (ioStatus == G_IO_STATUS_AGAIN); 296 | 297 | if (ioStatus == G_IO_STATUS_ERROR) 298 | // main_channel is NULL, so that we don't need to launch clear_channel() 299 | return socket_fault(GTK_SOCKET_ERROR_WRITE_BUFFER, error, channel, TRUE); 300 | 301 | // So far so good. shutdown and clear channel! 302 | clear_channel(channel, TRUE); 303 | 304 | // FIXME: sleep for 1 sec to wait the socket server. any better idea? 305 | sleep(1); 306 | 307 | return TRUE; 308 | } 309 | 310 | 311 | // it will return TRUE if scucceed 312 | gboolean clear_channel(GIOChannel *channel, gboolean unref) 313 | { 314 | #ifdef DETAIL 315 | g_debug("! Launch clear_channel() to clear channel data !"); 316 | #endif 317 | if (channel == NULL) return TRUE; 318 | 319 | gboolean return_value = TRUE; 320 | GError *error = NULL; 321 | 322 | if (g_io_channel_shutdown(channel, TRUE, &error) == G_IO_STATUS_ERROR) 323 | return_value = socket_fault(GTK_SOCKET_ERROR_SHUTDOWN_CHANNEL, error, NULL, FALSE); 324 | 325 | if (return_value && unref) 326 | { 327 | g_io_channel_unref(channel); 328 | channel = NULL; 329 | } 330 | 331 | return return_value; 332 | } 333 | 334 | 335 | // it will return TRUE if succeed 336 | gboolean init_socket_server(GSourceFunc read_function) 337 | { 338 | #ifdef DETAIL 339 | g_debug("! Launch init_socket_server() to init a %s socket server !", PACKAGE); 340 | #endif 341 | GError *error = NULL; 342 | 343 | // clear the prev file 344 | if (address.sun_path[0]) unlink(address.sun_path); 345 | 346 | // fchmod() on socket may cause unspecified behaviour. 347 | 348 | // bind the socket on a file 349 | if (bind(socket_fd, (struct sockaddr *)&address, address_len) < 0) 350 | // main_channel is NULL, so that we don't need to launch clear_channel() 351 | return socket_fault(GTK_SOCKET_ERROR_BIND_SOCKET, error, NULL, FALSE); 352 | 353 | // create socket queue 354 | if (listen(socket_fd, MAX_BACKLOG) < 0) 355 | // main_channel is NULL, so that we don't need to launch clear_channel() 356 | return socket_fault(GTK_SOCKET_ERROR_LISTEN_SOCKET, error, NULL, FALSE); 357 | 358 | main_channel = g_io_channel_unix_new(socket_fd); 359 | if (!main_channel) return socket_fault(GTK_SOCKET_ERROR_CREATE_CHANNEL, NULL, NULL, FALSE); 360 | 361 | // set the channel to read binary file 362 | if (g_io_channel_set_encoding(main_channel, NULL, &error) == G_IO_STATUS_ERROR) 363 | return socket_fault(GTK_SOCKET_ERROR_CHANNEL_ENCODING, error, main_channel, TRUE); 364 | 365 | // if any request from client, call accept_socket(). 366 | // the channel will be clean when shutdown_socket_server() 367 | if ( ! g_io_add_watch(main_channel, G_IO_IN|G_IO_HUP, (GIOFunc)accept_socket, (GSourceFunc)read_function)) 368 | return socket_fault(GTK_SOCKET_ERROR_WATCH_SOCKET, error, NULL, TRUE); 369 | 370 | return TRUE; 371 | } 372 | 373 | 374 | // it will return TRUE if succeed 375 | gboolean accept_socket(GIOChannel *source, GIOCondition condition, GSourceFunc read_function) 376 | { 377 | #ifdef DETAIL 378 | g_debug("! Launch accept_socket() to accept the request from client !"); 379 | #endif 380 | #ifdef SAFEMODE 381 | if (source==NULL) return FALSE; 382 | #endif 383 | GError *error = NULL; 384 | 385 | if (condition & G_IO_HUP) 386 | return socket_fault(GTK_SOCKET_ERROR_ACCEPT_REQUEST, error, source, FALSE); 387 | else 388 | { 389 | gint read_fd = accept(g_io_channel_unix_get_fd(source), NULL, NULL); 390 | 391 | if (read_fd < 0) return socket_fault(GTK_SOCKET_ERROR_CREATE_SOCKET_FILE, error, source, FALSE); 392 | 393 | if ( ! set_fd_non_block(&read_fd)) return FALSE; 394 | 395 | GIOChannel* channel = g_io_channel_unix_new(read_fd); 396 | // channel is NULL, so that we don't need to launch clear_channel() 397 | if (!channel) return socket_fault(GTK_SOCKET_ERROR_CREATE_CHANNEL, NULL, channel, FALSE); 398 | // set the channel to read binary file 399 | if (g_io_channel_set_encoding(channel, NULL, &error) == G_IO_STATUS_ERROR) 400 | return socket_fault(GTK_SOCKET_ERROR_CHANNEL_ENCODING, error, channel, TRUE); 401 | 402 | // read the data that client sent. 403 | if ( ! g_io_add_watch(channel, G_IO_HUP, (GIOFunc)read_socket, read_function)) 404 | return socket_fault(GTK_SOCKET_ERROR_WATCH_SOCKET, error, channel, TRUE); 405 | } 406 | return TRUE; 407 | } 408 | 409 | // it will return TRUE if succeed 410 | gboolean read_socket(GIOChannel *channel, GIOCondition condition, GSourceFunc read_function) 411 | { 412 | #ifdef DETAIL 413 | g_debug("! Launch read_socket() to read data !"); 414 | #endif 415 | #ifdef SAFEMODE 416 | if (channel==NULL) return FALSE; 417 | #endif 418 | GError *error = NULL; 419 | gchar *str = NULL; 420 | gsize len = 0; 421 | gsize term; 422 | 423 | if (g_io_channel_read_line (channel, &str, &len, &term, &error) == G_IO_STATUS_ERROR) 424 | socket_fault(GTK_SOCKET_ERROR_RECEIVE_DATA, error, channel, TRUE); 425 | 426 | // read_socket_functions... 427 | if ((len == 0) || (str==NULL)) 428 | socket_fault(GTK_SOCKET_ERROR_GOT_NULL_STRING, NULL, NULL, FALSE); 429 | else 430 | read_function(str); 431 | 432 | g_free(str); 433 | 434 | clear_channel(channel, TRUE); 435 | 436 | // return FALSE means this connection is finished. 437 | return FALSE; 438 | } 439 | 440 | 441 | // It should always return 0. 442 | gint shutdown_socket_server(gpointer data) 443 | { 444 | #ifdef DETAIL 445 | g_debug("! Launch shutdown_socket_server() to shutdown the %s socket server!", PACKAGE); 446 | #endif 447 | if (main_channel) clear_channel(main_channel, TRUE); 448 | if (address.sun_path[0]) unlink(address.sun_path); 449 | return 0; 450 | } 451 | 452 | 453 | // it will always return FALSE 454 | gboolean socket_fault(Unix_Socket_Error type, GError *error, GIOChannel *channel, gboolean unref) 455 | { 456 | #ifdef DETAIL 457 | g_debug("! Launch socket_fault(%d) to show the error message !", type); 458 | #endif 459 | #ifdef UNIT_TEST 460 | # define G_WARNING g_message 461 | #else 462 | # define G_WARNING g_warning 463 | #endif 464 | switch (type) 465 | { 466 | case GTK_SOCKET_ERROR_CREATE_SOCKET_FILE: 467 | G_WARNING("Error when create the socket file \"%s\": %s", 468 | address.sun_path, g_strerror (errno)); 469 | break; 470 | case GTK_SOCKET_ERROR_CONNECT_SOCKET: 471 | g_message("Can NOT connect to a existing unix socket!"); 472 | break; 473 | case GTK_SOCKET_ERROR_BIND_SOCKET: 474 | G_WARNING("Can NOT bind on the socket!"); 475 | break; 476 | case GTK_SOCKET_ERROR_LISTEN_SOCKET: 477 | G_WARNING("Can NOT listen on the socket!"); 478 | break; 479 | case GTK_SOCKET_ERROR_WATCH_SOCKET: 480 | G_WARNING("Can not watch on the socket!"); 481 | break; 482 | case GTK_SOCKET_ERROR_ACCEPT_REQUEST: 483 | G_WARNING("Error when accepting client request via socket!"); 484 | break; 485 | case GTK_SOCKET_ERROR_RECEIVE_DATA: 486 | G_WARNING("Error when reading the data client sent via socket!"); 487 | break; 488 | case GTK_SOCKET_ERROR_FCNTL: 489 | G_WARNING("Error when running fcntl command on socket!"); 490 | break; 491 | case GTK_SOCKET_ERROR_CHANNEL_ENCODING: 492 | if (error) 493 | G_WARNING("Error when setting the encoding of channel: %s", error->message); 494 | else 495 | G_WARNING("Error when setting the encoding of channel: (No further information)"); 496 | break; 497 | case GTK_SOCKET_ERROR_SHUTDOWN_CHANNEL: 498 | if (error) 499 | G_WARNING("Error when shutdowning a channel: %s", error->message); 500 | else 501 | G_WARNING("Error when shutdowning a channel: (No further information)"); 502 | break; 503 | case GTK_SOCKET_ERROR_WRITE_CHANNEL: 504 | if (error) 505 | G_WARNING("Error when writing data to the channel: %s", error->message); 506 | else 507 | G_WARNING("Error when writing data to the channel: (No further information)"); 508 | break; 509 | case GTK_SOCKET_ERROR_CREATE_CHANNEL: 510 | G_WARNING("Can NOT create a channel for this socket"); 511 | break; 512 | case GTK_SOCKET_ERROR_WRITE_BUFFER: 513 | if (error) 514 | G_WARNING("Error when flushing the write buffer for the channel: %s", error->message); 515 | else 516 | G_WARNING("Error when flushing the write buffer for the channel: (No further information)"); 517 | break; 518 | case GTK_SOCKET_ERROR_GOT_NULL_STRING: 519 | G_WARNING("Got a NULL string from the socket!"); 520 | break; 521 | case GTK_SOCKET_ERROR_TMP_DIR: 522 | G_WARNING("The /tmp dir is NOT exist!!"); 523 | break; 524 | default: 525 | #ifdef FATAL 526 | G_WARNING("The inputed %d for socket_fault() is Out of Range !!", type); 527 | #endif 528 | break; 529 | } 530 | 531 | if (error) g_clear_error (&error); 532 | clear_channel(channel, unref); 533 | 534 | if (type != GTK_SOCKET_ERROR_CONNECT_SOCKET) address_len = -1; 535 | 536 | return FALSE; 537 | } 538 | 539 | -------------------------------------------------------------------------------- /src/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * GtkSocket is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * GTK_Socket is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with GtkSocket. If not, see . 16 | */ 17 | 18 | #ifndef SOCKET_H 19 | #define SOCKET_H 20 | typedef enum { 21 | UNIX_SOCKET_SERVER_INITED, // 0 22 | UNIX_SOCKET_DATA_SENT, // 1 23 | UNIX_SOCKET_ERROR, // 2 24 | } Unix_Socket_States; 25 | #endif 26 | 27 | Unix_Socket_States init_gtk_socket(gchar *package_name, gchar *socket_str, GSourceFunc read_function); 28 | 29 | -------------------------------------------------------------------------------- /src/window.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008-2014 Lu, Chao-Ming (Tetralet). All rights reserved. 3 | * 4 | * This file is part of LilyTerm. 5 | * 6 | * LilyTerm is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * LilyTerm is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with LilyTerm. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | // for L10n 23 | #include 24 | #include 25 | // for exit() 26 | #include 27 | // for strcmp() 28 | #include 29 | // for chdir() 30 | #include 31 | // for opendir() readdir() closedir() 32 | #include 33 | // for getpwuid() 34 | #include 35 | #ifdef HAVE_GSTDIO_H 36 | // for g_chdir() 37 | # include 38 | #else 39 | # define g_chdir chdir 40 | #endif 41 | // for GDK_WINDOW_XID 42 | // #include 43 | 44 | #include "lilyterm.h" 45 | 46 | #ifdef USE_XPARSEGEOMETRY 47 | // for XParseGeometry() 48 | #include 49 | #endif 50 | 51 | gboolean window_option(struct Window *win_data, gchar *encoding, int argc, char *argv[]); 52 | char **set_process_data (pid_t entry_pid, gint *ppid, StrAddr **cmd); 53 | gboolean window_key_press(GtkWidget *widget, GdkEventKey *event, struct Window *win_data); 54 | gboolean window_key_release(GtkWidget *widget, GdkEventKey *event, struct Window *win_data); 55 | void window_style_set(GtkWidget *window, GtkStyle *previous_style, struct Window *win_data); 56 | #if defined(USE_GTK2_GEOMETRY_METHOD) || defined(UNIT_TEST) 57 | void window_size_request(GtkWidget *window, GtkRequisition *requisition, struct Window *win_data); 58 | gboolean window_state_event(GtkWidget *widget, GdkEventWindowState *event, struct Window *win_data); 59 | #endif 60 | #if defined(USE_GTK3_GEOMETRY_METHOD) || defined(UNIT_TEST) 61 | gboolean idle_show_or_hide_tabs_bar_and_scroll_bar(struct Window *win_data); 62 | gboolean idle_gtk_window_fullscreen(struct Window *win_data); 63 | void resize_to_exist_widget(struct Window *win_data); 64 | void save_vte_geometry(struct Window *win_data); 65 | gboolean idle_to_resize_window(struct Window *win_data); 66 | gboolean idle_hide_and_show_tabs_bar(struct Window *win_data); 67 | #endif 68 | void window_size_allocate(GtkWidget *window, GtkAllocation *allocation, struct Window *win_data); 69 | gboolean window_get_focus(GtkWidget *window, GdkEventFocus *event, struct Window *win_data); 70 | gboolean window_lost_focus(GtkWidget *window, GdkEventFocus *event, struct Window *win_data); 71 | #ifdef ENABLE_PAGE_ADDED 72 | void notebook_page_added(GtkNotebook *notebook, GtkWidget *child, guint page_num, struct Window *win_data); 73 | #endif 74 | // void notebook_page_removed (GtkNotebook *notebook, GtkWidget *child, guint page_num, struct Window *win_data); 75 | void reorder_page_after_added_removed_page(struct Window *win_data, guint page_num); 76 | void destroy_window(struct Window *win_data); 77 | GtkNotebook *create_window(GtkNotebook *notebook, GtkWidget *page, gint x, gint y, 78 | struct Window *win_data); 79 | #ifdef FATAL 80 | void dump_data(struct Window *win_data, struct Page *page_data); 81 | #endif 82 | void win_data_dup(struct Window *win_data_orig, struct Window *win_data); 83 | gboolean get_hide_or_show_tabs_bar(struct Window *win_data, Switch_Type show_tabs_bar); 84 | gboolean fullscreen_show_hide_scroll_bar (struct Window *win_data); 85 | --------------------------------------------------------------------------------