]> git.sur5r.net Git - i3/i3/commitdiff
inject_randr1.5: Add RRGetOutputInfo reply injection
authorVladimir Panteleev <git@thecybershadow.net>
Tue, 12 Sep 2017 07:03:20 +0000 (07:03 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 13 Sep 2017 16:45:46 +0000 (18:45 +0200)
Add a --getoutputinfo_reply switch to indicate a filename containing
the RRGetOutputInfo reply data to inject.

testcases/inject_randr1.5.c

index b09510d07bf4d7837d1b69f7b23b9db968599fca..955df1e5474690d333a906534ae3b5e5f78bcaf5 100644 (file)
@@ -48,6 +48,7 @@ struct injected_reply {
 
 /* BEGIN RandR 1.5 specific */
 static struct injected_reply getmonitors_reply = {NULL, 0};
+static struct injected_reply getoutputinfo_reply = {NULL, 0};
 /* END RandR 1.5 specific */
 
 #define XCB_PAD(i) (-(i)&3)
@@ -70,6 +71,8 @@ struct connstate {
     int getext_randr;
     /* sequence number of the most recent RRGetMonitors request */
     int getmonitors;
+    /* sequence number of the most recent RRGetOutputInfo request */
+    int getoutputinfo;
 
     int randr_major_opcode;
     /* END RandR 1.5 specific */
@@ -263,6 +266,8 @@ static void read_client_x11_packet_cb(EV_P_ ev_io *w, int revents) {
         const uint8_t randr_opcode = ((generic_x11_request_t *)request)->pad0;
         if (randr_opcode == XCB_RANDR_GET_MONITORS) {
             connstate->getmonitors = connstate->sequence;
+        } else if (randr_opcode == XCB_RANDR_GET_OUTPUT_INFO) {
+            connstate->getoutputinfo = connstate->sequence;
         }
     }
     /* END RandR 1.5 specific */
@@ -306,6 +311,17 @@ static void read_server_x11_packet_cb(EV_P_ ev_io *w, int revents) {
                     return;
                 }
             }
+
+            if (sequence == connstate->getoutputinfo) {
+                printf("RRGetOutputInfo reply!\n");
+                if (getoutputinfo_reply.buf != NULL) {
+                    printf("injecting reply\n");
+                    ((generic_x11_reply_t *)getoutputinfo_reply.buf)->sequence = sequence;
+                    must_write(writeall(connstate->clientw->fd, getoutputinfo_reply.buf, getoutputinfo_reply.len));
+                    free(packet);
+                    return;
+                }
+            }
             /* END RandR 1.5 specific */
 
             break;
@@ -347,6 +363,7 @@ static void must_read_reply(const char *filename, struct injected_reply *reply)
 int main(int argc, char *argv[]) {
     static struct option long_options[] = {
         {"getmonitors_reply", required_argument, 0, 0},
+        {"getoutputinfo_reply", required_argument, 0, 0},
         {0, 0, 0, 0},
     };
     char *options_string = "";
@@ -355,11 +372,15 @@ int main(int argc, char *argv[]) {
 
     while ((opt = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
         switch (opt) {
-            case 0:
-                if (strcmp(long_options[option_index].name, "getmonitors_reply") == 0) {
+            case 0: {
+                const char *option_name = long_options[option_index].name;
+                if (strcmp(option_name, "getmonitors_reply") == 0) {
                     must_read_reply(optarg, &getmonitors_reply);
+                } else if (strcmp(option_name, "getoutputinfo_reply") == 0) {
+                    must_read_reply(optarg, &getoutputinfo_reply);
                 }
                 break;
+            }
             default:
                 exit(EXIT_FAILURE);
         }