blob: 3b9a0e4d9db498920b1ae205e7db160ac3e3bdbf [file] [log] [blame]
// 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
}
}
}