committed by
Norman Feske
parent
09964463e9
commit
87ed5042c0
151
include/nim/audiooutclient.nim
Normal file
151
include/nim/audiooutclient.nim
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#
|
||||||
|
# \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
|
||||||
185
include/nim/genode.nim
Normal file
185
include/nim/genode.nim
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
#
|
||||||
|
# \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
|
||||||
|
|
||||||
|
template defineConstructible*(Final, Base: untyped) =
|
||||||
|
type Final* = Constructible[Base]
|
||||||
|
proc construct*(obj: Final) {.importcpp: "#.construct()".}
|
||||||
|
proc construct*(obj: ref Final) {.importcpp: "(*#).construct()".}
|
||||||
|
proc destruct*(obj: Final) {.importcpp: "#.destruct()".}
|
||||||
|
proc destruct*(obj: ref Final) {.importcpp: "(*#).destruct()".}
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
cpp: SignalDispatcherCpp
|
||||||
|
handler*: proc() {.closure.}
|
||||||
|
|
||||||
|
proc init(cpp: SignalDispatcherCpp; sh: SignalDispatcher)
|
||||||
|
{.importcpp: "#.init(&genodeEnv->ep(), #)".}
|
||||||
|
|
||||||
|
proc deinit(sd: SignalDispatcherCpp) {.importcpp.}
|
||||||
|
|
||||||
|
proc newSignalDispatcher*(): SignalDispatcher =
|
||||||
|
new result
|
||||||
|
init result.cpp, result
|
||||||
|
|
||||||
|
proc dissolve*(sig: SignalDispatcher) =
|
||||||
|
## Dissolve signal dispatcher from entrypoint.
|
||||||
|
deinit sig.cpp
|
||||||
|
sig.handler = nil
|
||||||
|
|
||||||
|
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
include/nim/input.nim.cfg
Normal file
1
include/nim/input.nim.cfg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-d:private=public
|
||||||
44
include/nim/inputclient.nim
Normal file
44
include/nim/inputclient.nim
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# \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]
|
||||||
38
include/nim/inputevent.nim
Normal file
38
include/nim/inputevent.nim
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#
|
||||||
|
# \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 == s:
|
||||||
|
return k
|
||||||
441
include/nim/keycodes.nim
Normal file
441
include/nim/keycodes.nim
Normal file
@@ -0,0 +1,441 @@
|
|||||||
|
#
|
||||||
|
# \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
|
||||||
63
include/nim/nitpickerclient.nim
Normal file
63
include/nim/nitpickerclient.nim
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#
|
||||||
|
# \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 destruct(conn: Connection) {.
|
||||||
|
importcpp: "#.destruct()".}
|
||||||
|
|
||||||
|
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()
|
||||||
50
include/nim/reportclient.nim
Normal file
50
include/nim/reportclient.nim
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#
|
||||||
|
# \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 destruct(c: Connection) {.tags: [RpcEffect],
|
||||||
|
importcpp: "#.destruct()".}
|
||||||
|
|
||||||
|
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
|
||||||
90
include/nim/romclient.nim
Normal file
90
include/nim/romclient.nim
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#
|
||||||
|
# \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 destruct(c: Connection) {.tags: [RpcEffect],
|
||||||
|
importcpp: "#.destruct()".}
|
||||||
|
|
||||||
|
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()
|
||||||
59
include/nim/signals.h
Normal file
59
include/nim/signals.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* \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