// 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
}
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.
_ = 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() {
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 {
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
}
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()