Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input: Forward the suspend/wakeup source on Kindle #1723

Merged
merged 2 commits into from Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
65 changes: 46 additions & 19 deletions input/input-kindle.h
Expand Up @@ -31,21 +31,39 @@ static void slider_handler(int sig)
}
}

// Using strtol right is *fun*...
static int strtol_d(const char* str)
{
char* endptr;
errno = 0;
long int val = strtol(str, &endptr, 10);
// NOTE: The string we're fed will have trailing garbage (a space followed by an LF) (because lipc & fgets), so we mostly ignore endptr...
if (errno || endptr == str || (int) val != val) {
// strtol failure || no digits were found || cast truncation
return -1; // this will conveniently never match a real powerd constant ;).
}

return (int) val;
}

static void sendEvent(int fd, struct input_event* ev)
{
if (write(fd, ev, sizeof(struct input_event)) == -1) {
fprintf(stderr, "[ko-input]: Failed to generate fake event.\n");
}
}

static void generateFakeEvent(int pipefd[2]) {
/* We send a SIGTERM to this child on exit, trap it to kill lipc properly. */
signal(SIGTERM, slider_handler);

FILE *fp;
char std_out[256];
int status;
struct input_event ev;
__u16 key_code = CODE_FAKE_IN_SAVER;

close(pipefd[0]);

ev.type = EV_KEY;
ev.code = key_code;
ev.value = 1;
// NOTE: We leave the timestamp at zero, we don't know the system's evdev clock source right now,
// and zero works just fine for EV_KEY events.
struct input_event ev = { 0 };
ev.type = EV_KEY;
ev.value = 1;

/* listen power slider events (listen for ever for multiple events) */
char *argv[] = {
Expand All @@ -55,43 +73,52 @@ static void generateFakeEvent(int pipefd[2]) {
/* @TODO 07.06 2012 (houqp)
* plugin and out event can only be watched by:
* lipc-wait-event com.lab126.hal usbPlugOut,usbPlugIn */
fp = popen_noshell("lipc-wait-event", (const char * const *)argv, "r", &pclose_arg, 0);
FILE *fp = popen_noshell("lipc-wait-event", (const char * const *)argv, "r", &pclose_arg, 0);
if (!fp) {
err(EXIT_FAILURE, "popen_noshell()");
}

/* Flush to get rid of buffering issues? */
fflush(fp);

while (fgets(std_out, sizeof(std_out)-1, fp)) {
char std_out[256];
while (fgets(std_out, sizeof(std_out), fp)) {
if (std_out[0] == 'g') {
ev.code = CODE_FAKE_IN_SAVER;
// Pass along the source constant
ev.value = strtol_d(std_out + sizeof("goingToScreenSaver"));
sendEvent(pipefd[1], &ev);
ev.value = 1;
} else if(std_out[0] == 'o') {
ev.code = CODE_FAKE_OUT_SAVER;
// Pass along the source constant
ev.value = strtol_d(std_out + sizeof("outOfScreenSaver"));
sendEvent(pipefd[1], &ev);
ev.value = 1;
} else if((std_out[0] == 'u') && (std_out[7] == 'I')) {
ev.code = CODE_FAKE_USB_PLUGGED_IN_TO_HOST;
sendEvent(pipefd[1], &ev);
} else if((std_out[0] == 'u') && (std_out[7] == 'O')) {
ev.code = CODE_FAKE_USB_PLUGGED_OUT_OF_HOST;
sendEvent(pipefd[1], &ev);
} else if(std_out[0] == 'c') {
ev.code = CODE_FAKE_CHARGING;
sendEvent(pipefd[1], &ev);
} else if(std_out[0] == 'n') {
ev.code = CODE_FAKE_NOT_CHARGING;
sendEvent(pipefd[1], &ev);
} else if(std_out[0] == 'w') {
ev.code = CODE_FAKE_WAKEUP_FROM_SUSPEND;
sendEvent(pipefd[1], &ev);
} else if(std_out[0] == 'r') {
ev.code = CODE_FAKE_READY_TO_SUSPEND;
sendEvent(pipefd[1], &ev);
} else {
fprintf(stderr, "Unrecognized event.\n");
}
/* fill event struct */
gettimeofday(&ev.time, NULL);
/* generate event */
if (write(pipefd[1], &ev, sizeof(struct input_event)) == -1) {
fprintf(stderr, "Failed to generate event.\n");
fprintf(stderr, "[ko-input]: Unrecognized powerd event: `%.*s`.\n", (int) (sizeof(std_out) - 1U), std_out);
}
}

status = pclose_noshell(&pclose_arg);
int status = pclose_noshell(&pclose_arg);
if (status == -1) {
err(EXIT_FAILURE, "pclose_noshell()");
} else {
Expand Down
2 changes: 2 additions & 0 deletions input/input-kobo.h
Expand Up @@ -106,11 +106,13 @@ static void generateFakeEvent(int pipefd[2])
// Pass along the evdev number
ev.value = strtol_d(uev.devname + sizeof("input/event") - 1U); // i.e., start right after the t of event
sendEvent(pipefd[1], &ev);
ev.value = 1;
break;
case UEVENT_ACTION_REMOVE:
ev.code = CODE_FAKE_USB_DEVICE_PLUGGED_OUT;
ev.value = strtol_d(uev.devname + sizeof("input/event") - 1U);
sendEvent(pipefd[1], &ev);
ev.value = 1;
break;
default:
// NOP
Expand Down
4 changes: 2 additions & 2 deletions input/input-remarkable.h
Expand Up @@ -73,7 +73,7 @@ static void generateFakeEventRM2(int pipefd) {

fflush(fp);

while (fgets(std_out, sizeof(std_out)-1, fp)) {
while (fgets(std_out, sizeof(std_out), fp)) {
if (!strncmp(std_out, " boolean false", 16)) {
gettimeofday(&ev.time, NULL);
if (write(pipefd, &ev, sizeof(struct input_event)) == -1) {
Expand Down Expand Up @@ -105,7 +105,7 @@ static void generateFakeEventRM1(int pipefd) {

re = ue_init_listener(&listener);
if (re < 0) {
fprintf(stderr, "[remarkable-fake-event] Failed to initilize libue listener (%d)\n", re);
fprintf(stderr, "[remarkable-fake-event] Failed to initialize libue listener (%d)\n", re);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion input/input-sony-prstux.h
Expand Up @@ -78,7 +78,7 @@ static void generateFakeEvent(int pipefd[2]) {

re = ue_init_listener(&listener);
if (re < 0) {
fprintf(stderr, "[sony-prstux-fake-event] Failed to initilize libue listener (%d)\n", re);
fprintf(stderr, "[sony-prstux-fake-event] Failed to initialize libue listener (%d)\n", re);
return;
}

Expand Down