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