1
0
mirror of https://github.com/golang/go synced 2024-11-24 18:10:02 -07:00

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
This commit is contained in:
Nigel Tao 2010-09-06 19:22:49 +10:00
parent 68cce4ab20
commit c849b23ce9
2 changed files with 33 additions and 48 deletions

View File

@ -16,35 +16,33 @@ type Context interface {
// FlushImage flushes changes made to Screen() back to screen. // FlushImage flushes changes made to Screen() back to screen.
FlushImage() FlushImage()
// KeyboardChan returns a channel carrying keystrokes. // EventChan returns a channel carrying UI events such as key presses,
// An event is sent each time a key is pressed or released. // 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 pressed.
// The value -k represents key k being released. // The value -k represents key k being released.
// The specific set of key values is not specified, // The specific set of key values is not specified,
// but ordinary character represent themselves. // but ordinary characters represent themselves.
KeyboardChan() <-chan int Key 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
} }
// A Mouse represents the state of the mouse. // A MouseEvent is sent for a button press or release or for a mouse movement.
type Mouse struct { type MouseEvent struct {
Buttons int // bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right // Buttons is a bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right.
image.Point // location of cursor // It represents button state and not necessarily the state delta: bit 0
Nsec int64 // time stamp // 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 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
} }

View File

@ -45,11 +45,8 @@ type conn struct {
gc, window, root, visual resID gc, window, root, visual resID
img *image.RGBA img *image.RGBA
kbd chan int eventc chan interface{}
mouse chan draw.Mouse mouseState draw.MouseEvent
resize chan bool
quit chan bool
mouseState draw.Mouse
buf [256]byte // General purpose scratch buffer. buf [256]byte // General purpose scratch buffer.
@ -134,13 +131,7 @@ func (c *conn) FlushImage() {
_ = c.flush <- false _ = c.flush <- false
} }
func (c *conn) KeyboardChan() <-chan int { return c.kbd } func (c *conn) EventChan() <-chan interface{} { return c.eventc }
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 }
// pumper runs in its own goroutine, reading X events and demuxing them over the kbd / mouse / resize / quit chans. // pumper runs in its own goroutine, reading X events and demuxing them over the kbd / mouse / resize / quit chans.
func (c *conn) pumper() { func (c *conn) pumper() {
@ -209,7 +200,7 @@ func (c *conn) pumper() {
if c.buf[0] == 0x03 { if c.buf[0] == 0x03 {
keysym = -keysym keysym = -keysym
} }
c.kbd <- keysym c.eventc <- draw.KeyEvent{keysym}
case 0x04, 0x05: // Button press, button release. case 0x04, 0x05: // Button press, button release.
mask := 1 << (c.buf[1] - 1) mask := 1 << (c.buf[1] - 1)
if c.buf[0] == 0x04 { if c.buf[0] == 0x04 {
@ -218,12 +209,12 @@ func (c *conn) pumper() {
c.mouseState.Buttons &^= mask c.mouseState.Buttons &^= mask
} }
// TODO(nigeltao): update mouseState's timestamp. // TODO(nigeltao): update mouseState's timestamp.
c.mouse <- c.mouseState c.eventc <- c.mouseState
case 0x06: // Motion notify. case 0x06: // Motion notify.
c.mouseState.Point.X = int(c.buf[25])<<8 | int(c.buf[24]) c.mouseState.Loc.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.Y = int(c.buf[27])<<8 | int(c.buf[26])
// TODO(nigeltao): update mouseState's timestamp. // TODO(nigeltao): update mouseState's timestamp.
c.mouse <- c.mouseState c.eventc <- c.mouseState
case 0x0c: // Expose. case 0x0c: // Expose.
// A single user action could trigger multiple expose events (e.g. if moving another // 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 // 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) c.img = image.NewRGBA(windowWidth, windowHeight)
// TODO(nigeltao): Should these channels be buffered? c.eventc = make(chan interface{})
c.kbd = make(chan int)
c.mouse = make(chan draw.Mouse)
c.resize = make(chan bool)
c.quit = make(chan bool)
c.flush = make(chan bool, 1) c.flush = make(chan bool, 1)
go c.flusher() go c.flusher()
go c.pumper() go c.pumper()