2013-10-19

WOP-35 two wheels mouse under Linux

If you have WOP-35 two wheels mouse you might this a bit interesting. I had this time very long time ago before "evdev" becom a default driver for any input device. It worked as a charm for me with "mouse" driver. But since that big "xorg.conf file blow" I've lost my second wheel. Moreover it both wheels scrols almost identically but both of them sometimes skip when I scroll.

I tried evtest program and found that it reports second wheel in a same event but with different value +/- 2 rather than first one +/- 1. I thought that is the end of second wheel, but... Behold /etc/X11/xorg.conf.d/24-input-mouse-wop35.conf I have:

# Looks like evdev doesn't report second wheel (ignore it)
Section "InputClass"
    Identifier      "Disable evdev-driven ImExPS/2 mouse"
    MatchProduct    "ImExPS/2 Generic Explorer Mouse"
    MatchDriver     "evdev"
    Option          "Ignore" "true"
EndSection
    
# Configure "mouse" driven WOP-35
Section "InputClass"
    Identifier      "ImExPS/2 mouse"
    MatchDevicePath "/dev/input/mouse*"
    MatchProduct    "ImExPS/2 Generic Explorer Mouse"
    Driver          "mouse"
    Option          "Protocol"  "ExplorerPS/2"
    Option          "Emulate3Buttons" "no"
    Option          "ZAxisMapping" "4 5 6 7"
    Option          "Buttons" "9"
    Option          "CorePointer"
EndSection

2012-12-19

Adding async in Bash

Today I had to wait for a pretty long time to get photos of hand-written pages converted to djvu/pdf with my small script. And the first idea was to get it make use of my 4 cores. First think was about using existing job control, but unfortunately it is too weak. So here is changes I had to do to get it to work:

2012-10-07

True polymorphic functions in C#

If you ever saw Haskell polymorphic functions you'll never forget that great feeling of full abstraction from who may implement typeclasses that you restrict your argument/result on. Of course OOP gives opportunity to taste some bit of that feeling when we create functions which works with base types and they naturally handles all descendant, but the way they do it is run-time polymorphism and for C# that always require heap allocated objects. Sample in this post doesn't produce box/unbox even in IL while leaving structs private (and thus in maintainable state). After JIT/AOT even if code is in separate assemblies Main() from app will cause specialization of VisitAll from library which will cause specialization of PokeVisitor from app.

2011-12-17

Vala bindings

No man who didn't tried to implement .vapi interface to C-library could fully understand me. I've gone a pretty short path through this hell and already hit so many issues...

Static field construction doesn't even happen for [Compact] classes (bye-bye RAII for library init/cleanup).

[CCode (lower_case_csuffix = "xxx")] - just makes nothing (btw, you can specify any properties and they just would be ignored).

struct don't allow other types declaration inside of it (have no idea what is the reason for that).

string get_driver(); and string dirver { get; } - is totally different things even that C-names for generated code are the same (be careful when uses them in .vapi). First one causes returned string to be freed, but second does nothing (you can try with any type). Nothing special mentioned in documentation.

After narrowing sample and putting it into .vala file you notice that get_dirver() { return "XXX"; } returns g_strdup() of returned value, but dirver { get { /* ... */ } } returns value directly.

To sort that out - you have to use all your charm to squize out of Google several letters in mail-list. 3 years and Google can't find documentation, small wiki page or blog post...

So now we are aware of the fact that default meaning owned/unowned might change depending on context. That makes sense when you want spend minimum effort (not only lines of code, but thinking) to bring another external library to Vala. But that small thing might make harm to your mind. We know that we should write string driver { owned get; } if you want caller to be responsible for removing object.

    [Compact]
    [CCode (cname = "char", free_function = "cpufreq_put_driver")]
    public class Driver : string {
    }

    [SimpleType]
    [Immutable]
    [CCode (cname = "unsigned int", cprefix = "cpufreq_")]
    public struct Cpu : uint {
        public Driver driver { owned get; }
    }
 

But if that would be all problems, I have had, I wouldn't write this post at all...

2011-12-15

Unboxed arrays in Haskell

There is a great idea of Data.Ix implemented for nice and fast Data.Array.Unboxed and others. That allows to form arrays, matrices and other schemas (even triangles) of data access. To gain that flexibility we separate storage implementation (i.e. continous sequence of bytes) from indexing schema implementation.
But sometimes we need a way to access more complex objects and still have that magic Unboxed storage. I.e. instead of accessing single object we need two of them. Once again mighty of Haskell type system comes to save us. Just add another index axis and hide it in the same way how Ix do.

2011-10-14

Hand-made allocator

Today I was asked at interview to write my own allocator in ANSI C. Pretty strange task as for me. You need some time to debug and doing that at paper is awful. So I've put simple single-listed allocator without merging free space. And of course I forgot to hanle some simple cases.

Let's see how it should look:

2011-08-17

Code path securing

I'd like to highlight difference in the way we secure code/calculation path in Haskell and C++

Since in Haskell we have no any creation/calculation we use type-level protection by injecting polymorphic object ("token") that should be passed (actually type is passed) to each function that requires access to our secure type (with phantom type "token")

2011-01-28

Do you like ad-hoc polymorphism like I do?..

Sometimes I feel that C++ is more about doing something that you want in a some weird way and do it on many pages of code.
With Haskell I have another feeling - when I do something with it I understand what I wanted by reading it in a slim snipet of code.
Part of vector-space package from Haskell may look like:

2010-12-25

Nested workspaces

For those who miss old nest_ws.lua the new API of Ion3 allows you to attach new tiling workspace to current WMPlex with:
_:attach_new({type="WGroupWS", switchto=true}):attach_new({type="WTiling", sizepolicy="full", bottom=true})
So your submenu, probably will look like:
defmenu("menuattach", {
    menuentry("Float WS", "_:attach_new({type=\"WGroupWS\", switchto=true})"),
    menuentry("Tiling WS", "_:attach_new({type=\"WGroupWS\", switchto=true}):attach_new({type=\"WTiling\", sizepolicy=\"full\", bottom=true})"),
})
As I understand there is no more pane workspace.
P.S. That's true for ion3-20090110

2010-12-11

Generics+specialization vs plain Interfaces.

For those who is interested in what comes out of generics and interfaces uses. Let's look at example:

2010-06-08

intset

There is std::vector specialization known as bit_vector. In the same way there may exist set of integers by using pages of bits accessed through std::map.

2010-04-25

Isn't that funny?...
class SuperType a b c | a b -> c
class Coerce a b where
    coerce :: a -> b

instance (Coerce a c, Coerce b d) => Coerce (a, b) (c, d) where
    coerce (a, b) = (coerce a, coerce b)

coerceSuper :: (SuperType a b c, Coerce a c, Coerce b c) => (a, b) -> (c, c)
coerceSuper = coerce

instance (Integral a, Integral b) => SuperType a b Integer
    -- I'm too lazy to enumerate supertype for all pairs

instance Integral a => Coerce a Integer where coerce = toInteger

-- ANum
class (Integral a, Num a) => NumCoerce a
instance (Integral a, Num a) => NumCoerce a

data ANum = forall a . NumCoerce a => ANum a

instance Show ANum where showsPrec n (ANum a) = showsPrec n a

instance Eq ANum where
    (ANum a) == (ANum b) = (uncurry (==) . coerceSuper) (a,b)

instance Num ANum where
    (ANum a) + (ANum b) = (ANum . uncurry (+) . coerceSuper) (a,b)
    (ANum a) * (ANum b) = (ANum . uncurry (*) . coerceSuper) (a,b)
    (ANum a) - (ANum b) = (ANum . uncurry (-) . coerceSuper) (a,b)
    negate (ANum a) = ANum (negate a)
    abs (ANum a) = ANum (abs a)
    signum (ANum a) = ANum (signum a)
    fromInteger = ANum
One thing I really miss is nice way to create type-sets like NumCoerce a

2010-01-21

By some reason Data.Decimal from Decimal-0.1.0 misses instance for Fractional instance Integral i => Fractional (DecimalRaw i) where (Decimal _ 0) / (Decimal _ ym) | ym /= 0 = Decimal 0 0 (Decimal p0 m0) / (Decimal 0 d) = divRem (Decimal p0 0) m0 where divRem z 0 = z -- out of decimalPlaces divRem (Decimal p m) r | p == maxBound = Decimal p (m + dm) where -- round for last digit dm | r'*2 >= d = dm0+1 | otherwise = dm0 (dm0, r') = r `divMod` d divRem (Decimal p m) r | r < d = divRem (Decimal (p+1) (m*10)) (r*10) divRem (Decimal p m) r = divRem (Decimal p (m+dm)) r' where (dm, r') = r `divMod` d -- divide decimalPlaces (Decimal xp xm) / (Decimal yp ym) | yp <= xp = Decimal (xp-yp) xm / Decimal 0 ym | otherwise = Decimal 0 (xm * (10^(yp-xp))) / Decimal 0 ym fromRational r = fromIntegral (numerator r) / fromIntegral (denominator r) class Scalable a where scale :: Integral b => Ratio b -> a -> a ratio :: Integral b => a -> a -> Ratio b instance Integral a => Scalable (DecimalRaw a) where r `scale` x = (x * n) / d where n = fromIntegral (numerator r) d = fromIntegral (denominator r) (Decimal xp xm) `ratio` (Decimal yp ym) = (fromIntegral xm * (10^yp)) % (fromIntegral ym * (10^xp))

2009-12-21

List processors, request/response map

Once I tried to implement TigerHash in Haskell. Pure implementation was very slow no matter how did I tried to optimize it and I switched to foreign implementation in C. As most of hash function it need to store intermediate state between calls to update to process long streams. So interface in haskell consist of init/reset/update/finalize. But implementing only tigerHash function means that it will create and destroy context at each call. To avoid that I thought that I can make tigerHashList which will hold context while processing the list. That was pretty easy to use that tigerHashList when you have to just mapM_ print (tigerHashList $ map getContents files) or something like that. But when you will need to calculate something complicated which the way to use that function isn't so straight. For example:
out = tigerHashList (inp out)
inp ~(nextHash:ys) = nextFile : walk nextHash files ys
And there you have two choices: to make tigerHashMonad or to wrap that tigerHashList. As I did used "list processors" several times before:
newtype LPMonad a b c = LPMonad { unLPMonad :: [b] -> ([a] -> [a], c, [b]) }

runLPMonad :: LPMonad a b c -> ([a] -> [b]) -> c
runLPMonad m f = r where
    (inp, r, _) = unLPMonad m out
    out = f (inp [])

request :: a -> LPMonad a b b
request x = LPMonad (\ ~(y:ys) -> ((x:), y, ys) )

instance Monad (LPMonad a b) where
    return z = LPMonad (\ ys -> (id, z, ys))
    m >>= f = LPMonad next where
        next ys = (inp . inp', r', ys'') where
            (inp, r, ys') = unLPMonad m ys
            (inp', r', ys'') = unLPMonad (f r) ys'

data Action = Withdraw Int
            | Deposit Int
            | Receipt
            | Balance Int


account :: Int -> [Action] -> [Int]
account balance (Withdraw amount : xs) = balance' : account balance' xs where balance' = balance - amount
account balance (Deposit amount : xs) = balance' : account balance' xs where balance' = balance + amount
account balance (Receipt : xs) = balance : account balance xs
account balance (Balance amount : xs) = (amount - balance) : account balance xs


test1 = do
    request $ Deposit 200
    request $ Withdraw 50
    x <- request Receipt
    request $ Withdraw 50
    y <- request $ Balance 100
    return (x,y)

{-
tth = tree . splitBlocks 1024 where
    tree xs = runLPMonad (getHash 0 (length xs)) tigerHashList where
        getHash n 1 = request (xs !! n)
        getHash n m = do
            let l = m `div` 2
            a <- getHash n l
            b <- getHash (n+l) (m-l)
            request . runPut $ do
                putWord8 1
                put a
                put b
-}

main = do
    print (runLPMonad test1 (account 1))
P.S. simplified example from Curry's (MCC) Ports library.