DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Split screen in script?

Thu Jan 17, 2013 4:37 pm

Ok, here's a puzzler. I'm not even sure if this CAN be done, but if it can I'd adore it.

I'm NOT running X on my Pi. Console only. What I'd like to do is "split" the console screen so that there's 2 frames. Top frame about 80%, and the bottom frame about 20%.

Now here's the kicker:
In the top frame, I want to display an image, which changes depending on the output of a script running in the bottom frame.

So how can I do it? Can it even be done?

Thanks!

User avatar
daveg
Posts: 137
Joined: Thu Dec 01, 2011 9:36 am

Re: Split screen in script?

Thu Jan 17, 2013 4:45 pm

tmux will let you split the screen as much as u want.

http://tmux.sourceforge.net/

sudo apt-get install tmux

as for what happens in the top frame and bottom frame, well thats down to you but I know you can use tmux to split the screen.

User avatar
bgreat
Posts: 235
Joined: Mon Jan 23, 2012 2:09 pm

Re: Split screen in script?

Thu Jan 17, 2013 4:59 pm

byobu is a tmux enhancement that has some nice default features and allows split screen and multi-panel screen configurations.

sudo apt-get install byobu

byobu Project Home

Enjoy!
Bill

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Thu Jan 17, 2013 5:32 pm

Looks like tmux is the way to go, with byobu a close second...

Next problem: Is there a better way to display the image mentioned earlier than what I'm doing now?

Code: Select all

fim -c '250%' $imagefile > /dev/tty0 > /dev/null 2>&1 &
sleep 1
kf=`pidof fim`
kill -9 $kf
wait $kf 2>/dev/null
Ideally, I'd have a program that displays the image and then exits on its own. Haven't found one yet though.

User avatar
jojopi
Posts: 3135
Joined: Tue Oct 11, 2011 8:38 pm

Re: Split screen in script?

Thu Jan 17, 2013 8:20 pm

There is no point using a terminal intercept daemon like screen or tmux (or byobu, yuck) to split the window if you control the output to one panel and the other is obscured with an overlay. Just do not print anything over the image.

For example, these will set a scroll region for the first or last five lines of the display, respectively:

Code: Select all

printf "\e[H\e[J\e[1;5r"
printf "\e[2J\e[$((LINES-4));${LINES}r\e[?6h\e[H"
I can not find a framebuffer image loader that is happy just to load an image and exit. And killing them -9 is a bit risky if they use raw keyboard mode or attempt to lock the console. So I would be tempted to "write" my own:

Code: Select all

#! /bin/sh
width="`fbset -depth 32 -s`"
width="${width#*\"}"
width="${width%%x*}"
convert "$1" -scale "${width}x" -depth 8 rgba:- >/dev/fb0
("convert" is from package "imagemagick".)

bulletmark
Posts: 121
Joined: Wed Oct 17, 2012 10:10 pm
Location: Brisbane Australia

Re: Split screen in script?

Thu Jan 17, 2013 9:51 pm

bgreat wrote:byobu is a tmux enhancement ... [/url]
Actually, just to correct you Bill. tmux is an enhanced alternative to the ancient gnu screen program. byobu is not related to tmux, it is a Ubuntu project which just adds slight cosmetic enhancements to screen.

I have used screen from before many here were born but use tmux exclusively nowadays because it is better. I also agree with jojopi that byobu is rubbish.

User avatar
bgreat
Posts: 235
Joined: Mon Jan 23, 2012 2:09 pm

Re: Split screen in script?

Thu Jan 17, 2013 10:16 pm

My mistake. I picked that up from another site with what I now know is incorrect information. A quick read of the dependencies shows tmux or screen as being required for byobu. If you install with neither present, then both are installed. Fascinating.

I typically use screen, but neither tmux or byobu. It's my safety net for dropped connections. Some day I'll have to check out tmux to see if it could benefit my workflows.

Thanks and enjoy!
Bill

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Thu Jan 17, 2013 11:06 pm

Fantastic, thanks! One problem though... The convert line makes the lower 1/3 of the image get cut off. Which is odd, since it's just a 150x150 image.

And should the printf go AFTER the convert, or before it?
jojopi wrote:There is no point using a terminal intercept daemon like screen or tmux (or byobu, yuck) to split the window if you control the output to one panel and the other is obscured with an overlay. Just do not print anything over the image.

For example, these will set a scroll region for the first or last five lines of the display, respectively:

Code: Select all

printf "\e[H\e[J\e[1;5r"
printf "\e[2J\e[$((LINES-4));${LINES}r\e[?6h\e[H"
I can not find a framebuffer image loader that is happy just to load an image and exit. And killing them -9 is a bit risky if they use raw keyboard mode or attempt to lock the console. So I would be tempted to "write" my own:

Code: Select all

#! /bin/sh
width="`fbset -depth 32 -s`"
width="${width#*\"}"
width="${width%%x*}"
convert "$1" -scale "${width}x" -depth 8 rgba:- >/dev/fb0
("convert" is from package "imagemagick".)

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Split screen in script?

Thu Jan 17, 2013 11:18 pm

Setting a scrolling region is a one-time thing. So it goes at the top of the file.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Thu Jan 17, 2013 11:24 pm

Is it possible that my "screen" is larger than my display? Because the image is literally covering the whole thing and getting cut off, and any text I'm outputting isn't showing at all.
rurwin wrote:Setting a scrolling region is a one-time thing. So it goes at the top of the file.

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Split screen in script?

Thu Jan 17, 2013 11:32 pm

What is happening is that the convert "scale" operator is scaling the image to be larger than your screen. What you need I think is to scale it according to the height, not the width. However I don't understand jojopi's magic bash code, so I can't give you a solution. The next question would be if it centred the image on the screen, but cross that bridge when you come to it. I'm surprised text isn't showing though.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Thu Jan 17, 2013 11:57 pm

I can't get it either. I know the convert line well enough, but ANY value other than 640 (the $width value) results in a badly distorted image.

Update: 320 doesn't scramble it, but gives me 2 of the image, side by side.
rurwin wrote:What is happening is that the convert "scale" operator is scaling the image to be larger than your screen. What you need I think is to scale it according to the height, not the width. However I don't understand jojopi's magic bash code, so I can't give you a solution. The next question would be if it centred the image on the screen, but cross that bridge when you come to it. I'm surprised text isn't showing though.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 12:22 am

Bit closer... Resized all the images to 640x480, and they display properly now, but there's STILL no text.

Here's the code I have so far:

Code: Select all

#!/bin/bash
printf "\e[2J\e[$((LINES-4));${LINES}r\e[?6h\e[H"
width="`fbset -depth 32 -s`"
width="${width#*\"}"
width="${width%%x*}"
convert "$1" -scale "${width}x" -depth 8 rgba:- >/dev/fb0

echo "Hello" > /dev/fb0

exit

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Split screen in script?

Fri Jan 18, 2013 12:25 am

just

Code: Select all

echo "Hello World!"
You don't need or want the "> /dev/fb0" there, only if you are sending raw picture data.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 1:02 am

Ok, that almost fixed it. Text shows up in the upper left now.

Update: I was using the wrong line of code. But now the text isn't showing up at all again.
rurwin wrote:just

Code: Select all

echo "Hello World!"
You don't need or want the "> /dev/fb0" there, only if you are sending raw picture data.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 1:37 am

Could part of the problem be that I'm running the script from an ssh session?

User avatar
jojopi
Posts: 3135
Joined: Tue Oct 11, 2011 8:38 pm

Re: Split screen in script?

Fri Jan 18, 2013 1:59 am

I assumed the image would be a wider aspect than the monitor, because of the original reference to it filling the top 80% of the screen.

It is essential that the data sent to /dev/fb0 have the right width, anyway. If scaling by height you would need to add a -border to ensure this. Or you can specify both width and height, but that will distort the shape of the image. Exactly what scaling rules did you want to achieve?

$LINES is bash-specific and only set in an interactive shell. In a script you must get the information from stty yourself:

Code: Select all

LINES="`stty size`"
LINES="${LINES% *}"
That should fix the scroll window and text location. It would be more portable to use "\033" for each escape character, instead of "\e", as well.

If you run over ssh then the image will be on the framebuffer and the text and scroll window will be on stdout. You can add:

Code: Select all

exec </dev/tty0 >/dev/tty0
But now the script requires privilege.

Ironically, you could also use screen or tmux. If you attach the same session on console and over ssh, and resize the ssh window to exactly match the console, you should get the same text on both.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 2:03 am

Eventually, the script will be running straight from the console. Right now I'm just testing, because the television I'm using for a monitor sucks so badly for long sessions of text.

The images as of now are 640x480, and work nicely. But I'm still having a devil of a time getting anything to display on the lower fifth of the screen. Would changing the images to 640x400 (or somewhere around that size) help?
jojopi wrote:I assumed the image would be a wider aspect than the monitor, because of the original reference to it filling the top 80% of the screen.

It is essential that the data sent to /dev/fb0 have the right width, anyway. If scaling by height you would need to add a -border to ensure this. Or you can specify both width and height, but that will distort the shape of the image. Exactly what scaling rules did you want to achieve?

$LINES is bash-specific and only set in an interactive shell. In a script you must get the information from stty yourself:

Code: Select all

LINES="`stty size`"
LINES="${LINES% *}"
That should fix the scroll window and text location. It would be more portable to use "\033" for each escape character, instead of "\e", as well.

If you run over ssh then the image will be on the framebuffer and the text and scroll window will be on stdout. You can add:

Code: Select all

exec </dev/tty0 >/dev/tty0
But now the script requires privilege.

Ironically, you could also use screen or tmux. If you attach the same session on console and over ssh, and resize the ssh window to exactly match the console, you should get the same text on both.

User avatar
jojopi
Posts: 3135
Joined: Tue Oct 11, 2011 8:38 pm

Re: Split screen in script?

Fri Jan 18, 2013 3:36 am

The size of image and where the text goes are independent. One is determined by the output from convert, the other by the scrolling region set with the terminal escape sequence.

The image temporarily covers any text already in the area of the screen where it loads, but subsequent text in the same area will damage the image. (If the framebuffer is fully redrawn, such as by a console switch or changing color depth, then the kernel will throw away the image and repaint any text that was under it.)

The "last five lines" code is working for me. For "lower fifth" try:

Code: Select all

#! /bin/bash
exec </dev/tty0 >/dev/tty0
LINES="`stty size`"
LINES="${LINES% *}"
printf "\e[2J\e[$(((LINES*8+15)/10));${LINES}r\e[?6h\e[H"

for i in {1..1000}; do
  printf "testing $i... "
done

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 3:37 am

Ok, as of right now, here's the script:

Code: Select all

#!/bin/bash
LINES="`stty size`"
LINES="${LINES% *}"
printf "\e[2J\e[$((LINES-5));${LINES}r\e[?6h\e[H" >/dev/fb0
width="`fbset -depth 32 -s`"
width="${width#*\"}"
width="${width%%x*}"
convert "$1" -scale "${width}x" -depth 8 rgba:- >/dev/fb0
echo "Hello" > /dev/fb0

exit
The image is displaying perfectly now, but the text never shows up at all. Even tried running it from console with all the >/dev/fb0 sections removed. Same result.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 3:44 am

Now THAT works!

When I resized the images (they were 150x150), all I did was resize the canvas to 640x480, so the actual part of the image isn't touched. :)
jojopi wrote:The size of image and where the text goes are independent. One is determined by the output from convert, the other by the scrolling region set with the terminal escape sequence.

The image temporarily covers any text already in the area of the screen where it loads, but subsequent text in the same area will damage the image. (If the framebuffer is fully redrawn, such as by a console switch or changing color depth, then the kernel will throw away the image and repaint any text that was under it.)

The "last five lines" code is working for me. For "lower fifth" try:

Code: Select all

#! /bin/bash
exec </dev/tty0 >/dev/tty0
LINES="`stty size`"
LINES="${LINES% *}"
printf "\e[2J\e[$(((LINES*8+15)/10));${LINES}r\e[?6h\e[H"

for i in {1..1000}; do
  printf "testing $i... "
done

User avatar
jojopi
Posts: 3135
Joined: Tue Oct 11, 2011 8:38 pm

Re: Split screen in script?

Fri Jan 18, 2013 3:56 am

DJ Charlie wrote:printf "\e[2J\e[$((LINES-5));${LINES}r\e[?6h\e[H" >/dev/fb0
/dev/fb0 is for binary image data, and /dev/tty0 for text and escape sequences. If you send text to /dev/fb0 you will just get a few random pixels at the top left.

Also, stty by default queries the terminal attached to standard input, so that would need to be redirected too. Hence the "exec" line at the top, which applies redirections to the whole script.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 3:58 am

It works, but integrating it into my actual running script breaks the script. :(

Code: Select all

#!/bin/bash
exec </dev/tty0 >/dev/tty0
LINES="`stty size`"
LINES="${LINES% *}"
printf "\e[2J\e[$(((LINES*8+15)/10));${LINES}r\e[?6h\e[H"

width="`fbset -depth 32 -s`"
width="${width#*\"}"
width="${width%%x*}"

ln=$(date "+%F")
lf="/home/logs/$ln.log"

tt=9999;

convert "/home/faces/sleep.jpg" -scale "${width}x" -depth 8 rgba:- >/dev/fb0
while [ $tt -gt 0 ]
do
ts=$(date "+%F_%T")
echo -n "Input: "
read says
if [ "$says" == "Ending keyword." ]
then
  exit
fi

repsrc=`replymodule "$says"`

reply="${repsrc%~*}"
emote="${repsrc#*~}"
if [ "$emote" != *.jpg* ]
then
  emote="smile.jpg"
  reply="$repsrc"
fi

reply="${reply%~*}"

convert "/home/faces/$emote" -scale "${width}x" -depth 8 rgba:- >/dev/fb0

echo "Reply: $reply"

echo "$ts - Input: $says" >> $lf
echo "$ts - Reply: $reply" >> $lf

done
exit
Soon as you enter any input, like for example: Hello.

-bash: Hello.: command not found

The script works perfectly without the fb stuff.

User avatar
jojopi
Posts: 3135
Joined: Tue Oct 11, 2011 8:38 pm

Re: Split screen in script?

Fri Jan 18, 2013 4:24 am

DJ Charlie wrote:-bash: Hello.: command not found
You are logged in on the console and your shell is still in the foreground because you started the script remotely. So when you type something it might be seen by either the shell or the script.

"sudo chvt 9" to switch to an empty console, or run the script locally.

DJ Charlie
Posts: 30
Joined: Wed Feb 01, 2012 6:33 pm

Re: Split screen in script?

Fri Jan 18, 2013 4:53 am

Yay! 99.9% working! But the second character is missing from every line displayed.

So basically, "Input" is being displayed as "I put".

Other than that, it's brilliant. :)
jojopi wrote:
DJ Charlie wrote:-bash: Hello.: command not found
You are logged in on the console and your shell is still in the foreground because you started the script remotely. So when you type something it might be seen by either the shell or the script.

"sudo chvt 9" to switch to an empty console, or run the script locally.

Return to “General discussion”