Remove Nim libraries
Libraries moved to https://github.com/ehmry/nim-genode
This commit is contained in:
committed by
Norman Feske
parent
a67a5de5ef
commit
affa36eb2d
@@ -1,151 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Audio_out client
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import genode
|
|
||||||
|
|
||||||
const
|
|
||||||
Header = "<audio_out_session/connection.h>"
|
|
||||||
PacketPeriod* = 512
|
|
||||||
PacketQueueSize* = 256
|
|
||||||
|
|
||||||
type
|
|
||||||
Packet* = ptr PacketObj
|
|
||||||
PacketObj {.importcpp: "Audio_out::Packet", header: Header, pure.} = object
|
|
||||||
|
|
||||||
PeriodBuffer* = ptr array[PacketPeriod, cfloat]
|
|
||||||
StereoPacket* = tuple
|
|
||||||
left, right: Packet
|
|
||||||
|
|
||||||
proc content(pkt: Packet | PacketObj): PeriodBuffer {.importcpp.}
|
|
||||||
proc played(pkt: Packet | PacketObj): bool {.importcpp.}
|
|
||||||
proc valid(pkt: Packet | PacketObj): bool {.importcpp.}
|
|
||||||
proc invalidate(pkt: Packet | PacketObj) {.importcpp.}
|
|
||||||
proc mark_as_played(pkt: Packet | PacketObj) {.importcpp.}
|
|
||||||
|
|
||||||
proc buffer*(pkt: Packet): PeriodBuffer = cast[PeriodBuffer](pkt.content())
|
|
||||||
|
|
||||||
proc `[]`*(pkt: Packet; i: int): float32 {.importcpp: "#->content()[#] ".}
|
|
||||||
|
|
||||||
proc `[]=`*(pkt: Packet; i: int; x: float32) {.importcpp: "#->content()[#] = #".}
|
|
||||||
|
|
||||||
proc `[]=`*(pkt: Packet; i: int; x: int16) {.importcpp: "#->content()[#] = # / 32768.0".}
|
|
||||||
|
|
||||||
type
|
|
||||||
Stream = ptr StreamObj
|
|
||||||
StreamObj {.importcpp: "Audio_out::Stream", header: Header, pure.} = object
|
|
||||||
|
|
||||||
proc pos(s: Stream): cuint {.importcpp.}
|
|
||||||
proc tail(s: Stream): cuint {.importcpp.}
|
|
||||||
proc queued(s: Stream): cuint {.importcpp.}
|
|
||||||
proc next(s: Stream): Packet {.importcpp.}
|
|
||||||
proc next(s: Stream; p: Packet): Packet {.importcpp.}
|
|
||||||
proc packet_position(s: Stream): Packet {.importcpp.}
|
|
||||||
proc packet_position(s: Stream; p: Packet): cuint {.importcpp.}
|
|
||||||
proc empty(s: Stream): bool {.importcpp.}
|
|
||||||
proc full(s: Stream): bool {.importcpp.}
|
|
||||||
proc get(s: Stream; pos: cuint): Packet {.importcpp.}
|
|
||||||
proc alloc(s: Stream): Packet {.importcpp.}
|
|
||||||
proc reset(s: Stream) {.importcpp.}
|
|
||||||
proc invalidate_all(s: Stream) {.importcpp.}
|
|
||||||
proc pos(s: Stream; p: cuint) {.importcpp.}
|
|
||||||
proc increment_position(s: Stream; p: cuint) {.importcpp.}
|
|
||||||
|
|
||||||
type
|
|
||||||
ConnectionBase {.
|
|
||||||
importcpp: "Audio_out::Connection", header: Header.} = object
|
|
||||||
Connection = Constructible[ConnectionBase]
|
|
||||||
|
|
||||||
AudioOutClient* = ref AudioOutClientObj
|
|
||||||
AudioOutClientObj = object
|
|
||||||
left, right: Connection
|
|
||||||
|
|
||||||
proc construct(conn: Connection; label: cstring) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#.construct(*genodeEnv, @, false, false)".}
|
|
||||||
|
|
||||||
proc destruct(conn: Connection) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#.destruct()".}
|
|
||||||
|
|
||||||
proc stream(conn: Connection): Stream {.importcpp: "#->stream()".}
|
|
||||||
|
|
||||||
proc start(conn: Connection) {.tags: [RpcEffect], importcpp: "#->start()".}
|
|
||||||
proc stop(conn: Connection) {.tags: [RpcEffect], importcpp: "#->stop()".}
|
|
||||||
|
|
||||||
proc progress_sigh(conn: Connection; sig: SignalContextCapability) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->progress_sigh(#)".}
|
|
||||||
|
|
||||||
proc alloc_sigh(conn: Connection; sig: SignalContextCapability) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->alloc_sigh(#)".}
|
|
||||||
|
|
||||||
proc submit(conn: Connection; pkt: Packet) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->submit(#)".}
|
|
||||||
|
|
||||||
proc newAudioOutClient*(): AudioOutClient =
|
|
||||||
new result
|
|
||||||
result.left.construct("left")
|
|
||||||
result.right.construct("right")
|
|
||||||
|
|
||||||
proc close*(dac: AudioOutClient) {.tags: [RpcEffect].} =
|
|
||||||
destruct dac.left
|
|
||||||
destruct dac.right
|
|
||||||
|
|
||||||
proc start*(dac: AudioOutClient) =
|
|
||||||
start dac.left
|
|
||||||
start dac.right
|
|
||||||
|
|
||||||
proc stop*(dac: AudioOutClient) =
|
|
||||||
stop dac.left
|
|
||||||
stop dac.right
|
|
||||||
|
|
||||||
proc setAllocSigh*(dac: AudioOutClient; cap: SignalContextCapability) =
|
|
||||||
## Install a signal handler to detect when the packet buffer ceases to be full.
|
|
||||||
dac.left.alloc_sigh cap
|
|
||||||
|
|
||||||
proc setProgressSigh*(dac: AudioOutClient; cap: SignalContextCapability) =
|
|
||||||
## Install a signal handler to detect when a packet had been played.
|
|
||||||
dac.left.progress_sigh cap
|
|
||||||
|
|
||||||
proc queued*(dac: AudioOutClient): uint =
|
|
||||||
## Return the number of packets queued.
|
|
||||||
dac.left.stream.queued
|
|
||||||
|
|
||||||
proc full*(dac: AudioOutClient): bool =
|
|
||||||
## Check if the packet stream is full.
|
|
||||||
dac.left.stream.full
|
|
||||||
|
|
||||||
iterator tailSubmission*(dac: AudioOutClient): Packet =
|
|
||||||
## Return the packets and the end of the buffer then submit.
|
|
||||||
doAssert(not dac.full, "cannot submit packets, stream is full")
|
|
||||||
let
|
|
||||||
lp = dac.left.stream.alloc()
|
|
||||||
rp = dac.right.stream.alloc()
|
|
||||||
yield lp
|
|
||||||
yield rp
|
|
||||||
dac.left.submit lp
|
|
||||||
dac.left.submit rp
|
|
||||||
|
|
||||||
proc next*(dac: AudioOutClient): StereoPacket =
|
|
||||||
## Return the successive packets from the current playback position.
|
|
||||||
(dac.left.stream.next, dac.right.stream.next)
|
|
||||||
|
|
||||||
proc next*(dac: AudioOutClient, pkts: StereoPacket): StereoPacket =
|
|
||||||
## Return the successive packets from the packet buffers.
|
|
||||||
(dac.left.stream.next(pkts.left), dac.right.stream.next(pkts.right))
|
|
||||||
|
|
||||||
proc alloc*(dac: AudioOutClient): StereoPacket =
|
|
||||||
## Return the first pair of unused packets.
|
|
||||||
(dac.left.stream.alloc(), dac.right.stream.alloc())
|
|
||||||
|
|
||||||
proc submit*(dac: AudioOutClient, pkts: StereoPacket) =
|
|
||||||
## Mark a pair of packets as active and wake the servers.
|
|
||||||
dac.left.submit pkts.left
|
|
||||||
dac.right.submit pkts.right
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Base Genode support for Nim
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
when not defined(genode) or defined(nimdoc):
|
|
||||||
{.error: "Genode only module".}
|
|
||||||
|
|
||||||
type RpcEffect* = object of RootEffect
|
|
||||||
## Effect describing a synchronous client-side RPC.
|
|
||||||
|
|
||||||
#
|
|
||||||
# C++ utilities
|
|
||||||
#
|
|
||||||
|
|
||||||
type Constructible* {.
|
|
||||||
importcpp: "Genode::Constructible", header: "<util/reconstructible.h>", final, pure.} [T] = object
|
|
||||||
|
|
||||||
proc construct*[T](x: Constructible[T]) {.importcpp.}
|
|
||||||
## Construct a constructible C++ object.
|
|
||||||
|
|
||||||
proc destruct*[T](x: Constructible[T]) {.importcpp.}
|
|
||||||
## Destruct a constructible C++ object.
|
|
||||||
|
|
||||||
#
|
|
||||||
# Signals
|
|
||||||
#
|
|
||||||
|
|
||||||
const SignalsH = "nim/signals.h"
|
|
||||||
|
|
||||||
type
|
|
||||||
SignalContextCapability* {.
|
|
||||||
importcpp: "Genode::Signal_context_capability",
|
|
||||||
header: "<base/signal.h>", final, pure.} = object
|
|
||||||
## Capability to an asynchronous signal context.
|
|
||||||
|
|
||||||
SignalDispatcherCpp {.importcpp, header: SignalsH, final, pure.} = object
|
|
||||||
cap {.importcpp.}: SignalContextCapability
|
|
||||||
|
|
||||||
SignalDispatcher* = ref object
|
|
||||||
## Nim object enclosing a Genode signal dispatcher.
|
|
||||||
cpp: SignalDispatcherCpp
|
|
||||||
handler*: proc() {.closure.}
|
|
||||||
|
|
||||||
proc init(cpp: SignalDispatcherCpp; sh: SignalDispatcher)
|
|
||||||
{.importcpp: "#.init(&genodeEnv->ep(), #)".}
|
|
||||||
|
|
||||||
proc deinit(sd: SignalDispatcherCpp) {.importcpp.}
|
|
||||||
|
|
||||||
proc newSignalDispatcher*(label = "unspecified"): SignalDispatcher =
|
|
||||||
## Create a new signal dispatcher. A label is recommended for
|
|
||||||
## debugging purposes. A signal dispatcher will not be garbage
|
|
||||||
## collected until after it has been dissolved.
|
|
||||||
new result
|
|
||||||
init result.cpp, result
|
|
||||||
GCref result
|
|
||||||
|
|
||||||
proc dissolve*(sig: SignalDispatcher) =
|
|
||||||
## Dissolve signal dispatcher from entrypoint.
|
|
||||||
deinit sig.cpp
|
|
||||||
sig.handler = nil
|
|
||||||
GCunref sig
|
|
||||||
|
|
||||||
proc cap*(sig: SignalDispatcher): SignalContextCapability = sig.cpp.cap
|
|
||||||
## Signal context capability. Can be delegated to external components.
|
|
||||||
|
|
||||||
proc nimHandleSignal(p: pointer) {.exportc.} =
|
|
||||||
## C symbol invoked by entrypoint during signal dispatch.
|
|
||||||
let dispatch = cast[SignalDispatcher](p)
|
|
||||||
if not dispatch.handler.isNil:
|
|
||||||
dispatch.handler()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Sessions
|
|
||||||
#
|
|
||||||
|
|
||||||
type SessionCapability* {.
|
|
||||||
importcpp: "Genode::Session_capability",
|
|
||||||
header: "<session/capability.h>", final, pure.} = object
|
|
||||||
## Capability to a session.
|
|
||||||
|
|
||||||
#
|
|
||||||
# Dataspaces
|
|
||||||
#
|
|
||||||
|
|
||||||
import streams
|
|
||||||
|
|
||||||
type
|
|
||||||
DataspaceCapability* {.
|
|
||||||
importcpp: "Genode::Dataspace_capability", header: "dataspace/capability.h".} = object
|
|
||||||
|
|
||||||
proc isValid*(cap: DataspaceCapability): bool {.
|
|
||||||
importcpp: "#.valid()", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc size*(cap: DataspaceCapability): int {.
|
|
||||||
importcpp: "Genode::Dataspace_client(@).size()", header: "dataspace/client.h",
|
|
||||||
tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc allocDataspace*(size: int): DataspaceCapability {.
|
|
||||||
importcpp: "genodeEnv->pd().alloc(#)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc freeDataspace*(cap: DataspaceCapability) {.
|
|
||||||
importcpp: "genodeEnv->pd().free(#)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc attach*(cap: DataspaceCapability): ByteAddress {.
|
|
||||||
importcpp: "genodeEnv->rm().attach(@)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc detach*(p: ByteAddress) {.
|
|
||||||
importcpp: "genodeEnv->rm().detach(@)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
type
|
|
||||||
DataspaceStream* = ref DataspaceStreamObj
|
|
||||||
## A stream that provides safe access to dataspace content
|
|
||||||
DataspaceStreamObj* = object of StreamObj
|
|
||||||
cap: DataspaceCapability
|
|
||||||
base: ByteAddress
|
|
||||||
size: int
|
|
||||||
pos: int
|
|
||||||
|
|
||||||
proc size*(ds: DataspaceStream): int = ds.size
|
|
||||||
|
|
||||||
proc dsClose(s: Stream) =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
if s.base != 0:
|
|
||||||
detach s.base
|
|
||||||
s.base = 0
|
|
||||||
s.size = 0
|
|
||||||
s.pos = 0
|
|
||||||
|
|
||||||
proc dsAtEnd(s: Stream): bool =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
result = s.pos <= s.size
|
|
||||||
|
|
||||||
proc dsSetPosition(s: Stream, pos: int) =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
s.pos = clamp(pos, 0, s.size)
|
|
||||||
|
|
||||||
proc dsGetPosition(s: Stream): int =
|
|
||||||
result = DataspaceStream(s).pos
|
|
||||||
|
|
||||||
proc dsPeekData(s: Stream, buffer: pointer, bufLen: int): int =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
result = min(bufLen, s.size - s.pos)
|
|
||||||
if result > 0:
|
|
||||||
copyMem(buffer, cast[pointer](cast[int](s.base) + s.pos), result)
|
|
||||||
|
|
||||||
proc dsReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
result = min(bufLen, s.size - s.pos)
|
|
||||||
if result > 0:
|
|
||||||
copyMem(buffer, cast[pointer](cast[int](s.base) + s.pos), result)
|
|
||||||
inc(s.pos, result)
|
|
||||||
|
|
||||||
proc dsWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
|
||||||
var s = DataspaceStream(s)
|
|
||||||
let count = clamp(bufLen, 0, s.size - s.pos)
|
|
||||||
copyMem(cast[pointer](cast[int](s.base) + s.pos), buffer, count)
|
|
||||||
inc(s.pos, count)
|
|
||||||
|
|
||||||
proc newDataspaceStream*(cap: DataspaceCapability): DataspaceStream =
|
|
||||||
result = DataspaceStream(
|
|
||||||
closeImpl: dsClose,
|
|
||||||
atEndImpl: dsAtEnd,
|
|
||||||
setPositionImpl: dsSetPosition,
|
|
||||||
getPositionImpl: dsGetPosition,
|
|
||||||
readDataImpl: dsReadData,
|
|
||||||
peekDataImpl: dsPeekData,
|
|
||||||
writeDataImpl: dsWriteData)
|
|
||||||
if cap.isValid:
|
|
||||||
result.cap = cap
|
|
||||||
result.base = attach cap
|
|
||||||
result.size = cap.size
|
|
||||||
|
|
||||||
proc update*(ds: DataspaceStream; cap: DataspaceCapability) =
|
|
||||||
ds.pos = 0
|
|
||||||
if cap.isValid:
|
|
||||||
ds.cap = cap
|
|
||||||
ds.base = attach cap
|
|
||||||
ds.size = cap.size
|
|
||||||
else:
|
|
||||||
ds.base = 0
|
|
||||||
ds.size = 0
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Nim utilities for Genode servers
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-12-10
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
# TODO: Provide sesion creation and destruction examples.
|
|
||||||
|
|
||||||
import parseutils, strutils, strtabs, streams,
|
|
||||||
parsexml, xmlparser, xmltree
|
|
||||||
|
|
||||||
const LabelSep = " ->"
|
|
||||||
## Pattern used to seperate session label elements.
|
|
||||||
|
|
||||||
proc lastLabelElement*(label: TaintedString): string =
|
|
||||||
## Return the last element in a session label.
|
|
||||||
let i = label.rFind LabelSep
|
|
||||||
if unlikely(i == -1):
|
|
||||||
label
|
|
||||||
else:
|
|
||||||
label[i+1+LabelSep.len..label.high]
|
|
||||||
|
|
||||||
iterator elements*(label: TaintedString): string =
|
|
||||||
## Iterate the elements of a session label from left to right.
|
|
||||||
var
|
|
||||||
buf = ""
|
|
||||||
pos = 0
|
|
||||||
while pos < label.len:
|
|
||||||
let n = parseuntil(label, buf, LabelSep, pos)
|
|
||||||
if n == 0: break
|
|
||||||
yield buf.strip
|
|
||||||
pos.inc(n + LabelSep.len+1)
|
|
||||||
|
|
||||||
proc lookupPolicy*(policies: seq[XmlNode]; label: TaintedString): XmlNode =
|
|
||||||
## Return a policy matching a given label or return nil.
|
|
||||||
# TODO: use less GC intensive parsing.
|
|
||||||
var resultScore: int
|
|
||||||
for p in policies.items:
|
|
||||||
if p.tag == "default-policy" and result.isNil:
|
|
||||||
# this is now the fallthrough policy
|
|
||||||
result = p
|
|
||||||
else:
|
|
||||||
let attrs = p.attrs
|
|
||||||
if attrs.contains "label":
|
|
||||||
if attrs["label"] == label:
|
|
||||||
# return the first policy with a label match
|
|
||||||
return p
|
|
||||||
else:
|
|
||||||
let
|
|
||||||
prefix = attrs.getOrDefault "prefix"
|
|
||||||
suffix = attrs.getOrDefault "suffix"
|
|
||||||
if label.startsWith(prefix) and label.endsWith(suffix):
|
|
||||||
# match the label against prefix and suffic (empty strings match)
|
|
||||||
let score = prefix.len*2 + suffix.len
|
|
||||||
# a prefix match is more significant that a suffix match
|
|
||||||
if score > resultScore:
|
|
||||||
# this is now the best match this far
|
|
||||||
resultScore = score
|
|
||||||
result = p
|
|
||||||
|
|
||||||
proc parseArgString*(args, key: string; default = ""): string =
|
|
||||||
## Extract a keyed value from session request arguments.
|
|
||||||
result = default
|
|
||||||
var off = args.find key
|
|
||||||
if off != -1:
|
|
||||||
off.inc key.len
|
|
||||||
if args[off] == '=' and args[off+1] == '"':
|
|
||||||
off.inc 2
|
|
||||||
off.inc parseuntil(args, result, '"', off)
|
|
||||||
if args[off] != '"':
|
|
||||||
result = default
|
|
||||||
|
|
||||||
proc parseArgInt*(args, key: string; default = -1): BiggestInt =
|
|
||||||
## Extract an integral argument from session request arguments.
|
|
||||||
result = default
|
|
||||||
var off = args.find key
|
|
||||||
if off != -1:
|
|
||||||
off.inc key.len
|
|
||||||
if args[off] == '=':
|
|
||||||
inc off
|
|
||||||
off.inc parseBiggestInt(args, result, off)
|
|
||||||
if off < args.len:
|
|
||||||
case args[off]
|
|
||||||
of ',':
|
|
||||||
discard
|
|
||||||
of 'K':
|
|
||||||
result = result shl 10
|
|
||||||
of 'M':
|
|
||||||
result = result shl 20
|
|
||||||
of 'G':
|
|
||||||
result = result shl 30
|
|
||||||
of 'P':
|
|
||||||
result = result shl 40
|
|
||||||
else:
|
|
||||||
result = -1
|
|
||||||
|
|
||||||
type SessionId* = distinct int
|
|
||||||
## Session identifier shared between
|
|
||||||
## parent and child components.
|
|
||||||
proc `==`*(x, y: SessionId): bool {.borrow.}
|
|
||||||
|
|
||||||
type
|
|
||||||
SessionRequestsParser = object
|
|
||||||
s: string
|
|
||||||
xp: XmlParser
|
|
||||||
args*: string ## Arguments of the session the parser is positioned on.
|
|
||||||
|
|
||||||
proc initSessionRequestsParser*(sessionRequestsROM: string): SessionRequestsParser =
|
|
||||||
## Initialize a parser of the Genode "session_requests" ROM.
|
|
||||||
result.s = sessionRequestsROM
|
|
||||||
result.args = ""
|
|
||||||
|
|
||||||
proc argString*(srp: var SessionRequestsParser; key: string; default = ""): string =
|
|
||||||
## Parse an string from the current session arguments.
|
|
||||||
if srp.args != "":
|
|
||||||
parseArgString(srp.args, key, default)
|
|
||||||
else:
|
|
||||||
default
|
|
||||||
|
|
||||||
proc argInt*(srp: var SessionRequestsParser; key: string; default = -1): BiggestInt =
|
|
||||||
## Parse an integer from the current session arguments.
|
|
||||||
if srp.args != "":
|
|
||||||
parseArgInt(srp.args, key, default)
|
|
||||||
else:
|
|
||||||
default
|
|
||||||
|
|
||||||
proc streamThatCanBeClosed(srp: var SessionRequestsParser): Stream {.inline.} =
|
|
||||||
# Need to create a new stream because the XML parser closes the stream
|
|
||||||
# when the XML parser is closed. And the XML parser needs to be closed,
|
|
||||||
# but that shouldn't mess up the dataspace stream that is stuck to the ROM
|
|
||||||
# client.
|
|
||||||
srp.s.newStringStream
|
|
||||||
|
|
||||||
proc next(srp: var SessionRequestsParser) {.inline.} =
|
|
||||||
next srp.xp
|
|
||||||
|
|
||||||
proc skipRest(srp: var SessionRequestsParser) =
|
|
||||||
var depth = 1
|
|
||||||
while depth > 0:
|
|
||||||
case srp.xp.kind
|
|
||||||
of xmlElementStart, xmlElementOpen: inc depth
|
|
||||||
of xmlElementEnd, xmlElementClose: dec depth
|
|
||||||
of xmlEof: break
|
|
||||||
of xmlError: raise newException(ValueError, srp.xp.errorMsg)
|
|
||||||
else: discard
|
|
||||||
next srp
|
|
||||||
|
|
||||||
iterator create*(srp: var SessionRequestsParser): tuple[id: SessionId, service, label: TaintedString] =
|
|
||||||
## Iterate over session creation requests.
|
|
||||||
let str = srp.streamThatCanBeClosed
|
|
||||||
open srp.xp, str, "session_requests"
|
|
||||||
next srp
|
|
||||||
block requestsLoop:
|
|
||||||
while true:
|
|
||||||
case srp.xp.kind:
|
|
||||||
of xmlElementOpen:
|
|
||||||
if srp.xp.elementName == "create":
|
|
||||||
next srp
|
|
||||||
block createLoop:
|
|
||||||
var result: tuple[id: SessionId, service, label: TaintedString]
|
|
||||||
srp.args.setLen 0
|
|
||||||
while srp.xp.kind == xmlAttribute:
|
|
||||||
case srp.xp.attrKey:
|
|
||||||
of "id":
|
|
||||||
result.id = srp.xp.attrValue.parseInt.SessionId
|
|
||||||
of "service":
|
|
||||||
result.service = srp.xp.attrValue
|
|
||||||
of "label":
|
|
||||||
result.label = srp.xp.attrValue
|
|
||||||
next srp
|
|
||||||
while srp.xp.kind != xmlElementClose: # skip until ``>``
|
|
||||||
next srp
|
|
||||||
next srp
|
|
||||||
if srp.xp.kind == xmlElementStart and srp.xp.elementName == "args":
|
|
||||||
next srp
|
|
||||||
while srp.xp.kind != xmlElementEnd:
|
|
||||||
if srp.xp.kind == xmlCharData:
|
|
||||||
srp.args.add srp.xp.charData
|
|
||||||
next srp
|
|
||||||
next srp
|
|
||||||
skipRest srp
|
|
||||||
yield result
|
|
||||||
else:
|
|
||||||
next srp
|
|
||||||
of xmlEof:
|
|
||||||
break requestsLoop
|
|
||||||
of xmlError:
|
|
||||||
raise newException(ValueError, srp.xp.errorMsg)
|
|
||||||
else: next srp # skip other events
|
|
||||||
close srp.xp
|
|
||||||
|
|
||||||
iterator close*(srp: var SessionRequestsParser): SessionId =
|
|
||||||
## Iterate over session close requests.
|
|
||||||
let str = srp.streamThatCanBeClosed
|
|
||||||
open srp.xp, str, "session_requests"
|
|
||||||
next srp
|
|
||||||
block requestsLoop:
|
|
||||||
while true:
|
|
||||||
case srp.xp.kind:
|
|
||||||
of xmlElementOpen:
|
|
||||||
case srp.xp.elementName:
|
|
||||||
of "close":
|
|
||||||
var id: SessionId
|
|
||||||
next srp
|
|
||||||
while srp.xp.kind == xmlAttribute:
|
|
||||||
if srp.xp.attrKey == "id":
|
|
||||||
id = srp.xp.attrValue.parseInt.SessionId
|
|
||||||
next srp
|
|
||||||
break
|
|
||||||
next srp
|
|
||||||
skipRest srp
|
|
||||||
yield id
|
|
||||||
else:
|
|
||||||
next srp
|
|
||||||
of xmlEof:
|
|
||||||
break requestsLoop
|
|
||||||
of xmlError:
|
|
||||||
raise newException(ValueError, srp.xp.errorMsg)
|
|
||||||
else: next srp # skip other events
|
|
||||||
close srp.xp
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
-d:private=public
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Input client
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import genode
|
|
||||||
include inputevent
|
|
||||||
|
|
||||||
type
|
|
||||||
InputClient* = ptr InputClientObj
|
|
||||||
InputClientObj {.importcpp: "Input::Session_client", header: "<input_session/client.h>".} = object
|
|
||||||
## Normally a Connection class is imported, but the Nitpicker connection
|
|
||||||
## contains an Input session in the form of the Rpc_client base class.
|
|
||||||
|
|
||||||
proc dataspace*(input: InputClient): DataspaceCapability {.tags: [RpcEffect], importcpp.}
|
|
||||||
|
|
||||||
proc pending*(input: InputClient): bool {.tags: [RpcEffect], importcpp.}
|
|
||||||
|
|
||||||
proc flush*(input: InputClient): int {.tags: [RpcEffect], importcpp.}
|
|
||||||
|
|
||||||
proc sigh*(input: InputClient; cap: SignalContextCapability) {.tags: [RpcEffect], importcpp.}
|
|
||||||
|
|
||||||
type EventBuffer {.unchecked.} = array[0, Event]
|
|
||||||
## Type to represent an unbounded Event array.
|
|
||||||
|
|
||||||
proc eventBuffer*(input: InputClient): ptr EventBuffer {.
|
|
||||||
importcpp: "#->_event_ds.local_addr<void>()".}
|
|
||||||
## Requires breaking the C++ private/public rules.
|
|
||||||
|
|
||||||
iterator events*(input: InputClient): Event =
|
|
||||||
## Flush and iterate over input events.
|
|
||||||
let
|
|
||||||
buf = input.eventBuffer
|
|
||||||
n = flush input
|
|
||||||
for i in 0..<n:
|
|
||||||
yield buf[i]
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Input event descriptions
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
const InputH = "<input/event.h>"
|
|
||||||
|
|
||||||
include keycodes
|
|
||||||
|
|
||||||
type
|
|
||||||
Event* {.importcpp: "Input::Event", header: InputH.} = object
|
|
||||||
Type* {.importcpp: "Input::Event::Type", header: InputH.} = enum
|
|
||||||
INVALID, MOTION, PRESS, RELEASE, WHEEL, FOCUS, LEAVE, TOUCH, CHARACTER
|
|
||||||
|
|
||||||
proc typ*(ev: Event): Type {.importcpp: "#.type()".}
|
|
||||||
proc code*(ev: Event): KeyCode {.importcpp.}
|
|
||||||
proc ax*(ev: Event): cint {.importcpp.}
|
|
||||||
proc ay*(ev: Event): cint {.importcpp.}
|
|
||||||
proc rx*(ev: Event): cint {.importcpp.}
|
|
||||||
proc ry*(ev: Event): cint {.importcpp.}
|
|
||||||
|
|
||||||
proc key_name(c: KeyCode): cstring {.
|
|
||||||
importcpp: "Input::key_name(#)", header: InputH.}
|
|
||||||
proc `$`*(c: KeyCode): string = $key_name(c)
|
|
||||||
|
|
||||||
proc lookupKey*(s: string): KeyCode =
|
|
||||||
result = KEY_UNKNOWN.KeyCode
|
|
||||||
for k in 0..<KEY_MAX.KeyCode:
|
|
||||||
if $(k.KeyCode) == s:
|
|
||||||
result = k.KeyCode
|
|
||||||
break
|
|
||||||
@@ -1,441 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Input keycode definitions
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import inputevent
|
|
||||||
|
|
||||||
type KeyCode* = cint
|
|
||||||
|
|
||||||
type KeyCodes* = enum
|
|
||||||
KEY_RESERVED = 0.Keycode,
|
|
||||||
KEY_ESC = 1.Keycode,
|
|
||||||
KEY_1 = 2.Keycode,
|
|
||||||
KEY_2 = 3.Keycode,
|
|
||||||
KEY_3 = 4.Keycode,
|
|
||||||
KEY_4 = 5.Keycode,
|
|
||||||
KEY_5 = 6.Keycode,
|
|
||||||
KEY_6 = 7.Keycode,
|
|
||||||
KEY_7 = 8.Keycode,
|
|
||||||
KEY_8 = 9.Keycode,
|
|
||||||
KEY_9 = 10.Keycode,
|
|
||||||
KEY_0 = 11.Keycode,
|
|
||||||
KEY_MINUS = 12.Keycode,
|
|
||||||
KEY_EQUAL = 13.Keycode,
|
|
||||||
KEY_BACKSPACE = 14.Keycode,
|
|
||||||
KEY_TAB = 15.Keycode,
|
|
||||||
KEY_Q = 16.Keycode,
|
|
||||||
KEY_W = 17.Keycode,
|
|
||||||
KEY_E = 18.Keycode,
|
|
||||||
KEY_R = 19.Keycode,
|
|
||||||
KEY_T = 20.Keycode,
|
|
||||||
KEY_Y = 21.Keycode,
|
|
||||||
KEY_U = 22.Keycode,
|
|
||||||
KEY_I = 23.Keycode,
|
|
||||||
KEY_O = 24.Keycode,
|
|
||||||
KEY_P = 25.Keycode,
|
|
||||||
KEY_LEFTBRACE = 26.Keycode,
|
|
||||||
KEY_RIGHTBRACE = 27.Keycode,
|
|
||||||
KEY_ENTER = 28.Keycode,
|
|
||||||
KEY_LEFTCTRL = 29.Keycode,
|
|
||||||
KEY_A = 30.Keycode,
|
|
||||||
KEY_S = 31.Keycode,
|
|
||||||
KEY_D = 32.Keycode,
|
|
||||||
KEY_F = 33.Keycode,
|
|
||||||
KEY_G = 34.Keycode,
|
|
||||||
KEY_H = 35.Keycode,
|
|
||||||
KEY_J = 36.Keycode,
|
|
||||||
KEY_K = 37.Keycode,
|
|
||||||
KEY_L = 38.Keycode,
|
|
||||||
KEY_SEMICOLON = 39.Keycode,
|
|
||||||
KEY_APOSTROPHE = 40.Keycode,
|
|
||||||
KEY_GRAVE = 41.Keycode,
|
|
||||||
KEY_LEFTSHIFT = 42.Keycode,
|
|
||||||
KEY_BACKSLASH = 43.Keycode,
|
|
||||||
KEY_Z = 44.Keycode,
|
|
||||||
KEY_X = 45.Keycode,
|
|
||||||
KEY_C = 46.Keycode,
|
|
||||||
KEY_V = 47.Keycode,
|
|
||||||
KEY_B = 48.Keycode,
|
|
||||||
KEY_N = 49.Keycode,
|
|
||||||
KEY_M = 50.Keycode,
|
|
||||||
KEY_COMMA = 51.Keycode,
|
|
||||||
KEY_DOT = 52.Keycode,
|
|
||||||
KEY_SLASH = 53.Keycode,
|
|
||||||
KEY_RIGHTSHIFT = 54.Keycode,
|
|
||||||
KEY_KPASTERISK = 55.Keycode,
|
|
||||||
KEY_LEFTALT = 56.Keycode,
|
|
||||||
KEY_SPACE = 57.Keycode,
|
|
||||||
KEY_CAPSLOCK = 58.Keycode,
|
|
||||||
KEY_F1 = 59.Keycode,
|
|
||||||
KEY_F2 = 60.Keycode,
|
|
||||||
KEY_F3 = 61.Keycode,
|
|
||||||
KEY_F4 = 62.Keycode,
|
|
||||||
KEY_F5 = 63.Keycode,
|
|
||||||
KEY_F6 = 64.Keycode,
|
|
||||||
KEY_F7 = 65.Keycode,
|
|
||||||
KEY_F8 = 66.Keycode,
|
|
||||||
KEY_F9 = 67.Keycode,
|
|
||||||
KEY_F10 = 68.Keycode,
|
|
||||||
KEY_NUMLOCK = 69.Keycode,
|
|
||||||
KEY_SCROLLLOCK = 70.Keycode,
|
|
||||||
KEY_KP7 = 71.Keycode,
|
|
||||||
KEY_KP8 = 72.Keycode,
|
|
||||||
KEY_KP9 = 73.Keycode,
|
|
||||||
KEY_KPMINUS = 74.Keycode,
|
|
||||||
KEY_KP4 = 75.Keycode,
|
|
||||||
KEY_KP5 = 76.Keycode,
|
|
||||||
KEY_KP6 = 77.Keycode,
|
|
||||||
KEY_KPPLUS = 78.Keycode,
|
|
||||||
KEY_KP1 = 79.Keycode,
|
|
||||||
KEY_KP2 = 80.Keycode,
|
|
||||||
KEY_KP3 = 81.Keycode,
|
|
||||||
KEY_KP0 = 82.Keycode,
|
|
||||||
KEY_KPDOT = 83.Keycode,
|
|
||||||
|
|
||||||
KEY_ZENKAKUHANKAKU = 85.Keycode,
|
|
||||||
KEY_102ND = 86.Keycode,
|
|
||||||
KEY_F11 = 87.Keycode,
|
|
||||||
KEY_F12 = 88.Keycode,
|
|
||||||
KEY_RO = 89.Keycode,
|
|
||||||
KEY_KATAKANA = 90.Keycode,
|
|
||||||
KEY_HIRAGANA = 91.Keycode,
|
|
||||||
KEY_HENKAN = 92.Keycode,
|
|
||||||
KEY_KATAKANAHIRAGANA = 93.Keycode,
|
|
||||||
KEY_MUHENKAN = 94.Keycode,
|
|
||||||
KEY_KPJPCOMMA = 95.Keycode,
|
|
||||||
KEY_KPENTER = 96.Keycode,
|
|
||||||
KEY_RIGHTCTRL = 97.Keycode,
|
|
||||||
KEY_KPSLASH = 98.Keycode,
|
|
||||||
KEY_SYSRQ = 99.Keycode,
|
|
||||||
KEY_RIGHTALT = 100.Keycode,
|
|
||||||
KEY_LINEFEED = 101.Keycode,
|
|
||||||
KEY_HOME = 102.Keycode,
|
|
||||||
KEY_UP = 103.Keycode,
|
|
||||||
KEY_PAGEUP = 104.Keycode,
|
|
||||||
KEY_LEFT = 105.Keycode,
|
|
||||||
KEY_RIGHT = 106.Keycode,
|
|
||||||
KEY_END = 107.Keycode,
|
|
||||||
KEY_DOWN = 108.Keycode,
|
|
||||||
KEY_PAGEDOWN = 109.Keycode,
|
|
||||||
KEY_INSERT = 110.Keycode,
|
|
||||||
KEY_DELETE = 111.Keycode,
|
|
||||||
KEY_MACRO = 112.Keycode,
|
|
||||||
KEY_MUTE = 113.Keycode,
|
|
||||||
KEY_VOLUMEDOWN = 114.Keycode,
|
|
||||||
KEY_VOLUMEUP = 115.Keycode,
|
|
||||||
KEY_POWER = 116.Keycode,
|
|
||||||
KEY_KPEQUAL = 117.Keycode,
|
|
||||||
KEY_KPPLUSMINUS = 118.Keycode,
|
|
||||||
KEY_PAUSE = 119.Keycode,
|
|
||||||
|
|
||||||
KEY_KPCOMMA = 121.Keycode,
|
|
||||||
KEY_HANGUEL = 122.Keycode,
|
|
||||||
KEY_HANJA = 123.Keycode,
|
|
||||||
KEY_YEN = 124.Keycode,
|
|
||||||
KEY_LEFTMETA = 125.Keycode,
|
|
||||||
KEY_RIGHTMETA = 126.Keycode,
|
|
||||||
KEY_COMPOSE = 127.Keycode,
|
|
||||||
|
|
||||||
KEY_STOP = 128.Keycode,
|
|
||||||
KEY_AGAIN = 129.Keycode,
|
|
||||||
KEY_PROPS = 130.Keycode,
|
|
||||||
KEY_UNDO = 131.Keycode,
|
|
||||||
KEY_FRONT = 132.Keycode,
|
|
||||||
KEY_COPY = 133.Keycode,
|
|
||||||
KEY_OPEN = 134.Keycode,
|
|
||||||
KEY_PASTE = 135.Keycode,
|
|
||||||
KEY_FIND = 136.Keycode,
|
|
||||||
KEY_CUT = 137.Keycode,
|
|
||||||
KEY_HELP = 138.Keycode,
|
|
||||||
KEY_MENU = 139.Keycode,
|
|
||||||
KEY_CALC = 140.Keycode,
|
|
||||||
KEY_SETUP = 141.Keycode,
|
|
||||||
KEY_SLEEP = 142.Keycode,
|
|
||||||
KEY_WAKEUP = 143.Keycode,
|
|
||||||
KEY_FILE = 144.Keycode,
|
|
||||||
KEY_SENDFILE = 145.Keycode,
|
|
||||||
KEY_DELETEFILE = 146.Keycode,
|
|
||||||
KEY_XFER = 147.Keycode,
|
|
||||||
KEY_PROG1 = 148.Keycode,
|
|
||||||
KEY_PROG2 = 149.Keycode,
|
|
||||||
KEY_WWW = 150.Keycode,
|
|
||||||
KEY_MSDOS = 151.Keycode,
|
|
||||||
KEY_SCREENLOCK = 152.Keycode,
|
|
||||||
KEY_DIRECTION = 153.Keycode,
|
|
||||||
KEY_CYCLEWINDOWS = 154.Keycode,
|
|
||||||
KEY_MAIL = 155.Keycode,
|
|
||||||
KEY_BOOKMARKS = 156.Keycode,
|
|
||||||
KEY_COMPUTER = 157.Keycode,
|
|
||||||
KEY_BACK = 158.Keycode,
|
|
||||||
KEY_FORWARD = 159.Keycode,
|
|
||||||
KEY_CLOSECD = 160.Keycode,
|
|
||||||
KEY_EJECTCD = 161.Keycode,
|
|
||||||
KEY_EJECTCLOSECD = 162.Keycode,
|
|
||||||
KEY_NEXTSONG = 163.Keycode,
|
|
||||||
KEY_PLAYPAUSE = 164.Keycode,
|
|
||||||
KEY_PREVIOUSSONG = 165.Keycode,
|
|
||||||
KEY_STOPCD = 166.Keycode,
|
|
||||||
KEY_RECORD = 167.Keycode,
|
|
||||||
KEY_REWIND = 168.Keycode,
|
|
||||||
KEY_PHONE = 169.Keycode,
|
|
||||||
KEY_ISO = 170.Keycode,
|
|
||||||
KEY_CONFIG = 171.Keycode,
|
|
||||||
KEY_HOMEPAGE = 172.Keycode,
|
|
||||||
KEY_REFRESH = 173.Keycode,
|
|
||||||
KEY_EXIT = 174.Keycode,
|
|
||||||
KEY_MOVE = 175.Keycode,
|
|
||||||
KEY_EDIT = 176.Keycode,
|
|
||||||
KEY_SCROLLUP = 177.Keycode,
|
|
||||||
KEY_SCROLLDOWN = 178.Keycode,
|
|
||||||
KEY_KPLEFTPAREN = 179.Keycode,
|
|
||||||
KEY_KPRIGHTPAREN = 180.Keycode,
|
|
||||||
KEY_NEW = 181.Keycode,
|
|
||||||
KEY_REDO = 182.Keycode,
|
|
||||||
|
|
||||||
KEY_F13 = 183.Keycode,
|
|
||||||
KEY_F14 = 184.Keycode,
|
|
||||||
KEY_F15 = 185.Keycode,
|
|
||||||
KEY_F16 = 186.Keycode,
|
|
||||||
KEY_F17 = 187.Keycode,
|
|
||||||
KEY_F18 = 188.Keycode,
|
|
||||||
KEY_F19 = 189.Keycode,
|
|
||||||
KEY_F20 = 190.Keycode,
|
|
||||||
KEY_F21 = 191.Keycode,
|
|
||||||
KEY_F22 = 192.Keycode,
|
|
||||||
KEY_F23 = 193.Keycode,
|
|
||||||
KEY_F24 = 194.Keycode,
|
|
||||||
|
|
||||||
KEY_PLAYCD = 200.Keycode,
|
|
||||||
KEY_PAUSECD = 201.Keycode,
|
|
||||||
KEY_PROG3 = 202.Keycode,
|
|
||||||
KEY_PROG4 = 203.Keycode,
|
|
||||||
KEY_DASHBOARD = 204.Keycode,
|
|
||||||
KEY_SUSPEND = 205.Keycode,
|
|
||||||
KEY_CLOSE = 206.Keycode,
|
|
||||||
KEY_PLAY = 207.Keycode,
|
|
||||||
KEY_FASTFORWARD = 208.Keycode,
|
|
||||||
KEY_BASSBOOST = 209.Keycode,
|
|
||||||
KEY_PRINT = 210.Keycode,
|
|
||||||
KEY_HP = 211.Keycode,
|
|
||||||
KEY_CAMERA = 212.Keycode,
|
|
||||||
KEY_SOUND = 213.Keycode,
|
|
||||||
KEY_QUESTION = 214.Keycode,
|
|
||||||
KEY_EMAIL = 215.Keycode,
|
|
||||||
KEY_CHAT = 216.Keycode,
|
|
||||||
KEY_SEARCH = 217.Keycode,
|
|
||||||
KEY_CONNECT = 218.Keycode,
|
|
||||||
KEY_FINANCE = 219.Keycode,
|
|
||||||
KEY_SPORT = 220.Keycode,
|
|
||||||
KEY_SHOP = 221.Keycode,
|
|
||||||
KEY_ALTERASE = 222.Keycode,
|
|
||||||
KEY_CANCEL = 223.Keycode,
|
|
||||||
KEY_BRIGHTNESSDOWN = 224.Keycode,
|
|
||||||
KEY_BRIGHTNESSUP = 225.Keycode,
|
|
||||||
KEY_MEDIA = 226.Keycode,
|
|
||||||
KEY_SWITCHVIDEOMODE = 227.Keycode,
|
|
||||||
KEY_KBDILLUMTOGGLE = 228.Keycode,
|
|
||||||
KEY_KBDILLUMDOWN = 229.Keycode,
|
|
||||||
KEY_KBDILLUMUP = 230.Keycode,
|
|
||||||
KEY_SEND = 231.Keycode,
|
|
||||||
KEY_REPLY = 232.Keycode,
|
|
||||||
KEY_FORWARDMAIL = 233.Keycode,
|
|
||||||
KEY_SAVE = 234.Keycode,
|
|
||||||
KEY_DOCUMENTS = 235.Keycode,
|
|
||||||
KEY_BATTERY = 236.Keycode,
|
|
||||||
KEY_BLUETOOTH = 237.Keycode,
|
|
||||||
KEY_WLAN = 238.Keycode,
|
|
||||||
|
|
||||||
BTN_0 = 0x100.Keycode,
|
|
||||||
BTN_1 = 0x101.Keycode,
|
|
||||||
BTN_2 = 0x102.Keycode,
|
|
||||||
BTN_3 = 0x103.Keycode,
|
|
||||||
BTN_4 = 0x104.Keycode,
|
|
||||||
BTN_5 = 0x105.Keycode,
|
|
||||||
BTN_6 = 0x106.Keycode,
|
|
||||||
BTN_7 = 0x107.Keycode,
|
|
||||||
BTN_8 = 0x108.Keycode,
|
|
||||||
BTN_9 = 0x109.Keycode,
|
|
||||||
|
|
||||||
BTN_LEFT = 0x110.Keycode,
|
|
||||||
BTN_RIGHT = 0x111.Keycode,
|
|
||||||
BTN_MIDDLE = 0x112.Keycode,
|
|
||||||
BTN_SIDE = 0x113.Keycode,
|
|
||||||
BTN_EXTRA = 0x114.Keycode,
|
|
||||||
BTN_FORWARD = 0x115.Keycode,
|
|
||||||
BTN_BACK = 0x116.Keycode,
|
|
||||||
BTN_TASK = 0x117.Keycode,
|
|
||||||
|
|
||||||
BTN_TRIGGER = 0x120.Keycode,
|
|
||||||
BTN_THUMB = 0x121.Keycode,
|
|
||||||
BTN_THUMB2 = 0x122.Keycode,
|
|
||||||
BTN_TOP = 0x123.Keycode,
|
|
||||||
BTN_TOP2 = 0x124.Keycode,
|
|
||||||
BTN_PINKIE = 0x125.Keycode,
|
|
||||||
BTN_BASE = 0x126.Keycode,
|
|
||||||
BTN_BASE2 = 0x127.Keycode,
|
|
||||||
BTN_BASE3 = 0x128.Keycode,
|
|
||||||
BTN_BASE4 = 0x129.Keycode,
|
|
||||||
BTN_BASE5 = 0x12a.Keycode,
|
|
||||||
BTN_BASE6 = 0x12b.Keycode,
|
|
||||||
BTN_DEAD = 0x12f.Keycode,
|
|
||||||
|
|
||||||
BTN_A = 0x130.Keycode,
|
|
||||||
BTN_B = 0x131.Keycode,
|
|
||||||
BTN_C = 0x132.Keycode,
|
|
||||||
BTN_X = 0x133.Keycode,
|
|
||||||
BTN_Y = 0x134.Keycode,
|
|
||||||
BTN_Z = 0x135.Keycode,
|
|
||||||
BTN_TL = 0x136.Keycode,
|
|
||||||
BTN_TR = 0x137.Keycode,
|
|
||||||
BTN_TL2 = 0x138.Keycode,
|
|
||||||
BTN_TR2 = 0x139.Keycode,
|
|
||||||
BTN_SELECT = 0x13a.Keycode,
|
|
||||||
BTN_START = 0x13b.Keycode,
|
|
||||||
BTN_MODE = 0x13c.Keycode,
|
|
||||||
BTN_THUMBL = 0x13d.Keycode,
|
|
||||||
BTN_THUMBR = 0x13e.Keycode,
|
|
||||||
|
|
||||||
BTN_TOOL_PEN = 0x140.Keycode,
|
|
||||||
BTN_TOOL_RUBBER = 0x141.Keycode,
|
|
||||||
BTN_TOOL_BRUSH = 0x142.Keycode,
|
|
||||||
BTN_TOOL_PENCIL = 0x143.Keycode,
|
|
||||||
BTN_TOOL_AIRBRUSH = 0x144.Keycode,
|
|
||||||
BTN_TOOL_FINGER = 0x145.Keycode,
|
|
||||||
BTN_TOOL_MOUSE = 0x146.Keycode,
|
|
||||||
BTN_TOOL_LENS = 0x147.Keycode,
|
|
||||||
BTN_TOUCH = 0x14a.Keycode,
|
|
||||||
BTN_STYLUS = 0x14b.Keycode,
|
|
||||||
BTN_STYLUS2 = 0x14c.Keycode,
|
|
||||||
BTN_TOOL_DOUBLETAP = 0x14d.Keycode,
|
|
||||||
BTN_TOOL_TRIPLETAP = 0x14e.Keycode,
|
|
||||||
|
|
||||||
BTN_GEAR_DOWN = 0x150.Keycode,
|
|
||||||
BTN_GEAR_UP = 0x151.Keycode,
|
|
||||||
|
|
||||||
KEY_OK = 0x160.Keycode,
|
|
||||||
KEY_SELECT = 0x161.Keycode,
|
|
||||||
KEY_GOTO = 0x162.Keycode,
|
|
||||||
KEY_CLEAR = 0x163.Keycode,
|
|
||||||
KEY_POWER2 = 0x164.Keycode,
|
|
||||||
KEY_OPTION = 0x165.Keycode,
|
|
||||||
KEY_INFO = 0x166.Keycode,
|
|
||||||
KEY_TIME = 0x167.Keycode,
|
|
||||||
KEY_VENDOR = 0x168.Keycode,
|
|
||||||
KEY_ARCHIVE = 0x169.Keycode,
|
|
||||||
KEY_PROGRAM = 0x16a.Keycode,
|
|
||||||
KEY_CHANNEL = 0x16b.Keycode,
|
|
||||||
KEY_FAVORITES = 0x16c.Keycode,
|
|
||||||
KEY_EPG = 0x16d.Keycode,
|
|
||||||
KEY_PVR = 0x16e.Keycode,
|
|
||||||
KEY_MHP = 0x16f.Keycode,
|
|
||||||
KEY_LANGUAGE = 0x170.Keycode,
|
|
||||||
KEY_TITLE = 0x171.Keycode,
|
|
||||||
KEY_SUBTITLE = 0x172.Keycode,
|
|
||||||
KEY_ANGLE = 0x173.Keycode,
|
|
||||||
KEY_ZOOM = 0x174.Keycode,
|
|
||||||
KEY_MODE = 0x175.Keycode,
|
|
||||||
KEY_KEYBOARD = 0x176.Keycode,
|
|
||||||
KEY_SCREEN = 0x177.Keycode,
|
|
||||||
KEY_PC = 0x178.Keycode,
|
|
||||||
KEY_TV = 0x179.Keycode,
|
|
||||||
KEY_TV2 = 0x17a.Keycode,
|
|
||||||
KEY_VCR = 0x17b.Keycode,
|
|
||||||
KEY_VCR2 = 0x17c.Keycode,
|
|
||||||
KEY_SAT = 0x17d.Keycode,
|
|
||||||
KEY_SAT2 = 0x17e.Keycode,
|
|
||||||
KEY_CD = 0x17f.Keycode,
|
|
||||||
KEY_TAPE = 0x180.Keycode,
|
|
||||||
KEY_RADIO = 0x181.Keycode,
|
|
||||||
KEY_TUNER = 0x182.Keycode,
|
|
||||||
KEY_PLAYER = 0x183.Keycode,
|
|
||||||
KEY_TEXT = 0x184.Keycode,
|
|
||||||
KEY_DVD = 0x185.Keycode,
|
|
||||||
KEY_AUX = 0x186.Keycode,
|
|
||||||
KEY_MP3 = 0x187.Keycode,
|
|
||||||
KEY_AUDIO = 0x188.Keycode,
|
|
||||||
KEY_VIDEO = 0x189.Keycode,
|
|
||||||
KEY_DIRECTORY = 0x18a.Keycode,
|
|
||||||
KEY_LIST = 0x18b.Keycode,
|
|
||||||
KEY_MEMO = 0x18c.Keycode,
|
|
||||||
KEY_CALENDAR = 0x18d.Keycode,
|
|
||||||
KEY_RED = 0x18e.Keycode,
|
|
||||||
KEY_GREEN = 0x18f.Keycode,
|
|
||||||
KEY_YELLOW = 0x190.Keycode,
|
|
||||||
KEY_BLUE = 0x191.Keycode,
|
|
||||||
KEY_CHANNELUP = 0x192.Keycode,
|
|
||||||
KEY_CHANNELDOWN = 0x193.Keycode,
|
|
||||||
KEY_FIRST = 0x194.Keycode,
|
|
||||||
KEY_LAST = 0x195.Keycode,
|
|
||||||
KEY_AB = 0x196.Keycode,
|
|
||||||
KEY_NEXT = 0x197.Keycode,
|
|
||||||
KEY_RESTART = 0x198.Keycode,
|
|
||||||
KEY_SLOW = 0x199.Keycode,
|
|
||||||
KEY_SHUFFLE = 0x19a.Keycode,
|
|
||||||
KEY_BREAK = 0x19b.Keycode,
|
|
||||||
KEY_PREVIOUS = 0x19c.Keycode,
|
|
||||||
KEY_DIGITS = 0x19d.Keycode,
|
|
||||||
KEY_TEEN = 0x19e.Keycode,
|
|
||||||
KEY_TWEN = 0x19f.Keycode,
|
|
||||||
KEY_VIDEOPHONE = 0x1a0.Keycode,
|
|
||||||
KEY_GAMES = 0x1a1.Keycode,
|
|
||||||
KEY_ZOOMIN = 0x1a2.Keycode,
|
|
||||||
KEY_ZOOMOUT = 0x1a3.Keycode,
|
|
||||||
KEY_ZOOMRESET = 0x1a4.Keycode,
|
|
||||||
KEY_WORDPROCESSOR = 0x1a5.Keycode,
|
|
||||||
KEY_EDITOR = 0x1a6.Keycode,
|
|
||||||
KEY_SPREADSHEET = 0x1a7.Keycode,
|
|
||||||
KEY_GRAPHICSEDITOR = 0x1a8.Keycode,
|
|
||||||
KEY_PRESENTATION = 0x1a9.Keycode,
|
|
||||||
KEY_DATABASE = 0x1aa.Keycode,
|
|
||||||
KEY_NEWS = 0x1ab.Keycode,
|
|
||||||
KEY_VOICEMAIL = 0x1ac.Keycode,
|
|
||||||
KEY_ADDRESSBOOK = 0x1ad.Keycode,
|
|
||||||
KEY_MESSENGER = 0x1ae.Keycode,
|
|
||||||
|
|
||||||
KEY_DEL_EOL = 0x1c0.Keycode,
|
|
||||||
KEY_DEL_EOS = 0x1c1.Keycode,
|
|
||||||
KEY_INS_LINE = 0x1c2.Keycode,
|
|
||||||
KEY_DEL_LINE = 0x1c3.Keycode,
|
|
||||||
|
|
||||||
KEY_FN = 0x1d0.Keycode,
|
|
||||||
KEY_FN_ESC = 0x1d1.Keycode,
|
|
||||||
KEY_FN_F1 = 0x1d2.Keycode,
|
|
||||||
KEY_FN_F2 = 0x1d3.Keycode,
|
|
||||||
KEY_FN_F3 = 0x1d4.Keycode,
|
|
||||||
KEY_FN_F4 = 0x1d5.Keycode,
|
|
||||||
KEY_FN_F5 = 0x1d6.Keycode,
|
|
||||||
KEY_FN_F6 = 0x1d7.Keycode,
|
|
||||||
KEY_FN_F7 = 0x1d8.Keycode,
|
|
||||||
KEY_FN_F8 = 0x1d9.Keycode,
|
|
||||||
KEY_FN_F9 = 0x1da.Keycode,
|
|
||||||
KEY_FN_F10 = 0x1db.Keycode,
|
|
||||||
KEY_FN_F11 = 0x1dc.Keycode,
|
|
||||||
KEY_FN_F12 = 0x1dd.Keycode,
|
|
||||||
KEY_FN_1 = 0x1de.Keycode,
|
|
||||||
KEY_FN_2 = 0x1df.Keycode,
|
|
||||||
KEY_FN_D = 0x1e0.Keycode,
|
|
||||||
KEY_FN_E = 0x1e1.Keycode,
|
|
||||||
KEY_FN_F = 0x1e2.Keycode,
|
|
||||||
KEY_FN_S = 0x1e3.Keycode,
|
|
||||||
KEY_FN_B = 0x1e4.Keycode,
|
|
||||||
|
|
||||||
KEY_BRL_DOT1 = 0x1f1.Keycode,
|
|
||||||
KEY_BRL_DOT2 = 0x1f2.Keycode,
|
|
||||||
KEY_BRL_DOT3 = 0x1f3.Keycode,
|
|
||||||
KEY_BRL_DOT4 = 0x1f4.Keycode,
|
|
||||||
KEY_BRL_DOT5 = 0x1f5.Keycode,
|
|
||||||
KEY_BRL_DOT6 = 0x1f6.Keycode,
|
|
||||||
KEY_BRL_DOT7 = 0x1f7.Keycode,
|
|
||||||
KEY_BRL_DOT8 = 0x1f8.Keycode,
|
|
||||||
|
|
||||||
KEY_UNKNOWN = 0x1fe.Keycode,
|
|
||||||
KEY_MAX = 0x1ff
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Nitpicker client
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import genode, inputclient
|
|
||||||
|
|
||||||
const NitpickerH = "<nitpicker_session/connection.h>"
|
|
||||||
|
|
||||||
type
|
|
||||||
ConnectionBase {.
|
|
||||||
importcpp: "Nitpicker::Connection", header: NitpickerH.} = object
|
|
||||||
Connection = Constructible[ConnectionBase]
|
|
||||||
|
|
||||||
NitpickerClient* = ref NitpickerClientObj
|
|
||||||
NitpickerClientObj = object
|
|
||||||
conn: Connection
|
|
||||||
|
|
||||||
proc construct(conn: Connection; label: cstring) {.
|
|
||||||
importcpp: "#.construct(#)".}
|
|
||||||
|
|
||||||
proc newNitpickerClient*(label = ""): NitpickerClient =
|
|
||||||
new result
|
|
||||||
construct result.conn, label
|
|
||||||
|
|
||||||
proc close*(np: NitpickerClient) =
|
|
||||||
destruct np.conn
|
|
||||||
|
|
||||||
type Mode* {.importcpp: "Framebuffer::Mode", header: NitpickerH.} = object
|
|
||||||
|
|
||||||
proc width*(m: Mode): int {.importcpp.}
|
|
||||||
proc height*(m: Mode): int {.importcpp.}
|
|
||||||
|
|
||||||
proc mode(conn: Connection): Mode {.
|
|
||||||
importcpp: "#->mode()".}
|
|
||||||
|
|
||||||
proc mode*(np: NitpickerClient): Mode = mode np.conn
|
|
||||||
## Return physical screen mode.
|
|
||||||
|
|
||||||
proc mode_sigh(conn: Connection; cap: SignalContextCapability) {.
|
|
||||||
importcpp: "#->mode_sigh(#)".}
|
|
||||||
|
|
||||||
proc modeSigh*(np: NitpickerClient; cap: SignalContextCapability) =
|
|
||||||
## Register signal handler to be notified about mode changes.
|
|
||||||
np.conn.modeSigh cap
|
|
||||||
|
|
||||||
proc input(conn: Connection): InputClient {.
|
|
||||||
importcpp: "#->input()".}
|
|
||||||
|
|
||||||
proc input*(np: NitpickerClient): InputClient =
|
|
||||||
## Return an object representing the Input sub-session.
|
|
||||||
result = np.conn.input()
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Report client
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import genode, streams
|
|
||||||
|
|
||||||
const ReportH = "<report_session/connection.h>"
|
|
||||||
|
|
||||||
type
|
|
||||||
ConnectionBase {.
|
|
||||||
importcpp: "Report::Connection", header: ReportH.} = object
|
|
||||||
Connection = Constructible[ConnectionBase]
|
|
||||||
|
|
||||||
ReportClient* = ref ReportClientObj
|
|
||||||
ReportClientObj = object
|
|
||||||
conn: Connection
|
|
||||||
stream*: DataspaceStream
|
|
||||||
|
|
||||||
proc construct(c: Connection, label: cstring, bufferSize: csize) {.
|
|
||||||
importcpp: "#.construct(*genodeEnv, @)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc dataspace(c: Connection): DataspaceCapability {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->dataspace()".}
|
|
||||||
|
|
||||||
proc submit(c: Connection, n: csize) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->submit(#)".}
|
|
||||||
|
|
||||||
proc newReportClient*(label: string, bufferSize = 4096): ReportClient=
|
|
||||||
new result
|
|
||||||
construct result.conn, label, bufferSize
|
|
||||||
result.stream = newDataspaceStream(result.conn.dataspace)
|
|
||||||
|
|
||||||
proc submit*(report: ReportClient) =
|
|
||||||
report.conn.submit(report.stream.size)
|
|
||||||
|
|
||||||
proc close*(report: ReportClient) =
|
|
||||||
close report.stream
|
|
||||||
destruct report.conn
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief ROM client
|
|
||||||
# \author Emery Hemingway
|
|
||||||
# \date 2017-10-15
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
#
|
|
||||||
# This file is part of the Genode OS framework, which is distributed
|
|
||||||
# under the terms of the GNU Affero General Public License version 3.
|
|
||||||
#
|
|
||||||
|
|
||||||
import genode, streams, xmlparser, xmltree
|
|
||||||
|
|
||||||
const RomH = "<rom_session/connection.h>"
|
|
||||||
|
|
||||||
type
|
|
||||||
ConnectionBase {.
|
|
||||||
importcpp: "Genode::Rom_connection", header: RomH.} = object
|
|
||||||
Connection = Constructible[ConnectionBase]
|
|
||||||
|
|
||||||
RomClient* = ref RomClientObj
|
|
||||||
RomClientObj = object
|
|
||||||
conn: Connection
|
|
||||||
dispatcher: SignalDispatcher
|
|
||||||
stream*: DataspaceStream
|
|
||||||
|
|
||||||
proc construct(c: Connection, label: cstring) {.
|
|
||||||
importcpp: "#.construct(*genodeEnv, @)", tags: [RpcEffect].}
|
|
||||||
|
|
||||||
proc dataspace(c: Connection): DataspaceCapability {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->dataspace()".}
|
|
||||||
## Return the current dataspace capability from the ROM server.
|
|
||||||
|
|
||||||
proc update(c: Connection) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->update()".}
|
|
||||||
|
|
||||||
proc sigh(c: Connection; cap: SignalContextCapability) {.tags: [RpcEffect],
|
|
||||||
importcpp: "#->sigh(#)".}
|
|
||||||
|
|
||||||
proc newRomClient*(label: string): RomClient =
|
|
||||||
## Open a new ROM connection.
|
|
||||||
new result
|
|
||||||
construct result.conn, label
|
|
||||||
result.stream = newDataspaceStream(result.conn.dataspace)
|
|
||||||
|
|
||||||
proc close*(rom: RomClient) =
|
|
||||||
close rom.stream
|
|
||||||
destruct rom.conn
|
|
||||||
if not rom.dispatcher.isNil:
|
|
||||||
dissolve rom.dispatcher
|
|
||||||
|
|
||||||
proc dataspace*(rom: RomClient): DataspaceCapability = rom.conn.dataspace
|
|
||||||
## Return the ROM dataspace. Use the stream object member whenever possible.
|
|
||||||
|
|
||||||
proc update*(rom: RomClient) =
|
|
||||||
## Update the ROM dataspace.
|
|
||||||
update rom.conn
|
|
||||||
rom.stream.update rom.conn.dataspace
|
|
||||||
|
|
||||||
proc sigh*(rom: RomClient; cap: SignalContextCapability) =
|
|
||||||
## Register a capability to a signal handler at the ROM server.
|
|
||||||
doAssert(rom.dispatcher.isNil, "ROM handler already set with `handler=`")
|
|
||||||
rom.conn.sigh cap
|
|
||||||
|
|
||||||
proc `handler=`*(rom: RomClient; cb: proc() {.closure.}) =
|
|
||||||
## Set the signal handling procedure for a ROM client.
|
|
||||||
## A nil procedure will disable signal handling.
|
|
||||||
if cb.isNil:
|
|
||||||
if not rom.dispatcher.isNil:
|
|
||||||
rom.conn.sigh(SignalContextCapability())
|
|
||||||
dissolve rom.dispatcher
|
|
||||||
rom.dispatcher = nil
|
|
||||||
else:
|
|
||||||
if rom.dispatcher.isNil:
|
|
||||||
rom.dispatcher = newSignalDispatcher()
|
|
||||||
rom.conn.sigh rom.dispatcher.cap
|
|
||||||
rom.dispatcher.handler = cb
|
|
||||||
|
|
||||||
proc xml*(rom: RomClient): XmlNode =
|
|
||||||
## Parse ROM content as XML.
|
|
||||||
try:
|
|
||||||
rom.stream.setPosition 0
|
|
||||||
result = parseXml rom.stream
|
|
||||||
except XmlError:
|
|
||||||
result = <>empty()
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Genode signal support for Nim
|
|
||||||
* \author Emery Hemingway
|
|
||||||
* \date 2015-10-15
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GENODE_CPP__SIGNALS_H_
|
|
||||||
#define _GENODE_CPP__SIGNALS_H_
|
|
||||||
|
|
||||||
#include <libc/component.h>
|
|
||||||
#include <base/signal.h>
|
|
||||||
#include <util/reconstructible.h>
|
|
||||||
#include <libc/component.h>
|
|
||||||
|
|
||||||
extern "C" void nimHandleSignal(void *arg);
|
|
||||||
|
|
||||||
struct SignalDispatcherCpp
|
|
||||||
{
|
|
||||||
struct _Dispatcher : Genode::Signal_dispatcher_base
|
|
||||||
{
|
|
||||||
void *arg;
|
|
||||||
|
|
||||||
void dispatch(unsigned num) override
|
|
||||||
{
|
|
||||||
Libc::with_libc([&] () {
|
|
||||||
nimHandleSignal(arg); });
|
|
||||||
}
|
|
||||||
|
|
||||||
_Dispatcher(void *arg) : arg(arg) {
|
|
||||||
Genode::Signal_context::_level = Genode::Signal_context::Level::App; }
|
|
||||||
};
|
|
||||||
|
|
||||||
Genode::Constructible<_Dispatcher> _dispatcher;
|
|
||||||
Genode::Entrypoint *entrypoint;
|
|
||||||
Genode::Signal_context_capability cap;
|
|
||||||
|
|
||||||
void init(Genode::Entrypoint *ep, void *arg)
|
|
||||||
{
|
|
||||||
_dispatcher.construct(arg);
|
|
||||||
entrypoint = ep;
|
|
||||||
cap = entrypoint->manage(*_dispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deinit()
|
|
||||||
{
|
|
||||||
entrypoint->dissolve(*_dispatcher);
|
|
||||||
_dispatcher.destruct();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user