Commit c849b23c authored by Nigel Tao's avatar Nigel Tao

exp/draw: unify a draw.Context's keyboard, mouse, etc. channels into a

single event channel.

A quit event is now represented by closing that channel.

R=r, rsc, nigeltao
CC=golang-dev
https://golang.org/cl/2114042
parent 68cce4ab
......@@ -16,35 +16,33 @@ type Context interface {
// FlushImage flushes changes made to Screen() back to screen.
FlushImage()
// KeyboardChan returns a channel carrying keystrokes.
// An event is sent each time a key is pressed or released.
// EventChan returns a channel carrying UI events such as key presses,
// mouse movements and window resizes.
EventChan() <-chan interface{}
}
// A KeyEvent is sent for a key press or release.
type KeyEvent struct {
// The value k represents key k being pressed.
// The value -k represents key k being released.
// The specific set of key values is not specified,
// but ordinary character represent themselves.
KeyboardChan() <-chan int
// MouseChan returns a channel carrying mouse events.
// A new event is sent each time the mouse moves or a
// button is pressed or released.
MouseChan() <-chan Mouse
// ResizeChan returns a channel carrying resize events.
// An event is sent each time the window is resized;
// the client should respond by calling Screen() to obtain
// the new screen image.
// The value sent on the channel is always ``true'' and can be ignored.
ResizeChan() <-chan bool
// QuitChan returns a channel carrying quit requests.
// After reading a value from the quit channel, the application
// should exit.
QuitChan() <-chan bool
// but ordinary characters represent themselves.
Key int
}
// A MouseEvent is sent for a button press or release or for a mouse movement.
type MouseEvent struct {
// Buttons is a bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right.
// It represents button state and not necessarily the state delta: bit 0
// being on means that the left mouse button is down, but does not imply
// that the same button was up in the previous MouseEvent.
Buttons int
// Loc is the location of the cursor.
Loc image.Point
}
// A Mouse represents the state of the mouse.
type Mouse struct {
Buttons int // bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right
image.Point // location of cursor
Nsec int64 // time stamp
// A ConfigEvent is sent each time the window's color model or size changes.
// The client should respond by calling Context.Screen to obtain a new image.
type ConfigEvent struct {
Config image.Config
}
......@@ -45,11 +45,8 @@ type conn struct {
gc, window, root, visual resID
img *image.RGBA
kbd chan int
mouse chan draw.Mouse
resize chan bool
quit chan bool
mouseState draw.Mouse
eventc chan interface{}
mouseState draw.MouseEvent
buf [256]byte // General purpose scratch buffer.
......@@ -134,13 +131,7 @@ func (c *conn) FlushImage() {
_ = c.flush <- false
}
func (c *conn) KeyboardChan() <-chan int { return c.kbd }
func (c *conn) MouseChan() <-chan draw.Mouse { return c.mouse }
func (c *conn) ResizeChan() <-chan bool { return c.resize }
func (c *conn) QuitChan() <-chan bool { return c.quit }
func (c *conn) EventChan() <-chan interface{} { return c.eventc }
// pumper runs in its own goroutine, reading X events and demuxing them over the kbd / mouse / resize / quit chans.
func (c *conn) pumper() {
......@@ -209,7 +200,7 @@ func (c *conn) pumper() {
if c.buf[0] == 0x03 {
keysym = -keysym
}
c.kbd <- keysym
c.eventc <- draw.KeyEvent{keysym}
case 0x04, 0x05: // Button press, button release.
mask := 1 << (c.buf[1] - 1)
if c.buf[0] == 0x04 {
......@@ -218,12 +209,12 @@ func (c *conn) pumper() {
c.mouseState.Buttons &^= mask
}
// TODO(nigeltao): update mouseState's timestamp.
c.mouse <- c.mouseState
c.eventc <- c.mouseState
case 0x06: // Motion notify.
c.mouseState.Point.X = int(c.buf[25])<<8 | int(c.buf[24])
c.mouseState.Point.Y = int(c.buf[27])<<8 | int(c.buf[26])
c.mouseState.Loc.X = int(c.buf[25])<<8 | int(c.buf[24])
c.mouseState.Loc.Y = int(c.buf[27])<<8 | int(c.buf[26])
// TODO(nigeltao): update mouseState's timestamp.
c.mouse <- c.mouseState
c.eventc <- c.mouseState
case 0x0c: // Expose.
// A single user action could trigger multiple expose events (e.g. if moving another
// window with XShape'd rounded corners over our window). In that case, the X server
......@@ -619,11 +610,7 @@ func NewWindowDisplay(display string) (draw.Context, os.Error) {
}
c.img = image.NewRGBA(windowWidth, windowHeight)
// TODO(nigeltao): Should these channels be buffered?
c.kbd = make(chan int)
c.mouse = make(chan draw.Mouse)
c.resize = make(chan bool)
c.quit = make(chan bool)
c.eventc = make(chan interface{})
c.flush = make(chan bool, 1)
go c.flusher()
go c.pumper()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment