5

Tl;dr

I need to use pygame but it can't initialize the screen as a normal user because of the permissions for the framebuffer driver. root can do pygame.display.init() but not the user. User is in the group 'video' and can write on /dev/fb0. What permission is missing to the user so pygame.display.init() would work.
Error encountered : pygame.error: Unable to open a console terminal

Description

So, I am trying to use pygame in order to display things on a framebuffer /dev/fb0. To use some functions I need (e.g pygame.Surface.convert) the display must be initialized. However, when calling pygame.display.init() I have an error, but only when not doing so as root.

According to @Nodraak (ref) it is related to the permissions of the framebuffer driver.

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)

A tree -fupg / | grep fb | grep rwx doesn't seem to show any binary which would be executable by root but not by others. I am quite sure that adding my user to a group, or tweaking the file permissions somewhere would be enough to fix the issue.

Note: For Security reasons, running the software as root is not an option.

Context

  • System : RaspberryPi
  • X Server: None
  • Screen: 1 (HDMI)
  • Connection: remote (SSH)

Origin of the error

I am trying to convert a surface with pygame.Surface.convert(...) function. But receive the following error :

pygame.error: cannot convert without pygame.display initialized

Nevertheless, initializing pygame.display with pygame.display.init() is giving the following error:

pygame.error: Unable to open a console terminal

I have the rights to write to the screen as I am part of the video group, and cat /dev/urandom > /dev/fb0 is effectively displaying snow on the screen.

Also I tried setting up the SDL_... environment variable to fbcon or dummy but it doesn't help. I also tried keeping the root env with user su -m user and same result.

Reproduce the error

On a raspberrypi without XServer, connect an HDMI screen, install pygame.

import pygame
pygame.display.init()

Error message:
pygame.error: Unable to open a console terminal

Software Versions

python     3.7.3
pygame     1.9.4.post1
OS         Raspbian Buster
libsdl     2

Related

6
  • Have you tried updating pygame? You can download wheels from the Piwheels project: piwheels.org/project/pygame, or build from source. (Or download a wheel from pip, but I'm not sure how different Rpi is from other Linux).
    – Starbuck5
    Commented Jan 28, 2022 at 22:26
  • Try setting the SDL_VIDEODRIVER variable to directfb. If it didn't work try rpi and kmsdrm Commented Jan 29, 2022 at 15:49
  • Okk, I will try this. But the thing is that it's working as root, so that's should not be a problem of library I think 😅
    – vinalti
    Commented Jan 30, 2022 at 9:32
  • Concerning SDL_VIDEODRIVER this didn't solve the issue. updating pygame to version 2.1.2 didn't help either. Any other idea ?
    – vinalti
    Commented Jan 31, 2022 at 8:46
  • @vinalti: maybe it helps if you describe the use case. I ran into the same issue as you and decided it's not worth trying this way. I ended up setting up the autostart so that the pi user boots directly into pygame (because this was my goal, I wanted to use the pi as a permanent display) - this works fine with the pygame that's installed on the pi with the "apt get..." command (which installes 1.9.4.post1), but (for me) not with the "pip" installed pygame.
    – 576i
    Commented Jan 31, 2022 at 10:07

2 Answers 2

2

Solution to the problem

OpenVT

So it appears that the best solution, which meet all requirement I listed, is to use openvt.

How ?

The procedure holds in a few bullet points :

1. Add User to tty group

As root, add your user to the group named tty, that will allow us to give it access to the TTYs.

# As root:
usermod -a -G tty $username

2. Give TTY access to users in group tty

Now that the user is part of the group tty we need it to be allowed to write on it, as openvt will use a tty. By default, the mode should be set at 620 we need to set it at 660 to allow the group to write on it.

# Edit file: /lib/udev/rules.d/50-udev-default.rules
SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660"
#                                      ensure mode is 0660  ^

3. Set SDL environment variables

Inside your software, make sure to set up the environment variables of SDL.

import os
# ...
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
os.environ["SDL_FBDEV"] = "/dev/fb0"

4. Reboot the Raspberry

Ok, you don't need a snippet for that.. Whether ? Well ok.

# as root / with sudo
reboot

5. Start software with openvt

openvt (open Virtual Terminal) allows us to run the interface directly with screen access. This must be executed by the final user, in the same directory as the software (preferably).

openvt -s -- python3 ./interface.py

And that should work.
Of course you can then integrate this in a Linux service so it starts at boot. but you may need to add After: [email protected] in the [Unit] section of the service file.

Well, it took me lots of time to figure that one out, so I hope it helps someone else as well.

0
+100

I ran into the same problem trying to use pygame as a permanent display.

I decided have the pi autostart on boot, which works and starts your pygame code as root.

To activate autostart, add lines to start your code into

/etc/rc.local

above the exit 0 line.

For example (I have the code in '/opt/pygame_prototype/pg.py')

cd /opt/pygame_prototype
/usr/bin/python3 pg.py

Then on boot, the pi will not go to the login, but start the pygame program.

Note: Use the "apt get " installed pygame without a virtual environment, the newer pip installed version failed me.

12
  • But then it runs as root, not as a user ?
    – vinalti
    Commented Jan 31, 2022 at 10:21
  • Yes, but if you stop it, it stops running as root and you're the pi user. It depends on your use case, if there's a pi that needs to display things or allow interaction only through pygame, running this as root to access the buffer makes sense
    – 576i
    Commented Jan 31, 2022 at 10:22
  • For security reasons I can't run it as root at all, I need to add the correct permissions to a specific user so he has enough right to run the interface not more, not less. :/
    – vinalti
    Commented Jan 31, 2022 at 10:25
  • 1
    Hmm, your pi runs a lot of services as root, so this would just be one of them. OK - looks like you need to discribe your use case a bit more (like how the service is started and what happends if it ends). I'm using pygame at a physical gate to show info like "access granted", "access forbidden", "scan your ticket to enter" - so running that as root is safe. BTW, I spent half a day researching this, if I find a better solution I'll update the answer.
    – 576i
    Commented Jan 31, 2022 at 10:29
  • 1
    Thanks very much. I still have this problem on my agendy (because I need it for my own interfaces) and will bother some Linux experts with this. If I find a late solution, I'll update the answer as promised.
    – 576i
    Commented Feb 1, 2022 at 9:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.