Documentation ¶
Overview ¶
Copyright 2016-2017 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Index ¶
- Constants
- Variables
- func Main(f func(s screen.Screen))
- func NewDrawCtrler() (*DrawCtrler, *DrawCtlMsg, error)
- func RuneToCode(r rune) (key.Code, key.Modifiers)
- type ButtonMask
- type DrawCtlMsg
- type DrawCtrler
- func (d *DrawCtrler) AllocBuffer(refresh byte, repl bool, r, clipr image.Rectangle, color color.Color) uint32
- func (d *DrawCtrler) AllocScreen() (screenId, error)
- func (d *DrawCtrler) Draw(dstid, srcid, maskid uint32, r image.Rectangle, srcp, maskp image.Point, ...)
- func (d *DrawCtrler) FreeID(id uint32)
- func (d *DrawCtrler) FreeScreen(id screenId)
- func (d *DrawCtrler) ReadSubimage(src uint32, r image.Rectangle) []uint8
- func (d *DrawCtrler) ReallocScreen(id screenId) error
- func (d *DrawCtrler) Reclip(dstid uint32, repl bool, r image.Rectangle)
- func (d *DrawCtrler) ReplaceSubimage(dstid uint32, r image.Rectangle, pixels []byte)
- Bugs
Constants ¶
const ( MouseButtonLeft = ButtonMask(1) MouseButtonMiddle = ButtonMask(2) MouseButtonRight = ButtonMask(4) MouseScrollUp = ButtonMask(8) MouseScrollDown = ButtonMask(16) )
const NewScreen = "/dev/draw/new"
Variables ¶
var NoScreen error = errors.New("Could not allocate screen")
Functions ¶
func Main ¶
Main spawns 2 goroutines to make blocking reads from /dev interfaces, one for the mouse and one for the keyboard. Window events such as resize and move come in over the mouse channel.
func NewDrawCtrler ¶
func NewDrawCtrler() (*DrawCtrler, *DrawCtlMsg, error)
NewDrawCtrler creates a new DrawCtrler to interact with the /dev/draw filesystem. It returns a reference to a DrawCtrler, and a DrawCtlMsg representing the data that was returned from opening /dev/draw/new.
func RuneToCode ¶
RuneToCode takes a unicode rune that came off of /dev/cons, and guesses keycode generated that rune. Since Plan 9 doesn't directly tell us what key resulted in the key press, we have to take a guess. This assumed a standard US keyboard layout where runes are generated in the obvious way.
9front has /dev/kbd which tells more information about the keypresses instead of the runes generated by the key press, but /dev/cons is the only thing that can be assumed to be present on every Plan 9 instance, so even if support is implemented for /dev/kbd this needs to remain here as a fallback.
This only supports the shift and control modifiers, because alt is used as the compose key at a lower level of the OS before passing the rune along /dev/cons
Types ¶
type ButtonMask ¶
type ButtonMask int
ButtonMask represents the Plan9 button masks as read from /dev/mouse. Plan9 uses a bitmask of the buttons that are pressed, while mouse.Event expects one event per action and a direction. We need to convert the bitmask to an event every time we receive a message by calculating the direction based on the previous button pressed.
type DrawCtlMsg ¶
type DrawCtlMsg struct { N int DisplayImageId int ChannelFormat string MysteryValue string DisplaySize image.Rectangle Clipping image.Rectangle }
A DrawCtlMsg represents the data that is returned from opening /dev/draw/new or reading /dev/draw/n/ctl.
type DrawCtrler ¶
type DrawCtrler struct { N int // contains filtered or unexported fields }
A DrawCtrler is an object which holds references to /dev/draw/n/^(data ctl), and allows you to send or receive messages from it.
func (*DrawCtrler) AllocBuffer ¶
func (d *DrawCtrler) AllocBuffer(refresh byte, repl bool, r, clipr image.Rectangle, color color.Color) uint32
AllocBuffer will send a message to /dev/draw/N/data of the form:
b id[4] screenid[4] refresh[1] chan[4] repl[1] r[4*r] clipr[4*4] color[4]
see draw(3) for details.
For the purposes of the using this helper method, id and screenid are automatically generated by the DrawDriver, and chan is always an RGBA channel.
Returns the ID that can be used to reference the allocated buffer
func (*DrawCtrler) AllocScreen ¶
func (d *DrawCtrler) AllocScreen() (screenId, error)
Allocates a new screen and returns either the ID for the screen, or a NoScreen error.
func (*DrawCtrler) Draw ¶
func (d *DrawCtrler) Draw(dstid, srcid, maskid uint32, r image.Rectangle, srcp, maskp image.Point, op draw.Op)
Draw formats the parameters appropriate to send the message:
d dstid[4] srcid[4] maskid[4] dstr[4*4] srcp[2*4] maskp[2*4]
to /dev/draw/n/data. See draw(3) for details.
func (*DrawCtrler) FreeID ¶
func (d *DrawCtrler) FreeID(id uint32)
FreeID will release the resources held by the imageID in this /dev/draw interface.
func (*DrawCtrler) FreeScreen ¶
func (d *DrawCtrler) FreeScreen(id screenId)
Frees the screen identified by id.
func (*DrawCtrler) ReadSubimage ¶
func (d *DrawCtrler) ReadSubimage(src uint32, r image.Rectangle) []uint8
ReadSubimage returns the pixel data of the rectangle r from the image identified by imageID src.
It sends /dev/draw/n/data the message:
r id[4] r[4*4]
and then reads the data from /dev/draw/n/data.
func (*DrawCtrler) ReallocScreen ¶
func (d *DrawCtrler) ReallocScreen(id screenId) error
Reallocate a screen.
func (*DrawCtrler) Reclip ¶
func (d *DrawCtrler) Reclip(dstid uint32, repl bool, r image.Rectangle)
Resizes dstid to be bound by r and changes the repl bit to repl. This is mostly used when a window is resized.
func (*DrawCtrler) ReplaceSubimage ¶
func (d *DrawCtrler) ReplaceSubimage(dstid uint32, r image.Rectangle, pixels []byte)
ReplaceSubimage replaces the rectangle r with the pixel buffer defined by pixels.
It sends /dev/draw/n/data the message:
y id[4] r[4*4] buf[x*1]
Notes ¶
Bugs ¶
This length that it searches back should probably be a tuneable parameter since the optimum value is going to be a function of bandwidth and CPU, but from trial and error on a Raspberry Pi 2 over a wifi connection (probably close to the worst case scenerio), looking back the full 1024 bytes is slower than not using compression, while 128 provides some gains. More powerful CPU servers will still get gains from this, just not as much as if they looked back farther.
This reallocs everything on every resize event, but it only needs to be triggered when the size of the new window is bigger than the size of the original window.