x11.go (2586B)
1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build linux,!android 6 7 package app 8 9 /* 10 Simple on-screen app debugging for X11. Not an officially supported 11 development target for apps, as screens with mice are very different 12 than screens with touch panels. 13 */ 14 15 /* 16 #cgo LDFLAGS: -lEGL -lGLESv2 -lX11 17 18 void createWindow(void); 19 void processEvents(void); 20 void swapBuffers(void); 21 */ 22 import "C" 23 import ( 24 "runtime" 25 "time" 26 27 "golang.org/x/mobile/event/lifecycle" 28 "golang.org/x/mobile/event/paint" 29 "golang.org/x/mobile/event/size" 30 "golang.org/x/mobile/event/touch" 31 "golang.org/x/mobile/geom" 32 ) 33 34 func init() { 35 theApp.registerGLViewportFilter() 36 } 37 38 func main(f func(App)) { 39 runtime.LockOSThread() 40 41 workAvailable := theApp.worker.WorkAvailable() 42 43 C.createWindow() 44 45 // TODO: send lifecycle events when e.g. the X11 window is iconified or moved off-screen. 46 theApp.sendLifecycle(lifecycle.StageFocused) 47 48 // TODO: translate X11 expose events to shiny paint events, instead of 49 // sending this synthetic paint event as a hack. 50 theApp.eventsIn <- paint.Event{} 51 52 donec := make(chan struct{}) 53 go func() { 54 f(theApp) 55 close(donec) 56 }() 57 58 // TODO: can we get the actual vsync signal? 59 ticker := time.NewTicker(time.Second / 60) 60 defer ticker.Stop() 61 var tc <-chan time.Time 62 63 for { 64 select { 65 case <-donec: 66 return 67 case <-workAvailable: 68 theApp.worker.DoWork() 69 case <-theApp.publish: 70 C.swapBuffers() 71 tc = ticker.C 72 case <-tc: 73 tc = nil 74 theApp.publishResult <- PublishResult{} 75 } 76 C.processEvents() 77 } 78 } 79 80 //export onResize 81 func onResize(w, h int) { 82 // TODO(nigeltao): don't assume 72 DPI. DisplayWidth and DisplayWidthMM 83 // is probably the best place to start looking. 84 pixelsPerPt := float32(1) 85 theApp.eventsIn <- size.Event{ 86 WidthPx: w, 87 HeightPx: h, 88 WidthPt: geom.Pt(w), 89 HeightPt: geom.Pt(h), 90 PixelsPerPt: pixelsPerPt, 91 } 92 } 93 94 func sendTouch(t touch.Type, x, y float32) { 95 theApp.eventsIn <- touch.Event{ 96 X: x, 97 Y: y, 98 Sequence: 0, // TODO: button?? 99 Type: t, 100 } 101 } 102 103 //export onTouchBegin 104 func onTouchBegin(x, y float32) { sendTouch(touch.TypeBegin, x, y) } 105 106 //export onTouchMove 107 func onTouchMove(x, y float32) { sendTouch(touch.TypeMove, x, y) } 108 109 //export onTouchEnd 110 func onTouchEnd(x, y float32) { sendTouch(touch.TypeEnd, x, y) } 111 112 var stopped bool 113 114 //export onStop 115 func onStop() { 116 if stopped { 117 return 118 } 119 stopped = true 120 theApp.sendLifecycle(lifecycle.StageDead) 121 theApp.eventsIn <- stopPumping{} 122 }