// 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 } } }