Archive for March 2012

LXDE and multiple screens: replacing lxrandr with a script

When using Gnome3 I was really impressed with the support for multiple screens. Then I switched to LXDE and was very disappointed in that desktop’s support for multiple screens. In fact so disappointed that I sat down and read the man-page for ‘randr’ and hacked up the following script:

#! /bin/bash
 
cmd=$1; shift
 
case $cmd in
    on)
        # turn on VGA1, auto-select size, right of laptop screen
        xrandr --output VGA1 --auto --right-of LVDS1
        ;;
    off)
        xrandr --output VGA1 --off
        ;;
    list)
        xrandr
        ;;
    *)
        echo "Commands: on, off, list"
esac

In my mind it’s vastly more usable than ‘lxrandr’ :)

0MQ and Haskell

Ever since I heard the FLOSS weekly episode on 0MQ I’ve been looking for a reason to take a look at it. Well, to hell with reason, I’ll have a first look without any specific goal in mind.

I found a simple introduction to it in Nicholas PiĆ«l’s post ZeroMQ an introduction. The only issue was that it was based on Python, and Python2 at that. So here are my attempts at translating two of the clients to Haskell (using zeromq-haskell).

req-rep

Here’s the client in Python3 first:

1
2
3
4
5
6
7
8
9
10
11
import zmq
 
ctx = zmq.Context()
socket = ctx.socket(zmq.REQ)
socket.connect('tcp://127.0.0.1:5000')
 
for i in range(10):
    msg = "msg %s" % i
    socket.send_unicode(msg)
    print('Sending', msg)
    msg_in = socket.recv()

And here in Haskell:

1
2
3
4
5
6
7
8
9
10
import System.ZMQ
import Data.ByteString.Char8 as CBS
 
main = withContext 1 $ \ ctx -> withSocket ctx Req $ \ soc -> do
    connect soc "tcp://127.0.0.1:5000"
    let msgs = [pack ("msg " ++ show i) | i <- [0..9]]
    flip mapM_ msgs $ \ msg -> do
        send soc msg []
        CBS.putStrLn msg
        receive soc []

pub-sub

In Python3:

1
2
3
4
5
6
7
8
9
10
import zmq
 
ctx = zmq.Context()
socket = ctx.socket(zmq.SUB)
socket.connect('tcp://127.0.0.1:5000')
socket.setsockopt(zmq.SUBSCRIBE, b'sweden')
socket.setsockopt(zmq.SUBSCRIBE, b'denmark')
 
while True:
    print(socket.recv())

Haskell:

1
2
3
4
5
6
7
8
9
import System.ZMQ
import Control.Monad
import Data.ByteString.Char8 as CBS
 
main = withContext 1 $ \ ctx -> withSocket ctx Sub $ \ soc -> do
    connect soc "tcp://127.0.0.1:5000"
    subscribe soc "sweden"
    subscribe soc "denmark"
    forever $ receive soc [] >>= CBS.putStrLn

Two comments on the Haskell code here:

  • I’m not sure why, but the Haskell client dies after receiving just a few messages (they are properly filtered though).
  • The API for subscribe is a bit strange, it would make more sense if it took a ByteString rather than a String.