From 498aed50d24ef4e8110ec11c8a062c41d7efb797 Mon Sep 17 00:00:00 2001 From: lucca Date: Sat, 19 Sep 2026 21:23:27 -0400 Subject: [PATCH] added profile --- addCRTModes.sh | 5 +- controller-off/compile.sh | 2 + controller-off/controller-off | Bin 0 -> 22472 bytes controller-off/controller-off.c | 704 ++++++++++++++++++++++++++++++++ profile | 155 +++++++ remove1280x960modes.sh | 11 + screenlayout/mirror900p.sh | 4 + screenlayout/tv1080p.sh | 2 +- screenlayout/tv720p.sh | 5 +- vsyncToggle.sh | 13 + 10 files changed, 898 insertions(+), 3 deletions(-) create mode 100755 controller-off/compile.sh create mode 100755 controller-off/controller-off create mode 100644 controller-off/controller-off.c create mode 100644 profile create mode 100755 remove1280x960modes.sh create mode 100755 screenlayout/mirror900p.sh create mode 100755 vsyncToggle.sh diff --git a/addCRTModes.sh b/addCRTModes.sh index 04b4d13..2005dd1 100755 --- a/addCRTModes.sh +++ b/addCRTModes.sh @@ -10,7 +10,10 @@ addMode "1280x960_120i" 105.90 1280 1360 1496 1712 960 963 969 1031 -HSync +VSyn addMode "1600x900_120i" 120.000 1600 1696 1864 2128 900 903 908 975 -HSync +VSync Interlace addMode "1600x1000_120i" 133.000 1600 1696 1864 2128 1000 1003 1008 1075 -HSync +VSync Interlace #addMode "640x480_120p" 52.50 640 680 744 848 480 483 487 518 -hsync +vsync -addMode "640x480_120p" 52.41 640 680 744 848 480 481 484 515 +HSync -Vsync +#addMode "640x480_120p" 52.41 640 680 744 848 480 481 484 515 +HSync -Vsync +#addMode "640x480_120p" 52.35 640 680 744 848 480 481 484 515 +HSync -Vsync #flicker fix (119hz) +#addMode "640x480_120p" 51.97 640 680 744 848 480 481 484 515 +HSync -Vsync +addMode "640x480_120p" 52.95 640 680 748 856 480 482 485 516 -HSync +VSync addMode "480x360_120p" 29.00 480 504 552 624 360 363 367 389 -hsync +vsync #enter the gungeon addMode "760x284_120p" 35.50 760 792 864 968 284 287 297 308 -hsync +vsync #downwell addMode "1920x240_120p" 92.443 1920 2202 2266 2744 240 245 250 281 -HSync -VSync diff --git a/controller-off/compile.sh b/controller-off/compile.sh new file mode 100755 index 0000000..5b16a79 --- /dev/null +++ b/controller-off/compile.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cc controller-off.c -o controller-off $(pkg-config --cflags --libs sdl3) diff --git a/controller-off/controller-off b/controller-off/controller-off new file mode 100755 index 0000000000000000000000000000000000000000..4a05ad9a5c796ee91d68692c0696c5f7eb43f9d4 GIT binary patch literal 22472 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 literal 0 HcmV?d00001 diff --git a/controller-off/controller-off.c b/controller-off/controller-off.c new file mode 100644 index 0000000..c4752c2 --- /dev/null +++ b/controller-off/controller-off.c @@ -0,0 +1,704 @@ +/* + * controller-off.c + * + * Global SDL3 controller disconnect utility. + * + * Button combination: + * + * Guide/Home + North + * + * SDL mapping: + * + * PlayStation -> Home + Triangle + * Xbox -> Guide + Y + * Nintendo -> Home + X + * + * Build: + * + * cc controller-off.c -o controller-off \ + * $(pkg-config --cflags --libs sdl3) + * + * Run: + * + * ./controller-off + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_CONTROLLERS 32 +#define MAC_LEN 18 + +typedef struct { + SDL_JoystickID id; + SDL_Gamepad *gamepad; + + int guide_pressed; + int north_pressed; + + /* + * Prevent repeated triggers while both buttons + * remain held. + */ + int triggered; +} Controller; + +static Controller controllers[MAX_CONTROLLERS]; +static int controller_count = 0; + +static volatile sig_atomic_t running = 1; + + +/* + * ------------------------------------------------------------ + * Check for XX:XX:XX:XX:XX:XX + * ------------------------------------------------------------ + */ +static int is_mac(const char *s) +{ + if (!s || strlen(s) != 17) + return 0; + + for (int i = 0; i < 17; i++) { + + if (i == 2 || + i == 5 || + i == 8 || + i == 11 || + i == 14) { + + if (s[i] != ':') + return 0; + + } else { + + if (!isxdigit( + (unsigned char)s[i])) + return 0; + } + } + + return 1; +} + + +/* + * ------------------------------------------------------------ + * Find a connected Bluetooth device whose name matches + * the SDL controller name. + * + * bluetoothctl output: + * + * Device AA:BB:CC:DD:EE:FF PS3 Controller + * + * We use: + * + * bluetoothctl devices Connected + * ------------------------------------------------------------ + */ +static int find_bluetooth_device( + const char *controller_name, + char mac[MAC_LEN]) +{ + if (!controller_name) + return 0; + + FILE *fp = popen( + "bluetoothctl devices Connected 2>/dev/null", + "r" + ); + + if (!fp) + return 0; + + char line[1024]; + + while (fgets( + line, + sizeof(line), + fp + )) { + + char candidate_mac[MAC_LEN]; + char device_name[768]; + + memset( + candidate_mac, + 0, + sizeof(candidate_mac) + ); + + memset( + device_name, + 0, + sizeof(device_name) + ); + + + /* + * bluetoothctl: + * + * Device MAC NAME + */ + if (sscanf( + line, + "Device %17s %[^\n]", + candidate_mac, + device_name + ) != 2) { + + continue; + } + + + if (!is_mac(candidate_mac)) + continue; + + + /* + * SDL and bluetoothctl may use slightly + * different names. + * + * First try exact match. + */ + if (strcmp( + controller_name, + device_name + ) == 0) { + + strncpy( + mac, + candidate_mac, + MAC_LEN + ); + + mac[MAC_LEN - 1] = '\0'; + + pclose(fp); + + return 1; + } + + + /* + * PS3-specific fallback. + * + * SDL: + * + * PS3 Controller + * + * BlueZ: + * + * PLAYSTATION(R)3 Controller + */ + if ( + strstr(controller_name, "PS3") && + strstr(device_name, "3 Controller") + ) { + + strncpy( + mac, + candidate_mac, + MAC_LEN + ); + + mac[MAC_LEN - 1] = '\0'; + + pclose(fp); + + return 1; + } + } + + pclose(fp); + + return 0; +} + + +/* + * ------------------------------------------------------------ + * Disconnect Bluetooth device. + * ------------------------------------------------------------ + */ +static void disconnect_bluetooth( + const char *mac) +{ + if (!is_mac(mac)) + return; + + + printf( + "Disconnecting Bluetooth device %s\n", + mac + ); + + fflush(stdout); + + + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return; + } + + + if (pid == 0) { + + /* + * Suppress bluetoothctl output. + */ + FILE *devnull = + fopen("/dev/null", "w"); + + if (devnull) { + + dup2( + fileno(devnull), + STDOUT_FILENO + ); + + dup2( + fileno(devnull), + STDERR_FILENO + ); + + fclose(devnull); + } + + + execlp( + "bluetoothctl", + "bluetoothctl", + "disconnect", + mac, + (char *)NULL + ); + + + _exit(127); + } + + + /* + * Reap child process. + */ + waitpid( + pid, + NULL, + 0 + ); +} + + +/* + * ------------------------------------------------------------ + * Handle the button combination. + * ------------------------------------------------------------ + */ +static void disconnect_controller( + Controller *controller) +{ + if (!controller || + !controller->gamepad) + return; + + + const char *name = + SDL_GetGamepadName( + controller->gamepad + ); + + + printf("\n"); + printf( + "PS/Home + North detected\n" + ); + + printf( + "Controller: %s\n", + name ? name : "Unknown" + ); + + + char mac[MAC_LEN]; + + + if (!find_bluetooth_device( + name, + mac + )) { + + fprintf( + stderr, + "Could not find a connected Bluetooth " + "device matching \"%s\".\n", + name ? name : "Unknown" + ); + + return; + } + + + printf( + "Bluetooth MAC: %s\n", + mac + ); + + + disconnect_bluetooth(mac); +} + + +/* + * ------------------------------------------------------------ + * Find SDL controller. + * ------------------------------------------------------------ + */ +static Controller *find_controller( + SDL_JoystickID id) +{ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].id == id) + return &controllers[i]; + } + + return NULL; +} + + +/* + * ------------------------------------------------------------ + * Add controller. + * ------------------------------------------------------------ + */ +static void add_controller( + SDL_JoystickID id) +{ + if (controller_count >= + MAX_CONTROLLERS) { + + fprintf( + stderr, + "Controller limit reached.\n" + ); + + return; + } + + + SDL_Gamepad *gamepad = + SDL_OpenGamepad(id); + + + if (!gamepad) { + + fprintf( + stderr, + "SDL_OpenGamepad failed: %s\n", + SDL_GetError() + ); + + return; + } + + + Controller *controller = + &controllers[ + controller_count++ + ]; + + + memset( + controller, + 0, + sizeof(*controller) + ); + + + controller->id = id; + controller->gamepad = gamepad; + + + const char *name = + SDL_GetGamepadName(gamepad); + + + printf( + "Controller connected: %s\n", + name ? name : "Unknown" + ); +} + + +/* + * ------------------------------------------------------------ + * Remove controller. + * ------------------------------------------------------------ + */ +static void remove_controller( + SDL_JoystickID id) +{ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].id != id) + continue; + + + SDL_CloseGamepad( + controllers[i].gamepad + ); + + + /* + * Fill the removed slot with the last + * controller. + */ + controllers[i] = + controllers[ + controller_count - 1 + ]; + + + controller_count--; + + return; + } +} + + +/* + * ------------------------------------------------------------ + * Signal handler. + * ------------------------------------------------------------ + */ +static void handle_signal( + int signal) +{ + (void)signal; + + running = 0; +} + + +/* + * ------------------------------------------------------------ + * Main + * ------------------------------------------------------------ + */ +int main(void) +{ + signal( + SIGINT, + handle_signal + ); + + signal( + SIGTERM, + handle_signal + ); + + + if (!SDL_Init( + SDL_INIT_GAMEPAD)) { + + fprintf( + stderr, + "SDL_Init failed: %s\n", + SDL_GetError() + ); + + return 1; + } + + + /* + * Receive controller events even though we have + * no window/focus. + */ + SDL_SetHint( + SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, + "1" + ); + + + printf( + "====================================\n" + " Controller Off\n" + "====================================\n" + "Hold Home/Guide + Triangle/North\n" + "to disconnect the controller.\n\n" + ); + + + /* + * Open controllers that already exist. + */ + int count = 0; + + SDL_JoystickID *ids = + SDL_GetGamepads(&count); + + + if (ids) { + + for (int i = 0; + i < count; + i++) { + + add_controller(ids[i]); + } + + SDL_free(ids); + } + + + SDL_Event event; + + + while (running) { + + while (SDL_PollEvent(&event)) { + + + /* + * Controller added. + */ + if (event.type == + SDL_EVENT_GAMEPAD_ADDED) { + + add_controller( + event.gdevice.which + ); + } + + + /* + * Controller removed. + */ + else if (event.type == + SDL_EVENT_GAMEPAD_REMOVED) { + + remove_controller( + event.gdevice.which + ); + } + + + /* + * Button press/release. + */ + else if ( + event.type == + SDL_EVENT_GAMEPAD_BUTTON_DOWN || + + event.type == + SDL_EVENT_GAMEPAD_BUTTON_UP + ) { + + Controller *controller = + find_controller( + event.gbutton.which + ); + + + if (!controller) + continue; + + + int pressed = + event.type == + SDL_EVENT_GAMEPAD_BUTTON_DOWN; + + + /* + * Guide/Home/PS. + */ + if (event.gbutton.button == + SDL_GAMEPAD_BUTTON_GUIDE) { + + controller->guide_pressed = + pressed; + } + + + /* + * North: + * + * PS = Triangle + * Xbox = Y + * Nintendo = X + */ + if (event.gbutton.button == + SDL_GAMEPAD_BUTTON_NORTH) { + + controller->north_pressed = + pressed; + } + + + /* + * Trigger only once per press. + */ + if (controller->guide_pressed && + controller->north_pressed && + !controller->triggered) { + + controller->triggered = 1; + + disconnect_controller( + controller + ); + } + + + /* + * Allow another trigger after + * either button is released. + */ + if (!controller->guide_pressed || + !controller->north_pressed) { + + controller->triggered = 0; + } + } + } + + + SDL_Delay(5); + } + + + /* + * Cleanup. + */ + for (int i = 0; + i < controller_count; + i++) { + + if (controllers[i].gamepad) + SDL_CloseGamepad( + controllers[i].gamepad + ); + } + + + SDL_Quit(); + + return 0; +} + diff --git a/profile b/profile new file mode 100644 index 0000000..c2d5eb1 --- /dev/null +++ b/profile @@ -0,0 +1,155 @@ +#profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. + +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 + + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi + +#text colors +txtblk='\e[0;30m' # Black - Regular +txtred='\e[0;31m' # Red +txtgrn='\e[0;32m' # Green +txtylw='\e[0;33m' # Yellow +txtblu='\e[0;34m' # Blue +txtpur='\e[0;35m' # Purple +txtcyn='\e[0;36m' # Cyan +txtwht='\e[0;37m' # White + +x="/etc/X11/xorg.conf.d" +xmonad="$HOME/.xmonad/xmonad.hs" +xmo=$xmonad +gpc="$HOME/mnt/gaming-win/C:/Users/lucka/" +brc="$HOME/.bashrc" +alias v="vim" +alias s="sudo" +alias mg="sshfs gaming-pc.mario:/ ~/mnt/gaming-pc" +alias mt="sshfs lucka@terraria.mario: ~/mnt/terraria.mario" +alias umg="umount ~/mnt/gaming-pc" +#alias ms="sshfs truenas.mario:/mnt/b8ce9a57-7ce7-47b8-a233-21184c8a0953/share ~/share -o reconnect -o ServerAliveInterval=15" +#alias ums="umount ~/share" +alias p="~/sh/ytmusicquick" +alias nas="ssh nas.mario" +#alias mn="sshfs -o allow_root truenas.mario:/mnt/mario ~/mnt/truenas.mario" +mn () { +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/share ~/mnt/truenas.mario/share +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/websites ~/mnt/truenas.mario/websites +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/roms ~/mnt/truenas.mario/roms +#sudo mount -o rsize=130048,wsize=131007,bsize=16777216,username=roms,password=00P9sVAgGQymKp2hZi79TYXliJt20tAT,uid=1000,gid=1000,iocharset=utf8,mapposix,actimeo=6,echo_interval=1,nostrictsync,cache=loose,nocase,soft,vers=3.1.1 -t cifs //10.0.21.1/roms ~/mnt/truenas.mario/roms +sudo mount --bind /home/lucka/.steam/steam/steamapps/compatdata /home/lucka/mnt/truenas.mario/roms/windows/Steamm/steamapps/compatdata +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/slowpool/movies ~/mnt/truenas.mario/movies +sudo mount -o rsize=131072,wsize=131072,nconnect=16 -t nfs 10.0.21.1:/mnt/mario/os-isos/template/iso ~/mnt/truenas.mario/os-isos +} +alias umn="sudo umount ~/mnt/truenas.mario/*" +alias mfs="~/sh/mount-all-filesystems.sh" +alias lgctl="~/sh/lgctl" +alias bs="barriers -f -c ~/.config/barrier-server.conf --disable-crypto" +alias xe="vim ~/.xmonad/xmonad.hs" +sshfs(){ +/usr/bin/sshfs -o reconnect,allow_root,workaround=buflimit,ServerAliveInterval=15,ServerAliveCountMax=3 $* +} +ytmp3 () { +yt-dlp --extract-audio --audio-format mp3 $@ +} +ytmp3numbered () { +ytmp3 --output "%(autonumber)s - %(title)s.%(ext)s" $@ +} +ytdl () { +yt-dlp "$*" +} +tfcfg () { +ssh gaming-win -t "e: && cd steamlibrary\steamapps\common\team fortress 2\tf\cfg && cmd" +} +gremote () { +#bash -c 'sleep 2 && remmina -c vnc://127.0.0.1:5901' & +ssh -L 5901:127.0.0.1:5901 $1 'pkill x11vnc; x11vnc -display :0 -rfbport 5901 -localhost -threads -noxfixes -noxdamage' +} +i () { +sudo apt install "$*" +} +u () { +sudo apt purge "$*" +} +sshmnt () { + mkdir -p ~/mnt/$1 + sshfs -o ServerAliveInterval=7 $1 ~/mnt/$1 +} +n () { + numlockx off +} +terminal-open () { + xfce4-terminal --command "$*" +} +topen () { + terminal-open "$*" +} ++x () { + chmod ug+x $* +} +cdwm () { + cd ~/compile/lukedwm/dwm +} +recordto () { + ffmpeg -f pulse -i default -codec:a flac "${1}.flac" +} +getclip () { + xclip -selection c -o +} +setclip () { + xclip -selection c +} +sshsus () { + ssh -J root@10.0.42.69 $* +} +webp () { + ffmpeg -i $1 -vcodec libwebp -filter:v fps=fps=60 -lossless 1 -loop 0 -preset default -an -vsync 0 $1.webp +} +alias py="python3" +pssh () { + adb forward tcp:65522 tcp:22; ssh root@127.0.0.1 -p 65522 $* +} +testvidmode () { + xrandr --delmode HDMI-A-0 $1 + xrandr --rmmode $1 + xrandr --newmode $* + xrandr --addmode HDMI-A-0 $1 + xrandr --output HDMI-A-0 --mode $1 +} +testvidmode2 () { + xrandr --delmode DisplayPort-0 $1 + xrandr --rmmode $1 + xrandr --newmode $* + xrandr --addmode DisplayPort-0 $1 + xrandr --output DisplayPort-0 --mode $1 +} +nintendontify () { + for i in *; do mkdir "$(echo $i | sed 's/.iso//')"; mv "$i" "$(echo $i | sed 's/.iso//')"/game.iso; done +} +wiiconnect () { + bluetoothctl connect 00:1E:35:3A:A9:B5 +} +vsync () { + picom --backend glx --vsync +} +crtTV () { +       testvidmode "1280x480_60i" 26.108 1280 1332 1455 1664 480 483 489 523 interlace -hsync -vsync +       xrandr --output DisplayPort-0 --mode 1280x480_60i --scale-from 640x480 --below HDMI-A-0 +} +crtTVscale () { +       testvidmode "1280x480_60i" 26.108 1280 1332 1455 1664 480 483 489 523 interlace -hsync -vsync +       xrandr --output DisplayPort-0 --mode 1280x480_60i --scale-from 1280x960 --below HDMI-A-0 +} + diff --git a/remove1280x960modes.sh b/remove1280x960modes.sh new file mode 100755 index 0000000..555533e --- /dev/null +++ b/remove1280x960modes.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +delMode () { + xrandr --delmode HDMI-A-0 "$1" + xrandr --rmmode "$1" +} + +for i in $(xrandr | grep -o '1280x960_[^ ]*') +do + delMode $i +done diff --git a/screenlayout/mirror900p.sh b/screenlayout/mirror900p.sh new file mode 100755 index 0000000..be34427 --- /dev/null +++ b/screenlayout/mirror900p.sh @@ -0,0 +1,4 @@ +#!/bin/bash +xrandr --newmode "1600x900_60p" 118.25 1600 1688 1856 2112 900 903 908 934 -hsync +vsync +xrandr --addmode DisplayPort-1 1600x900_60p +xrandr --output HDMI-A-0 --mode 1600x900_120i --primary --output DisplayPort-1 --mode 1600x900_60p --same-as HDMI-A-0 diff --git a/screenlayout/tv1080p.sh b/screenlayout/tv1080p.sh index 00379da..0c59e28 100755 --- a/screenlayout/tv1080p.sh +++ b/screenlayout/tv1080p.sh @@ -1,2 +1,2 @@ #!/bin/sh -xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off +xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1920x1080 --scale-from 1920x1080 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off diff --git a/screenlayout/tv720p.sh b/screenlayout/tv720p.sh index a80627b..d48ca31 100755 --- a/screenlayout/tv720p.sh +++ b/screenlayout/tv720p.sh @@ -1,2 +1,5 @@ #!/bin/sh -xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode 1280x720 --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off +xrandr --newmode "1280x720_60.00" 74.50 1280 1344 1472 1664 720 723 728 748 -hsync +vsync +xrandr --addmode DisplayPort-1 "1280x720_60.00" + +xrandr --output DisplayPort-0 --off --output DisplayPort-1 --primary --mode "1280x720_60.00" --pos 0x0 --rotate normal --output DisplayPort-2 --off --output HDMI-A-0 --off diff --git a/vsyncToggle.sh b/vsyncToggle.sh new file mode 100755 index 0000000..5381b77 --- /dev/null +++ b/vsyncToggle.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Toggle picom with --backend glx --vsync + +if pgrep -x "picom" > /dev/null; then + # Picom is running → kill it + pkill -x picom + notify-send "Picom" "Compositor disabled" 2>/dev/null || true +else + # Picom is not running → start it + picom --backend glx --vsync & + notify-send "Picom" "Compositor enabled (GLX + VSync)" 2>/dev/null || true +fi