Monday, February 09, 2015

Typing on Windows, Making Magic on Linux - Adventures in Linux Desktop Remote Control

I always keep two laptops in rotation and every Monday I toggle back and forth between the one I'm using. At the moment, one runs Windows, the other Linux. Last week I spent on the Linux box, this week it's Windows time.

As an aside, one of the trickiest aspects of setting up Linux was learning that my touchpad wasn't properly recognized (it needed to be marked as a touchpad). Basic operations like dragging windows and selecting text wouldn't work; it was terrifically frustrating. This morning, like an attention seeking toddler, my Windows box decided that it too should have touchpad problems. It stopped working, and caused the keyboard to go haywire. I've since turned off the trackpad, and the system appears to be functioning. Guess Windows isn't always the Just Works OS I claimed it was.

OK, back to the task at hand.

I'm typing on my Windows box, but my Linux box is right next to it. I can reach over, and type plsplayer http://somafm.com/bootliquor.pls to start playing some background music. But this is Linux, surely I can do better than that? Of course I can.

The first order of business was to get the ssh daemon running on my Linux box. This turned out to be easily done with these commands. Next I needed to figure out how I was going to learn the IP address of my Linux box. I was imagining the need to run some sort of internal DNS. Turns out, it's far easier than that. My router, upon giving my Linux box its IP address, noted its hostname. To my complete shock and amazement I can do:

  ssh longshot ls

Where 'longshot' is the name I gave my Linux box. It just works. I knew the router provided DNS services, I never imagined it was smart enough to incorporate names from DHCP into this service. Note to self: don't underestimate the router.

OK, so I can now ssh to my Linux box. This is good. But it gets better: because I'm relying ratpoison as my window manager, and because ratpoison is scriptable I can have it switch windows around remotely with great ease. I just type:

  ssh longshot DISPLAY=:0.0 ratpoison -c next

I can trivially kick of my voice commands, too:

 ssh longshot saytime

By default, Firefox will open up the URL handed to it within currently focused instance. So the following opens up CNN in the current browser:

 ssh longshot DISPLAY=:0.0 firefox http://cnn.com 

And for complete control, I can use xdotool to simulate mouse and cursor events. I can bring up a word definition by using the following set of commands:

ssh longshot DISPLAY=:0.0 firefox http://google.com 
ssh longshot DISPLAY=:0.0 xdotool key Return
ssh longshot DISPLAY=:0.0 xdotool type definition
ssh longshot DISPLAY=:0.0 xdotool key space
ssh longshot DISPLAY=:0.0 xdotool type their
ssh longshot DISPLAY=:0.0 xdotool key Return

Or, perhaps I want to bring up cnn.com and then page down the screen:

( ssh longshot DISPLAY=:0.0 firefox http://cnn.com ;
  sleep 5 ;
  ssh longshot DISPLAY=:0.0 xdotool key Next ;
  sleep 5
  ssh longshot DISPLAY=:0.0 xdotool key Next  )

Note that xdotool type sends text, whereas xdotool key sends a particular key.

Of course, typing all this in by hand is silly. I whipped up a quick shell script which I run from Cygwin on my Windows box. There's almost certainly some fancy keyboard / screen sharing solution I could setup between these laptops. But that's not really what I'm after. I love exploiting the power of the command line, and using the above tools I can do that even if the command line I'm typing at happens to be on a different computer.

Note: none of the above commands X-related commands will work for you unless you do something like xhost + in your X-session. You almost certainly don't want to do this, though, a it allows anyone on your local network to broadcast something to your screen. Back in college, if a TA or perhaps even professor happened to do this, we'd make them pay by doing something like:

  xv -display 192.183.282.47:0.0 -root foo.jpg

and in the middle of their lecture and foo.jpg would become their new background. Yeah, not something you want to allow a bunch of kids in a lab, two buildings away, to be able to do.

Anyway, think through how you want to share access to your screen before you do.

Here's that script:

#!/bin/bash

##
## Run commands on my Linux box who happens to be named
## longshot.
##

HOST=longshot
DISPLAY=:0.0
RP=ratpoison
cmds="saytime|sayforecaste|xeyes|nextwin|prevwin|ff|pgdn|pgup|sh|vol"
cmd=$1 ; shift
expr2=''

case $cmd in
  saytime)
    expr="$cmd" ;;
  sayforecast)
    expr="$cmd" ;;
  xeyes)
    expr="$cmd" ;;
  nextwin)
    expr="$RP -c 'next'" ;;
  prevwin)
    expr="$RP -c 'next'" ;;
  ff)
    expr="firefox $@" ;;
  pgdn)
    expr="xdotool key Next" ;;
  pgup)
    expr="xdotool key Prior" ;;
  sh)
    expr="$@" ;;
  vol)
    expr="amixer set Master $1" ;;
  *)
    echo "Usage: `basename $0` {$cmds}"
    exit ;;
esac

ssh $HOST DISPLAY=$DISPLAY $expr

if [ -n "$expr2" ] ; then
  ssh $HOST DISPLAY=$DISPLAY $expr2
fi

No comments:

Post a Comment