Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

OSD (on screen display) w/o X

Tue Sep 11, 2012 10:42 pm

Hey guys, I just started hacking around on the Pi with the raspbian distro. Since X is not accelerated I've been mostly sticking to the terminal. I've never tried running a media center from the command line, but it's kind of fun.

So far I've just been streaming YouTube and internet radio with MPD/MPC. I just have the Pi connected to the TV. What I'd like is an OSD that doesn't require X to be running, so that I can script it to pop up a toast notification whenever the song changes, or maybe just show the current song continuously. Seems like an OSD library / command line program that works without X would be generally useful.

Looking at the hello_font VG example, it seems it should be pretty simple to write this, but I don't want to reinvent the wheel. Is there something out there already for this? Should I try to get DirectFB running? Has anyone looked at getting something like growl/snarl running?

Thanks!

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Tue Sep 11, 2012 11:18 pm

Chinasaur wrote:So far I've just been streaming YouTube and internet radio with MPD/MPC.
Sorry, this was confusing. Streaming YouTube is separate from MPD; for that I'm using this: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=8157.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Sep 17, 2012 3:51 am

Okay, I poked around but didn't find anything for putting text onscreen without X. I started writing my own version based on the hello_text example.

It appears there's a bug in vgft_get_text_extents / line_extents when it gets passed a char* with newlines. It gets correctly that the height is a multiple of the number of lines, but it gives the width according to the total number of characters instead of the max number of characters on any line. I can see where in line_extents to fix this; can I submit a patch? Would rather not clone the whole firmware repo.

There's also a small bug in hello_text itself; it displays the resource before setting its background to transparent, so you get a black flash on the screen before the text appears.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Sep 17, 2012 4:16 am

Here's the patched version (in /opt/vc/src/hello_pi/libs/vgfont/vgft.c):

Code: Select all

// Text extents for some ASCII text.
// Use text_length if non-zero, otherwise look for trailing '\0'.
void vgft_get_text_extents(VGFT_FONT_T *font,
                           const char *text,
                           unsigned text_length,
                           VGfloat start_x, VGfloat start_y,
                           VGfloat *w, VGfloat *h) {
   int last_draw = 0;
   VGfloat max_x = start_x;
   VGfloat y = start_y;

   int i, last;
   for (i = 0, last = 0; !last; ++i) {
      last = !text[i] || (text_length && i==text_length);
      if ((text[i] == '\n') || last) {
         VGfloat x = 0;
         line_extents(font, &x, &y, text + last_draw, i - last_draw);
         last_draw = i+1;
         y -= float_from_26_6(font->ft_face->size->metrics.height);
         if (x > max_x) max_x = x;
      }
   }
   *w = max_x - start_x;
   *h = start_y - y;
}

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Sep 17, 2012 4:21 am

To patch hello_font to avoid the screen flash, simply add (in main.c)

Code: Select all

graphics_resource_fill(img, 0, 0, width, height, GRAPHICS_RGBA32(0,0,0,0x00));
before the line

Code: Select all

graphics_display_resource(img, 0, LAYER, 0, 0, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, VC_DISPMAN_ROT0, 1);
(untested but should work)

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Sep 17, 2012 5:27 am

Another apparent bug in vgfont. The x_offset and y_offset used for rendering are declared as uint32_t, but these eventually get passed down to functions that want VGInt, which is in turn really a khronos_int32_t which in turn is an int32_t. In other words, OpenVG actually has no problem with you giving it a negative offset when plotting stuff. If you don't fix it and you try to use a negative offset, you'll underrun the uint32 and end up with an offset about a million miles off the edge of your screen :).

To fix, change the type of arguments x and y in graphics_resource_render_text_ext (vgfont.h, graphics.c) and gx_priv_render_text (graphics_x_private.h, font.c) to const int32_t instead of const uint32_t.

While you're at it I guess maybe fix graphics_resource_render_text too.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Sep 17, 2012 7:17 am

Here's a very preliminary version of my on screen display hack that works without X running. https://github.com/chinasaur/poptart

Won't work well with long strings or strings with embedded newlines without the libvgfont patches. I sent a pull request for all the above. mpcpop is how I'm using it.

Much room for improvement :).

furyfire
Posts: 25
Joined: Wed Aug 08, 2012 10:54 am

Re: OSD (on screen display) w/o X

Tue Sep 18, 2012 1:51 pm

Nice work - I've been looking to create something similar.
My goal goes more towards creating a server that accepts screen commands on a TCP connection.
Wanna create really simple gauges/sliders/tables etc without the overhead of X11 and from whatever scripting language/programming language that supports a basic TCP connection :)
Need accessories?
Checkout my verified list of cheap DX.com accessories.
http://furyfi.re/raspberrypi/accessories.pdf

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Tue Sep 18, 2012 4:26 pm

furyfire wrote:Nice work - I've been looking to create something similar.
My goal goes more towards creating a server that accepts screen commands on a TCP connection.
Wanna create really simple gauges/sliders/tables etc without the overhead of X11 and from whatever scripting language/programming language that supports a basic TCP connection :)
Thanks, yeah I'm interested in trying to link this up more. Like it looks like my Raspbian is running the DBus server without X, so I wonder if there are some standard notification bus addresses that I could hook this into. It should be easy to configure it so that once someone starts X it would yield the address to a more standard OSD program.

Growl and XOSD are both kind of like that I think; accepting socket connections and posting notifications; and there are others.

I included a mode in poptart where you pass it a command to run and it uses the output as its OSD text. You can tell it to loop infinitely, rerunning the command. So seems you could wrap that in python or a bash script to hack together a server. I'm planning to add a file/pipe read option too.

Of course, right now poptart only supports text notifications; the tricky thing for your goal is that it sounds like you want to be able to flexibly draw a pretty wide range of things with just a socket connection? So that would imply that you need to invent a protocol with the different draw commands you want to support and then parse them as they come in?

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Mon Oct 08, 2012 2:24 am

Fixes mentioned above have been pulled into raspberrypi/firmware so should now be included in new releases. I am still hoping to submit a few more small fixes.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Thu Oct 18, 2012 6:09 pm

furyfire wrote:Nice work - I've been looking to create something similar.
My goal goes more towards creating a server that accepts screen commands on a TCP connection.
Wanna create really simple gauges/sliders/tables etc without the overhead of X11 and from whatever scripting language/programming language that supports a basic TCP connection :)
Conky may cover a lot of the ground you're interested in here? I'm interested in trying to get a conky backend together that will run without X. Linking it directly to VG/DISPMANX would be work but seems doable. Currently I'm working on getting Cairo working without X; conky has a cairo backend, but I'm not clear how difficult it will be to disentangle that from X.

lunchbox
Posts: 16
Joined: Tue Oct 23, 2012 4:03 am
Location: Jincheng, Shanxi, China

Re: OSD (on screen display) w/o X

Tue Oct 23, 2012 4:47 am

It may be helpful to have a look at twmn. This is a very lightweight OSD application written in C that can either be called directly or you can run it as a daemon to listen to dbus. It's not exactly what you are looking for (it runs in X and requires qt I believe), but looking at the source code should be informative. I use it on my desktop machine as a replacement for other OSD because it works well and is very very lightweight. Its perfect for notifications, but probably would not be at all appropriate for the Conky-related stuff mentioned above.

On the other end there are easy to use python libraries for abstracting talking to dbus, ie dbus-python. This makes it super-easy to add notifications in a script.

http://github.com/sboli/twmn - twmn developer's page

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Tue Oct 23, 2012 7:14 am

lunchbox wrote:It may be helpful to have a look at twmn.
Cool, thanks very much. I think I've worked most of the kinks out of the actual text display on screen, but I don't have much experience writing Linux command-line programs in C, so this will be helpful.
lunchbox wrote:On the other end there are easy to use python libraries for abstracting talking to dbus, ie dbus-python. This makes it super-easy to add notifications in a script.
Yeah, it seems like it makes sense to keep things simple and modular and use scripting to wrap most of the other bells and whistles.

npope
Posts: 1
Joined: Tue Oct 23, 2012 4:30 pm
Location: Suwanee, GA

Re: OSD (on screen display) w/o X

Tue Oct 23, 2012 4:42 pm

Just a thought, but maybe pygame could be a good choice (at least for the display part of what you are talking about). It seems to work without X.

Given the main goals for the foundation and the emphasis on education and providing an accessible platform for kids, there seems to be a pretty strong emphasis on python/pygame as a simple way for people to get started with the Pi.

My guess is that python/pygame will see a good bit of optimization on the RPi platform going forward, given this focus.

-Nick

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Tue Oct 23, 2012 5:27 pm

npope wrote:Just a thought, but maybe pygame could be a good choice (at least for the display part of what you are talking about). It seems to work without X.
Huh, good point; hadn't occurred to me; I'll take a look.

lunchbox
Posts: 16
Joined: Tue Oct 23, 2012 4:03 am
Location: Jincheng, Shanxi, China

Re: OSD (on screen display) w/o X

Wed Oct 24, 2012 6:37 am

npope wrote:Given the main goals for the foundation and the emphasis on education and providing an accessible platform for kids, there seems to be a pretty strong emphasis on python/pygame as a simple way for people to get started with the Pi.
I used to have a OLPC XO1 which ran Sugar. They wanted to make a computer that kids could hack so the whole interface is written in python. Kids can use the text editor to add colors or change the way the system works, which is very, very cool. C is going to be way less accessible for hacking. The trade off is that C is compiled and can run very fast and light, something that's kind of important for a daemon running all the time on such a low-spec system.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Wed Oct 24, 2012 4:07 pm

I've submitted a new pull request. The vgfont library had a limitation of only 200 characters per line; trying to draw more than that caused an assertion fail (or I assume a segfault if you have assertions off). This patch releases the limitation: https://github.com/chinasaur/firmware/c ... 3c88d49f71

The previous patches were accepted into the repo but have not gone out in a new release yet, so you'd still need to patch manually if you're having any of the problems (multiline text or long line text not displaying properly).

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Wed Oct 24, 2012 4:16 pm

lunchbox wrote:C is compiled and can run very fast and light, something that's kind of important for a daemon running all the time on such a low-spec system.
Good points. I'm kind of at a point for design decisions.

My basic version (https://github.com/chinasaur/poptart) doesn't run as a daemon; you just call it and pass it the text to display (as arg, stdin, or command to run). I liked keeping things simple this way but the major drawback is that every time the program exits you lose the screen resources so if you are trying to make a continuously updating screen this way (e.g. wrapping it in a daemon script) you get screen flashes between updates. I bent a little over backwards to avoid this, so now you can tell it to loop infinitely and keep calling a command with each update; this way you can have updating output without the screen flashes. I am planning to add a feature where it can read continuously from stdin also (currently if you pass stdin it reads it only once all the way to EOF).

Probably better way to keep flexibility while avoiding the screen flashes would be to bite the bullet and daemonize. I haven't done it before but imagine it's a well documented process. This will probably be my next step when/if I find time.

One thing I wonder is if it would be nice to daemonize at a lower level; have a dispmanx daemon that just holds the screen resources and can hand them off to callers. Not sure how easy it is to pass a dispmanx window or openvg surface between processes though. Probably more trouble than it's worth at this stage.

Thanks for all the input!

Manfredo
Posts: 3
Joined: Thu Feb 14, 2013 8:40 am

Re: OSD (on screen display) w/o X

Thu Feb 14, 2013 8:56 am

Hello,

I have created a little project in geany (on raspian) and now i will show some text on the screen like the hello_font sample. But my problem is to import the header files #include "bcm_host.h" and
#include "vgfont.h

A I already copied the two includes in my project folder but there are so many other "sub includes" and so the path's to this includes can't find.

How can I import the vgfont function in my project?

Sorry for that newbie question :roll:

Fred

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Thu Feb 14, 2013 8:45 pm

Hi Fred, what are you using to compile your project? Probably the simplest thing is to copy the compile flags (CFLAGS, INCLUDES) and link flags (LDFLAGS) from the hello_font Makefile and then use make to build. In particular there is a Makefile.include file in an outer directory that sets most stuff up across the hello_pi projects. Take a look at my very simple program for an example Makefile, etc.: https://github.com/chinasaur/poptart

My project will also show you what needs to be included to set up your drawing surface for text, etc. You are on Raspbian right? The hello_pi stuff is in different places on different distros I believe. Make sure your system is up to date as some things in here get moved around once in a while. I just had to update the poptart Makefile for some new include path requirements...

As a more detailed answer, you generally need to:
  • 1) Include the relevant headers as you already mentioned
    2) Make sure the compiler knows where to find the headers. If they're in a standard location it's already taken care of. Since hello_pi is not a standard location on Raspbian, you need to find some other way to tell the compiler where to look. A one time solution is to include -I /opt/vc/... flags on your compile command to tell it what directory to look in. (That is a capital "i" for "include".) See the Makefile in poptart above; the INCLUDES variable sets this up.
    3) Tell the linker where to find the libraries. Normally you do this with just -lLIBNAME. (That is a lowercase "L" for "library".) So if you are linking libm you just do -lm without the "lib". If the libraries are in standard locations that's it. Since hello_pi is not standard, you again need to add some flags to your linking command to tell it where to look. You do that with -L /opt/vc/... This is also handled in the Makefile in poptart; it's just added into the LDFLAGS.
Hope that's helpful.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Thu Feb 14, 2013 8:46 pm

Hi Fred, just reread your question and I believe you're getting off on the wrong track. To be clear, you should not be copying any of the header files into your own project. Just leave them in their include directory and tell the compiler where to go to find them all.

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Thu Feb 14, 2013 10:14 pm

Chinasaur wrote:
  • 1) Include the relevant headers as you already mentioned
So, what is meant by "include the relevant headers" is to give the #include "headername.h" preprocessor instruction in your code files and then do steps 2 and 3 above to tell the compiler where to find the headers and libraries.

Manfredo
Posts: 3
Joined: Thu Feb 14, 2013 8:40 am

Re: OSD (on screen display) w/o X

Fri Feb 15, 2013 4:29 pm

Hi Chinasaur ,

cool, thank's for your helpful suggestions!! I will try this out and let you know what happend :)

see you, then!
Fred

Manfredo
Posts: 3
Joined: Thu Feb 14, 2013 8:40 am

Re: OSD (on screen display) w/o X

Mon Feb 18, 2013 1:20 pm

Hello again,

last weekend i tryed out to re-configure my make file to use the hello_font libs. I copied all the LDFALGS and INCLUDES from the existing make -file into my own make file and now it is working fine :)

Thanks to Chinasaur for his helpful comments :D

PS: What is the standard function to write a text on the screen? Is it the graphics_resource_render_text_ext?

Best wishes!
Fred

Chinasaur
Posts: 116
Joined: Tue Sep 11, 2012 10:15 pm

Re: OSD (on screen display) w/o X

Sun Feb 24, 2013 7:45 am

Hi Fred, I recommend you take a look at my poptart program (linked above). The file poptart.c includes everything you need to get a drawing surface open and text rendered. Probably just compiling poptart and playing with it is a good place to start to verify that everything is working for you, and then you can proceed to tweak things as you like. I am handling a lot of funny cases with poptart, but the simplest way to test it is just to run "poptart TEXT" and TEXT should appear on your screen. poptart currently only renders text to the bottom center of the screen; the calculation for this position is done in the render_toast function.

Return to “General discussion”