Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello everybody,
I work a lot in console (no X windows), mostly for viewing and editing program files. My laptop has a rather wide screen, which means I see some lines of code on the left but the right half of the screen is almost useless. I would like to make a better use of the right half of the screen.
But I don't want two consoles. I want only one virtual console, double the height of the screen, half the width of the screen, cut in half, its upper half displayed in the left half of the screen, its lower half displayed in the right half of the screen. Like two pages of a book, you see ?
In particular, when I give a bash command (suppose the pointer is at the bottom of the right half of the screen) the text on the right scrolls up. I want the text on the left to scroll up too and I want the lines of text which disappear from the top of the right half to re-appear at the bottom of the left half.
I cheched multiplexers like screen or tmux but they don't do this "book" trick.
I guess I have to make some changes to the console driver, or perhaps create a new driver of my own, right ? I am thinking of declaring fake dimensions for the virtual console (twice the height of the screen, half the width). When the driver wants to draw a glyph on the upper half of the console, let it do its job normally. When the driver wants to draw a glyph on the lower half of the console, remap its position to the right half of the (physical) screen.
No mouse support for now, let's leave it for later.
I have some programming experience in FORTRAN, Python, C++ and JavaScript, but I never dwelled into the kernel source. So I guess I could use some advice.
Where should I start ? Where do I find the piece of code that actually puts a glyph on the screen, so I can remap it to another zone of the screen ? Is it here ? http://lxr.free-electrons.com/source/drivers/tty/vt/
Do I need to compile the whole kernel or can I just plug the new console driver as a module ?
Also, some textbook or tutorial for kernel/modules programming would be greatly appreciated.
Or is a terminal emulator more appropriate for this task, rather than messing with the console driver ? Tweaking the console driver seems simpler to me, but I might be wrong.
Thanks a lot
Cristian Barbarosie
I want only one virtual console, double the height of the screen, half the width of the screen, cut in half, its upper half displayed in the left half of the screen, its lower half displayed in the right half of the screen. Like two pages of a book, you see ?
In particular, when I give a bash command (suppose the pointer is at the bottom of the right half of the screen) the text on the right scrolls up. I want the text on the left to scroll up too and I want the lines of text which disappear from the top of the right half to re-appear at the bottom of the left half.
I am interested in this too but tmux can't do multiple columns yet.
The only thing I found in searching was this one, which is already quite old:
OK, here is the promised feedback.
tcvt does exactly what I want : emulates a two-column terminal. Works smoothly and it's very easy to install. And : it's written in Python, my favourite programming language. I couldn't ask for more.
However ...
tcvt has some drawbacks. It does not pass correctly some characters (pageup, pagedown, home, end). This is clearly referred in the documentation and could be corrected without much effort, I guess.
tcvt runs on top of the python interpreter, which is a waste of resources (RAM, processor load).
My feeling is that it is not the best approach. For instance, if you want to rotate the console, or merely change the font, you don't use a terminal emulator, right ? You just reconfigure the console driver, telling it to change the geometry of the screen or to use another font.
I still think that tweaking the console driver could be a simple and sound solution. Or maybe it's only me wanting to get my hands dirty ...
So, I gues I could still use some advice. Many of the questions in my original post are still pertinent. Roughly speaking, where should I start in order to get my hands dirty ?
Speaking of rotation of the screen, does anyone know where is the piece of code in the kernel (or in some module) which changes the geometry of the screen when I give a command like echo 1 > /sys/class/graphics/fbcon/rotate ?
Many thanks
Cristian Barbarosie
Last edited by cristian.barbarosie; 01-27-2017 at 02:05 PM.
Reason: small typos
yes, i think simply rotating the screen to portrait orientation should be a satisfactory compromise?
it must be possible on console; what did you find and where does it fail?
maybe this?
yes, i think simply rotating the screen to portrait orientation should be a satisfactory compromise?
it must be possible on console; what did you find and where does it fail?
maybe this?
Simply rotating the screen works great - if you can rotate physically your monitor in the opposite direction. I did it on another computer and it's awesome. But this laptop is not built that way; you cannot rotate the physical screen as you wish. Working on such a display would be - quite literally - a pain in the neck.
My question was just which piece of code in the kernel source (or in some module's) actually performs the changes the console's geometry when we send a digit to fbcon/rotate, simply as a starting point for messing with the console driver.
Any other hints for a beginner like me would be greatly appreciated.
Last edited by cristian.barbarosie; 01-27-2017 at 06:06 PM.
Reason: minor edit
tcvt is buggy. In emacs, it sometimes displays pieces of text totally out of the place. I'm giving up on tcvt.
Also, tweaking the console driver is probably not my kind of stuff. Out of my league, so to speak. Maybe some day later.
Anyway, I had a new idea. What I want could be implemented directly in emacs. Creating two views of the same buffer and linking them somehow, making them scroll in tandem and all the stuff. Sounds like some programming effort, but may be worth.
I know this is not the right forum for emacs questions, so I'm closig the thread.
Last edited by cristian.barbarosie; 01-30-2017 at 04:12 PM.
Thanks. That was a great tip. As an aside, I guess I'll have to retire my GNU Emacs reference book, follow-mode is not in it, so it is too old to keep around. The web-paglet has few words, so it's quite something that you were able to either find it on purpose or stumble on it by accident.
Something like follow-mode would be great for tmux, too.
follow-mode in emacs works very well, but is somewhat slow. At least, on my old laptop I really notice increased latency, compared with emacs with follow-mode disabled. The cursor is less responsive, as well as text selection highlighting.
My blog about using two (or more) Xephyr windows and Xdmx to make one very tall xterm. Requires X though and quirks. I've been working on a script to automate this a bit.
Still a work in progress, but functional.
Bash Script: large_term_via_xephyr.sh
Code:
#!/bin/bash
#SCREEN_X=3840; # horizontal resolution of the screen
#SCREEN_Y=2160; # vertical resolution of the screen
#SCREEN_X=1920; # horizontal resolution of the screen
#SCREEN_Y=1080; # vertical resolution of the screen
SCREEN_X=1600; # horizontal resolution of the screen
SCREEN_Y=900; # vertical resolution of the screen
SEGMENTS=2; # how many xephyr sessions to merge (2 to 4)
WD_X=2; # horizontal window decoration (left + right)(px)
WD_Y=2; # vertical window decoration (top + bottom + taskbar)(px)
XLSNORM="-*-neep-medium-r-semicondensed-*-13-*"
XLSBOLD="-*-neep-bold-r-semicondensed-*-13-*"
FONT_X=6; # font width (px)
FONT_Y=13; # font height (px)
# XLSNORM="-*-neep-medium-r-normal-*-20-*"
# XLSBOLD="-*-neep-bold-r-normal-*-20-*"
# FONT_X=10; # font width (px)
# FONT_Y=20; # font height (px)
# Verify that the needed applications are installed.
REKT="NO"
for PROGRAM in sleep wmctrl oclock Xephyr Xdmx xset fc-cache xterm END
do
if [ "$PROGRAM" = "END" ]; then
if [ "$REKT" = "YES" ]; then
exit 1
fi
else
TEMP_VAR=$(which $PROGRAM)
if [ "${#TEMP_VAR}" -lt "2" ]; then
echo $PROGRAM" is NOT installed or NOT available."
REKT="YES"
fi
fi
done
# do some math
# max X / $COLUMNS per screen
MAX_X=$(( $(($SCREEN_X - $(($WD_X * $SEGMENTS)) )) / $FONT_X ))
# max X / $COLUMNS per segment
# man sure $COLUMNS is a multiple of 2 per segment (personal preference)
COL_X=$(( $(( $MAX_X / $SEGMENTS )) - $(( $(( $MAX_X / $SEGMENTS )) % 2 )) ))
# max X pixels per segment without window decoration
# (window decoration handled by environment / out of our control)
RES_X=$(( $COL_X * $FONT_X ))
# max Y / $LINES per screen
MAX_Y=$(( $(($SCREEN_Y - $WD_Y)) / $FONT_Y ))
# make sure $LINES is a multiple of 2 per segment (personal preference)
ROW_Y=$(( $MAX_Y - $(( $MAX_Y % 2 )) ))
# max Y / $LINES for the combined terminal
ROWS_Y=$(( $ROW_Y * $SEGMENTS ))
# max Y in pixels per segment without window decoration
# (window decoration handled by environment / out of our control)
RES_Y=$(( $ROW_Y * $FONT_Y ))
# where to place these segments
WIDTH=$(( $SCREEN_X / $SEGMENTS ))
OFFSET_X0=0
OFFSET_X1=0
OFFSET_X2=0
OFFSET_X3=0
if [ "$SEGMENTS" = "2" ]; then
OFFSET_X0=$(($(($WIDTH*0)) + 0))
OFFSET_X1=$(($(($WIDTH*1)) + $(($(($WIDTH-$WD_X))-$RES_X))))
fi
if [ "$SEGMENTS" = "3" ]; then
OFFSET_X0=$(($(($WIDTH*0)) + 0))
OFFSET_X1=$(($(($WIDTH*1)) + $(($(($(($WIDTH-$WD_X))-$RES_X))/2))))
OFFSET_X2=$(($(($WIDTH*2)) + $(($(($WIDTH-$WD_X))-$RES_X))))
fi
if [ "$SEGMENTS" = "4" ]; then
OFFSET_X0=$(($(($WIDTH*0)) + 0))
OFFSET_X1=$(($(($WIDTH*1)) + $(($(($(($(($WIDTH-$WD_X))-$RES_X))/3))*1))))
OFFSET_X2=$(($(($WIDTH*2)) + $(($(($(($(($WIDTH-$WD_X))-$RES_X))/3))*2))))
OFFSET_X3=$(($(($WIDTH*3)) + $(($(($WIDTH-$WD_X))-$RES_X))))
fi
# Some INFORMATION to validate our assumptions
echo "===== COLUMNS: "$COL_X" LINES: "$ROWS_Y" ROWS: "$ROW_Y
echo "==== px_X: "$RES_X" px_Y: "$RES_Y" "
echo "=== OFFSET: "$OFFSET_X0" "$OFFSET_X1" "$OFFSET_X2" "$OFFSET_X3" "
#exit 0; # ... verify the math for testing purposes
XDMX_CONF_NAME="$HOME""/large_term_1x""$SEGMENTS""_""$FONT_X""x""$FONT_Y"".xdmx"
RES_OY0=$(( $RES_Y * 0 ))
RES_OY1=$(( $RES_Y * 1 ))
RES_OY2=$(( $RES_Y * 2 ))
RES_OY3=$(( $RES_Y * 3 ))
# create a configfile for Xdmx that meets our specifications
echo "virtual tiled1x"$SEGMENTS" {" > "$XDMX_CONF_NAME"
echo " display \":11\" "$RES_X"x"$RES_Y" @0x"$RES_OY0";" >> "$XDMX_CONF_NAME"
echo " display \":12\" "$RES_X"x"$RES_Y" @0x"$RES_OY1";" >> "$XDMX_CONF_NAME"
if [ "$SEGMENTS" -gt "2" ]; then
echo " display \":13\" "$RES_X"x"$RES_Y" @0x"$RES_OY2";" >> "$XDMX_CONF_NAME"
fi
if [ "$SEGMENTS" -gt "3" ]; then
echo " display \":14\" "$RES_X"x"$RES_Y" @0x"$RES_OY3";" >> "$XDMX_CONF_NAME"
fi
echo "}" >> "$XDMX_CONF_NAME"
echo "filename: "$XDMX_CONF_NAME
echo "========= "
cat $XDMX_CONF_NAME
#exit 0 # ... verify the conf for testing purposes
Xephyr :11 -screen "$RES_X"x"$RES_Y" -title Xephyr11 &
sleep 0.3; wmctrl -r Xephyr11 -e 0,"$OFFSET_X0",0,"$RES_X","$RES_Y"
Xephyr :12 -screen "$RES_X"x"$RES_Y" -title Xephyr12 &
sleep 0.3; wmctrl -r Xephyr12 -e 0,"$OFFSET_X1",0,"$RES_X","$RES_Y"
if [ "$SEGMENTS" -gt "2" ]; then
Xephyr :13 -screen "$RES_X"x"$RES_Y" -title Xephyr13 &
sleep 0.3; wmctrl -r Xephyr13 -e 0,"$OFFSET_X2",0,"$RES_X","$RES_Y"
fi
if [ "$SEGMENTS" -gt "3" ]; then
Xephyr :14 -screen "$RES_X"x"$RES_Y" -title Xephyr14 &
sleep 0.3; wmctrl -r Xephyr14 -e 0,"$OFFSET_X3",0,"$RES_X","$RES_Y"
fi
Xdmx :1 -configfile "$XDMX_CONF_NAME" \
-config tiled1x"$SEGMENTS" -depth 24 -ignorebadfontpaths +xinerama &
sleep 4
# start with an oclock, since a wm/de is bloated and unnecessary
# when the last program ends in the Xdmx, then Xdmx restarts (annoying)
OC_SX=$(( $RES_X / 2 )); # pixels wide
OC_SY=$OC_SX
OC_OX=$(( $(($RES_X / 2)) - $(($OC_SX / 2)) ))
OC_OY=$(($RES_Y - $(($OC_OX+$OC_SX)) ))
oclock -fg rgb:00/00/aa -minute rgb:00/00/ff -bd rgb:00/00/aa \
-transparent -shape -geometry "$OC_SX"x"$OC_SX"+"$OC_OX"+"$OC_OY" -display :1 &
sleep 1
# ensure that the custom fonts apply to the new environment
# could comment out this section if using neep or distro supplied font
xset -display :1 fp+ $HOME/.fonts/
sleep 0.3
xset -display :1 fp rehash
sleep 0.3
xterm -display :1 +hold -e fc-cache -f -v
sleep 0.3
# make that beautifully tall terminal
#urxvt -display :1 -b 0 -w 0 +sb \
xterm -display :1 -b 0 -bw 0 +sb \
-fg rgb:99/99/99 -bg rgb:00/00/00 -cr rgb:ff/ff/00 \
-fn "$XLSNORM" -fb "$XLSBOLD" -geometry "$COL_X"x"$ROWS_Y"+0+0 &
exit 0
$ sudo apt-get install xfonts-jmk x11-apps xdmx xserver-xephyr wmctrl
to make available the neep font, oclock, Xdmx, and Xephyr.
Some other stuff needed, but probably installed on most systems. With wmctrl to position the Xephyr windows. And oclock since it's a window manager-less session, keeps Xdmx from restarting and messing up custom fonts when you exit the last terminal. In my case I use cwm which has minimal decorations so you might need to adjust WD_X, WD_Y to help it fit in your environment of choice. Xdmx hasn't seen much love since 2004 so the input method is old style. Window focus on the first window or you can't type. Which prevents highlighting of text on the 2nd+ windows. So not much use outside of keyboard warriors that don't have a dozen thing going on one machine. And more for examining code than writing it. Various other quirks which can be mitigated by min and restore of the windows. Plus an emacs bug that freezes emacs if your term is more than 256 lines tall. With nano, vim, less, and such NOT having that issue.
$ echo $COLUMNS x $LINES
Once in the terminal you might need this to enable certain color schemes in things like vim.
Other side notes on the Xdmx to link multiple Xephyr windows. If you run into issues, or are using non-remote machines with monitors (What Xdmx is typically used for), you may need to start X without the -nolisten tcp option and change the .xdmx config file for localhost:XID or IP:XID for each (psuedo) X session you want to merge. The script is only setup for 2, 3, or 4 Xephyr sessions. And Xdmx has a built in limit of 16 X sessions that it can merge.
If you start X with more than one user after boot, you may need to rm -rf /tmp/.X* while X is NOT running so that Xdmx has permissions for the current user when the time comes. I tend to start X with startx as one user and can mostly ignore these quirks. But I sometimes start X with another user to make youtube videos, which is when quirks can get in the way.
I also have some custom fonts derived from the fntcol16 collection. And the 8x8 fonts on a 1080p display can get me 3x Xephyr windows with no window decorations and result in an 80x405 xterm. Although x402 in the scripts current state, since I prejudice it towards even number $COLUMNS and $LINES (rows).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.