I got something to work. It seems that createmsgport and createiorequest are the proper system calls.
        asm
        move [4].d,a6
        ; create msgport
        jsr [a6-666]
        tst d0.d
        beq fail5
        move d0,[msgport].d
        ; createiorequest
        move [msgport].d,a0
        move $30,d0.d
        jsr [a6-654]
        tst d0.d
        beq fail6
        move d0,[ioreq].d
        ; open input.device
        move inputname,a0.d
        move [ioreq],a1.d
        move 0,d0.d
        move 0,d1.d
        jsr [a6-444]            ; opendevice
        tst d0.b
        bne fail7
        ; install input handler
        move [ioreq],a1.d
        move 9,[a1+$1C].w
        move ihheader.a,[a1+$28].d
        jsr [a6-456]            ; doio
Also need this goofy thing and an input routine.
ihheader:
        dd 0,0
        db 2,127
        dd ihname.a
        dd 0
        dd ihcode.a
ihname:
        db "great input handler",0
        ; input handler
        asm
ihcode:
        move a0.d,[a7-]
ihloop:
        move [a0+4].w,d0
        cmp $0100,d0                   ; keyboard event?
        bne ihnotkey        
        move [a0+6].w,d0
        move $7F,d1.d
        and d0,d1.w
        add keytable,d1
        move d1,a1.d
        move d0.b,[a1]
;        move 0,[a0+4].b                ; clear event
ihnotkey:
        move [a0].d,a0
        move a0.d,d0
        bne ihloop
        move [a7+],d0.d
        rts
        endasm
This receives all input though even if its window is not in focus. That's a bit awkward.