zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

x11.go (2615B)


      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 }