github.com/c-darwin/mobile@v0.0.0-20160313183840-ff625c46f7c9/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  // +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  On Ubuntu 14.04 'Trusty', you may have to install these libraries:
    15  sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libx11-dev
    16  */
    17  
    18  /*
    19  #cgo LDFLAGS: -lEGL -lGLESv2 -lX11
    20  
    21  void createWindow(void);
    22  void processEvents(void);
    23  void swapBuffers(void);
    24  */
    25  import "C"
    26  import (
    27  	"runtime"
    28  	"time"
    29  
    30  	"github.com/c-darwin/mobile/event/lifecycle"
    31  	"github.com/c-darwin/mobile/event/paint"
    32  	"github.com/c-darwin/mobile/event/size"
    33  	"github.com/c-darwin/mobile/event/touch"
    34  	"github.com/c-darwin/mobile/geom"
    35  	"github.com/c-darwin/mobile/gl"
    36  )
    37  
    38  func init() {
    39  	registerGLViewportFilter()
    40  }
    41  
    42  func main(f func(App)) {
    43  	runtime.LockOSThread()
    44  	C.createWindow()
    45  
    46  	// TODO: send lifecycle events when e.g. the X11 window is iconified or moved off-screen.
    47  	sendLifecycle(lifecycle.StageFocused)
    48  
    49  	donec := make(chan struct{})
    50  	go func() {
    51  		f(app{})
    52  		close(donec)
    53  	}()
    54  
    55  	// TODO: can we get the actual vsync signal?
    56  	ticker := time.NewTicker(time.Second / 60)
    57  	defer ticker.Stop()
    58  	tc := ticker.C
    59  
    60  	for {
    61  		select {
    62  		case <-donec:
    63  			return
    64  		case <-gl.WorkAvailable:
    65  			gl.DoWork()
    66  		case <-endPaint:
    67  			C.swapBuffers()
    68  			tc = ticker.C
    69  		case <-tc:
    70  			tc = nil
    71  			eventsIn <- paint.Event{}
    72  		}
    73  		C.processEvents()
    74  	}
    75  }
    76  
    77  //export onResize
    78  func onResize(w, h int) {
    79  	// TODO(nigeltao): don't assume 72 DPI. DisplayWidth and DisplayWidthMM
    80  	// is probably the best place to start looking.
    81  	pixelsPerPt := float32(1)
    82  	eventsIn <- size.Event{
    83  		WidthPx:     w,
    84  		HeightPx:    h,
    85  		WidthPt:     geom.Pt(w),
    86  		HeightPt:    geom.Pt(h),
    87  		PixelsPerPt: pixelsPerPt,
    88  	}
    89  }
    90  
    91  func sendTouch(t touch.Type, x, y float32) {
    92  	eventsIn <- touch.Event{
    93  		X:        x,
    94  		Y:        y,
    95  		Sequence: 0, // TODO: button??
    96  		Type:     t,
    97  	}
    98  }
    99  
   100  //export onTouchBegin
   101  func onTouchBegin(x, y float32) { sendTouch(touch.TypeBegin, x, y) }
   102  
   103  //export onTouchMove
   104  func onTouchMove(x, y float32) { sendTouch(touch.TypeMove, x, y) }
   105  
   106  //export onTouchEnd
   107  func onTouchEnd(x, y float32) { sendTouch(touch.TypeEnd, x, y) }
   108  
   109  var stopped bool
   110  
   111  //export onStop
   112  func onStop() {
   113  	if stopped {
   114  		return
   115  	}
   116  	stopped = true
   117  	sendLifecycle(lifecycle.StageDead)
   118  	eventsIn <- stopPumping{}
   119  }