/**************************************************************************** * stickymap.c - re-run xmodmap on ACPI resume events * * Version: 0 * * * * Author: D J Capelis * * Contact: mail at capelis dot dj * * Released to Public Domain, 2011. * * * * Disclaimer: I'm not responsible for anything at all not even a little. * ***************************************************************************/ /* Documentation */ /* Compile: gcc -o stickymap stickymap.c */ /* Install: Copy it somewhere, chmod +x it */ /* Depends: libc, linux, acpid */ /* Run: Launch stickymap in the background via .xinitrc, it'll re-run xmodmap on ~/.Xmodmap 5 seconds after resume */ #include #include #include #include #include #include #include #include #include #define chk_error(cond) if (cond) { goto err; } #define BUFSIZE 1024 void handle_acpi_event(char * acpi_event); char * cmd; int main() { struct passwd * user_ent; int buf_max; int acpid_sock; struct sockaddr_un * sockloc; char * parsebuffer; /* Setup string to pass to system() */ user_ent = getpwuid(getuid()); chk_error(user_ent == NULL); buf_max = sysconf(_SC_GETPW_R_SIZE_MAX); chk_error(buf_max < 1); cmd = calloc(1, 7 + 1 + buf_max + 9 + 1); // "xmodmap" + ' ' + homedir + "/.Xmodmap" + \0 chk_error(cmd == NULL); cmd = strncat(cmd, "xmodmap ", 8); cmd = strncat(cmd, user_ent->pw_dir, buf_max); cmd = strncat(cmd, "/.Xmodmap", 9); /* Connect to acpid socket */ acpid_sock = socket(AF_UNIX, SOCK_STREAM, 0); chk_error(acpid_sock < 0); sockloc = calloc(1, sizeof(struct sockaddr_un)); chk_error(sockloc == NULL); sockloc->sun_family = AF_UNIX; strcpy(sockloc->sun_path,"/var/run/acpid.socket"); chk_error(connect(acpid_sock, (struct sockaddr *) sockloc, 108) != 0); /* Parse the buffer and do the stuff */ parsebuffer = calloc(1, BUFSIZE); while(1) { chk_error(read(acpid_sock, parsebuffer, BUFSIZE) < 0); handle_acpi_event(parsebuffer); memset(parsebuffer, 0, BUFSIZE); } /* Never reached */ printf("stickymap is terminating, this shouldn't happen...\n"); return -2; err: perror("stickymap"); return -1; } void handle_acpi_event(char * acpi_event) { if(strncmp(acpi_event, "button/lid LID open", 19) == 0) { sleep(5); // Hope X picks up the keyboard within the first 5 seconds of resume chk_error(system(cmd) == -1); } return; err: perror("stickymap"); exit(-1); }