pygame.display.init() fails for non-root user

Issue

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

Solution

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.

Answered By – vinalti

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published