chiark / gitweb /
keystroke injection attempts
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 6 Jun 2009 00:21:45 +0000 (01:21 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 6 Jun 2009 00:21:45 +0000 (01:21 +0100)
.gitignore
pctb/ls-xwindow-names [new file with mode: 0755]
pctb/x-manip-window.c [new file with mode: 0644]

index 88757775e233672f7b7992bb78535e5e19bf49e7..fd7f3213c39b90db697aeaa580599c5e1f3e0095 100644 (file)
@@ -5,6 +5,7 @@ pctb/*.o
 pctb/t.*
 pctb/u.*
 pctb/convert
+pctb/x-manip-window
 
 pctb/stuff/text.ppm
 pctb/stuff/text.png
diff --git a/pctb/ls-xwindow-names b/pctb/ls-xwindow-names
new file mode 100755 (executable)
index 0000000..7fbbe40
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+use strict (qw(vars));
+
+use IO::File;
+
+our @pipes;
+
+sub reap_pipe () {
+    my ($child, $pipe) = @{ shift @pipes };
+    { local ($/) = undef; $_= <$pipe>; }
+    if (m/^WM_NAME: +not found/) {
+    } elsif (m/^WM_NAME\(STRING\) = $/) {
+    } elsif (m/^WM_NAME\(STRING\) = \"(.*)\"$/) {
+       print "$child $1\n" or die $!;
+    } else {
+       die "$child $_ ?";
+    }
+    $!=0; $pipe->close(); $? and die "$? $! ?";
+}
+
+open WI, "LC_ALL=C xwininfo -root -children |" or die $!;
+while (<WI>) {
+    next unless m/^\s+\d+ children:/..0;
+    next unless m/^\s+(0x[0-9a-f]+) /;
+    my $child= $1;
+
+    my $pipe= new IO::File "LC_ALL=C xprop -id $child WM_NAME |" or die $!;
+    push @pipes, [ $child, $pipe ];
+
+    while (@pipes > 40) { reap_pipe(); }
+}
+$!=0; close WI; $? and die "$? $! ?";
+
+while (@pipes) { reap_pipe(); }
+
+close STDOUT or die $!;
diff --git a/pctb/x-manip-window.c b/pctb/x-manip-window.c
new file mode 100644 (file)
index 0000000..2ff1135
--- /dev/null
@@ -0,0 +1,69 @@
+/**/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+
+#define eassert assert
+
+static Display *disp;
+static long id;
+
+static void kmevent(XEvent *ev) {
+  int r;
+  r= XSendEvent(disp,id,False,0,ev);  assert(r);
+}
+
+static KeyCode keycode(const char *s) {
+  KeySym sym= XStringToKeysym(s);
+  return XKeysymToKeycode(disp,sym);
+}
+
+int main(int argc, const char *const *argv) {
+  char *ep;
+  XWindowAttributes attr;
+  XEvent ev;
+  int r;
+
+  id= strtoul(*++argv,&ep,0);
+  disp= XOpenDisplay(0);  eassert(disp);
+
+  r= XGetWindowAttributes(disp, id, &attr);  eassert(r);
+
+  while (*++argv) {
+    
+    memset(&ev,0,sizeof(ev));
+#define KE ev.xkey
+#define ME ev.xbutton
+
+    switch (**argv) {
+    case 'r':
+      r= XRaiseWindow(disp, id);  eassert(r);
+      break;
+
+#define KMEVENT(e,t)                           \
+      e.type= t;                               \
+      e.window= id;                            \
+      e.root= attr.root;                       \
+      e.x= atoi(*++argv);                      \
+      e.y= atoi(*++argv);                      \
+      e.x_root= e.x;                           \
+      e.y_root= e.y;                           \
+      e.same_screen= True;                     \
+      kmevent(&ev);                            \
+      break;
+
+    case 'K': KE.keycode= keycode(*++argv);      KMEVENT(KE,KeyPress);
+    case 'k': KE.keycode= keycode(*++argv);      KMEVENT(KE,KeyRelease);
+    case 'M': ME.button=1;                       KMEVENT(ME,ButtonPress);
+    case 'm': ME.button=1; ME.state=Button1Mask; KMEVENT(ME,ButtonRelease);
+    default:
+      abort();
+    }
+  }
+      
+  r= XSync(disp, False);  eassert(r);
+  exit(0);
+}