Question

I have a class that checks for suitable framebuffer, and it works fine. One a couple of computers (mostly embedded older boards) there is no framebuffer, so I remove the init(self): function and manually set it to run under X. Both ways work on their respective systems, I'm just tired of porting it every time I make a change.

Here is the working framebuffer code:

    class wxdisplay :
        screen = None;

        def __init__(self):
            "Ininitializes a new pygame screen using the framebuffer"
            # Based on "Python GUI in Linux frame buffer"
            # http://www.karoltomala.com/blog/?p=679
            disp_no = os.getenv("DISPLAY")
            if disp_no:
                print "I'm running under X display = {0}".format(disp_no)

            # Check which frame buffer drivers are available
            # Start with fbcon since directfb hangs with composite output
            drivers = ['fbcon', 'directfb', 'svgalib']
            found = False
            for driver in drivers:
                # Make sure that SDL_VIDEODRIVER is set
                if not os.getenv('SDL_VIDEODRIVER'):
                    os.putenv('SDL_VIDEODRIVER', driver)
                try:
                    pygame.display.init()
                except pygame.error:
                    print 'Driver: {0} failed.'.format(driver)
                    continue
                found = True
                break

            if not found:
                raise Exception('No suitable video driver found!')

            size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
            print "Framebuffer size: %d x %d" % (size[0], size[1])
            self.screen = pygame.display.set_mode(size, pygame.FULLSCREEN)class wxdisplay :

And here is the non-framebuffered version:

    class wxdisplay :
        pygame.init()
        size = (1024, 768)
        screen = pygame.display.set_mode(size)
        print "Framebuffer size: %d x %d" % (size[0], size[1])

I would like to try and initialize the framebuffer and if it fails, try and just run it on the console. Every thing I have try'd or if'd or excepted fails...

    class wxdisplay :
        def __init__(self):
                    # Try to use framebuffer, and use the local X server if not there
                    try:
                            screen = None;
                            "Ininitializes a new pygame screen using the framebuffer"
                            # Based on "Python GUI in Linux frame buffer"
                            # http://www.karoltomala.com/blog/?p=679
                            disp_no = os.getenv("DISPLAY")
                            print("disp_no " +disp_no)
                            if disp_no:
                                    print "I'm running under X display = {0}".format(disp_no)

                            # Check which frame buffer drivers are available
                            # Start with fbcon since directfb hangs with composite output
                            drivers = ['fbcon', 'directfb', 'svgalib', 'xvfb', 'Xvfb']
                            found = False
                            for driver in drivers:
                                    # Make sure that SDL_VIDEODRIVER is set
                                    if not os.getenv('SDL_VIDEODRIVER'):
                                            os.putenv('SDL_VIDEODRIVER', driver)
                                    try:
                                            print("Driver: "+driver)
                                            pygame.display.init()
                                    except pygame.error:
                                            print 'Driver: {0} failed.'.format(driver)
                                            continue
                                    found = True
                                    print("break")
                                    break


                            if not found:
                                    raise Exception('No suitable video driver found!')

                            size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
                            print "Framebuffer size: %d x %d" % (size[0], size[1])
                            self.screen = pygame.display.set_mode(size, pygame.FULLSCREEN)

                    except:
                            print('No suitable Framebuffer found!')
                            pygame.init()
                            size = (1024, 768)
                            print "X server size: %d x %d" % (size[0], size[1])
                            self.screen = pygame.display.set_mode(size)

fails with:

starting from __main__ call
disp_no localhost:11.0
I'm running under X display = localhost:11.0
Driver: fbcon
Driver: fbcon failed.
Driver: directfb
commandline read: python
commandline read: ./PiWxDisplay.py

~~~~~~~~~~~~~~~~~~~~~~~~~~| DirectFB 1.2.10 |~~~~~~~~~~~~~~~~~~~~~~~~~~
    (c) 2001-2008  The world wide DirectFB Open Source Community
    (c) 2000-2004  Convergence (integrated media) GmbH
  ----------------------------------------------------------------

(*) DirectFB/Core: Single Application Core. (2012-05-20 13:17)
(!) Direct/Util: opening '/dev/fb0' and '/dev/fb/0' failed
    --> No such file or directory
(!) DirectFB/FBDev: Error opening framebuffer device!
(!) DirectFB/FBDev: Use 'fbdev' option or set FRAMEBUFFER environment variable.
(!) DirectFB/Core: Could not initialize 'system_core' core!
    --> Initialization error!
Driver: directfb failed.
Driver: svgalib
Driver: svgalib failed..
No suitable Framebuffer found!
X server size: 1024 x 768
Traceback (most recent call last):
  File "./PiWxDisplay.py", line 366, in <module>
    wxdisplay().start_screen()
  File "./PiWxDisplay.py", line 66, in __init__
    self.screen = pygame.display.set_mode(size)
pygame.error: No available video device

I obviously don't fully understand how to initialize pygame correctly. How would I get it to

  1. Check for a FB driver
  2. Use the X server if the FB driver detection fails
Was it helpful?

Solution 2

You have already changed the SDL_VIDEODRIVER environment to check only for fb devices.

I'd suggest using this before your pygame.init() call in your exception handler:

os.putenv('SDL_VIDEODRIVER', 'x11')

or unset the SDL_VIDEODRIVER environment var, so that pygame.init() doesn't think it's already dealt with.

see: http://www.pygame.org/docs/ref/display.html#pygame.display.init

OTHER TIPS

Late answer but I wish I would have tried that earlier :

You may need to be root to use a frame buffer driver.

(It helped in my case: RaspberryPi 2 without X running but with a screen connected. I can now open a display through SSH or directly on the RPi)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top