| // Copyright 2009 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. |
| |
| // NaCl GUI events. |
| // Clients do not have raw access to the event stream |
| // (only filtered through the lens of package draw) |
| // but perhaps they will. |
| |
| package av |
| |
| import ( |
| "encoding/binary" |
| "exp/draw" |
| "log" |
| "os" |
| "time" |
| ) |
| |
| // An eventType identifies the type of a Native Client Event. |
| type eventType uint8 |
| |
| const ( |
| eventActive = 1 + iota |
| eventExpose |
| eventKeyDown |
| eventKeyUp |
| eventMouseMotion |
| eventMouseButtonDown |
| eventMouseButtonUp |
| eventQuit |
| eventUnsupported |
| ) |
| |
| // A key represents a key on a keyboard. |
| type key uint16 |
| |
| const ( |
| keyUnknown = 0 |
| keyFirst = 0 |
| keyBackspace = 8 |
| keyTab = 9 |
| keyClear = 12 |
| keyReturn = 13 |
| keyPause = 19 |
| keyEscape = 27 |
| keySpace = 32 |
| keyExclaim = 33 |
| keyQuotedbl = 34 |
| keyHash = 35 |
| keyDollar = 36 |
| keyAmpersand = 38 |
| keyQuote = 39 |
| keyLeftparen = 40 |
| keyRightparen = 41 |
| keyAsterisk = 42 |
| keyPlus = 43 |
| keyComma = 44 |
| keyMinus = 45 |
| keyPeriod = 46 |
| keySlash = 47 |
| key0 = 48 |
| key1 = 49 |
| key2 = 50 |
| key3 = 51 |
| key4 = 52 |
| key5 = 53 |
| key6 = 54 |
| key7 = 55 |
| key8 = 56 |
| key9 = 57 |
| keyColon = 58 |
| keySemicolon = 59 |
| keyLess = 60 |
| keyEquals = 61 |
| keyGreater = 62 |
| keyQuestion = 63 |
| keyAt = 64 |
| keyLeftbracket = 91 |
| keyBackslash = 92 |
| keyRightbracket = 93 |
| keyCaret = 94 |
| keyUnderscore = 95 |
| keyBackquote = 96 |
| keyA = 97 |
| keyB = 98 |
| keyC = 99 |
| keyD = 100 |
| keyE = 101 |
| keyF = 102 |
| keyG = 103 |
| keyH = 104 |
| keyI = 105 |
| keyJ = 106 |
| keyK = 107 |
| keyL = 108 |
| keyM = 109 |
| keyN = 110 |
| keyO = 111 |
| keyP = 112 |
| keyQ = 113 |
| keyR = 114 |
| keyS = 115 |
| keyT = 116 |
| keyU = 117 |
| keyV = 118 |
| keyW = 119 |
| keyX = 120 |
| keyY = 121 |
| keyZ = 122 |
| keyDelete = 127 |
| keyWorld0 = 160 |
| keyWorld1 = 161 |
| keyWorld2 = 162 |
| keyWorld3 = 163 |
| keyWorld4 = 164 |
| keyWorld5 = 165 |
| keyWorld6 = 166 |
| keyWorld7 = 167 |
| keyWorld8 = 168 |
| keyWorld9 = 169 |
| keyWorld10 = 170 |
| keyWorld11 = 171 |
| keyWorld12 = 172 |
| keyWorld13 = 173 |
| keyWorld14 = 174 |
| keyWorld15 = 175 |
| keyWorld16 = 176 |
| keyWorld17 = 177 |
| keyWorld18 = 178 |
| keyWorld19 = 179 |
| keyWorld20 = 180 |
| keyWorld21 = 181 |
| keyWorld22 = 182 |
| keyWorld23 = 183 |
| keyWorld24 = 184 |
| keyWorld25 = 185 |
| keyWorld26 = 186 |
| keyWorld27 = 187 |
| keyWorld28 = 188 |
| keyWorld29 = 189 |
| keyWorld30 = 190 |
| keyWorld31 = 191 |
| keyWorld32 = 192 |
| keyWorld33 = 193 |
| keyWorld34 = 194 |
| keyWorld35 = 195 |
| keyWorld36 = 196 |
| keyWorld37 = 197 |
| keyWorld38 = 198 |
| keyWorld39 = 199 |
| keyWorld40 = 200 |
| keyWorld41 = 201 |
| keyWorld42 = 202 |
| keyWorld43 = 203 |
| keyWorld44 = 204 |
| keyWorld45 = 205 |
| keyWorld46 = 206 |
| keyWorld47 = 207 |
| keyWorld48 = 208 |
| keyWorld49 = 209 |
| keyWorld50 = 210 |
| keyWorld51 = 211 |
| keyWorld52 = 212 |
| keyWorld53 = 213 |
| keyWorld54 = 214 |
| keyWorld55 = 215 |
| keyWorld56 = 216 |
| keyWorld57 = 217 |
| keyWorld58 = 218 |
| keyWorld59 = 219 |
| keyWorld60 = 220 |
| keyWorld61 = 221 |
| keyWorld62 = 222 |
| keyWorld63 = 223 |
| keyWorld64 = 224 |
| keyWorld65 = 225 |
| keyWorld66 = 226 |
| keyWorld67 = 227 |
| keyWorld68 = 228 |
| keyWorld69 = 229 |
| keyWorld70 = 230 |
| keyWorld71 = 231 |
| keyWorld72 = 232 |
| keyWorld73 = 233 |
| keyWorld74 = 234 |
| keyWorld75 = 235 |
| keyWorld76 = 236 |
| keyWorld77 = 237 |
| keyWorld78 = 238 |
| keyWorld79 = 239 |
| keyWorld80 = 240 |
| keyWorld81 = 241 |
| keyWorld82 = 242 |
| keyWorld83 = 243 |
| keyWorld84 = 244 |
| keyWorld85 = 245 |
| keyWorld86 = 246 |
| keyWorld87 = 247 |
| keyWorld88 = 248 |
| keyWorld89 = 249 |
| keyWorld90 = 250 |
| keyWorld91 = 251 |
| keyWorld92 = 252 |
| keyWorld93 = 253 |
| keyWorld94 = 254 |
| keyWorld95 = 255 |
| |
| // Numeric keypad |
| keyKp0 = 256 |
| keyKp1 = 257 |
| keyKp2 = 258 |
| keyKp3 = 259 |
| keyKp4 = 260 |
| keyKp5 = 261 |
| keyKp6 = 262 |
| keyKp7 = 263 |
| keyKp8 = 264 |
| keyKp9 = 265 |
| keyKpPeriod = 266 |
| keyKpDivide = 267 |
| keyKpMultiply = 268 |
| keyKpMinus = 269 |
| keyKpPlus = 270 |
| keyKpEnter = 271 |
| keyKpEquals = 272 |
| |
| // Arrow & insert/delete pad |
| keyUp = 273 |
| keyDown = 274 |
| keyRight = 275 |
| keyLeft = 276 |
| keyInsert = 277 |
| keyHome = 278 |
| keyEnd = 279 |
| keyPageup = 280 |
| keyPagedown = 281 |
| |
| // Function keys |
| keyF1 = 282 |
| keyF2 = 283 |
| keyF3 = 284 |
| keyF4 = 285 |
| keyF5 = 286 |
| keyF6 = 287 |
| keyF7 = 288 |
| keyF8 = 289 |
| keyF9 = 290 |
| keyF10 = 291 |
| keyF11 = 292 |
| keyF12 = 293 |
| keyF13 = 294 |
| keyF14 = 295 |
| keyF15 = 296 |
| |
| // Modifier keys |
| keyNumlock = 300 |
| keyCapslock = 301 |
| keyScrollock = 302 |
| keyRshift = 303 |
| keyLshift = 304 |
| keyRctrl = 305 |
| keyLctrl = 306 |
| keyRalt = 307 |
| keyLalt = 308 |
| keyRmeta = 309 |
| keyLmeta = 310 |
| keyLsuper = 311 |
| keyRsuper = 312 |
| keyMode = 313 |
| keyCompose = 314 |
| |
| // Misc keys |
| keyHelp = 315 |
| keyPrint = 316 |
| keySysreq = 317 |
| keyBreak = 318 |
| keyMenu = 319 |
| keyPower = 320 |
| keyEuro = 321 |
| keyUndo = 322 |
| |
| // Add any other keys here |
| keyLast |
| ) |
| |
| // A keymod is a set of bit flags |
| type keymod uint16 |
| |
| const ( |
| keymodNone = 0x0000 |
| keymodLshift = 0x0001 |
| keymodRshift = 0x0002 |
| keymodLctrl = 0x0040 |
| keymodRctrl = 0x0080 |
| keymodLalt = 0x0100 |
| keymodRalt = 0x0200 |
| keymodLmeta = 0x0400 |
| keymodRmeta = 0x0800 |
| keymodNum = 0x1000 |
| keymodCaps = 0x2000 |
| keymodMode = 0x4000 |
| keymodReserved = 0x8000 |
| ) |
| |
| const ( |
| mouseButtonLeft = 1 |
| mouseButtonMiddle = 2 |
| mouseButtonRight = 3 |
| mouseScrollUp = 4 |
| mouseScrollDown = 5 |
| ) |
| |
| const ( |
| mouseStateLeftButtonPressed = 1 |
| mouseStateMiddleButtonPressed = 2 |
| mouseStateRightButtonPressed = 4 |
| ) |
| |
| const ( |
| activeMouse = 1 // mouse leaving/entering |
| activeInputFocus = 2 // input focus lost/restored |
| activeApplication = 4 // application minimized/restored |
| ) |
| |
| const maxEventBytes = 64 |
| |
| type activeEvent struct { |
| EventType eventType |
| Gain uint8 |
| State uint8 |
| } |
| |
| type exposeEvent struct { |
| EventType eventType |
| } |
| |
| type keyboardEvent struct { |
| EventType eventType |
| Device uint8 |
| State uint8 |
| Pad uint8 |
| ScanCode uint8 |
| Pad1 uint8 |
| Key key |
| Mod keymod |
| Unicode uint16 |
| } |
| |
| type mouseMotionEvent struct { |
| EventType eventType |
| Device uint8 |
| Buttons uint8 |
| Pad uint8 |
| X uint16 |
| Y uint16 |
| Xrel int16 |
| Yrel int16 |
| } |
| |
| type mouseButtonEvent struct { |
| EventType eventType |
| Device uint8 |
| Button uint8 |
| State uint8 |
| X uint16 |
| Y uint16 |
| } |
| |
| type quitEvent struct { |
| EventType eventType |
| } |
| |
| type syncEvent struct{} |
| |
| type event interface{} |
| |
| type reader []byte |
| |
| func (r *reader) Read(p []byte) (n int, err os.Error) { |
| b := *r |
| if len(b) == 0 && len(p) > 0 { |
| return 0, os.EOF |
| } |
| n = copy(p, b) |
| *r = b[n:] |
| return |
| } |
| |
| func (w *Window) readEvents() { |
| buf := make([]byte, maxEventBytes) |
| clean := false |
| var ( |
| ea *activeEvent |
| ee *exposeEvent |
| ke *keyboardEvent |
| mme *mouseMotionEvent |
| mbe *mouseButtonEvent |
| qe *quitEvent |
| ) |
| var m draw.Mouse |
| for { |
| if err := videoPollEvent(buf); err != nil { |
| if !clean { |
| clean = w.resizec <- false |
| } |
| time.Sleep(10e6) // 10ms |
| continue |
| } |
| clean = false |
| var e event |
| switch buf[0] { |
| default: |
| log.Stdout("unsupported event type", buf[0]) |
| continue |
| case eventActive: |
| ea = new(activeEvent) |
| e = ea |
| case eventExpose: |
| ee = new(exposeEvent) |
| e = ee |
| case eventKeyDown, eventKeyUp: |
| ke = new(keyboardEvent) |
| e = ke |
| case eventMouseMotion: |
| mme = new(mouseMotionEvent) |
| e = mme |
| case eventMouseButtonDown, eventMouseButtonUp: |
| mbe = new(mouseButtonEvent) |
| e = mbe |
| case eventQuit: |
| qe = new(quitEvent) |
| e = qe |
| } |
| r := reader(buf) |
| if err := binary.Read(&r, binary.LittleEndian, e); err != nil { |
| log.Stdout("unpacking %T event: %s", e, err) |
| continue |
| } |
| // log.Stdoutf("%#v\n", e); |
| switch buf[0] { |
| case eventExpose: |
| w.resizec <- true |
| case eventKeyDown: |
| w.kbdc <- int(ke.Key) |
| case eventKeyUp: |
| w.kbdc <- -int(ke.Key) |
| case eventMouseMotion: |
| m.X = int(mme.X) |
| m.Y = int(mme.Y) |
| m.Buttons = int(mme.Buttons) |
| m.Nsec = time.Nanoseconds() |
| _ = w.mousec <- m |
| case eventMouseButtonDown: |
| m.X = int(mbe.X) |
| m.Y = int(mbe.Y) |
| // TODO(rsc): Remove uint cast once 8g bug is fixed. |
| m.Buttons |= 1 << uint(mbe.Button-1) |
| m.Nsec = time.Nanoseconds() |
| _ = w.mousec <- m |
| case eventMouseButtonUp: |
| m.X = int(mbe.X) |
| m.Y = int(mbe.Y) |
| // TODO(rsc): Remove uint cast once 8g bug is fixed. |
| m.Buttons &^= 1 << uint(mbe.Button-1) |
| m.Nsec = time.Nanoseconds() |
| _ = w.mousec <- m |
| case eventQuit: |
| w.quitc <- true |
| } |
| } |
| } |