| // 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 ( |
| "bytes"; |
| "debug/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 = bytes.Copy(p, b); |
| *r = b[n:len(b)]; |
| 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 |
| } |
| } |
| } |