Overview
The Pacman game includes a sophisticated resolution management system to handle fullscreen mode gracefully on multi-monitor Linux systems. When running in fullscreen (-f flag), the game:
Detects current monitor configuration using GLFW
Generates an xrandr restoration script
Restores the original configuration on exit
This ensures the desktop environment returns to its original state even if the game crashes or is force-quit.
Architecture
The system uses two complementary technologies:
Purpose: Monitor detection and video mode queryGLFW provides a cross-platform API to query monitor information without needing X11-specific code. Used in:
guardarResolucionOriginal() - Detect primary monitor resolution
Clean C API that initializes/terminates easily
Purpose: Resolution and monitor layout restorationxrandr (X Resize and Rotate) is the standard X11 tool for:
Querying display configuration
Setting resolution, position, and rotation
Managing multi-monitor layouts
The game generates shell scripts that call xrandr commands.
Resolution backup
The guardarResolucionOriginal() function in src/main.c:24-111 handles the backup process.
GLFW-based detection
From src/main.c:26-54 :
void guardarResolucionOriginal ()
{
if ( ! glfwInit ())
{
fprintf (stderr, "No se pudo inicializar GLFW \n " );
return ;
}
GLFWmonitor * monitor = glfwGetPrimaryMonitor ();
if ( ! monitor)
{
fprintf (stderr, "No se pudo obtener el monitor principal \n " );
glfwTerminate ();
return ;
}
const GLFWvidmode * mode = glfwGetVideoMode (monitor);
if ( ! mode)
{
fprintf (stderr, "No se pudo obtener el modo de video \n " );
glfwTerminate ();
return ;
}
resolucion_ancho = mode -> width ;
resolucion_alto = mode -> height ;
refresco_hz = mode -> refreshRate ;
printf ( "Resolución guardada: %d x %d @ %d Hz \n " ,
resolucion_ancho, resolucion_alto, refresco_hz);
glfwTerminate ();
// ... xrandr script generation continues
}
Primary monitor width in pixels
Primary monitor height in pixels
Monitor refresh rate in Hz (typically 60, 144, etc.)
Script generation
The function creates a bash script at /tmp/restaurar_xrandr.sh:
const char * script_restauracion = "/tmp/restaurar_xrandr.sh" ;
FILE * fp = fopen (script_restauracion, "w" );
if ( ! fp)
{
perror ( "No se pudo crear el script de restauración" );
return ;
}
fprintf (fp, "#!/bin/bash \n " );
Primary output detection
From src/main.c:66-76 :
// Obtener salida primaria
FILE * primary_pipe = popen (
"xrandr --query | awk '/ connected primary/ {print $1}'" , "r" );
char primary_output [ 32 ] = { 0 };
if (primary_pipe)
{
if ( fgets (primary_output, sizeof (primary_output), primary_pipe))
{
primary_output [ strcspn (primary_output, " \n " )] = 0 ; // quitar salto
}
pclose (primary_pipe);
}
This AWK command extracts the primary monitor’s output name (e.g., “HDMI-1”, “DP-1”, “eDP-1”).
Multi-monitor configuration
The most complex part generates xrandr commands for all connected monitors with their current position and mode.
From src/main.c:78-106 :
// Generar comandos xrandr por cada salida activa con modo y posición
FILE * pipe = popen (
"xrandr --query | grep ' connected' | awk '{"
" salida=$1;"
" for(i=1;i<=NF;i++) if ($i ~ /[0-9]+x[0-9]+ \\ +[0-9]+ \\ +[0-9]+/) modo=$i;"
" if (modo != \"\" ) {"
" split(modo, parts, /[x+]/);"
" ancho=parts[1]; alto=parts[2]; posx=parts[3]; posy=parts[4];"
" cmd= \" xrandr --output \" salida \" --mode \" ancho \" x \" alto \" --pos \" posx \" x \" posy;"
" for(j=1;j<=NF;j++) if ($j == \" primary \" ) cmd=cmd \" --primary \" ;"
" print cmd;"
" }"
"}' \n " ,
"r" );
if ( ! pipe)
{
perror ( "No se pudo obtener la configuración de pantalla" );
fclose (fp);
return ;
}
char linea [ 256 ];
while ( fgets (linea, sizeof (linea), pipe))
{
fputs (linea, fp);
}
pclose (pipe);
fclose (fp);
The AWK script processes xrandr output line by line:
Extract output name: salida=$1 (e.g., “HDMI-1”)
Find geometry: Match pattern like 1920x1080+0+0
Split geometry: ancho=1920, alto=1080, posx=0, posy=0
Build command: xrandr --output HDMI-1 --mode 1920x1080 --pos 0x0
Add primary flag: If line contains “primary”, append --primary
Print command: Each line becomes one xrandr invocation
Example generated script
For a dual-monitor setup:
#!/bin/bash
xrandr --output eDP-1 --mode 1920x1080 --pos 0x0 --primary
xrandr --output HDMI-1 --mode 2560x1440 --pos 1920x0
Making the script executable
From src/main.c:109-110 :
system ( "chmod +x /tmp/restaurar_xrandr.sh" );
printf ( "📝 Script de restauración generado con disposición y salida primaria en %s \n " ,
script_restauracion);
Resolution restoration
The restaurarResolucionOriginal() function in src/main.c:114-127 executes the generated script.
void restaurarResolucionOriginal ()
{
if (resolucion_ancho > 0 && resolucion_alto > 0 )
{
printf ( "Restaurando configuración de monitores desde script... \n " );
char comando [ 128 ];
snprintf (comando, sizeof (comando), " %s " , script_restauracion);
system (comando);
}
else
{
fprintf (stderr, "Resolución original no válida, no se puede restaurar. \n " );
}
}
The validation check ensures that GLFW successfully detected a resolution before attempting restoration. This prevents executing an empty or malformed script.
Called from main
From src/main.c:184-193 :
guardarResolucionOriginal (); // Before SDL init
init_gfx ();
TimerStart (timerfunc, 18 );
getsprites ();
menu_opciones ( TRUE );
stargame ( & fan , & pc , COMENZAR);
restaurarResolucionOriginal (); // After game exits
exit ( 0 );
xrandr availability check
The xrandr_disponible() function in src/main.c:129-138 verifies xrandr is installed:
int xrandr_disponible ()
{
// Comprobamos si xrandr está en /usr/bin
if ( access ( "/usr/bin/xrandr" , X_OK) == 0 )
{
return 1 ;
}
// Alternativamente, usamos `which xrandr`
return ( system ( "which xrandr > /dev/null 2>&1" ) == 0 );
}
This checks:
Direct path check: /usr/bin/xrandr with execute permission
Fallback: which xrandr searches PATH
Setup function
From src/main.c:140-151 :
void setup ()
{
if ( ! xrandr_disponible ())
{
fprintf (stderr, "⚠️ ADVERTENCIA: 'xrandr' no está disponible en el sistema. \n " );
fprintf (stderr, "No se podrá guardar ni restaurar la resolución automáticamente. \n\n " );
}
else
{
printf ( "✅ xrandr disponible. Se podrá guardar/restaurar la configuración de pantalla. \n " );
}
}
This is called at the very start of main() (main.c:162) to warn users if resolution management won’t work.
Static variables
Resolution state is stored in file-scope static variables in main.c:15-18 :
static int resolucion_ancho = 0 ;
static int resolucion_alto = 0 ;
static int refresco_hz = 0 ;
static const char * script_restauracion = "/tmp/restaurar_xrandr.sh" ;
Detected primary monitor width
Detected primary monitor height
Detected refresh rate in Hz
Path to the generated restoration script
Error handling
GLFW initialization failure
If GLFW fails to initialize (main.c:26-30):
if ( ! glfwInit ())
{
fprintf (stderr, "No se pudo inicializar GLFW \n " );
return ; // Continue without resolution backup
}
The game continues running but resolution won’t be restored.
Monitor query failure
If no monitor is detected (main.c:32-38):
GLFWmonitor * monitor = glfwGetPrimaryMonitor ();
if ( ! monitor)
{
fprintf (stderr, "No se pudo obtener el monitor principal \n " );
glfwTerminate ();
return ;
}
Script creation failure
If the script file can’t be created (main.c:58-62):
FILE * fp = fopen (script_restauracion, "w" );
if ( ! fp)
{
perror ( "No se pudo crear el script de restauración" );
return ;
}
All failures are non-fatal - the game proceeds, but resolution restoration is skipped.
Why this approach?
Multi-monitor aware: Restores all displays, not just primary
Crash-safe: Script persists in /tmp even if game crashes
Position preservation: Maintains monitor arrangement (laptop left of external monitor, etc.)
Primary display: Correctly sets which monitor is primary
Independent libraries: GLFW for detection, xrandr for restoration
Linux-only: xrandr is X11-specific
Requires xrandr: Silently fails if not installed
No Wayland support: Uses X11 tools exclusively
Manual script execution: Uses system() calls
Alternative approaches
Other methods that could be used:
SDL_SetDisplayMode
X11 XRandR library
Config file
SDL 2.0+ has SDL_SetDisplayMode() for resolution changes, but:
Pacman uses SDL 1.2 (no built-in resolution management)
Doesn’t handle multi-monitor layouts
Less control over restoration
Could use XRandR C library directly instead of shell commands: #include <X11/extensions/Xrandr.h>
Pros: Programmatic control Cons: More complex, requires X11 development headers Save configuration to a file instead of generating script: FILE * cfg = fopen ( "~/.pacman_resolution" , "w" );
fprintf (cfg, " %d x %d @ %d \n " , width, height, refresh);
Pros: Simpler Cons: Doesn’t handle multi-monitor, requires parsing on restore
Integration with SDL
The resolution management happens before SDL initialization:
main ()
|
+-- setup () // Check xrandr availability
+-- guardarResolucionOriginal () // GLFW detection + script generation
+-- init_gfx () // SDL init (may change resolution)
+-- ... game runs ...
+-- restaurarResolucionOriginal () // Execute xrandr script
+-- exit ()
SDL’s atexit(SDL_Quit) (gfx.c:27) ensures SDL cleanup happens before the restoration script runs.
Testing the system
To test resolution management:
# Run in fullscreen
./pacman -f
# Check generated script
cat /tmp/restaurar_xrandr.sh
# Should see xrandr commands for all monitors
# Example output:
#!/bin/bash
xrandr --output eDP-1 --mode 1920x1080 --pos 0x0 --primary
xrandr --output HDMI-1 --mode 2560x1440 --pos 1920x0
# Verify restoration works after quit
xrandr --query # Should match original configuration