summaryrefslogtreecommitdiff
path: root/libgo/go/exp/nacl/av/event.go
blob: f8fe329b8a8f1308f0dcf7afa38cdf1add6e6400 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
// 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"
	"image"
	"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.MouseEvent
	for {
		if err := videoPollEvent(buf); err != nil {
			if !clean {
				clean = w.eventc <- draw.ConfigEvent{image.Config{ColorModel, w.Image.Bounds().Dx(), w.Image.Bounds().Dy()}}
			}
			time.Sleep(10e6) // 10ms
			continue
		}
		clean = false
		var e event
		switch buf[0] {
		default:
			log.Print("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.Print("unpacking %T event: %s", e, err)
			continue
		}
		// log.Printf("%#v\n", e);
		switch buf[0] {
		case eventExpose:
			w.eventc <- draw.ConfigEvent{image.Config{ColorModel, w.Image.Bounds().Dx(), w.Image.Bounds().Dy()}}
		case eventKeyDown:
			w.eventc <- draw.KeyEvent{int(ke.Key)}
		case eventKeyUp:
			w.eventc <- draw.KeyEvent{-int(ke.Key)}
		case eventMouseMotion:
			m.Loc.X = int(mme.X)
			m.Loc.Y = int(mme.Y)
			m.Buttons = int(mme.Buttons)
			m.Nsec = time.Nanoseconds()
			_ = w.eventc <- m
		case eventMouseButtonDown:
			m.Loc.X = int(mbe.X)
			m.Loc.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.eventc <- m
		case eventMouseButtonUp:
			m.Loc.X = int(mbe.X)
			m.Loc.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.eventc <- m
		case eventQuit:
			close(w.eventc)
		}
	}
}