Merge branch 'lukesmith-0.8.5' of https://github.com/equwal/st into equwal-lukesmith-0.8.5
This commit is contained in:
		
						commit
						a63ef65ef1
					
				
							
								
								
									
										250
									
								
								FAQ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								FAQ
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,250 @@ | |||||||
|  | ## Why does st not handle utmp entries? | ||||||
|  | 
 | ||||||
|  | Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever! | ||||||
|  | 
 | ||||||
|  | It means that st doesn’t have any terminfo entry on your system. Chances are | ||||||
|  | you did not `make install`. If you just want to test it without installing it, | ||||||
|  | you can manually run `tic -sx st.info`. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Nothing works, and nothing is said about an unknown terminal! | ||||||
|  | 
 | ||||||
|  | * Some programs just assume they’re running in xterm i.e. they don’t rely on | ||||||
|  |   terminfo. What you see is the current state of the “xterm compliance”. | ||||||
|  | * Some programs don’t complain about the lacking st description and default to | ||||||
|  |   another terminal. In that case see the question about terminfo. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## How do I scroll back up? | ||||||
|  | 
 | ||||||
|  | * Using a terminal multiplexer. | ||||||
|  | 	* `st -e tmux` using C-b [ | ||||||
|  | 	* `st -e screen` using C-a ESC | ||||||
|  | * Using the excellent tool of [scroll](https://git.suckless.org/scroll/). | ||||||
|  | * Using the scrollback [patch](https://st.suckless.org/patches/scrollback/). | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## I would like to have utmp and/or scroll functionality by default | ||||||
|  | 
 | ||||||
|  | You can add the absolute path of both programs in your config.h file. You only | ||||||
|  | have to modify the value of utmp and scroll variables. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Why doesn't the Del key work in some programs? | ||||||
|  | 
 | ||||||
|  | Taken from the terminfo manpage: | ||||||
|  | 
 | ||||||
|  | 	If the terminal has a keypad that transmits codes when the keys | ||||||
|  | 	are pressed, this information can be given. Note that it is not | ||||||
|  | 	possible to handle terminals where the keypad only works in | ||||||
|  | 	local (this applies, for example, to the unshifted HP 2621 keys). | ||||||
|  | 	If the keypad can be set to transmit or not transmit, give these | ||||||
|  | 	codes as smkx and rmkx. Otherwise the keypad is assumed to | ||||||
|  | 	always transmit. | ||||||
|  | 
 | ||||||
|  | In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that | ||||||
|  | applications which want to test against keypad keys send these | ||||||
|  | sequences. | ||||||
|  | 
 | ||||||
|  | But buggy applications (like bash and irssi, for example) don't do this. A fast | ||||||
|  | solution for them is to use the following command: | ||||||
|  | 
 | ||||||
|  | 	$ printf '\033[?1h\033=' >/dev/tty | ||||||
|  | 
 | ||||||
|  | or | ||||||
|  | 	$ tput smkx | ||||||
|  | 
 | ||||||
|  | In the case of bash, readline is used. Readline has a different note in its | ||||||
|  | manpage about this issue: | ||||||
|  | 
 | ||||||
|  | 	enable-keypad (Off) | ||||||
|  | 		When set to On, readline will try to enable the | ||||||
|  | 		application keypad when it is called. Some systems | ||||||
|  | 		need this to enable arrow keys. | ||||||
|  | 
 | ||||||
|  | Adding this option to your .inputrc will fix the keypad problem for all | ||||||
|  | applications using readline. | ||||||
|  | 
 | ||||||
|  | If you are using zsh, then read the zsh FAQ | ||||||
|  | <http://zsh.sourceforge.net/FAQ/zshfaq03.html#l25>: | ||||||
|  | 
 | ||||||
|  | 	It should be noted that the O / [ confusion can occur with other keys | ||||||
|  | 	such as Home and End. Some systems let you query the key sequences | ||||||
|  | 	sent by these keys from the system's terminal database, terminfo. | ||||||
|  | 	Unfortunately, the key sequences given there typically apply to the | ||||||
|  | 	mode that is not the one zsh uses by default (it's the "application" | ||||||
|  | 	mode rather than the "raw" mode). Explaining the use of terminfo is | ||||||
|  | 	outside of the scope of this FAQ, but if you wish to use the key | ||||||
|  | 	sequences given there you can tell the line editor to turn on | ||||||
|  | 	"application" mode when it starts and turn it off when it stops: | ||||||
|  | 
 | ||||||
|  | 		function zle-line-init () { echoti smkx } | ||||||
|  | 		function zle-line-finish () { echoti rmkx } | ||||||
|  | 		zle -N zle-line-init | ||||||
|  | 		zle -N zle-line-finish | ||||||
|  | 
 | ||||||
|  | Putting these lines into your .zshrc will fix the problems. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## How can I use meta in 8bit mode? | ||||||
|  | 
 | ||||||
|  | St supports meta in 8bit mode, but the default terminfo entry doesn't | ||||||
|  | use this capability. If you want it, you have to use the 'st-meta' value | ||||||
|  | in TERM. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## I cannot compile st in OpenBSD | ||||||
|  | 
 | ||||||
|  | OpenBSD lacks librt, despite it being mandatory in POSIX | ||||||
|  | <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_13>. | ||||||
|  | If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and | ||||||
|  | st will compile without any loss of functionality, because all the functions are | ||||||
|  | included in libc on this platform. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## The Backspace Case | ||||||
|  | 
 | ||||||
|  | St is emulating the Linux way of handling backspace being delete and delete being | ||||||
|  | backspace. | ||||||
|  | 
 | ||||||
|  | This is an issue that was discussed in suckless mailing list | ||||||
|  | <https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy | ||||||
|  | terminal users wants its backspace to be how he feels it: | ||||||
|  | 
 | ||||||
|  | 	Well, I am going to comment why I want to change the behaviour | ||||||
|  | 	of this key. When ASCII was defined in 1968, communication | ||||||
|  | 	with computers was done using punched cards, or hardcopy | ||||||
|  | 	terminals (basically a typewriter machine connected with the | ||||||
|  | 	computer using a serial port).  ASCII defines DELETE as 7F, | ||||||
|  | 	because, in punched-card terms, it means all the holes of the | ||||||
|  | 	card punched; it is thus a kind of 'physical delete'. In the | ||||||
|  | 	same way, the BACKSPACE key was a non-destructive backspace, | ||||||
|  | 	as on a typewriter.  So, if you wanted to delete a character, | ||||||
|  | 	you had to BACKSPACE and then DELETE.  Another use of BACKSPACE | ||||||
|  | 	was to type accented characters, for example 'a BACKSPACE `'. | ||||||
|  | 	The VT100 had no BACKSPACE key; it was generated using the | ||||||
|  | 	CONTROL key as another control character (CONTROL key sets to | ||||||
|  | 	0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code | ||||||
|  | 	0x08)), but it had a DELETE key in a similar position where | ||||||
|  | 	the BACKSPACE key is located today on common PC keyboards. | ||||||
|  | 	All the terminal emulators emulated the difference between | ||||||
|  | 	these keys correctly: the backspace key generated a BACKSPACE | ||||||
|  | 	(^H) and delete key generated a DELETE (^?). | ||||||
|  | 
 | ||||||
|  | 	But a problem arose when Linus Torvalds wrote Linux. Unlike | ||||||
|  | 	earlier terminals, the Linux virtual terminal (the terminal | ||||||
|  | 	emulator integrated in the kernel) returned a DELETE when | ||||||
|  | 	backspace was pressed, due to the VT100 having a DELETE key in | ||||||
|  | 	the same position.  This created a lot of problems (see [1] | ||||||
|  | 	and [2]). Since Linux has become the king, a lot of terminal | ||||||
|  | 	emulators today generate a DELETE when the backspace key is | ||||||
|  | 	pressed in order to avoid problems with Linux. The result is | ||||||
|  | 	that the only way of generating a BACKSPACE on these systems | ||||||
|  | 	is by using CONTROL + H. (I also think that emacs had an | ||||||
|  | 	important point here because the CONTROL + H prefix is used | ||||||
|  | 	in emacs in some commands (help commands).) | ||||||
|  | 
 | ||||||
|  | 	From point of view of the kernel, you can change the key | ||||||
|  | 	for deleting a previous character with stty erase. When you | ||||||
|  | 	connect a real terminal into a machine you describe the type | ||||||
|  | 	of terminal, so getty configures the correct value of stty | ||||||
|  | 	erase for this terminal. In the case of terminal emulators, | ||||||
|  | 	however, you don't have any getty that can set the correct | ||||||
|  | 	value of stty erase, so you always get the default value. | ||||||
|  | 	For this reason, it is necessary to add 'stty erase ^H' to your | ||||||
|  | 	profile if you have changed the value of the backspace key. | ||||||
|  | 	Of course, another solution is for st itself to modify the | ||||||
|  | 	value of stty erase.  I usually have the inverse problem: | ||||||
|  | 	when I connect to non-Unix machines, I have to press CONTROL + | ||||||
|  | 	h to get a BACKSPACE. The inverse problem occurs when a user | ||||||
|  | 	connects to my Unix machines from a different system with a | ||||||
|  | 	correct backspace key. | ||||||
|  | 
 | ||||||
|  | 	[1] http://www.ibb.net/~anne/keyboard.html | ||||||
|  | 	[2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## But I really want the old grumpy behaviour of my terminal | ||||||
|  | 
 | ||||||
|  | Apply [1]. | ||||||
|  | 
 | ||||||
|  | [1] https://st.suckless.org/patches/delkey | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Why do images not work in st using the w3m image hack? | ||||||
|  | 
 | ||||||
|  | w3mimg uses a hack that draws an image on top of the terminal emulator Drawable | ||||||
|  | window. The hack relies on the terminal to use a single buffer to draw its | ||||||
|  | contents directly. | ||||||
|  | 
 | ||||||
|  | st uses double-buffered drawing so the image is quickly replaced and may show a | ||||||
|  | short flicker effect. | ||||||
|  | 
 | ||||||
|  | Below is a patch example to change st double-buffering to a single Drawable | ||||||
|  | buffer. | ||||||
|  | 
 | ||||||
|  | diff --git a/x.c b/x.c | ||||||
|  | --- a/x.c | ||||||
|  | +++ b/x.c | ||||||
|  | @@ -732,10 +732,6 @@ xresize(int col, int row) | ||||||
|  |  	win.tw = col * win.cw; | ||||||
|  |  	win.th = row * win.ch; | ||||||
|  |   | ||||||
|  | -	XFreePixmap(xw.dpy, xw.buf); | ||||||
|  | -	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | ||||||
|  | -			DefaultDepth(xw.dpy, xw.scr)); | ||||||
|  | -	XftDrawChange(xw.draw, xw.buf); | ||||||
|  |  	xclear(0, 0, win.w, win.h); | ||||||
|  |   | ||||||
|  |  	/* resize to new width */ | ||||||
|  | @@ -1148,8 +1144,7 @@ xinit(int cols, int rows) | ||||||
|  |  	gcvalues.graphics_exposures = False; | ||||||
|  |  	dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, | ||||||
|  |  			&gcvalues); | ||||||
|  | -	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | ||||||
|  | -			DefaultDepth(xw.dpy, xw.scr)); | ||||||
|  | +	xw.buf = xw.win; | ||||||
|  |  	XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); | ||||||
|  |  	XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); | ||||||
|  |   | ||||||
|  | @@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2) | ||||||
|  |  void | ||||||
|  |  xfinishdraw(void) | ||||||
|  |  { | ||||||
|  | -	XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, | ||||||
|  | -			win.h, 0, 0); | ||||||
|  |  	XSetForeground(xw.dpy, dc.gc, | ||||||
|  |  			dc.col[IS_SET(MODE_REVERSE)? | ||||||
|  |  				defaultfg : defaultbg].pixel); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## BadLength X error in Xft when trying to render emoji | ||||||
|  | 
 | ||||||
|  | Xft makes st crash when rendering color emojis with the following error: | ||||||
|  | 
 | ||||||
|  | "X Error of failed request:  BadLength (poly request too large or internal Xlib length error)" | ||||||
|  |   Major opcode of failed request:  139 (RENDER) | ||||||
|  |   Minor opcode of failed request:  20 (RenderAddGlyphs) | ||||||
|  |   Serial number of failed request: 1595 | ||||||
|  |   Current serial number in output stream:  1818" | ||||||
|  | 
 | ||||||
|  | This is a known bug in Xft (not st) which happens on some platforms and | ||||||
|  | combination of particular fonts and fontconfig settings. | ||||||
|  | 
 | ||||||
|  | See also: | ||||||
|  | https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=107534 | ||||||
|  | https://bugzilla.redhat.com/show_bug.cgi?id=1498269 | ||||||
|  | 
 | ||||||
|  | The solution is to remove color emoji fonts or disable this in the fontconfig | ||||||
|  | XML configuration.  As an ugly workaround (which may work only on newer | ||||||
|  | fontconfig versions (FC_COLOR)), the following code can be used to mask color | ||||||
|  | fonts: | ||||||
|  | 
 | ||||||
|  | 	FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); | ||||||
|  | 
 | ||||||
|  | Please don't bother reporting this bug to st, but notify the upstream Xft | ||||||
|  | developers about fixing this bug. | ||||||
							
								
								
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,6 +1,10 @@ | |||||||
| MIT/X Consortium License | MIT/X Consortium License | ||||||
| 
 | 
 | ||||||
|  | <<<<<<< HEAD | ||||||
| © 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org> | © 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org> | ||||||
|  | ======= | ||||||
|  | © 2014-2022 Hiltjo Posthuma <hiltjo at codemadness dot org> | ||||||
|  | >>>>>>> suckless-master | ||||||
| © 2018 Devin J. Pohly <djpohly at gmail dot com> | © 2018 Devin J. Pohly <djpohly at gmail dot com> | ||||||
| © 2014-2017 Quentin Rameau <quinq at fifth dot space> | © 2014-2017 Quentin Rameau <quinq at fifth dot space> | ||||||
| © 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com> | © 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com> | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								PKGBUILD
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								PKGBUILD
									
									
									
									
									
								
							| @ -13,7 +13,7 @@ options=('zipman') | |||||||
| depends=('libxft') | depends=('libxft') | ||||||
| makedepends=('ncurses' 'libxext' 'git') | makedepends=('ncurses' 'libxext' 'git') | ||||||
| optdepends=('dmenu: feed urls to dmenu') | optdepends=('dmenu: feed urls to dmenu') | ||||||
| source=('git://github.com/LukeSmithxyz/st') | source=(git+https://github.com/LukeSmithxyz/st) | ||||||
| sha1sums=('SKIP') | sha1sums=('SKIP') | ||||||
| 
 | 
 | ||||||
| provides=("${_pkgname}") | provides=("${_pkgname}") | ||||||
|  | |||||||
							
								
								
									
										474
									
								
								config.def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								config.def.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,474 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * appearance | ||||||
|  |  * | ||||||
|  |  * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
 | ||||||
|  |  */ | ||||||
|  | static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; | ||||||
|  | static int borderpx = 2; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * What program is execed by st depends of these precedence rules: | ||||||
|  |  * 1: program passed with -e | ||||||
|  |  * 2: scroll and/or utmp | ||||||
|  |  * 3: SHELL environment variable | ||||||
|  |  * 4: value of shell in /etc/passwd | ||||||
|  |  * 5: value of shell in config.h | ||||||
|  |  */ | ||||||
|  | static char *shell = "/bin/sh"; | ||||||
|  | char *utmp = NULL; | ||||||
|  | /* scroll program: to enable use a string like "scroll" */ | ||||||
|  | char *scroll = NULL; | ||||||
|  | char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; | ||||||
|  | 
 | ||||||
|  | /* identification sequence returned in DA and DECID */ | ||||||
|  | char *vtiden = "\033[?6c"; | ||||||
|  | 
 | ||||||
|  | /* Kerning / character bounding-box multipliers */ | ||||||
|  | static float cwscale = 1.0; | ||||||
|  | static float chscale = 1.0; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * word delimiter string | ||||||
|  |  * | ||||||
|  |  * More advanced example: L" `'\"()[]{}" | ||||||
|  |  */ | ||||||
|  | wchar_t *worddelimiters = L" "; | ||||||
|  | 
 | ||||||
|  | /* selection timeouts (in milliseconds) */ | ||||||
|  | static unsigned int doubleclicktimeout = 300; | ||||||
|  | static unsigned int tripleclicktimeout = 600; | ||||||
|  | 
 | ||||||
|  | /* alt screens */ | ||||||
|  | int allowaltscreen = 1; | ||||||
|  | 
 | ||||||
|  | /* allow certain non-interactive (insecure) window operations such as:
 | ||||||
|  |    setting the clipboard text */ | ||||||
|  | int allowwindowops = 0; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * draw latency range in ms - from new content/keypress/etc until drawing. | ||||||
|  |  * within this range, st draws when content stops arriving (idle). mostly it's | ||||||
|  |  * near minlatency, but it waits longer for slow updates to avoid partial draw. | ||||||
|  |  * low minlatency will tear/flicker more, as it can "detect" idle too early. | ||||||
|  |  */ | ||||||
|  | static double minlatency = 8; | ||||||
|  | static double maxlatency = 33; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * blinking timeout (set to 0 to disable blinking) for the terminal blinking | ||||||
|  |  * attribute. | ||||||
|  |  */ | ||||||
|  | static unsigned int blinktimeout = 800; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * thickness of underline and bar cursors | ||||||
|  |  */ | ||||||
|  | static unsigned int cursorthickness = 2; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * bell volume. It must be a value between -100 and 100. Use 0 for disabling | ||||||
|  |  * it | ||||||
|  |  */ | ||||||
|  | static int bellvolume = 0; | ||||||
|  | 
 | ||||||
|  | /* default TERM value */ | ||||||
|  | char *termname = "st-256color"; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * spaces per tab | ||||||
|  |  * | ||||||
|  |  * When you are changing this value, don't forget to adapt the »it« value in | ||||||
|  |  * the st.info and appropriately install the st.info in the environment where | ||||||
|  |  * you use this st version. | ||||||
|  |  * | ||||||
|  |  *	it#$tabspaces, | ||||||
|  |  * | ||||||
|  |  * Secondly make sure your kernel is not expanding tabs. When running `stty | ||||||
|  |  * -a` »tab0« should appear. You can tell the terminal to not expand tabs by | ||||||
|  |  *  running following command: | ||||||
|  |  * | ||||||
|  |  *	stty tabs | ||||||
|  |  */ | ||||||
|  | unsigned int tabspaces = 8; | ||||||
|  | 
 | ||||||
|  | /* Terminal colors (16 first used in escape sequence) */ | ||||||
|  | static const char *colorname[] = { | ||||||
|  | 	/* 8 normal colors */ | ||||||
|  | 	"black", | ||||||
|  | 	"red3", | ||||||
|  | 	"green3", | ||||||
|  | 	"yellow3", | ||||||
|  | 	"blue2", | ||||||
|  | 	"magenta3", | ||||||
|  | 	"cyan3", | ||||||
|  | 	"gray90", | ||||||
|  | 
 | ||||||
|  | 	/* 8 bright colors */ | ||||||
|  | 	"gray50", | ||||||
|  | 	"red", | ||||||
|  | 	"green", | ||||||
|  | 	"yellow", | ||||||
|  | 	"#5c5cff", | ||||||
|  | 	"magenta", | ||||||
|  | 	"cyan", | ||||||
|  | 	"white", | ||||||
|  | 
 | ||||||
|  | 	[255] = 0, | ||||||
|  | 
 | ||||||
|  | 	/* more colors can be added after 255 to use with DefaultXX */ | ||||||
|  | 	"#cccccc", | ||||||
|  | 	"#555555", | ||||||
|  | 	"gray90", /* default foreground colour */ | ||||||
|  | 	"black", /* default background colour */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Default colors (colorname index) | ||||||
|  |  * foreground, background, cursor, reverse cursor | ||||||
|  |  */ | ||||||
|  | unsigned int defaultfg = 258; | ||||||
|  | unsigned int defaultbg = 259; | ||||||
|  | unsigned int defaultcs = 256; | ||||||
|  | static unsigned int defaultrcs = 257; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Default shape of cursor | ||||||
|  |  * 2: Block ("█") | ||||||
|  |  * 4: Underline ("_") | ||||||
|  |  * 6: Bar ("|") | ||||||
|  |  * 7: Snowman ("☃") | ||||||
|  |  */ | ||||||
|  | static unsigned int cursorshape = 2; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Default columns and rows numbers | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | static unsigned int cols = 80; | ||||||
|  | static unsigned int rows = 24; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Default colour and shape of the mouse cursor | ||||||
|  |  */ | ||||||
|  | static unsigned int mouseshape = XC_xterm; | ||||||
|  | static unsigned int mousefg = 7; | ||||||
|  | static unsigned int mousebg = 0; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Color used to display font attributes when fontconfig selected a font which | ||||||
|  |  * doesn't match the ones requested. | ||||||
|  |  */ | ||||||
|  | static unsigned int defaultattr = 11; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). | ||||||
|  |  * Note that if you want to use ShiftMask with selmasks, set this to an other | ||||||
|  |  * modifier, set to 0 to not use it. | ||||||
|  |  */ | ||||||
|  | static uint forcemousemod = ShiftMask; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Internal mouse shortcuts. | ||||||
|  |  * Beware that overloading Button1 will disable the selection. | ||||||
|  |  */ | ||||||
|  | static MouseShortcut mshortcuts[] = { | ||||||
|  | 	/* mask                 button   function        argument       release */ | ||||||
|  | 	{ XK_ANY_MOD,           Button2, selpaste,       {.i = 0},      1 }, | ||||||
|  | 	{ ShiftMask,            Button4, ttysend,        {.s = "\033[5;2~"} }, | ||||||
|  | 	{ XK_ANY_MOD,           Button4, ttysend,        {.s = "\031"} }, | ||||||
|  | 	{ ShiftMask,            Button5, ttysend,        {.s = "\033[6;2~"} }, | ||||||
|  | 	{ XK_ANY_MOD,           Button5, ttysend,        {.s = "\005"} }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Internal keyboard shortcuts. */ | ||||||
|  | #define MODKEY Mod1Mask | ||||||
|  | #define TERMMOD (ControlMask|ShiftMask) | ||||||
|  | 
 | ||||||
|  | static Shortcut shortcuts[] = { | ||||||
|  | 	/* mask                 keysym          function        argument */ | ||||||
|  | 	{ XK_ANY_MOD,           XK_Break,       sendbreak,      {.i =  0} }, | ||||||
|  | 	{ ControlMask,          XK_Print,       toggleprinter,  {.i =  0} }, | ||||||
|  | 	{ ShiftMask,            XK_Print,       printscreen,    {.i =  0} }, | ||||||
|  | 	{ XK_ANY_MOD,           XK_Print,       printsel,       {.i =  0} }, | ||||||
|  | 	{ TERMMOD,              XK_Prior,       zoom,           {.f = +1} }, | ||||||
|  | 	{ TERMMOD,              XK_Next,        zoom,           {.f = -1} }, | ||||||
|  | 	{ TERMMOD,              XK_Home,        zoomreset,      {.f =  0} }, | ||||||
|  | 	{ TERMMOD,              XK_C,           clipcopy,       {.i =  0} }, | ||||||
|  | 	{ TERMMOD,              XK_V,           clippaste,      {.i =  0} }, | ||||||
|  | 	{ TERMMOD,              XK_Y,           selpaste,       {.i =  0} }, | ||||||
|  | 	{ ShiftMask,            XK_Insert,      selpaste,       {.i =  0} }, | ||||||
|  | 	{ TERMMOD,              XK_Num_Lock,    numlock,        {.i =  0} }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Special keys (change & recompile st.info accordingly) | ||||||
|  |  * | ||||||
|  |  * Mask value: | ||||||
|  |  * * Use XK_ANY_MOD to match the key no matter modifiers state | ||||||
|  |  * * Use XK_NO_MOD to match the key alone (no modifiers) | ||||||
|  |  * appkey value: | ||||||
|  |  * * 0: no value | ||||||
|  |  * * > 0: keypad application mode enabled | ||||||
|  |  * *   = 2: term.numlock = 1 | ||||||
|  |  * * < 0: keypad application mode disabled | ||||||
|  |  * appcursor value: | ||||||
|  |  * * 0: no value | ||||||
|  |  * * > 0: cursor application mode enabled | ||||||
|  |  * * < 0: cursor application mode disabled | ||||||
|  |  * | ||||||
|  |  * Be careful with the order of the definitions because st searches in | ||||||
|  |  * this table sequentially, so any XK_ANY_MOD must be in the last | ||||||
|  |  * position for a key. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) | ||||||
|  |  * to be mapped below, add them to this array. | ||||||
|  |  */ | ||||||
|  | static KeySym mappedkeys[] = { -1 }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * State bits to ignore when matching key or button events.  By default, | ||||||
|  |  * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. | ||||||
|  |  */ | ||||||
|  | static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This is the huge key array which defines all compatibility to the Linux | ||||||
|  |  * world. Please decide about changes wisely. | ||||||
|  |  */ | ||||||
|  | static Key key[] = { | ||||||
|  | 	/* keysym           mask            string      appkey appcursor */ | ||||||
|  | 	{ XK_KP_Home,       ShiftMask,      "\033[2J",       0,   -1}, | ||||||
|  | 	{ XK_KP_Home,       ShiftMask,      "\033[1;2H",     0,   +1}, | ||||||
|  | 	{ XK_KP_Home,       XK_ANY_MOD,     "\033[H",        0,   -1}, | ||||||
|  | 	{ XK_KP_Home,       XK_ANY_MOD,     "\033[1~",       0,   +1}, | ||||||
|  | 	{ XK_KP_Up,         XK_ANY_MOD,     "\033Ox",       +1,    0}, | ||||||
|  | 	{ XK_KP_Up,         XK_ANY_MOD,     "\033[A",        0,   -1}, | ||||||
|  | 	{ XK_KP_Up,         XK_ANY_MOD,     "\033OA",        0,   +1}, | ||||||
|  | 	{ XK_KP_Down,       XK_ANY_MOD,     "\033Or",       +1,    0}, | ||||||
|  | 	{ XK_KP_Down,       XK_ANY_MOD,     "\033[B",        0,   -1}, | ||||||
|  | 	{ XK_KP_Down,       XK_ANY_MOD,     "\033OB",        0,   +1}, | ||||||
|  | 	{ XK_KP_Left,       XK_ANY_MOD,     "\033Ot",       +1,    0}, | ||||||
|  | 	{ XK_KP_Left,       XK_ANY_MOD,     "\033[D",        0,   -1}, | ||||||
|  | 	{ XK_KP_Left,       XK_ANY_MOD,     "\033OD",        0,   +1}, | ||||||
|  | 	{ XK_KP_Right,      XK_ANY_MOD,     "\033Ov",       +1,    0}, | ||||||
|  | 	{ XK_KP_Right,      XK_ANY_MOD,     "\033[C",        0,   -1}, | ||||||
|  | 	{ XK_KP_Right,      XK_ANY_MOD,     "\033OC",        0,   +1}, | ||||||
|  | 	{ XK_KP_Prior,      ShiftMask,      "\033[5;2~",     0,    0}, | ||||||
|  | 	{ XK_KP_Prior,      XK_ANY_MOD,     "\033[5~",       0,    0}, | ||||||
|  | 	{ XK_KP_Begin,      XK_ANY_MOD,     "\033[E",        0,    0}, | ||||||
|  | 	{ XK_KP_End,        ControlMask,    "\033[J",       -1,    0}, | ||||||
|  | 	{ XK_KP_End,        ControlMask,    "\033[1;5F",    +1,    0}, | ||||||
|  | 	{ XK_KP_End,        ShiftMask,      "\033[K",       -1,    0}, | ||||||
|  | 	{ XK_KP_End,        ShiftMask,      "\033[1;2F",    +1,    0}, | ||||||
|  | 	{ XK_KP_End,        XK_ANY_MOD,     "\033[4~",       0,    0}, | ||||||
|  | 	{ XK_KP_Next,       ShiftMask,      "\033[6;2~",     0,    0}, | ||||||
|  | 	{ XK_KP_Next,       XK_ANY_MOD,     "\033[6~",       0,    0}, | ||||||
|  | 	{ XK_KP_Insert,     ShiftMask,      "\033[2;2~",    +1,    0}, | ||||||
|  | 	{ XK_KP_Insert,     ShiftMask,      "\033[4l",      -1,    0}, | ||||||
|  | 	{ XK_KP_Insert,     ControlMask,    "\033[L",       -1,    0}, | ||||||
|  | 	{ XK_KP_Insert,     ControlMask,    "\033[2;5~",    +1,    0}, | ||||||
|  | 	{ XK_KP_Insert,     XK_ANY_MOD,     "\033[4h",      -1,    0}, | ||||||
|  | 	{ XK_KP_Insert,     XK_ANY_MOD,     "\033[2~",      +1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     ControlMask,    "\033[M",       -1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     ControlMask,    "\033[3;5~",    +1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     ShiftMask,      "\033[2K",      -1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     ShiftMask,      "\033[3;2~",    +1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     XK_ANY_MOD,     "\033[P",       -1,    0}, | ||||||
|  | 	{ XK_KP_Delete,     XK_ANY_MOD,     "\033[3~",      +1,    0}, | ||||||
|  | 	{ XK_KP_Multiply,   XK_ANY_MOD,     "\033Oj",       +2,    0}, | ||||||
|  | 	{ XK_KP_Add,        XK_ANY_MOD,     "\033Ok",       +2,    0}, | ||||||
|  | 	{ XK_KP_Enter,      XK_ANY_MOD,     "\033OM",       +2,    0}, | ||||||
|  | 	{ XK_KP_Enter,      XK_ANY_MOD,     "\r",           -1,    0}, | ||||||
|  | 	{ XK_KP_Subtract,   XK_ANY_MOD,     "\033Om",       +2,    0}, | ||||||
|  | 	{ XK_KP_Decimal,    XK_ANY_MOD,     "\033On",       +2,    0}, | ||||||
|  | 	{ XK_KP_Divide,     XK_ANY_MOD,     "\033Oo",       +2,    0}, | ||||||
|  | 	{ XK_KP_0,          XK_ANY_MOD,     "\033Op",       +2,    0}, | ||||||
|  | 	{ XK_KP_1,          XK_ANY_MOD,     "\033Oq",       +2,    0}, | ||||||
|  | 	{ XK_KP_2,          XK_ANY_MOD,     "\033Or",       +2,    0}, | ||||||
|  | 	{ XK_KP_3,          XK_ANY_MOD,     "\033Os",       +2,    0}, | ||||||
|  | 	{ XK_KP_4,          XK_ANY_MOD,     "\033Ot",       +2,    0}, | ||||||
|  | 	{ XK_KP_5,          XK_ANY_MOD,     "\033Ou",       +2,    0}, | ||||||
|  | 	{ XK_KP_6,          XK_ANY_MOD,     "\033Ov",       +2,    0}, | ||||||
|  | 	{ XK_KP_7,          XK_ANY_MOD,     "\033Ow",       +2,    0}, | ||||||
|  | 	{ XK_KP_8,          XK_ANY_MOD,     "\033Ox",       +2,    0}, | ||||||
|  | 	{ XK_KP_9,          XK_ANY_MOD,     "\033Oy",       +2,    0}, | ||||||
|  | 	{ XK_Up,            ShiftMask,      "\033[1;2A",     0,    0}, | ||||||
|  | 	{ XK_Up,            Mod1Mask,       "\033[1;3A",     0,    0}, | ||||||
|  | 	{ XK_Up,         ShiftMask|Mod1Mask,"\033[1;4A",     0,    0}, | ||||||
|  | 	{ XK_Up,            ControlMask,    "\033[1;5A",     0,    0}, | ||||||
|  | 	{ XK_Up,      ShiftMask|ControlMask,"\033[1;6A",     0,    0}, | ||||||
|  | 	{ XK_Up,       ControlMask|Mod1Mask,"\033[1;7A",     0,    0}, | ||||||
|  | 	{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A",  0,    0}, | ||||||
|  | 	{ XK_Up,            XK_ANY_MOD,     "\033[A",        0,   -1}, | ||||||
|  | 	{ XK_Up,            XK_ANY_MOD,     "\033OA",        0,   +1}, | ||||||
|  | 	{ XK_Down,          ShiftMask,      "\033[1;2B",     0,    0}, | ||||||
|  | 	{ XK_Down,          Mod1Mask,       "\033[1;3B",     0,    0}, | ||||||
|  | 	{ XK_Down,       ShiftMask|Mod1Mask,"\033[1;4B",     0,    0}, | ||||||
|  | 	{ XK_Down,          ControlMask,    "\033[1;5B",     0,    0}, | ||||||
|  | 	{ XK_Down,    ShiftMask|ControlMask,"\033[1;6B",     0,    0}, | ||||||
|  | 	{ XK_Down,     ControlMask|Mod1Mask,"\033[1;7B",     0,    0}, | ||||||
|  | 	{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0,    0}, | ||||||
|  | 	{ XK_Down,          XK_ANY_MOD,     "\033[B",        0,   -1}, | ||||||
|  | 	{ XK_Down,          XK_ANY_MOD,     "\033OB",        0,   +1}, | ||||||
|  | 	{ XK_Left,          ShiftMask,      "\033[1;2D",     0,    0}, | ||||||
|  | 	{ XK_Left,          Mod1Mask,       "\033[1;3D",     0,    0}, | ||||||
|  | 	{ XK_Left,       ShiftMask|Mod1Mask,"\033[1;4D",     0,    0}, | ||||||
|  | 	{ XK_Left,          ControlMask,    "\033[1;5D",     0,    0}, | ||||||
|  | 	{ XK_Left,    ShiftMask|ControlMask,"\033[1;6D",     0,    0}, | ||||||
|  | 	{ XK_Left,     ControlMask|Mod1Mask,"\033[1;7D",     0,    0}, | ||||||
|  | 	{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0,    0}, | ||||||
|  | 	{ XK_Left,          XK_ANY_MOD,     "\033[D",        0,   -1}, | ||||||
|  | 	{ XK_Left,          XK_ANY_MOD,     "\033OD",        0,   +1}, | ||||||
|  | 	{ XK_Right,         ShiftMask,      "\033[1;2C",     0,    0}, | ||||||
|  | 	{ XK_Right,         Mod1Mask,       "\033[1;3C",     0,    0}, | ||||||
|  | 	{ XK_Right,      ShiftMask|Mod1Mask,"\033[1;4C",     0,    0}, | ||||||
|  | 	{ XK_Right,         ControlMask,    "\033[1;5C",     0,    0}, | ||||||
|  | 	{ XK_Right,   ShiftMask|ControlMask,"\033[1;6C",     0,    0}, | ||||||
|  | 	{ XK_Right,    ControlMask|Mod1Mask,"\033[1;7C",     0,    0}, | ||||||
|  | 	{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0,   0}, | ||||||
|  | 	{ XK_Right,         XK_ANY_MOD,     "\033[C",        0,   -1}, | ||||||
|  | 	{ XK_Right,         XK_ANY_MOD,     "\033OC",        0,   +1}, | ||||||
|  | 	{ XK_ISO_Left_Tab,  ShiftMask,      "\033[Z",        0,    0}, | ||||||
|  | 	{ XK_Return,        Mod1Mask,       "\033\r",        0,    0}, | ||||||
|  | 	{ XK_Return,        XK_ANY_MOD,     "\r",            0,    0}, | ||||||
|  | 	{ XK_Insert,        ShiftMask,      "\033[4l",      -1,    0}, | ||||||
|  | 	{ XK_Insert,        ShiftMask,      "\033[2;2~",    +1,    0}, | ||||||
|  | 	{ XK_Insert,        ControlMask,    "\033[L",       -1,    0}, | ||||||
|  | 	{ XK_Insert,        ControlMask,    "\033[2;5~",    +1,    0}, | ||||||
|  | 	{ XK_Insert,        XK_ANY_MOD,     "\033[4h",      -1,    0}, | ||||||
|  | 	{ XK_Insert,        XK_ANY_MOD,     "\033[2~",      +1,    0}, | ||||||
|  | 	{ XK_Delete,        ControlMask,    "\033[M",       -1,    0}, | ||||||
|  | 	{ XK_Delete,        ControlMask,    "\033[3;5~",    +1,    0}, | ||||||
|  | 	{ XK_Delete,        ShiftMask,      "\033[2K",      -1,    0}, | ||||||
|  | 	{ XK_Delete,        ShiftMask,      "\033[3;2~",    +1,    0}, | ||||||
|  | 	{ XK_Delete,        XK_ANY_MOD,     "\033[P",       -1,    0}, | ||||||
|  | 	{ XK_Delete,        XK_ANY_MOD,     "\033[3~",      +1,    0}, | ||||||
|  | 	{ XK_BackSpace,     XK_NO_MOD,      "\177",          0,    0}, | ||||||
|  | 	{ XK_BackSpace,     Mod1Mask,       "\033\177",      0,    0}, | ||||||
|  | 	{ XK_Home,          ShiftMask,      "\033[2J",       0,   -1}, | ||||||
|  | 	{ XK_Home,          ShiftMask,      "\033[1;2H",     0,   +1}, | ||||||
|  | 	{ XK_Home,          XK_ANY_MOD,     "\033[H",        0,   -1}, | ||||||
|  | 	{ XK_Home,          XK_ANY_MOD,     "\033[1~",       0,   +1}, | ||||||
|  | 	{ XK_End,           ControlMask,    "\033[J",       -1,    0}, | ||||||
|  | 	{ XK_End,           ControlMask,    "\033[1;5F",    +1,    0}, | ||||||
|  | 	{ XK_End,           ShiftMask,      "\033[K",       -1,    0}, | ||||||
|  | 	{ XK_End,           ShiftMask,      "\033[1;2F",    +1,    0}, | ||||||
|  | 	{ XK_End,           XK_ANY_MOD,     "\033[4~",       0,    0}, | ||||||
|  | 	{ XK_Prior,         ControlMask,    "\033[5;5~",     0,    0}, | ||||||
|  | 	{ XK_Prior,         ShiftMask,      "\033[5;2~",     0,    0}, | ||||||
|  | 	{ XK_Prior,         XK_ANY_MOD,     "\033[5~",       0,    0}, | ||||||
|  | 	{ XK_Next,          ControlMask,    "\033[6;5~",     0,    0}, | ||||||
|  | 	{ XK_Next,          ShiftMask,      "\033[6;2~",     0,    0}, | ||||||
|  | 	{ XK_Next,          XK_ANY_MOD,     "\033[6~",       0,    0}, | ||||||
|  | 	{ XK_F1,            XK_NO_MOD,      "\033OP" ,       0,    0}, | ||||||
|  | 	{ XK_F1, /* F13 */  ShiftMask,      "\033[1;2P",     0,    0}, | ||||||
|  | 	{ XK_F1, /* F25 */  ControlMask,    "\033[1;5P",     0,    0}, | ||||||
|  | 	{ XK_F1, /* F37 */  Mod4Mask,       "\033[1;6P",     0,    0}, | ||||||
|  | 	{ XK_F1, /* F49 */  Mod1Mask,       "\033[1;3P",     0,    0}, | ||||||
|  | 	{ XK_F1, /* F61 */  Mod3Mask,       "\033[1;4P",     0,    0}, | ||||||
|  | 	{ XK_F2,            XK_NO_MOD,      "\033OQ" ,       0,    0}, | ||||||
|  | 	{ XK_F2, /* F14 */  ShiftMask,      "\033[1;2Q",     0,    0}, | ||||||
|  | 	{ XK_F2, /* F26 */  ControlMask,    "\033[1;5Q",     0,    0}, | ||||||
|  | 	{ XK_F2, /* F38 */  Mod4Mask,       "\033[1;6Q",     0,    0}, | ||||||
|  | 	{ XK_F2, /* F50 */  Mod1Mask,       "\033[1;3Q",     0,    0}, | ||||||
|  | 	{ XK_F2, /* F62 */  Mod3Mask,       "\033[1;4Q",     0,    0}, | ||||||
|  | 	{ XK_F3,            XK_NO_MOD,      "\033OR" ,       0,    0}, | ||||||
|  | 	{ XK_F3, /* F15 */  ShiftMask,      "\033[1;2R",     0,    0}, | ||||||
|  | 	{ XK_F3, /* F27 */  ControlMask,    "\033[1;5R",     0,    0}, | ||||||
|  | 	{ XK_F3, /* F39 */  Mod4Mask,       "\033[1;6R",     0,    0}, | ||||||
|  | 	{ XK_F3, /* F51 */  Mod1Mask,       "\033[1;3R",     0,    0}, | ||||||
|  | 	{ XK_F3, /* F63 */  Mod3Mask,       "\033[1;4R",     0,    0}, | ||||||
|  | 	{ XK_F4,            XK_NO_MOD,      "\033OS" ,       0,    0}, | ||||||
|  | 	{ XK_F4, /* F16 */  ShiftMask,      "\033[1;2S",     0,    0}, | ||||||
|  | 	{ XK_F4, /* F28 */  ControlMask,    "\033[1;5S",     0,    0}, | ||||||
|  | 	{ XK_F4, /* F40 */  Mod4Mask,       "\033[1;6S",     0,    0}, | ||||||
|  | 	{ XK_F4, /* F52 */  Mod1Mask,       "\033[1;3S",     0,    0}, | ||||||
|  | 	{ XK_F5,            XK_NO_MOD,      "\033[15~",      0,    0}, | ||||||
|  | 	{ XK_F5, /* F17 */  ShiftMask,      "\033[15;2~",    0,    0}, | ||||||
|  | 	{ XK_F5, /* F29 */  ControlMask,    "\033[15;5~",    0,    0}, | ||||||
|  | 	{ XK_F5, /* F41 */  Mod4Mask,       "\033[15;6~",    0,    0}, | ||||||
|  | 	{ XK_F5, /* F53 */  Mod1Mask,       "\033[15;3~",    0,    0}, | ||||||
|  | 	{ XK_F6,            XK_NO_MOD,      "\033[17~",      0,    0}, | ||||||
|  | 	{ XK_F6, /* F18 */  ShiftMask,      "\033[17;2~",    0,    0}, | ||||||
|  | 	{ XK_F6, /* F30 */  ControlMask,    "\033[17;5~",    0,    0}, | ||||||
|  | 	{ XK_F6, /* F42 */  Mod4Mask,       "\033[17;6~",    0,    0}, | ||||||
|  | 	{ XK_F6, /* F54 */  Mod1Mask,       "\033[17;3~",    0,    0}, | ||||||
|  | 	{ XK_F7,            XK_NO_MOD,      "\033[18~",      0,    0}, | ||||||
|  | 	{ XK_F7, /* F19 */  ShiftMask,      "\033[18;2~",    0,    0}, | ||||||
|  | 	{ XK_F7, /* F31 */  ControlMask,    "\033[18;5~",    0,    0}, | ||||||
|  | 	{ XK_F7, /* F43 */  Mod4Mask,       "\033[18;6~",    0,    0}, | ||||||
|  | 	{ XK_F7, /* F55 */  Mod1Mask,       "\033[18;3~",    0,    0}, | ||||||
|  | 	{ XK_F8,            XK_NO_MOD,      "\033[19~",      0,    0}, | ||||||
|  | 	{ XK_F8, /* F20 */  ShiftMask,      "\033[19;2~",    0,    0}, | ||||||
|  | 	{ XK_F8, /* F32 */  ControlMask,    "\033[19;5~",    0,    0}, | ||||||
|  | 	{ XK_F8, /* F44 */  Mod4Mask,       "\033[19;6~",    0,    0}, | ||||||
|  | 	{ XK_F8, /* F56 */  Mod1Mask,       "\033[19;3~",    0,    0}, | ||||||
|  | 	{ XK_F9,            XK_NO_MOD,      "\033[20~",      0,    0}, | ||||||
|  | 	{ XK_F9, /* F21 */  ShiftMask,      "\033[20;2~",    0,    0}, | ||||||
|  | 	{ XK_F9, /* F33 */  ControlMask,    "\033[20;5~",    0,    0}, | ||||||
|  | 	{ XK_F9, /* F45 */  Mod4Mask,       "\033[20;6~",    0,    0}, | ||||||
|  | 	{ XK_F9, /* F57 */  Mod1Mask,       "\033[20;3~",    0,    0}, | ||||||
|  | 	{ XK_F10,           XK_NO_MOD,      "\033[21~",      0,    0}, | ||||||
|  | 	{ XK_F10, /* F22 */ ShiftMask,      "\033[21;2~",    0,    0}, | ||||||
|  | 	{ XK_F10, /* F34 */ ControlMask,    "\033[21;5~",    0,    0}, | ||||||
|  | 	{ XK_F10, /* F46 */ Mod4Mask,       "\033[21;6~",    0,    0}, | ||||||
|  | 	{ XK_F10, /* F58 */ Mod1Mask,       "\033[21;3~",    0,    0}, | ||||||
|  | 	{ XK_F11,           XK_NO_MOD,      "\033[23~",      0,    0}, | ||||||
|  | 	{ XK_F11, /* F23 */ ShiftMask,      "\033[23;2~",    0,    0}, | ||||||
|  | 	{ XK_F11, /* F35 */ ControlMask,    "\033[23;5~",    0,    0}, | ||||||
|  | 	{ XK_F11, /* F47 */ Mod4Mask,       "\033[23;6~",    0,    0}, | ||||||
|  | 	{ XK_F11, /* F59 */ Mod1Mask,       "\033[23;3~",    0,    0}, | ||||||
|  | 	{ XK_F12,           XK_NO_MOD,      "\033[24~",      0,    0}, | ||||||
|  | 	{ XK_F12, /* F24 */ ShiftMask,      "\033[24;2~",    0,    0}, | ||||||
|  | 	{ XK_F12, /* F36 */ ControlMask,    "\033[24;5~",    0,    0}, | ||||||
|  | 	{ XK_F12, /* F48 */ Mod4Mask,       "\033[24;6~",    0,    0}, | ||||||
|  | 	{ XK_F12, /* F60 */ Mod1Mask,       "\033[24;3~",    0,    0}, | ||||||
|  | 	{ XK_F13,           XK_NO_MOD,      "\033[1;2P",     0,    0}, | ||||||
|  | 	{ XK_F14,           XK_NO_MOD,      "\033[1;2Q",     0,    0}, | ||||||
|  | 	{ XK_F15,           XK_NO_MOD,      "\033[1;2R",     0,    0}, | ||||||
|  | 	{ XK_F16,           XK_NO_MOD,      "\033[1;2S",     0,    0}, | ||||||
|  | 	{ XK_F17,           XK_NO_MOD,      "\033[15;2~",    0,    0}, | ||||||
|  | 	{ XK_F18,           XK_NO_MOD,      "\033[17;2~",    0,    0}, | ||||||
|  | 	{ XK_F19,           XK_NO_MOD,      "\033[18;2~",    0,    0}, | ||||||
|  | 	{ XK_F20,           XK_NO_MOD,      "\033[19;2~",    0,    0}, | ||||||
|  | 	{ XK_F21,           XK_NO_MOD,      "\033[20;2~",    0,    0}, | ||||||
|  | 	{ XK_F22,           XK_NO_MOD,      "\033[21;2~",    0,    0}, | ||||||
|  | 	{ XK_F23,           XK_NO_MOD,      "\033[23;2~",    0,    0}, | ||||||
|  | 	{ XK_F24,           XK_NO_MOD,      "\033[24;2~",    0,    0}, | ||||||
|  | 	{ XK_F25,           XK_NO_MOD,      "\033[1;5P",     0,    0}, | ||||||
|  | 	{ XK_F26,           XK_NO_MOD,      "\033[1;5Q",     0,    0}, | ||||||
|  | 	{ XK_F27,           XK_NO_MOD,      "\033[1;5R",     0,    0}, | ||||||
|  | 	{ XK_F28,           XK_NO_MOD,      "\033[1;5S",     0,    0}, | ||||||
|  | 	{ XK_F29,           XK_NO_MOD,      "\033[15;5~",    0,    0}, | ||||||
|  | 	{ XK_F30,           XK_NO_MOD,      "\033[17;5~",    0,    0}, | ||||||
|  | 	{ XK_F31,           XK_NO_MOD,      "\033[18;5~",    0,    0}, | ||||||
|  | 	{ XK_F32,           XK_NO_MOD,      "\033[19;5~",    0,    0}, | ||||||
|  | 	{ XK_F33,           XK_NO_MOD,      "\033[20;5~",    0,    0}, | ||||||
|  | 	{ XK_F34,           XK_NO_MOD,      "\033[21;5~",    0,    0}, | ||||||
|  | 	{ XK_F35,           XK_NO_MOD,      "\033[23;5~",    0,    0}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Selection types' masks. | ||||||
|  |  * Use the same masks as usual. | ||||||
|  |  * Button1Mask is always unset, to make masks match between ButtonPress. | ||||||
|  |  * ButtonRelease and MotionNotify. | ||||||
|  |  * If no match is found, regular selection is used. | ||||||
|  |  */ | ||||||
|  | static uint selmasks[] = { | ||||||
|  | 	[SEL_RECTANGULAR] = Mod1Mask, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Printable characters in ASCII, used to estimate the advance width | ||||||
|  |  * of single wide characters. | ||||||
|  |  */ | ||||||
|  | static char ascii_printable[] = | ||||||
|  | 	" !\"#$%&'()*+,-./0123456789:;<=>?" | ||||||
|  | 	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" | ||||||
|  | 	"`abcdefghijklmnopqrstuvwxyz{|}~"; | ||||||
							
								
								
									
										3
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								config.h
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | |||||||
|  * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
 |  * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
 | ||||||
|  */ |  */ | ||||||
| static char *font = "mono:pixelsize=12:antialias=true:autohint=true"; | static char *font = "mono:pixelsize=12:antialias=true:autohint=true"; | ||||||
| static char *font2[] = { "JoyPixels:pixelsize=10:antialias=true:autohint=true" }; | static char *font2[] = { "NotoColorEmoji:pixelsize=10:antialias=true:autohint=true" }; | ||||||
| static int borderpx = 2; | static int borderpx = 2; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| @ -555,3 +555,4 @@ static char ascii_printable[] = | |||||||
| 	" !\"#$%&'()*+,-./0123456789:;<=>?" | 	" !\"#$%&'()*+,-./0123456789:;<=>?" | ||||||
| 	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" | 	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" | ||||||
| 	"`abcdefghijklmnopqrstuvwxyz{|}~"; | 	"`abcdefghijklmnopqrstuvwxyz{|}~"; | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| # st version
 | # st version
 | ||||||
| VERSION = 0.8.4 | VERSION = 0.8.5 | ||||||
| 
 | 
 | ||||||
| # Customize below to fit your system
 | # Customize below to fit your system
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								st.1
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								st.1
									
									
									
									
									
								
							| @ -176,6 +176,24 @@ Print the full screen to the | |||||||
| .B Print Screen | .B Print Screen | ||||||
| Print the selection to the | Print the selection to the | ||||||
| .I iofile. | .I iofile. | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-Page Up | ||||||
|  | Increase font size. | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-Page Down | ||||||
|  | Decrease font size. | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-Home | ||||||
|  | Reset to default font size. | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-y | ||||||
|  | Paste from primary selection (middle mouse button). | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-c | ||||||
|  | Copy the selected text to the clipboard selection. | ||||||
|  | .TP | ||||||
|  | .B Ctrl-Shift-v | ||||||
|  | Paste from the clipboard selection. | ||||||
| .SH CUSTOMIZATION | .SH CUSTOMIZATION | ||||||
| .B st | .B st | ||||||
| can be customized by creating a custom config.h and (re)compiling the source | can be customized by creating a custom config.h and (re)compiling the source | ||||||
|  | |||||||
							
								
								
									
										137
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								st.c
									
									
									
									
									
								
							| @ -170,6 +170,7 @@ static void csidump(void); | |||||||
| static void csihandle(void); | static void csihandle(void); | ||||||
| static void csiparse(void); | static void csiparse(void); | ||||||
| static void csireset(void); | static void csireset(void); | ||||||
|  | static void osc_color_response(int, int, int); | ||||||
| static int eschandle(uchar); | static int eschandle(uchar); | ||||||
| static void strdump(void); | static void strdump(void); | ||||||
| static void strhandle(void); | static void strhandle(void); | ||||||
| @ -195,17 +196,17 @@ static void tputc(Rune); | |||||||
| static void treset(void); | static void treset(void); | ||||||
| static void tscrollup(int, int, int); | static void tscrollup(int, int, int); | ||||||
| static void tscrolldown(int, int, int); | static void tscrolldown(int, int, int); | ||||||
| static void tsetattr(int *, int); | static void tsetattr(const int *, int); | ||||||
| static void tsetchar(Rune, Glyph *, int, int); | static void tsetchar(Rune, const Glyph *, int, int); | ||||||
| static void tsetdirt(int, int); | static void tsetdirt(int, int); | ||||||
| static void tsetscroll(int, int); | static void tsetscroll(int, int); | ||||||
| static void tswapscreen(void); | static void tswapscreen(void); | ||||||
| static void tsetmode(int, int, int *, int); | static void tsetmode(int, int, const int *, int); | ||||||
| static int twrite(const char *, int, int); | static int twrite(const char *, int, int); | ||||||
| static void tcontrolcode(uchar ); | static void tcontrolcode(uchar ); | ||||||
| static void tdectest(char ); | static void tdectest(char ); | ||||||
| static void tdefutf8(char); | static void tdefutf8(char); | ||||||
| static int32_t tdefcolor(int *, int *, int); | static int32_t tdefcolor(const int *, int *, int); | ||||||
| static void tdeftran(char); | static void tdeftran(char); | ||||||
| static void tstrsequence(uchar); | static void tstrsequence(uchar); | ||||||
| 
 | 
 | ||||||
| @ -234,10 +235,10 @@ static int iofd = 1; | |||||||
| static int cmdfd; | static int cmdfd; | ||||||
| static pid_t pid; | static pid_t pid; | ||||||
| 
 | 
 | ||||||
| static uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0}; | static const uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0}; | ||||||
| static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | ||||||
| static Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000}; | static const Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000}; | ||||||
| static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | ||||||
| 
 | 
 | ||||||
| ssize_t | ssize_t | ||||||
| xwrite(int fd, const char *s, size_t len) | xwrite(int fd, const char *s, size_t len) | ||||||
| @ -277,12 +278,16 @@ xrealloc(void *p, size_t len) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char * | char * | ||||||
| xstrdup(char *s) | xstrdup(const char *s) | ||||||
| { | { | ||||||
| 	if ((s = strdup(s)) == NULL) | 	if ((s = strdup(s)) == NULL) | ||||||
| 		die("strdup: %s\n", strerror(errno)); | 		die("strdup: %s\n", strerror(errno)); | ||||||
|  | 	char *p; | ||||||
| 
 | 
 | ||||||
| 	return s; | 	if ((p = strdup(s)) == NULL) | ||||||
|  | 		die("strdup: %s\n", strerror(errno)); | ||||||
|  | 
 | ||||||
|  | 	return p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t | size_t | ||||||
| @ -355,25 +360,10 @@ utf8validate(Rune *u, size_t i) | |||||||
| 	return i; | 	return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char base64_digits[] = { |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, |  | ||||||
| 	63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, |  | ||||||
| 	2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, |  | ||||||
| 	22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, |  | ||||||
| 	35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |  | ||||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| char | char | ||||||
| base64dec_getc(const char **src) | base64dec_getc(const char **src) | ||||||
| { | { | ||||||
| 	while (**src && !isprint(**src)) | 	while (**src && !isprint((unsigned char)**src)) | ||||||
| 		(*src)++; | 		(*src)++; | ||||||
| 	return **src ? *((*src)++) : '=';  /* emulate padding if string ends */ | 	return **src ? *((*src)++) : '=';  /* emulate padding if string ends */ | ||||||
| } | } | ||||||
| @ -383,6 +373,13 @@ base64dec(const char *src) | |||||||
| { | { | ||||||
| 	size_t in_len = strlen(src); | 	size_t in_len = strlen(src); | ||||||
| 	char *result, *dst; | 	char *result, *dst; | ||||||
|  | 	static const char base64_digits[256] = { | ||||||
|  | 		[43] = 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, | ||||||
|  | 		0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, | ||||||
|  | 		13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, | ||||||
|  | 		0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, | ||||||
|  | 		40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 | ||||||
|  | 	}; | ||||||
| 
 | 
 | ||||||
| 	if (in_len % 4) | 	if (in_len % 4) | ||||||
| 		in_len += 4 - (in_len % 4); | 		in_len += 4 - (in_len % 4); | ||||||
| @ -491,6 +488,7 @@ selextend(int col, int row, int type, int done) | |||||||
| 	sel.mode = done ? SEL_IDLE : SEL_READY; | 	sel.mode = done ? SEL_IDLE : SEL_READY; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| void | void | ||||||
| selnormalize(void) | selnormalize(void) | ||||||
| { | { | ||||||
| @ -540,7 +538,7 @@ selsnap(int *x, int *y, int direction) | |||||||
| { | { | ||||||
| 	int newx, newy, xt, yt; | 	int newx, newy, xt, yt; | ||||||
| 	int delim, prevdelim; | 	int delim, prevdelim; | ||||||
| 	Glyph *gp, *prevgp; | 	const Glyph *gp, *prevgp; | ||||||
| 
 | 
 | ||||||
| 	switch (sel.snap) { | 	switch (sel.snap) { | ||||||
| 	case SNAP_WORD: | 	case SNAP_WORD: | ||||||
| @ -613,7 +611,7 @@ getsel(void) | |||||||
| { | { | ||||||
| 	char *str, *ptr; | 	char *str, *ptr; | ||||||
| 	int y, bufsize, lastx, linelen; | 	int y, bufsize, lastx, linelen; | ||||||
| 	Glyph *gp, *last; | 	const Glyph *gp, *last; | ||||||
| 
 | 
 | ||||||
| 	if (sel.ob.x == -1) | 	if (sel.ob.x == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| @ -780,7 +778,7 @@ stty(char **args) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| ttynew(char *line, char *cmd, char *out, char **args) | ttynew(const char *line, char *cmd, const char *out, char **args) | ||||||
| { | { | ||||||
| 	int m, s; | 	int m, s; | ||||||
| 
 | 
 | ||||||
| @ -813,14 +811,15 @@ ttynew(char *line, char *cmd, char *out, char **args) | |||||||
| 		break; | 		break; | ||||||
| 	case 0: | 	case 0: | ||||||
| 		close(iofd); | 		close(iofd); | ||||||
|  | 		close(m); | ||||||
| 		setsid(); /* create a new process group */ | 		setsid(); /* create a new process group */ | ||||||
| 		dup2(s, 0); | 		dup2(s, 0); | ||||||
| 		dup2(s, 1); | 		dup2(s, 1); | ||||||
| 		dup2(s, 2); | 		dup2(s, 2); | ||||||
| 		if (ioctl(s, TIOCSCTTY, NULL) < 0) | 		if (ioctl(s, TIOCSCTTY, NULL) < 0) | ||||||
| 			die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); | 			die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); | ||||||
| 		close(s); | 		if (s > 2) | ||||||
| 		close(m); | 			close(s); | ||||||
| #ifdef __OpenBSD__ | #ifdef __OpenBSD__ | ||||||
| 		if (pledge("stdio getpw proc exec", NULL) == -1) | 		if (pledge("stdio getpw proc exec", NULL) == -1) | ||||||
| 			die("pledge\n"); | 			die("pledge\n"); | ||||||
| @ -1263,9 +1262,9 @@ tmoveto(int x, int y) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tsetchar(Rune u, Glyph *attr, int x, int y) | tsetchar(Rune u, const Glyph *attr, int x, int y) | ||||||
| { | { | ||||||
| 	static char *vt100_0[62] = { /* 0x41 - 0x7e */ | 	static const char *vt100_0[62] = { /* 0x41 - 0x7e */ | ||||||
| 		"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ | 		"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ | ||||||
| 		0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ | 		0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ | ||||||
| 		0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ | 		0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ | ||||||
| @ -1380,7 +1379,7 @@ tdeleteline(int n) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t | int32_t | ||||||
| tdefcolor(int *attr, int *npar, int l) | tdefcolor(const int *attr, int *npar, int l) | ||||||
| { | { | ||||||
| 	int32_t idx = -1; | 	int32_t idx = -1; | ||||||
| 	uint r, g, b; | 	uint r, g, b; | ||||||
| @ -1430,7 +1429,7 @@ tdefcolor(int *attr, int *npar, int l) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tsetattr(int *attr, int l) | tsetattr(const int *attr, int l) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
| 	int32_t idx; | 	int32_t idx; | ||||||
| @ -1548,9 +1547,9 @@ tsetscroll(int t, int b) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| tsetmode(int priv, int set, int *args, int narg) | tsetmode(int priv, int set, const int *args, int narg) | ||||||
| { | { | ||||||
| 	int alt, *lim; | 	int alt; const int *lim; | ||||||
| 
 | 
 | ||||||
| 	for (lim = args + narg; args < lim; ++args) { | 	for (lim = args + narg; args < lim; ++args) { | ||||||
| 		if (priv) { | 		if (priv) { | ||||||
| @ -1919,11 +1918,41 @@ csireset(void) | |||||||
| 	memset(&csiescseq, 0, sizeof(csiescseq)); | 	memset(&csiescseq, 0, sizeof(csiescseq)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | osc_color_response(int num, int index, int is_osc4) | ||||||
|  | { | ||||||
|  | 	int n; | ||||||
|  | 	char buf[32]; | ||||||
|  | 	unsigned char r, g, b; | ||||||
|  | 
 | ||||||
|  | 	if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) { | ||||||
|  | 		fprintf(stderr, "erresc: failed to fetch %s color %d\n", | ||||||
|  | 		        is_osc4 ? "osc4" : "osc", | ||||||
|  | 		        is_osc4 ? num : index); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", | ||||||
|  | 	             is_osc4 ? "4;" : "", num, r, r, g, g, b, b); | ||||||
|  | 	if (n < 0 || n >= sizeof(buf)) { | ||||||
|  | 		fprintf(stderr, "error: %s while printing %s response\n", | ||||||
|  | 		        n < 0 ? "snprintf failed" : "truncation occurred", | ||||||
|  | 		        is_osc4 ? "osc4" : "osc"); | ||||||
|  | 	} else { | ||||||
|  | 		ttywrite(buf, n, 1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| strhandle(void) | strhandle(void) | ||||||
| { | { | ||||||
| 	char *p = NULL, *dec; | 	char *p = NULL, *dec; | ||||||
| 	int j, narg, par; | 	int j, narg, par; | ||||||
|  | 	const struct { int idx; char *str; } osc_table[] = { | ||||||
|  | 		{ defaultfg, "foreground" }, | ||||||
|  | 		{ defaultbg, "background" }, | ||||||
|  | 		{ defaultcs, "cursor" } | ||||||
|  | 	}; | ||||||
| 
 | 
 | ||||||
| 	term.esc &= ~(ESC_STR_END|ESC_STR); | 	term.esc &= ~(ESC_STR_END|ESC_STR); | ||||||
| 	strparse(); | 	strparse(); | ||||||
| @ -1957,14 +1986,35 @@ strhandle(void) | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
|  | 		case 10: | ||||||
|  | 		case 11: | ||||||
|  | 		case 12: | ||||||
|  | 			if (narg < 2) | ||||||
|  | 				break; | ||||||
|  | 			p = strescseq.args[1]; | ||||||
|  | 			if ((j = par - 10) < 0 || j >= LEN(osc_table)) | ||||||
|  | 				break; /* shouldn't be possible */ | ||||||
|  | 
 | ||||||
|  | 			if (!strcmp(p, "?")) { | ||||||
|  | 				osc_color_response(par, osc_table[j].idx, 0); | ||||||
|  | 			} else if (xsetcolorname(osc_table[j].idx, p)) { | ||||||
|  | 				fprintf(stderr, "erresc: invalid %s color: %s\n", | ||||||
|  | 				        osc_table[j].str, p); | ||||||
|  | 			} else { | ||||||
|  | 				tfulldirt(); | ||||||
|  | 			} | ||||||
|  | 			return; | ||||||
| 		case 4: /* color set */ | 		case 4: /* color set */ | ||||||
| 			if (narg < 3) | 			if (narg < 3) | ||||||
| 				break; | 				break; | ||||||
| 			p = strescseq.args[2]; | 			p = strescseq.args[2]; | ||||||
| 			/* FALLTHROUGH */ | 			/* FALLTHROUGH */ | ||||||
| 		case 104: /* color reset, here p = NULL */ | 		case 104: /* color reset */ | ||||||
| 			j = (narg > 1) ? atoi(strescseq.args[1]) : -1; | 			j = (narg > 1) ? atoi(strescseq.args[1]) : -1; | ||||||
| 			if (xsetcolorname(j, p)) { | 
 | ||||||
|  | 			if (p && !strcmp(p, "?")) { | ||||||
|  | 				osc_color_response(j, 0, 1); | ||||||
|  | 			} else if (xsetcolorname(j, p)) { | ||||||
| 				if (par == 104 && narg <= 1) | 				if (par == 104 && narg <= 1) | ||||||
| 					return; /* color reset without parameter */ | 					return; /* color reset without parameter */ | ||||||
| 				fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", | 				fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", | ||||||
| @ -1974,7 +2024,7 @@ strhandle(void) | |||||||
| 				 * TODO if defaultbg color is changed, borders | 				 * TODO if defaultbg color is changed, borders | ||||||
| 				 * are dirty | 				 * are dirty | ||||||
| 				 */ | 				 */ | ||||||
| 				redraw(); | 				tfulldirt(); | ||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @ -2155,7 +2205,7 @@ void | |||||||
| tdumpline(int n) | tdumpline(int n) | ||||||
| { | { | ||||||
| 	char buf[UTF_SIZ]; | 	char buf[UTF_SIZ]; | ||||||
| 	Glyph *bp, *end; | 	const Glyph *bp, *end; | ||||||
| 
 | 
 | ||||||
| 	bp = &term.line[n][0]; | 	bp = &term.line[n][0]; | ||||||
| 	end = &bp[MIN(tlinelen(n), term.col) - 1]; | 	end = &bp[MIN(tlinelen(n), term.col) - 1]; | ||||||
| @ -2561,6 +2611,10 @@ check_control_code: | |||||||
| 	if (width == 2) { | 	if (width == 2) { | ||||||
| 		gp->mode |= ATTR_WIDE; | 		gp->mode |= ATTR_WIDE; | ||||||
| 		if (term.c.x+1 < term.col) { | 		if (term.c.x+1 < term.col) { | ||||||
|  | 			if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) { | ||||||
|  | 				gp[2].u = ' '; | ||||||
|  | 				gp[2].mode &= ~ATTR_WDUMMY; | ||||||
|  | 			} | ||||||
| 			gp[1].u = '\0'; | 			gp[1].u = '\0'; | ||||||
| 			gp[1].mode = ATTR_WDUMMY; | 			gp[1].mode = ATTR_WDUMMY; | ||||||
| 		} | 		} | ||||||
| @ -2759,3 +2813,4 @@ redraw(void) | |||||||
| 	tfulldirt(); | 	tfulldirt(); | ||||||
| 	draw(); | 	draw(); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								st.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								st.h
									
									
									
									
									
								
							| @ -88,6 +88,7 @@ void draw(void); | |||||||
| void externalpipe(const Arg *); | void externalpipe(const Arg *); | ||||||
| void kscrolldown(const Arg *); | void kscrolldown(const Arg *); | ||||||
| void kscrollup(const Arg *); | void kscrollup(const Arg *); | ||||||
|  | 
 | ||||||
| void printscreen(const Arg *); | void printscreen(const Arg *); | ||||||
| void printsel(const Arg *); | void printsel(const Arg *); | ||||||
| void sendbreak(const Arg *); | void sendbreak(const Arg *); | ||||||
| @ -98,7 +99,7 @@ void tnew(int, int); | |||||||
| void tresize(int, int); | void tresize(int, int); | ||||||
| void tsetdirtattr(int); | void tsetdirtattr(int); | ||||||
| void ttyhangup(void); | void ttyhangup(void); | ||||||
| int ttynew(char *, char *, char *, char **); | int ttynew(const char *, char *, const char *, char **); | ||||||
| size_t ttyread(void); | size_t ttyread(void); | ||||||
| void ttyresize(int, int); | void ttyresize(int, int); | ||||||
| void ttywrite(const char *, size_t, int); | void ttywrite(const char *, size_t, int); | ||||||
| @ -116,7 +117,7 @@ size_t utf8encode(Rune, char *); | |||||||
| 
 | 
 | ||||||
| void *xmalloc(size_t); | void *xmalloc(size_t); | ||||||
| void *xrealloc(void *, size_t); | void *xrealloc(void *, size_t); | ||||||
| char *xstrdup(char *); | char *xstrdup(const char *); | ||||||
| 
 | 
 | ||||||
| int isboxdraw(Rune); | int isboxdraw(Rune); | ||||||
| ushort boxdrawindex(const Glyph *); | ushort boxdrawindex(const Glyph *); | ||||||
| @ -141,3 +142,5 @@ extern unsigned int defaultbg; | |||||||
| extern float alpha; | extern float alpha; | ||||||
| extern float alphaUnfocus; | extern float alphaUnfocus; | ||||||
| extern const int boxdraw, boxdraw_bold, boxdraw_braille; | extern const int boxdraw, boxdraw_bold, boxdraw_braille; | ||||||
|  | extern unsigned int defaultcs; | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								win.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								win.h
									
									
									
									
									
								
							| @ -30,6 +30,7 @@ void xdrawline(Line, int, int, int); | |||||||
| void xfinishdraw(void); | void xfinishdraw(void); | ||||||
| void xloadcols(void); | void xloadcols(void); | ||||||
| int xsetcolorname(int, const char *); | int xsetcolorname(int, const char *); | ||||||
|  | int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *); | ||||||
| void xseticontitle(char *); | void xseticontitle(char *); | ||||||
| void xsettitle(char *); | void xsettitle(char *); | ||||||
| int xsetcursor(int); | int xsetcursor(int); | ||||||
| @ -38,3 +39,4 @@ void xsetpointermotion(int); | |||||||
| void xsetsel(char *); | void xsetsel(char *); | ||||||
| int xstartdraw(void); | int xstartdraw(void); | ||||||
| void xximspot(int, int); | void xximspot(int, int); | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										57
									
								
								x.c
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								x.c
									
									
									
									
									
								
							| @ -63,7 +63,7 @@ typedef struct { | |||||||
| /* X modifiers */ | /* X modifiers */ | ||||||
| #define XK_ANY_MOD    UINT_MAX | #define XK_ANY_MOD    UINT_MAX | ||||||
| #define XK_NO_MOD     0 | #define XK_NO_MOD     0 | ||||||
| #define XK_SWITCH_MOD (1<<13) | #define XK_SWITCH_MOD (1<<13|1<<14) | ||||||
| 
 | 
 | ||||||
| /* function definitions used in config.h */ | /* function definitions used in config.h */ | ||||||
| static void clipcopy(const Arg *); | static void clipcopy(const Arg *); | ||||||
| @ -173,9 +173,9 @@ static void xresize(int, int); | |||||||
| static void xhints(void); | static void xhints(void); | ||||||
| static int xloadcolor(int, const char *, Color *); | static int xloadcolor(int, const char *, Color *); | ||||||
| static int xloadfont(Font *, FcPattern *); | static int xloadfont(Font *, FcPattern *); | ||||||
| static void xloadfonts(char *, double); |  | ||||||
| static int xloadsparefont(FcPattern *, int); | static int xloadsparefont(FcPattern *, int); | ||||||
| static void xloadsparefonts(void); | static void xloadsparefonts(void); | ||||||
|  | static void xloadfonts(const char *, double); | ||||||
| static void xunloadfont(Font *); | static void xunloadfont(Font *); | ||||||
| static void xunloadfonts(void); | static void xunloadfonts(void); | ||||||
| static void xsetenv(void); | static void xsetenv(void); | ||||||
| @ -276,6 +276,7 @@ static char *opt_title = NULL; | |||||||
| static int focused = 0; | static int focused = 0; | ||||||
| 
 | 
 | ||||||
| static int oldbutton = 3; /* button event on startup: 3 = release */ | static int oldbutton = 3; /* button event on startup: 3 = release */ | ||||||
|  | static uint buttons; /* bit field of pressed buttons */ | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| clipcopy(const Arg *dummy) | clipcopy(const Arg *dummy) | ||||||
| @ -409,6 +410,7 @@ mousesel(XEvent *e, int done) | |||||||
| void | void | ||||||
| mousereport(XEvent *e) | mousereport(XEvent *e) | ||||||
| { | { | ||||||
|  |     int code; | ||||||
| 	int len, x = evcol(e), y = evrow(e), | 	int len, x = evcol(e), y = evrow(e), | ||||||
| 	    button = e->xbutton.button, state = e->xbutton.state; | 	    button = e->xbutton.button, state = e->xbutton.state; | ||||||
| 	char buf[40]; | 	char buf[40]; | ||||||
| @ -457,11 +459,11 @@ mousereport(XEvent *e) | |||||||
| 
 | 
 | ||||||
| 	if (IS_SET(MODE_MOUSESGR)) { | 	if (IS_SET(MODE_MOUSESGR)) { | ||||||
| 		len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", | 		len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", | ||||||
| 				button, x+1, y+1, | 				code, x+1, y+1, | ||||||
| 				e->xbutton.type == ButtonRelease ? 'm' : 'M'); | 				e->type == ButtonRelease ? 'm' : 'M'); | ||||||
| 	} else if (x < 223 && y < 223) { | 	} else if (x < 223 && y < 223) { | ||||||
| 		len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", | 		len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", | ||||||
| 				32+button, 32+x+1, 32+y+1); | 				32+code, 32+x+1, 32+y+1); | ||||||
| 	} else { | 	} else { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| @ -504,9 +506,13 @@ mouseaction(XEvent *e, uint release) | |||||||
| void | void | ||||||
| bpress(XEvent *e) | bpress(XEvent *e) | ||||||
| { | { | ||||||
|  | 	int btn = e->xbutton.button; | ||||||
| 	struct timespec now; | 	struct timespec now; | ||||||
| 	int snap; | 	int snap; | ||||||
| 
 | 
 | ||||||
|  | 	if (1 <= btn && btn <= 11) | ||||||
|  | 		buttons |= 1 << (btn-1); | ||||||
|  | 
 | ||||||
| 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { | 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { | ||||||
| 		mousereport(e); | 		mousereport(e); | ||||||
| 		return; | 		return; | ||||||
| @ -515,7 +521,7 @@ bpress(XEvent *e) | |||||||
| 	if (mouseaction(e, 0)) | 	if (mouseaction(e, 0)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if (e->xbutton.button == Button1) { | 	if (btn == Button1) { | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * If the user clicks below predefined timeouts specific | 		 * If the user clicks below predefined timeouts specific | ||||||
| 		 * snapping behaviour is exposed. | 		 * snapping behaviour is exposed. | ||||||
| @ -729,6 +735,11 @@ xsetsel(char *str) | |||||||
| void | void | ||||||
| brelease(XEvent *e) | brelease(XEvent *e) | ||||||
| { | { | ||||||
|  | 	int btn = e->xbutton.button; | ||||||
|  | 
 | ||||||
|  | 	if (1 <= btn && btn <= 11) | ||||||
|  | 		buttons &= ~(1 << (btn-1)); | ||||||
|  | 
 | ||||||
| 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { | 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { | ||||||
| 		mousereport(e); | 		mousereport(e); | ||||||
| 		return; | 		return; | ||||||
| @ -736,7 +747,7 @@ brelease(XEvent *e) | |||||||
| 
 | 
 | ||||||
| 	if (mouseaction(e, 1)) | 	if (mouseaction(e, 1)) | ||||||
| 		return; | 		return; | ||||||
| 	if (e->xbutton.button == Button1) | 	if (btn == Button1) | ||||||
| 		mousesel(e, 1); | 		mousesel(e, 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -854,6 +865,19 @@ xloadcols(void) | |||||||
| 	loaded = 1; | 	loaded = 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int | ||||||
|  | xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) | ||||||
|  | { | ||||||
|  | 	if (!BETWEEN(x, 0, dc.collen)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	*r = dc.col[x].color.red >> 8; | ||||||
|  | 	*g = dc.col[x].color.green >> 8; | ||||||
|  | 	*b = dc.col[x].color.blue >> 8; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int | int | ||||||
| xsetcolorname(int x, const char *name) | xsetcolorname(int x, const char *name) | ||||||
| { | { | ||||||
| @ -1007,7 +1031,7 @@ xloadfont(Font *f, FcPattern *pattern) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| xloadfonts(char *fontstr, double fontsize) | xloadfonts(const char *fontstr, double fontsize) | ||||||
| { | { | ||||||
| 	FcPattern *pattern; | 	FcPattern *pattern; | ||||||
| 	double fontval; | 	double fontval; | ||||||
| @ -1015,7 +1039,7 @@ xloadfonts(char *fontstr, double fontsize) | |||||||
| 	if (fontstr[0] == '-') | 	if (fontstr[0] == '-') | ||||||
| 		pattern = XftXlfdParse(fontstr, False, False); | 		pattern = XftXlfdParse(fontstr, False, False); | ||||||
| 	else | 	else | ||||||
| 		pattern = FcNameParse((FcChar8 *)fontstr); | 		pattern = FcNameParse((const FcChar8 *)fontstr); | ||||||
| 
 | 
 | ||||||
| 	if (!pattern) | 	if (!pattern) | ||||||
| 		die("can't open font %s\n", fontstr); | 		die("can't open font %s\n", fontstr); | ||||||
| @ -1641,11 +1665,11 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i | |||||||
| 	/* Render underline and strikethrough. */ | 	/* Render underline and strikethrough. */ | ||||||
| 	if (base.mode & ATTR_UNDERLINE) { | 	if (base.mode & ATTR_UNDERLINE) { | ||||||
| 		XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, | 		XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, | ||||||
| 				width, 1); |                 width, 1); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (base.mode & ATTR_STRUCK) { | 	if (base.mode & ATTR_STRUCK) { | ||||||
| 		XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, | 		XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, | ||||||
| 				width, 1); | 				width, 1); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -1767,8 +1791,9 @@ xseticontitle(char *p) | |||||||
| 	XTextProperty prop; | 	XTextProperty prop; | ||||||
| 	DEFAULT(p, opt_title); | 	DEFAULT(p, opt_title); | ||||||
| 
 | 
 | ||||||
| 	Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | 	if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | ||||||
| 			&prop); | 	                                &prop) != Success) | ||||||
|  | 		return; | ||||||
| 	XSetWMIconName(xw.dpy, xw.win, &prop); | 	XSetWMIconName(xw.dpy, xw.win, &prop); | ||||||
| 	XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); | 	XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); | ||||||
| 	XFree(prop.value); | 	XFree(prop.value); | ||||||
| @ -1780,8 +1805,9 @@ xsettitle(char *p) | |||||||
| 	XTextProperty prop; | 	XTextProperty prop; | ||||||
| 	DEFAULT(p, opt_title); | 	DEFAULT(p, opt_title); | ||||||
| 
 | 
 | ||||||
| 	Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | 	if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | ||||||
| 			&prop); | 	                                &prop) != Success) | ||||||
|  | 		return; | ||||||
| 	XSetWMName(xw.dpy, xw.win, &prop); | 	XSetWMName(xw.dpy, xw.win, &prop); | ||||||
| 	XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); | 	XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); | ||||||
| 	XFree(prop.value); | 	XFree(prop.value); | ||||||
| @ -2315,3 +2341,4 @@ run: | |||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Luke Smith
						Luke Smith