diff options
Diffstat (limited to 'vendor/gioui.org/app/internal/window')
36 files changed, 0 insertions, 10493 deletions
diff --git a/vendor/gioui.org/app/internal/window/Gio.java b/vendor/gioui.org/app/internal/window/Gio.java deleted file mode 100644 index 33e1a68..0000000 --- a/vendor/gioui.org/app/internal/window/Gio.java +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package org.gioui; - -import android.content.ClipboardManager; -import android.content.ClipData; -import android.content.Context; -import android.os.Handler; -import android.os.Looper; - -import java.io.UnsupportedEncodingException; - -public final class Gio { - private static final Object initLock = new Object(); - private static boolean jniLoaded; - private static final Handler handler = new Handler(Looper.getMainLooper()); - - /** - * init loads and initializes the Go native library and runs - * the Go main function. - * - * It is exported for use by Android apps that need to run Go code - * outside the lifecycle of the Gio activity. - */ - public static synchronized void init(Context appCtx) { - synchronized (initLock) { - if (jniLoaded) { - return; - } - String dataDir = appCtx.getFilesDir().getAbsolutePath(); - byte[] dataDirUTF8; - try { - dataDirUTF8 = dataDir.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - System.loadLibrary("gio"); - runGoMain(dataDirUTF8, appCtx); - jniLoaded = true; - } - } - - static private native void runGoMain(byte[] dataDir, Context context); - - static void writeClipboard(Context ctx, String s) { - ClipboardManager m = (ClipboardManager)ctx.getSystemService(Context.CLIPBOARD_SERVICE); - m.setPrimaryClip(ClipData.newPlainText(null, s)); - } - - static String readClipboard(Context ctx) { - ClipboardManager m = (ClipboardManager)ctx.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData c = m.getPrimaryClip(); - if (c == null || c.getItemCount() < 1) { - return null; - } - return c.getItemAt(0).coerceToText(ctx).toString(); - } - - static void wakeupMainThread() { - handler.post(new Runnable() { - @Override public void run() { - scheduleMainFuncs(); - } - }); - } - - static private native void scheduleMainFuncs(); -} diff --git a/vendor/gioui.org/app/internal/window/GioActivity.java b/vendor/gioui.org/app/internal/window/GioActivity.java deleted file mode 100644 index 260d4b6..0000000 --- a/vendor/gioui.org/app/internal/window/GioActivity.java +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package org.gioui; - -import android.app.Activity; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; - -public final class GioActivity extends Activity { - private GioView view; - - @Override public void onCreate(Bundle state) { - super.onCreate(state); - - Window w = getWindow(); - - this.view = new GioView(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - this.view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); - } - this.view.setLayoutParams(new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)); - setContentView(view); - } - - @Override public void onDestroy() { - view.destroy(); - super.onDestroy(); - } - - @Override public void onStart() { - super.onStart(); - view.start(); - } - - @Override public void onStop() { - view.stop(); - super.onStop(); - } - - @Override public void onConfigurationChanged(Configuration c) { - super.onConfigurationChanged(c); - view.configurationChanged(); - } - - @Override public void onLowMemory() { - super.onLowMemory(); - view.lowMemory(); - } - - @Override public void onBackPressed() { - if (!view.backPressed()) - super.onBackPressed(); - } -} diff --git a/vendor/gioui.org/app/internal/window/GioView.java b/vendor/gioui.org/app/internal/window/GioView.java deleted file mode 100644 index be90c50..0000000 --- a/vendor/gioui.org/app/internal/window/GioView.java +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package org.gioui; - -import java.lang.Class; -import java.lang.IllegalAccessException; -import java.lang.InstantiationException; -import java.lang.ExceptionInInitializerError; -import java.lang.SecurityException; -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.Context; -import android.graphics.Rect; -import android.os.Build; -import android.text.Editable; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.Choreographer; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.WindowInsets; -import android.view.Surface; -import android.view.SurfaceView; -import android.view.SurfaceHolder; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.EditorInfo; - -import java.io.UnsupportedEncodingException; - -public final class GioView extends SurfaceView implements Choreographer.FrameCallback { - private final static Object initLock = new Object(); - private static boolean jniLoaded; - - private final SurfaceHolder.Callback surfCallbacks; - private final View.OnFocusChangeListener focusCallback; - private final InputMethodManager imm; - private final float scrollXScale; - private final float scrollYScale; - - private long nhandle; - - public GioView(Context context) { - this(context, null); - } - - public GioView(Context context, AttributeSet attrs) { - super(context, attrs); - - // Late initialization of the Go runtime to wait for a valid context. - Gio.init(context.getApplicationContext()); - - ViewConfiguration conf = ViewConfiguration.get(context); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - scrollXScale = conf.getScaledHorizontalScrollFactor(); - scrollYScale = conf.getScaledVerticalScrollFactor(); - } else { - float listItemHeight = 48; // dp - float px = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - listItemHeight, - getResources().getDisplayMetrics() - ); - scrollXScale = px; - scrollYScale = px; - } - - nhandle = onCreateView(this); - imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); - setFocusable(true); - setFocusableInTouchMode(true); - focusCallback = new View.OnFocusChangeListener() { - @Override public void onFocusChange(View v, boolean focus) { - GioView.this.onFocusChange(nhandle, focus); - } - }; - setOnFocusChangeListener(focusCallback); - surfCallbacks = new SurfaceHolder.Callback() { - @Override public void surfaceCreated(SurfaceHolder holder) { - // Ignore; surfaceChanged is guaranteed to be called immediately after this. - } - @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - onSurfaceChanged(nhandle, getHolder().getSurface()); - } - @Override public void surfaceDestroyed(SurfaceHolder holder) { - onSurfaceDestroyed(nhandle); - } - }; - getHolder().addCallback(surfCallbacks); - } - - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - onKeyEvent(nhandle, keyCode, event.getUnicodeChar(), event.getEventTime()); - return false; - } - - @Override public boolean onGenericMotionEvent(MotionEvent event) { - dispatchMotionEvent(event); - return true; - } - - @Override public boolean onTouchEvent(MotionEvent event) { - // Ask for unbuffered events. Flutter and Chrome does it - // so I assume its good for us as well. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - requestUnbufferedDispatch(event); - } - - dispatchMotionEvent(event); - return true; - } - - private void dispatchMotionEvent(MotionEvent event) { - for (int j = 0; j < event.getHistorySize(); j++) { - long time = event.getHistoricalEventTime(j); - for (int i = 0; i < event.getPointerCount(); i++) { - onTouchEvent( - nhandle, - event.ACTION_MOVE, - event.getPointerId(i), - event.getToolType(i), - event.getHistoricalX(i, j), - event.getHistoricalY(i, j), - scrollXScale*event.getHistoricalAxisValue(MotionEvent.AXIS_HSCROLL, i, j), - scrollYScale*event.getHistoricalAxisValue(MotionEvent.AXIS_VSCROLL, i, j), - event.getButtonState(), - time); - } - } - int act = event.getActionMasked(); - int idx = event.getActionIndex(); - for (int i = 0; i < event.getPointerCount(); i++) { - int pact = event.ACTION_MOVE; - if (i == idx) { - pact = act; - } - onTouchEvent( - nhandle, - pact, - event.getPointerId(i), - event.getToolType(i), - event.getX(i), event.getY(i), - scrollXScale*event.getAxisValue(MotionEvent.AXIS_HSCROLL, i), - scrollYScale*event.getAxisValue(MotionEvent.AXIS_VSCROLL, i), - event.getButtonState(), - event.getEventTime()); - } - } - - @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - return new InputConnection(this); - } - - void showTextInput() { - post(new Runnable() { - @Override public void run() { - GioView.this.requestFocus(); - imm.showSoftInput(GioView.this, 0); - } - }); - } - - void hideTextInput() { - post(new Runnable() { - @Override public void run() { - imm.hideSoftInputFromWindow(getWindowToken(), 0); - } - }); - } - - @Override protected boolean fitSystemWindows(Rect insets) { - onWindowInsets(nhandle, insets.top, insets.right, insets.bottom, insets.left); - return true; - } - - void postFrameCallback() { - Choreographer.getInstance().removeFrameCallback(this); - Choreographer.getInstance().postFrameCallback(this); - } - - @Override public void doFrame(long nanos) { - onFrameCallback(nhandle, nanos); - } - - int getDensity() { - return getResources().getDisplayMetrics().densityDpi; - } - - float getFontScale() { - return getResources().getConfiguration().fontScale; - } - - void start() { - onStartView(nhandle); - } - - void stop() { - onStopView(nhandle); - } - - void destroy() { - setOnFocusChangeListener(null); - getHolder().removeCallback(surfCallbacks); - onDestroyView(nhandle); - nhandle = 0; - } - - void configurationChanged() { - onConfigurationChanged(nhandle); - } - - void lowMemory() { - onLowMemory(); - } - - boolean backPressed() { - return onBack(nhandle); - } - - static private native long onCreateView(GioView view); - static private native void onDestroyView(long handle); - static private native void onStartView(long handle); - static private native void onStopView(long handle); - static private native void onSurfaceDestroyed(long handle); - static private native void onSurfaceChanged(long handle, Surface surface); - static private native void onConfigurationChanged(long handle); - static private native void onWindowInsets(long handle, int top, int right, int bottom, int left); - static private native void onLowMemory(); - static private native void onTouchEvent(long handle, int action, int pointerID, int tool, float x, float y, float scrollX, float scrollY, int buttons, long time); - static private native void onKeyEvent(long handle, int code, int character, long time); - static private native void onFrameCallback(long handle, long nanos); - static private native boolean onBack(long handle); - static private native void onFocusChange(long handle, boolean focus); - - private static class InputConnection extends BaseInputConnection { - private final Editable editable; - - InputConnection(View view) { - // Passing false enables "dummy mode", where the BaseInputConnection - // attempts to convert IME operations to key events. - super(view, false); - editable = Editable.Factory.getInstance().newEditable(""); - } - - @Override public Editable getEditable() { - return editable; - } - } -} diff --git a/vendor/gioui.org/app/internal/window/d3d11_windows.go b/vendor/gioui.org/app/internal/window/d3d11_windows.go deleted file mode 100644 index f1e06a6..0000000 --- a/vendor/gioui.org/app/internal/window/d3d11_windows.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -import ( - "gioui.org/app/internal/d3d11" - "gioui.org/gpu/backend" -) - -type d3d11Context struct { - win *window - swchain *d3d11.SwapChain - fbo *d3d11.Framebuffer - backend backend.Device - *d3d11.Device - width, height int -} - -func init() { - backends = append(backends, gpuAPI{ - priority: 1, - initializer: func(w *window) (Context, error) { - hwnd, _, _ := w.HWND() - dev, err := d3d11.NewDevice() - if err != nil { - return nil, err - } - swchain, err := dev.CreateSwapChain(hwnd) - if err != nil { - dev.Release() - return nil, err - } - return &d3d11Context{win: w, Device: dev, swchain: swchain}, nil - }, - }) -} - -func (c *d3d11Context) Backend() (backend.Device, error) { - backend, err := d3d11.NewBackend(c.Device) - if err != nil { - return nil, err - } - c.backend = backend - c.backend.BindFramebuffer(c.fbo) - return backend, nil -} - -func (c *d3d11Context) Present() error { - if err := c.swchain.Present(); err != nil { - if err, ok := err.(d3d11.ErrorCode); ok { - switch err.Code { - case d3d11.DXGI_STATUS_OCCLUDED: - // Ignore - return nil - case d3d11.DXGI_ERROR_DEVICE_RESET, d3d11.DXGI_ERROR_DEVICE_REMOVED, d3d11.D3DDDIERR_DEVICEREMOVED: - return ErrDeviceLost - } - } - } - return nil -} - -func (c *d3d11Context) MakeCurrent() error { - _, width, height := c.win.HWND() - if c.fbo != nil && width == c.width && height == c.height { - c.backend.BindFramebuffer(c.fbo) - return nil - } - if c.fbo != nil { - c.fbo.Release() - c.fbo = nil - } - if err := c.swchain.Resize(); err != nil { - return err - } - c.width = width - c.height = height - fbo, err := c.swchain.Framebuffer(c.Device) - if err != nil { - return err - } - c.fbo = fbo - if c.backend != nil { - c.backend.BindFramebuffer(c.fbo) - } - return nil -} - -func (c *d3d11Context) Lock() {} - -func (c *d3d11Context) Unlock() {} - -func (c *d3d11Context) Release() { - if c.fbo != nil { - c.fbo.Release() - } - c.swchain.Release() - c.Device.Release() - c.fbo = nil - c.swchain = nil - c.Device = nil -} diff --git a/vendor/gioui.org/app/internal/window/egl_android.go b/vendor/gioui.org/app/internal/window/egl_android.go deleted file mode 100644 index 19c8d63..0000000 --- a/vendor/gioui.org/app/internal/window/egl_android.go +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -/* -#include <EGL/egl.h> -*/ -import "C" - -import ( - "unsafe" - - "gioui.org/app/internal/egl" -) - -type context struct { - win *window - *egl.Context -} - -func (w *window) NewContext() (Context, error) { - ctx, err := egl.NewContext(nil) - if err != nil { - return nil, err - } - return &context{win: w, Context: ctx}, nil -} - -func (c *context) Release() { - if c.Context != nil { - c.Context.Release() - c.Context = nil - } -} - -func (c *context) MakeCurrent() error { - c.Context.ReleaseSurface() - win, width, height := c.win.nativeWindow(c.Context.VisualID()) - if win == nil { - return nil - } - eglSurf := egl.NativeWindowType(unsafe.Pointer(win)) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - if err := c.Context.MakeCurrent(); err != nil { - return err - } - return nil -} - -func (c *context) Lock() {} - -func (c *context) Unlock() {} diff --git a/vendor/gioui.org/app/internal/window/egl_wayland.go b/vendor/gioui.org/app/internal/window/egl_wayland.go deleted file mode 100644 index b4878b4..0000000 --- a/vendor/gioui.org/app/internal/window/egl_wayland.go +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android,!nowayland freebsd - -package window - -import ( - "errors" - "unsafe" - - "gioui.org/app/internal/egl" -) - -/* -#cgo linux pkg-config: egl wayland-egl -#cgo freebsd openbsd LDFLAGS: -lwayland-egl -#cgo CFLAGS: -DMESA_EGL_NO_X11_HEADERS - -#include <EGL/egl.h> -#include <wayland-client.h> -#include <wayland-egl.h> -*/ -import "C" - -type context struct { - win *window - *egl.Context - eglWin *C.struct_wl_egl_window -} - -func (w *window) NewContext() (Context, error) { - disp := egl.NativeDisplayType(unsafe.Pointer(w.display())) - ctx, err := egl.NewContext(disp) - if err != nil { - return nil, err - } - return &context{Context: ctx, win: w}, nil -} - -func (c *context) Release() { - if c.Context != nil { - c.Context.Release() - c.Context = nil - } - if c.eglWin != nil { - C.wl_egl_window_destroy(c.eglWin) - c.eglWin = nil - } -} - -func (c *context) MakeCurrent() error { - c.Context.ReleaseSurface() - if c.eglWin != nil { - C.wl_egl_window_destroy(c.eglWin) - c.eglWin = nil - } - surf, width, height := c.win.surface() - if surf == nil { - return errors.New("wayland: no surface") - } - eglWin := C.wl_egl_window_create(surf, C.int(width), C.int(height)) - if eglWin == nil { - return errors.New("wayland: wl_egl_window_create failed") - } - c.eglWin = eglWin - eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin))) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - return c.Context.MakeCurrent() -} - -func (c *context) Lock() {} - -func (c *context) Unlock() {} diff --git a/vendor/gioui.org/app/internal/window/egl_windows.go b/vendor/gioui.org/app/internal/window/egl_windows.go deleted file mode 100644 index 654d279..0000000 --- a/vendor/gioui.org/app/internal/window/egl_windows.go +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -import ( - "gioui.org/app/internal/egl" -) - -type glContext struct { - win *window - *egl.Context -} - -func init() { - backends = append(backends, gpuAPI{ - priority: 2, - initializer: func(w *window) (Context, error) { - disp := egl.NativeDisplayType(w.HDC()) - ctx, err := egl.NewContext(disp) - if err != nil { - return nil, err - } - return &glContext{win: w, Context: ctx}, nil - }, - }) -} - -func (c *glContext) Release() { - if c.Context != nil { - c.Context.Release() - c.Context = nil - } -} - -func (c *glContext) MakeCurrent() error { - c.Context.ReleaseSurface() - win, width, height := c.win.HWND() - eglSurf := egl.NativeWindowType(win) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - if err := c.Context.MakeCurrent(); err != nil { - return err - } - c.Context.EnableVSync(true) - return nil -} - -func (c *glContext) Lock() {} - -func (c *glContext) Unlock() {} diff --git a/vendor/gioui.org/app/internal/window/egl_x11.go b/vendor/gioui.org/app/internal/window/egl_x11.go deleted file mode 100644 index ffe69c6..0000000 --- a/vendor/gioui.org/app/internal/window/egl_x11.go +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android,!nox11 freebsd openbsd - -package window - -import ( - "unsafe" - - "gioui.org/app/internal/egl" -) - -type x11Context struct { - win *x11Window - *egl.Context -} - -func (w *x11Window) NewContext() (Context, error) { - disp := egl.NativeDisplayType(unsafe.Pointer(w.display())) - ctx, err := egl.NewContext(disp) - if err != nil { - return nil, err - } - return &x11Context{win: w, Context: ctx}, nil -} - -func (c *x11Context) Release() { - if c.Context != nil { - c.Context.Release() - c.Context = nil - } -} - -func (c *x11Context) MakeCurrent() error { - c.Context.ReleaseSurface() - win, width, height := c.win.window() - eglSurf := egl.NativeWindowType(uintptr(win)) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - if err := c.Context.MakeCurrent(); err != nil { - return err - } - c.Context.EnableVSync(true) - return nil -} - -func (c *x11Context) Lock() {} - -func (c *x11Context) Unlock() {} diff --git a/vendor/gioui.org/app/internal/window/framework_ios.h b/vendor/gioui.org/app/internal/window/framework_ios.h deleted file mode 100644 index 18e5a02..0000000 --- a/vendor/gioui.org/app/internal/window/framework_ios.h +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -#include <UIKit/UIKit.h> - -@interface GioViewController : UIViewController -@end diff --git a/vendor/gioui.org/app/internal/window/gl_ios.go b/vendor/gioui.org/app/internal/window/gl_ios.go deleted file mode 100644 index 0099189..0000000 --- a/vendor/gioui.org/app/internal/window/gl_ios.go +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,ios - -package window - -/* -#include <CoreFoundation/CoreFoundation.h> -#include <OpenGLES/ES2/gl.h> -#include <OpenGLES/ES2/glext.h> - -__attribute__ ((visibility ("hidden"))) int gio_renderbufferStorage(CFTypeRef ctx, CFTypeRef layer, GLenum buffer); -__attribute__ ((visibility ("hidden"))) int gio_presentRenderbuffer(CFTypeRef ctx, GLenum buffer); -__attribute__ ((visibility ("hidden"))) int gio_makeCurrent(CFTypeRef ctx); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createContext(void); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createGLLayer(void); -*/ -import "C" - -import ( - "errors" - "fmt" - - "gioui.org/app/internal/glimpl" - "gioui.org/gpu/backend" - "gioui.org/gpu/gl" -) - -type context struct { - owner *window - c *glimpl.Functions - ctx C.CFTypeRef - layer C.CFTypeRef - init bool - frameBuffer gl.Framebuffer - colorBuffer, depthBuffer gl.Renderbuffer -} - -func init() { - layerFactory = func() uintptr { - return uintptr(C.gio_createGLLayer()) - } -} - -func newContext(w *window) (*context, error) { - ctx := C.gio_createContext() - if ctx == 0 { - return nil, fmt.Errorf("failed to create EAGLContext") - } - c := &context{ - ctx: ctx, - owner: w, - layer: C.CFTypeRef(w.contextLayer()), - c: new(glimpl.Functions), - } - return c, nil -} - -func (c *context) Backend() (backend.Device, error) { - return gl.NewBackend(c.c) -} - -func (c *context) Release() { - if c.ctx == 0 { - return - } - C.gio_renderbufferStorage(c.ctx, 0, C.GLenum(gl.RENDERBUFFER)) - c.c.DeleteFramebuffer(c.frameBuffer) - c.c.DeleteRenderbuffer(c.colorBuffer) - c.c.DeleteRenderbuffer(c.depthBuffer) - C.gio_makeCurrent(0) - C.CFRelease(c.ctx) - c.ctx = 0 -} - -func (c *context) Present() error { - if c.layer == 0 { - panic("context is not active") - } - // Discard depth buffer as recommended in - // https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html - c.c.BindFramebuffer(gl.FRAMEBUFFER, c.frameBuffer) - c.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT) - c.c.BindRenderbuffer(gl.RENDERBUFFER, c.colorBuffer) - if C.gio_presentRenderbuffer(c.ctx, C.GLenum(gl.RENDERBUFFER)) == 0 { - return errors.New("presentRenderBuffer failed") - } - return nil -} - -func (c *context) Lock() {} - -func (c *context) Unlock() {} - -func (c *context) MakeCurrent() error { - if C.gio_makeCurrent(c.ctx) == 0 { - C.CFRelease(c.ctx) - c.ctx = 0 - return errors.New("[EAGLContext setCurrentContext] failed") - } - if !c.init { - c.init = true - c.frameBuffer = c.c.CreateFramebuffer() - c.colorBuffer = c.c.CreateRenderbuffer() - c.depthBuffer = c.c.CreateRenderbuffer() - } - if !c.owner.isVisible() { - // Make sure any in-flight GL commands are complete. - c.c.Finish() - return nil - } - currentRB := gl.Renderbuffer{uint(c.c.GetInteger(gl.RENDERBUFFER_BINDING))} - c.c.BindRenderbuffer(gl.RENDERBUFFER, c.colorBuffer) - if C.gio_renderbufferStorage(c.ctx, c.layer, C.GLenum(gl.RENDERBUFFER)) == 0 { - return errors.New("renderbufferStorage failed") - } - w := c.c.GetRenderbufferParameteri(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH) - h := c.c.GetRenderbufferParameteri(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT) - c.c.BindRenderbuffer(gl.RENDERBUFFER, c.depthBuffer) - c.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h) - c.c.BindRenderbuffer(gl.RENDERBUFFER, currentRB) - c.c.BindFramebuffer(gl.FRAMEBUFFER, c.frameBuffer) - c.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, c.colorBuffer) - c.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, c.depthBuffer) - if st := c.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE { - return fmt.Errorf("framebuffer incomplete, status: %#x\n", st) - } - return nil -} - -func (w *window) NewContext() (Context, error) { - return newContext(w) -} diff --git a/vendor/gioui.org/app/internal/window/gl_ios.m b/vendor/gioui.org/app/internal/window/gl_ios.m deleted file mode 100644 index 065ea97..0000000 --- a/vendor/gioui.org/app/internal/window/gl_ios.m +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,ios - -@import UIKit; -@import OpenGLES; - -#include "_cgo_export.h" - -int gio_renderbufferStorage(CFTypeRef ctxRef, CFTypeRef layerRef, GLenum buffer) { - EAGLContext *ctx = (__bridge EAGLContext *)ctxRef; - CAEAGLLayer *layer = (__bridge CAEAGLLayer *)layerRef; - return (int)[ctx renderbufferStorage:buffer fromDrawable:layer]; -} - -int gio_presentRenderbuffer(CFTypeRef ctxRef, GLenum buffer) { - EAGLContext *ctx = (__bridge EAGLContext *)ctxRef; - return (int)[ctx presentRenderbuffer:buffer]; -} - -int gio_makeCurrent(CFTypeRef ctxRef) { - EAGLContext *ctx = (__bridge EAGLContext *)ctxRef; - return (int)[EAGLContext setCurrentContext:ctx]; -} - -CFTypeRef gio_createContext(void) { - EAGLContext *ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - if (ctx == nil) { - return nil; - } - return CFBridgingRetain(ctx); -} - -CFTypeRef gio_createGLLayer(void) { - CAEAGLLayer *layer = [[CAEAGLLayer layer] init]; - if (layer == nil) { - return nil; - } - layer.drawableProperties = @{kEAGLDrawablePropertyColorFormat: kEAGLColorFormatSRGBA8}; - layer.opaque = YES; - layer.anchorPoint = CGPointMake(0, 0); - return CFBridgingRetain(layer); -} diff --git a/vendor/gioui.org/app/internal/window/gl_js.go b/vendor/gioui.org/app/internal/window/gl_js.go deleted file mode 100644 index 0adbdf4..0000000 --- a/vendor/gioui.org/app/internal/window/gl_js.go +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -import ( - "errors" - "syscall/js" - - "gioui.org/app/internal/glimpl" - "gioui.org/app/internal/srgb" - "gioui.org/gpu/backend" - "gioui.org/gpu/gl" -) - -type context struct { - ctx js.Value - cnv js.Value - f *glimpl.Functions - srgbFBO *srgb.FBO -} - -func newContext(w *window) (*context, error) { - args := map[string]interface{}{ - // Enable low latency rendering. - // See https://developers.google.com/web/updates/2019/05/desynchronized. - "desynchronized": true, - "preserveDrawingBuffer": true, - } - version := 2 - ctx := w.cnv.Call("getContext", "webgl2", args) - if ctx.IsNull() { - version = 1 - ctx = w.cnv.Call("getContext", "webgl", args) - } - if ctx.IsNull() { - return nil, errors.New("app: webgl is not supported") - } - f := &glimpl.Functions{Ctx: ctx} - if err := f.Init(version); err != nil { - return nil, err - } - c := &context{ - ctx: ctx, - cnv: w.cnv, - f: f, - } - return c, nil -} - -func (c *context) Backend() (backend.Device, error) { - return gl.NewBackend(c.f) -} - -func (c *context) Release() { - if c.srgbFBO != nil { - c.srgbFBO.Release() - c.srgbFBO = nil - } -} - -func (c *context) Present() error { - if c.srgbFBO != nil { - c.srgbFBO.Blit() - } - if c.srgbFBO != nil { - c.srgbFBO.AfterPresent() - } - if c.ctx.Call("isContextLost").Bool() { - return errors.New("context lost") - } - return nil -} - -func (c *context) Lock() {} - -func (c *context) Unlock() {} - -func (c *context) MakeCurrent() error { - if c.srgbFBO == nil { - var err error - c.srgbFBO, err = srgb.New(c.f) - if err != nil { - c.Release() - c.srgbFBO = nil - return err - } - } - w, h := c.cnv.Get("width").Int(), c.cnv.Get("height").Int() - if err := c.srgbFBO.Refresh(w, h); err != nil { - c.Release() - return err - } - return nil -} - -func (w *window) NewContext() (Context, error) { - return newContext(w) -} diff --git a/vendor/gioui.org/app/internal/window/gl_macos.go b/vendor/gioui.org/app/internal/window/gl_macos.go deleted file mode 100644 index e4e293d..0000000 --- a/vendor/gioui.org/app/internal/window/gl_macos.go +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,!ios - -package window - -import ( - "gioui.org/app/internal/glimpl" - "gioui.org/gpu/backend" - "gioui.org/gpu/gl" -) - -/* -#include <CoreFoundation/CoreFoundation.h> -#include <CoreGraphics/CoreGraphics.h> -#include <AppKit/AppKit.h> -#include <OpenGL/gl3.h> - -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createGLView(void); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_contextForView(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) void gio_makeCurrentContext(CFTypeRef ctx); -__attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ctx); -__attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext(void); -__attribute__ ((visibility ("hidden"))) void gio_lockContext(CFTypeRef ctxRef); -__attribute__ ((visibility ("hidden"))) void gio_unlockContext(CFTypeRef ctxRef); -*/ -import "C" - -type context struct { - c *glimpl.Functions - ctx C.CFTypeRef - view C.CFTypeRef -} - -func init() { - viewFactory = func() C.CFTypeRef { - return C.gio_createGLView() - } -} - -func newContext(w *window) (*context, error) { - view := w.contextView() - ctx := C.gio_contextForView(view) - c := &context{ - ctx: ctx, - c: new(glimpl.Functions), - view: view, - } - return c, nil -} - -func (c *context) Backend() (backend.Device, error) { - return gl.NewBackend(c.c) -} - -func (c *context) Release() { - c.Lock() - defer c.Unlock() - C.gio_clearCurrentContext() - // We could release the context with [view clearGLContext] - // and rely on [view openGLContext] auto-creating a new context. - // However that second context is not properly set up by - // OpenGLContextView, so we'll stay on the safe side and keep - // the first context around. -} - -func (c *context) Present() error { - // Assume the caller already locked the context. - C.glFlush() - return nil -} - -func (c *context) Lock() { - C.gio_lockContext(c.ctx) -} - -func (c *context) Unlock() { - C.gio_unlockContext(c.ctx) -} - -func (c *context) MakeCurrent() error { - c.Lock() - defer c.Unlock() - C.gio_makeCurrentContext(c.ctx) - return nil -} - -func (w *window) NewContext() (Context, error) { - return newContext(w) -} diff --git a/vendor/gioui.org/app/internal/window/gl_macos.m b/vendor/gioui.org/app/internal/window/gl_macos.m deleted file mode 100644 index 0d7f772..0000000 --- a/vendor/gioui.org/app/internal/window/gl_macos.m +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,!ios - -@import AppKit; - -#include <CoreFoundation/CoreFoundation.h> -#include <OpenGL/OpenGL.h> -#include <OpenGL/gl3.h> -#include "_cgo_export.h" - -static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) { - NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil]; - if (!event.hasPreciseScrollingDeltas) { - // dx and dy are in rows and columns. - dx *= 10; - dy *= 10; - } - gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp], [event modifierFlags]); -} - -@interface GioView : NSOpenGLView -@end - -@implementation GioView -- (instancetype)initWithFrame:(NSRect)frameRect - pixelFormat:(NSOpenGLPixelFormat *)format { - return [super initWithFrame:frameRect pixelFormat:format]; -} -- (void)prepareOpenGL { - [super prepareOpenGL]; - // Bind a default VBA to emulate OpenGL ES 2. - GLuint defVBA; - glGenVertexArrays(1, &defVBA); - glBindVertexArray(defVBA); - glEnable(GL_FRAMEBUFFER_SRGB); -} -- (BOOL)isFlipped { - return YES; -} -- (void)update { - [super update]; - [self setNeedsDisplay:YES]; -} -- (void)drawRect:(NSRect)r { - gio_onDraw((__bridge CFTypeRef)self); -} -- (void)mouseDown:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0); -} -- (void)mouseUp:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_UP, 0, 0); -} -- (void)middleMouseDown:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0); -} -- (void)middletMouseUp:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_UP, 0, 0); -} -- (void)rightMouseDown:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_DOWN, 0, 0); -} -- (void)rightMouseUp:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_UP, 0, 0); -} -- (void)mouseMoved:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0); -} -- (void)mouseDragged:(NSEvent *)event { - handleMouse(self, event, GIO_MOUSE_MOVE, 0, 0); -} -- (void)scrollWheel:(NSEvent *)event { - CGFloat dx = -event.scrollingDeltaX; - CGFloat dy = -event.scrollingDeltaY; - handleMouse(self, event, GIO_MOUSE_SCROLL, dx, dy); -} -- (void)keyDown:(NSEvent *)event { - NSString *keys = [event charactersIgnoringModifiers]; - gio_onKeys((__bridge CFTypeRef)self, (char *)[keys UTF8String], [event timestamp], [event modifierFlags]); - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; -} -- (void)insertText:(id)string { - const char *utf8 = [string UTF8String]; - gio_onText((__bridge CFTypeRef)self, (char *)utf8); -} -- (void)doCommandBySelector:(SEL)sel { - // Don't pass commands up the responder chain. - // They will end up in a beep. -} -@end - -CFTypeRef gio_createGLView(void) { - @autoreleasepool { - NSOpenGLPixelFormatAttribute attr[] = { - NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFADepthSize, 16, - NSOpenGLPFAAccelerated, - // Opt-in to automatic GPU switching. CGL-only property. - kCGLPFASupportsAutomaticGraphicsSwitching, - NSOpenGLPFAAllowOfflineRenderers, - 0 - }; - id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr]; - - NSRect frame = NSMakeRect(0, 0, 0, 0); - GioView* view = [[GioView alloc] initWithFrame:frame pixelFormat:pixFormat]; - - [view setWantsBestResolutionOpenGLSurface:YES]; - [view setWantsLayer:YES]; // The default in Mojave. - - return CFBridgingRetain(view); - } -} - -void gio_setNeedsDisplay(CFTypeRef viewRef) { - NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef; - [view setNeedsDisplay:YES]; -} - -CFTypeRef gio_contextForView(CFTypeRef viewRef) { - NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef; - return (__bridge CFTypeRef)view.openGLContext; -} - -void gio_clearCurrentContext(void) { - [NSOpenGLContext clearCurrentContext]; -} - -void gio_makeCurrentContext(CFTypeRef ctxRef) { - NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef; - [ctx makeCurrentContext]; -} - -void gio_lockContext(CFTypeRef ctxRef) { - NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef; - CGLLockContext([ctx CGLContextObj]); -} - -void gio_unlockContext(CFTypeRef ctxRef) { - NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef; - CGLUnlockContext([ctx CGLContextObj]); -} diff --git a/vendor/gioui.org/app/internal/window/os_android.c b/vendor/gioui.org/app/internal/window/os_android.c deleted file mode 100644 index 8a2c62d..0000000 --- a/vendor/gioui.org/app/internal/window/os_android.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -#include <jni.h> -#include "_cgo_export.h" - -jint gio_jni_GetEnv(JavaVM *vm, JNIEnv **env, jint version) { - return (*vm)->GetEnv(vm, (void **)env, version); -} - -jint gio_jni_GetJavaVM(JNIEnv *env, JavaVM **jvm) { - return (*env)->GetJavaVM(env, jvm); -} - -jint gio_jni_AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args) { - return (*vm)->AttachCurrentThread(vm, p_env, thr_args); -} - -jint gio_jni_DetachCurrentThread(JavaVM *vm) { - return (*vm)->DetachCurrentThread(vm); -} - -jobject gio_jni_NewGlobalRef(JNIEnv *env, jobject obj) { - return (*env)->NewGlobalRef(env, obj); -} - -void gio_jni_DeleteGlobalRef(JNIEnv *env, jobject obj) { - (*env)->DeleteGlobalRef(env, obj); -} - -jclass gio_jni_GetObjectClass(JNIEnv *env, jobject obj) { - return (*env)->GetObjectClass(env, obj); -} - -jmethodID gio_jni_GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { - return (*env)->GetMethodID(env, clazz, name, sig); -} - -jmethodID gio_jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { - return (*env)->GetStaticMethodID(env, clazz, name, sig); -} - -jfloat gio_jni_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID) { - return (*env)->CallFloatMethod(env, obj, methodID); -} - -jint gio_jni_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID) { - return (*env)->CallIntMethod(env, obj, methodID); -} - -void gio_jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args) { - (*env)->CallStaticVoidMethodA(env, cls, methodID, args); -} - -void gio_jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args) { - (*env)->CallVoidMethodA(env, obj, methodID, args); -} - -jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr) { - return (*env)->GetByteArrayElements(env, arr, NULL); -} - -void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes) { - (*env)->ReleaseByteArrayElements(env, arr, bytes, JNI_ABORT); -} - -jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr) { - return (*env)->GetArrayLength(env, arr); -} - -jstring gio_jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len) { - return (*env)->NewString(env, unicodeChars, len); -} - -jsize gio_jni_GetStringLength(JNIEnv *env, jstring str) { - return (*env)->GetStringLength(env, str); -} - -const jchar *gio_jni_GetStringChars(JNIEnv *env, jstring str) { - return (*env)->GetStringChars(env, str, NULL); -} - -jthrowable gio_jni_ExceptionOccurred(JNIEnv *env) { - return (*env)->ExceptionOccurred(env); -} - -void gio_jni_ExceptionClear(JNIEnv *env) { - (*env)->ExceptionClear(env); -} - -jobject gio_jni_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args) { - return (*env)->CallObjectMethodA(env, obj, method, args); -} - -jobject gio_jni_CallStaticObjectMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args) { - return (*env)->CallStaticObjectMethodA(env, cls, method, args); -} diff --git a/vendor/gioui.org/app/internal/window/os_android.go b/vendor/gioui.org/app/internal/window/os_android.go deleted file mode 100644 index 3458b26..0000000 --- a/vendor/gioui.org/app/internal/window/os_android.go +++ /dev/null @@ -1,684 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -/* -#cgo CFLAGS: -Werror -#cgo LDFLAGS: -landroid - -#include <android/native_window_jni.h> -#include <android/configuration.h> -#include <android/keycodes.h> -#include <android/input.h> -#include <stdlib.h> - -__attribute__ ((visibility ("hidden"))) jint gio_jni_GetEnv(JavaVM *vm, JNIEnv **env, jint version); -__attribute__ ((visibility ("hidden"))) jint gio_jni_GetJavaVM(JNIEnv *env, JavaVM **jvm); -__attribute__ ((visibility ("hidden"))) jint gio_jni_AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args); -__attribute__ ((visibility ("hidden"))) jint gio_jni_DetachCurrentThread(JavaVM *vm); - -__attribute__ ((visibility ("hidden"))) jobject gio_jni_NewGlobalRef(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) void gio_jni_DeleteGlobalRef(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) jclass gio_jni_GetObjectClass(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) jmethodID gio_jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); -__attribute__ ((visibility ("hidden"))) jmethodID gio_jni_GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); -__attribute__ ((visibility ("hidden"))) jfloat gio_jni_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID); -__attribute__ ((visibility ("hidden"))) jint gio_jni_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID); -__attribute__ ((visibility ("hidden"))) void gio_jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args); -__attribute__ ((visibility ("hidden"))) void gio_jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); -__attribute__ ((visibility ("hidden"))) jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr); -__attribute__ ((visibility ("hidden"))) void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes); -__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr); -__attribute__ ((visibility ("hidden"))) jstring gio_jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len); -__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetStringLength(JNIEnv *env, jstring str); -__attribute__ ((visibility ("hidden"))) const jchar *gio_jni_GetStringChars(JNIEnv *env, jstring str); -__attribute__ ((visibility ("hidden"))) jthrowable gio_jni_ExceptionOccurred(JNIEnv *env); -__attribute__ ((visibility ("hidden"))) void gio_jni_ExceptionClear(JNIEnv *env); -__attribute__ ((visibility ("hidden"))) jobject gio_jni_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args); -__attribute__ ((visibility ("hidden"))) jobject gio_jni_CallStaticObjectMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args); -*/ -import "C" - -import ( - "errors" - "fmt" - "image" - "reflect" - "runtime" - "runtime/debug" - "sync" - "time" - "unicode/utf16" - "unsafe" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" -) - -type window struct { - callbacks Callbacks - - view C.jobject - - dpi int - fontScale float32 - insets system.Insets - - stage system.Stage - started bool - - mu sync.Mutex - win *C.ANativeWindow - animating bool - - // Cached Java methods. - mgetDensity C.jmethodID - mgetFontScale C.jmethodID - mshowTextInput C.jmethodID - mhideTextInput C.jmethodID - mpostFrameCallback C.jmethodID -} - -type jvalue uint64 // The largest JNI type fits in 64 bits. - -var dataDirChan = make(chan string, 1) - -var android struct { - // mu protects all fields of this structure. However, once a - // non-nil jvm is returned from javaVM, all the other fields may - // be accessed unlocked. - mu sync.Mutex - jvm *C.JavaVM - - // appCtx is the global Android App context. - appCtx C.jobject - // gioCls is the class of the Gio class. - gioCls C.jclass - - mwriteClipboard C.jmethodID - mreadClipboard C.jmethodID - mwakeupMainThread C.jmethodID -} - -var views = make(map[C.jlong]*window) - -var mainWindow = newWindowRendezvous() - -var mainFuncs = make(chan func(env *C.JNIEnv), 1) - -func getMethodID(env *C.JNIEnv, class C.jclass, method, sig string) C.jmethodID { - m := C.CString(method) - defer C.free(unsafe.Pointer(m)) - s := C.CString(sig) - defer C.free(unsafe.Pointer(s)) - jm := C.gio_jni_GetMethodID(env, class, m, s) - if err := exception(env); err != nil { - panic(err) - } - return jm -} - -func getStaticMethodID(env *C.JNIEnv, class C.jclass, method, sig string) C.jmethodID { - m := C.CString(method) - defer C.free(unsafe.Pointer(m)) - s := C.CString(sig) - defer C.free(unsafe.Pointer(s)) - jm := C.gio_jni_GetStaticMethodID(env, class, m, s) - if err := exception(env); err != nil { - panic(err) - } - return jm -} - -//export Java_org_gioui_Gio_runGoMain -func Java_org_gioui_Gio_runGoMain(env *C.JNIEnv, class C.jclass, jdataDir C.jbyteArray, context C.jobject) { - initJVM(env, class, context) - dirBytes := C.gio_jni_GetByteArrayElements(env, jdataDir) - if dirBytes == nil { - panic("runGoMain: GetByteArrayElements failed") - } - n := C.gio_jni_GetArrayLength(env, jdataDir) - dataDir := C.GoStringN((*C.char)(unsafe.Pointer(dirBytes)), n) - dataDirChan <- dataDir - C.gio_jni_ReleaseByteArrayElements(env, jdataDir, dirBytes) - - runMain() -} - -func initJVM(env *C.JNIEnv, gio C.jclass, ctx C.jobject) { - android.mu.Lock() - defer android.mu.Unlock() - if res := C.gio_jni_GetJavaVM(env, &android.jvm); res != 0 { - panic("gio: GetJavaVM failed") - } - android.appCtx = C.gio_jni_NewGlobalRef(env, ctx) - android.gioCls = C.jclass(C.gio_jni_NewGlobalRef(env, C.jobject(gio))) - android.mwriteClipboard = getStaticMethodID(env, gio, "writeClipboard", "(Landroid/content/Context;Ljava/lang/String;)V") - android.mreadClipboard = getStaticMethodID(env, gio, "readClipboard", "(Landroid/content/Context;)Ljava/lang/String;") - android.mwakeupMainThread = getStaticMethodID(env, gio, "wakeupMainThread", "()V") -} - -func JavaVM() uintptr { - jvm := javaVM() - return uintptr(unsafe.Pointer(jvm)) -} - -func javaVM() *C.JavaVM { - android.mu.Lock() - defer android.mu.Unlock() - return android.jvm -} - -func AppContext() uintptr { - android.mu.Lock() - defer android.mu.Unlock() - return uintptr(android.appCtx) -} - -func GetDataDir() string { - return <-dataDirChan -} - -//export Java_org_gioui_GioView_onCreateView -func Java_org_gioui_GioView_onCreateView(env *C.JNIEnv, class C.jclass, view C.jobject) C.jlong { - view = C.gio_jni_NewGlobalRef(env, view) - w := &window{ - view: view, - mgetDensity: getMethodID(env, class, "getDensity", "()I"), - mgetFontScale: getMethodID(env, class, "getFontScale", "()F"), - mshowTextInput: getMethodID(env, class, "showTextInput", "()V"), - mhideTextInput: getMethodID(env, class, "hideTextInput", "()V"), - mpostFrameCallback: getMethodID(env, class, "postFrameCallback", "()V"), - } - wopts := <-mainWindow.out - w.callbacks = wopts.window - w.callbacks.SetDriver(w) - handle := C.jlong(view) - views[handle] = w - w.loadConfig(env, class) - w.setStage(system.StagePaused) - return handle -} - -//export Java_org_gioui_GioView_onDestroyView -func Java_org_gioui_GioView_onDestroyView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.callbacks.SetDriver(nil) - delete(views, handle) - C.gio_jni_DeleteGlobalRef(env, w.view) - w.view = 0 -} - -//export Java_org_gioui_GioView_onStopView -func Java_org_gioui_GioView_onStopView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.started = false - w.setStage(system.StagePaused) -} - -//export Java_org_gioui_GioView_onStartView -func Java_org_gioui_GioView_onStartView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.started = true - if w.aNativeWindow() != nil { - w.setVisible() - } -} - -//export Java_org_gioui_GioView_onSurfaceDestroyed -func Java_org_gioui_GioView_onSurfaceDestroyed(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.mu.Lock() - w.win = nil - w.mu.Unlock() - w.setStage(system.StagePaused) -} - -//export Java_org_gioui_GioView_onSurfaceChanged -func Java_org_gioui_GioView_onSurfaceChanged(env *C.JNIEnv, class C.jclass, handle C.jlong, surf C.jobject) { - w := views[handle] - w.mu.Lock() - w.win = C.ANativeWindow_fromSurface(env, surf) - w.mu.Unlock() - if w.started { - w.setVisible() - } -} - -//export Java_org_gioui_GioView_onLowMemory -func Java_org_gioui_GioView_onLowMemory() { - runtime.GC() - debug.FreeOSMemory() -} - -//export Java_org_gioui_GioView_onConfigurationChanged -func Java_org_gioui_GioView_onConfigurationChanged(env *C.JNIEnv, class C.jclass, view C.jlong) { - w := views[view] - w.loadConfig(env, class) - if w.stage >= system.StageRunning { - w.draw(true) - } -} - -//export Java_org_gioui_GioView_onFrameCallback -func Java_org_gioui_GioView_onFrameCallback(env *C.JNIEnv, class C.jclass, view C.jlong, nanos C.jlong) { - w, exist := views[view] - if !exist { - return - } - if w.stage < system.StageRunning { - return - } - w.mu.Lock() - anim := w.animating - w.mu.Unlock() - if anim { - runInJVM(javaVM(), func(env *C.JNIEnv) { - callVoidMethod(env, w.view, w.mpostFrameCallback) - }) - w.draw(false) - } -} - -//export Java_org_gioui_GioView_onBack -func Java_org_gioui_GioView_onBack(env *C.JNIEnv, class C.jclass, view C.jlong) C.jboolean { - w := views[view] - ev := &system.CommandEvent{Type: system.CommandBack} - w.callbacks.Event(ev) - if ev.Cancel { - return C.JNI_TRUE - } - return C.JNI_FALSE -} - -//export Java_org_gioui_GioView_onFocusChange -func Java_org_gioui_GioView_onFocusChange(env *C.JNIEnv, class C.jclass, view C.jlong, focus C.jboolean) { - w := views[view] - w.callbacks.Event(key.FocusEvent{Focus: focus == C.JNI_TRUE}) -} - -//export Java_org_gioui_GioView_onWindowInsets -func Java_org_gioui_GioView_onWindowInsets(env *C.JNIEnv, class C.jclass, view C.jlong, top, right, bottom, left C.jint) { - w := views[view] - w.insets = system.Insets{ - Top: unit.Px(float32(top)), - Right: unit.Px(float32(right)), - Bottom: unit.Px(float32(bottom)), - Left: unit.Px(float32(left)), - } - if w.stage >= system.StageRunning { - w.draw(true) - } -} - -func (w *window) setVisible() { - win := w.aNativeWindow() - width, height := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - if width == 0 || height == 0 { - return - } - w.setStage(system.StageRunning) - w.draw(true) -} - -func (w *window) setStage(stage system.Stage) { - if stage == w.stage { - return - } - w.stage = stage - w.callbacks.Event(system.StageEvent{stage}) -} - -func (w *window) nativeWindow(visID int) (*C.ANativeWindow, int, int) { - win := w.aNativeWindow() - var width, height int - if win != nil { - if C.ANativeWindow_setBuffersGeometry(win, 0, 0, C.int32_t(visID)) != 0 { - panic(errors.New("ANativeWindow_setBuffersGeometry failed")) - } - w, h := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - width, height = int(w), int(h) - } - return win, width, height -} - -func (w *window) aNativeWindow() *C.ANativeWindow { - w.mu.Lock() - defer w.mu.Unlock() - return w.win -} - -func (w *window) loadConfig(env *C.JNIEnv, class C.jclass) { - dpi := int(C.gio_jni_CallIntMethod(env, w.view, w.mgetDensity)) - w.fontScale = float32(C.gio_jni_CallFloatMethod(env, w.view, w.mgetFontScale)) - switch dpi { - case C.ACONFIGURATION_DENSITY_NONE, - C.ACONFIGURATION_DENSITY_DEFAULT, - C.ACONFIGURATION_DENSITY_ANY: - // Assume standard density. - w.dpi = C.ACONFIGURATION_DENSITY_MEDIUM - default: - w.dpi = int(dpi) - } -} - -func (w *window) SetAnimating(anim bool) { - w.mu.Lock() - w.animating = anim - w.mu.Unlock() - if anim { - runOnMain(func(env *C.JNIEnv) { - if w.view == 0 { - // View was destroyed while switching to main thread. - return - } - callVoidMethod(env, w.view, w.mpostFrameCallback) - }) - } -} - -func (w *window) draw(sync bool) { - win := w.aNativeWindow() - width, height := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - if width == 0 || height == 0 { - return - } - const inchPrDp = 1.0 / 160 - ppdp := float32(w.dpi) * inchPrDp - w.callbacks.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: int(width), - Y: int(height), - }, - Insets: w.insets, - Metric: unit.Metric{ - PxPerDp: ppdp, - PxPerSp: w.fontScale * ppdp, - }, - }, - Sync: sync, - }) -} - -type keyMapper func(devId, keyCode C.int32_t) rune - -func runInJVM(jvm *C.JavaVM, f func(env *C.JNIEnv)) { - if jvm == nil { - panic("nil JVM") - } - runtime.LockOSThread() - defer runtime.UnlockOSThread() - var env *C.JNIEnv - if res := C.gio_jni_GetEnv(jvm, &env, C.JNI_VERSION_1_6); res != C.JNI_OK { - if res != C.JNI_EDETACHED { - panic(fmt.Errorf("JNI GetEnv failed with error %d", res)) - } - if C.gio_jni_AttachCurrentThread(jvm, &env, nil) != C.JNI_OK { - panic(errors.New("runInJVM: AttachCurrentThread failed")) - } - defer C.gio_jni_DetachCurrentThread(jvm) - } - - f(env) -} - -func convertKeyCode(code C.jint) (string, bool) { - var n string - switch code { - case C.AKEYCODE_DPAD_UP: - n = key.NameUpArrow - case C.AKEYCODE_DPAD_DOWN: - n = key.NameDownArrow - case C.AKEYCODE_DPAD_LEFT: - n = key.NameLeftArrow - case C.AKEYCODE_DPAD_RIGHT: - n = key.NameRightArrow - case C.AKEYCODE_FORWARD_DEL: - n = key.NameDeleteForward - case C.AKEYCODE_DEL: - n = key.NameDeleteBackward - default: - return "", false - } - return n, true -} - -//export Java_org_gioui_GioView_onKeyEvent -func Java_org_gioui_GioView_onKeyEvent(env *C.JNIEnv, class C.jclass, handle C.jlong, keyCode, r C.jint, t C.jlong) { - w := views[handle] - if n, ok := convertKeyCode(keyCode); ok { - w.callbacks.Event(key.Event{Name: n}) - } - if r != 0 { - w.callbacks.Event(key.EditEvent{Text: string(rune(r))}) - } -} - -//export Java_org_gioui_GioView_onTouchEvent -func Java_org_gioui_GioView_onTouchEvent(env *C.JNIEnv, class C.jclass, handle C.jlong, action, pointerID, tool C.jint, x, y, scrollX, scrollY C.jfloat, jbtns C.jint, t C.jlong) { - w := views[handle] - var typ pointer.Type - switch action { - case C.AMOTION_EVENT_ACTION_DOWN, C.AMOTION_EVENT_ACTION_POINTER_DOWN: - typ = pointer.Press - case C.AMOTION_EVENT_ACTION_UP, C.AMOTION_EVENT_ACTION_POINTER_UP: - typ = pointer.Release - case C.AMOTION_EVENT_ACTION_CANCEL: - typ = pointer.Cancel - case C.AMOTION_EVENT_ACTION_MOVE: - typ = pointer.Move - case C.AMOTION_EVENT_ACTION_SCROLL: - typ = pointer.Scroll - default: - return - } - var src pointer.Source - var btns pointer.Buttons - if jbtns&C.AMOTION_EVENT_BUTTON_PRIMARY != 0 { - btns |= pointer.ButtonLeft - } - if jbtns&C.AMOTION_EVENT_BUTTON_SECONDARY != 0 { - btns |= pointer.ButtonRight - } - if jbtns&C.AMOTION_EVENT_BUTTON_TERTIARY != 0 { - btns |= pointer.ButtonMiddle - } - switch tool { - case C.AMOTION_EVENT_TOOL_TYPE_FINGER: - src = pointer.Touch - case C.AMOTION_EVENT_TOOL_TYPE_MOUSE: - src = pointer.Mouse - case C.AMOTION_EVENT_TOOL_TYPE_UNKNOWN: - // For example, triggered via 'adb shell input tap'. - // Instead of discarding it, treat it as a touch event. - src = pointer.Touch - default: - return - } - w.callbacks.Event(pointer.Event{ - Type: typ, - Source: src, - Buttons: btns, - PointerID: pointer.ID(pointerID), - Time: time.Duration(t) * time.Millisecond, - Position: f32.Point{X: float32(x), Y: float32(y)}, - Scroll: f32.Pt(float32(scrollX), float32(scrollY)), - }) -} - -func (w *window) ShowTextInput(show bool) { - if w.view == 0 { - return - } - runInJVM(javaVM(), func(env *C.JNIEnv) { - if show { - callVoidMethod(env, w.view, w.mshowTextInput) - } else { - callVoidMethod(env, w.view, w.mhideTextInput) - } - }) -} - -func javaString(env *C.JNIEnv, str string) C.jstring { - if str == "" { - return 0 - } - utf16Chars := utf16.Encode([]rune(str)) - return C.gio_jni_NewString(env, (*C.jchar)(unsafe.Pointer(&utf16Chars[0])), C.int(len(utf16Chars))) -} - -// Do invokes the function with a global JNI handle to the view. If -// the view is destroyed, Do returns false and does not invoke the -// function. -// -// NOTE: Do must be invoked on the Android main thread. -func (w *window) Do(f func(view uintptr)) bool { - if w.view == 0 { - return false - } - runInJVM(javaVM(), func(env *C.JNIEnv) { - view := C.gio_jni_NewGlobalRef(env, w.view) - defer C.gio_jni_DeleteGlobalRef(env, view) - f(uintptr(view)) - }) - return true -} - -func varArgs(args []jvalue) *C.jvalue { - if len(args) == 0 { - return nil - } - return (*C.jvalue)(unsafe.Pointer(&args[0])) -} - -func callStaticVoidMethod(env *C.JNIEnv, cls C.jclass, method C.jmethodID, args ...jvalue) error { - C.gio_jni_CallStaticVoidMethodA(env, cls, method, varArgs(args)) - return exception(env) -} - -func callStaticObjectMethod(env *C.JNIEnv, cls C.jclass, method C.jmethodID, args ...jvalue) (C.jobject, error) { - res := C.gio_jni_CallStaticObjectMethodA(env, cls, method, varArgs(args)) - return res, exception(env) -} - -func callVoidMethod(env *C.JNIEnv, obj C.jobject, method C.jmethodID, args ...jvalue) error { - C.gio_jni_CallVoidMethodA(env, obj, method, varArgs(args)) - return exception(env) -} - -func callObjectMethod(env *C.JNIEnv, obj C.jobject, method C.jmethodID, args ...jvalue) (C.jobject, error) { - res := C.gio_jni_CallObjectMethodA(env, obj, method, varArgs(args)) - return res, exception(env) -} - -// exception returns an error corresponding to the pending -// exception, or nil if no exception is pending. The pending -// exception is cleared. -func exception(env *C.JNIEnv) error { - thr := C.gio_jni_ExceptionOccurred(env) - if thr == 0 { - return nil - } - C.gio_jni_ExceptionClear(env) - cls := getObjectClass(env, C.jobject(thr)) - toString := getMethodID(env, cls, "toString", "()Ljava/lang/String;") - msg, err := callObjectMethod(env, C.jobject(thr), toString) - if err != nil { - return err - } - return errors.New(goString(env, C.jstring(msg))) -} - -func getObjectClass(env *C.JNIEnv, obj C.jobject) C.jclass { - if obj == 0 { - panic("null object") - } - cls := C.gio_jni_GetObjectClass(env, C.jobject(obj)) - if err := exception(env); err != nil { - // GetObjectClass should never fail. - panic(err) - } - return cls -} - -// goString converts the JVM jstring to a Go string. -func goString(env *C.JNIEnv, str C.jstring) string { - if str == 0 { - return "" - } - strlen := C.gio_jni_GetStringLength(env, C.jstring(str)) - chars := C.gio_jni_GetStringChars(env, C.jstring(str)) - var utf16Chars []uint16 - hdr := (*reflect.SliceHeader)(unsafe.Pointer(&utf16Chars)) - hdr.Data = uintptr(unsafe.Pointer(chars)) - hdr.Cap = int(strlen) - hdr.Len = int(strlen) - utf8 := utf16.Decode(utf16Chars) - return string(utf8) -} - -func Main() { -} - -func NewWindow(window Callbacks, opts *Options) error { - mainWindow.in <- windowAndOptions{window, opts} - return <-mainWindow.errs -} - -func (w *window) WriteClipboard(s string) { - runOnMain(func(env *C.JNIEnv) { - jstr := javaString(env, s) - callStaticVoidMethod(env, android.gioCls, android.mwriteClipboard, - jvalue(android.appCtx), jvalue(jstr)) - }) -} - -func (w *window) ReadClipboard() { - runOnMain(func(env *C.JNIEnv) { - c, err := callStaticObjectMethod(env, android.gioCls, android.mreadClipboard, - jvalue(android.appCtx)) - if err != nil { - return - } - content := goString(env, C.jstring(c)) - w.callbacks.Event(system.ClipboardEvent{Text: content}) - }) -} - -// Close the window. Not implemented for Android. -func (w *window) Close() {} - -// RunOnMain is the exported version of runOnMain without a JNI -// environement. -func RunOnMain(f func()) { - runOnMain(func(_ *C.JNIEnv) { - f() - }) -} - -// runOnMain runs a function on the Java main thread. -func runOnMain(f func(env *C.JNIEnv)) { - go func() { - mainFuncs <- f - runInJVM(javaVM(), func(env *C.JNIEnv) { - callStaticVoidMethod(env, android.gioCls, android.mwakeupMainThread) - }) - }() -} - -//export Java_org_gioui_Gio_scheduleMainFuncs -func Java_org_gioui_Gio_scheduleMainFuncs(env *C.JNIEnv, cls C.jclass) { - for { - select { - case f := <-mainFuncs: - f(env) - default: - return - } - } -} diff --git a/vendor/gioui.org/app/internal/window/os_darwin.go b/vendor/gioui.org/app/internal/window/os_darwin.go deleted file mode 100644 index a3b77dc..0000000 --- a/vendor/gioui.org/app/internal/window/os_darwin.go +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -/* -#include <Foundation/Foundation.h> - -__attribute__ ((visibility ("hidden"))) void gio_wakeupMainThread(void); -__attribute__ ((visibility ("hidden"))) NSUInteger gio_nsstringLength(CFTypeRef str); -__attribute__ ((visibility ("hidden"))) void gio_nsstringGetCharacters(CFTypeRef str, unichar *chars, NSUInteger loc, NSUInteger length); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createDisplayLink(void); -__attribute__ ((visibility ("hidden"))) void gio_releaseDisplayLink(CFTypeRef dl); -__attribute__ ((visibility ("hidden"))) int gio_startDisplayLink(CFTypeRef dl); -__attribute__ ((visibility ("hidden"))) int gio_stopDisplayLink(CFTypeRef dl); -__attribute__ ((visibility ("hidden"))) void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did); -*/ -import "C" -import ( - "errors" - "sync" - "sync/atomic" - "time" - "unicode/utf16" - "unsafe" -) - -// displayLink is the state for a display link (CVDisplayLinkRef on macOS, -// CADisplayLink on iOS). It runs a state-machine goroutine that keeps the -// display link running for a while after being stopped to avoid the thread -// start/stop overhead and because the CVDisplayLink sometimes fails to -// start, stop and start again within a short duration. -type displayLink struct { - callback func() - // states is for starting or stopping the display link. - states chan bool - // done is closed when the display link is destroyed. - done chan struct{} - // dids receives the display id when the callback owner is moved - // to a different screen. - dids chan uint64 - // running tracks the desired state of the link. running is accessed - // with atomic. - running uint32 -} - -// displayLinks maps CFTypeRefs to *displayLinks. -var displayLinks sync.Map - -var mainFuncs = make(chan func(), 1) - -// runOnMain runs the function on the main thread. -func runOnMain(f func()) { - go func() { - mainFuncs <- f - C.gio_wakeupMainThread() - }() -} - -//export gio_dispatchMainFuncs -func gio_dispatchMainFuncs() { - for { - select { - case f := <-mainFuncs: - f() - default: - return - } - } -} - -// nsstringToString converts a NSString to a Go string, and -// releases the original string. -func nsstringToString(str C.CFTypeRef) string { - defer C.CFRelease(str) - n := C.gio_nsstringLength(str) - if n == 0 { - return "" - } - chars := make([]uint16, n) - C.gio_nsstringGetCharacters(str, (*C.unichar)(unsafe.Pointer(&chars[0])), 0, n) - utf8 := utf16.Decode(chars) - return string(utf8) -} - -func NewDisplayLink(callback func()) (*displayLink, error) { - d := &displayLink{ - callback: callback, - done: make(chan struct{}), - states: make(chan bool), - dids: make(chan uint64), - } - dl := C.gio_createDisplayLink() - if dl == 0 { - return nil, errors.New("app: failed to create display link") - } - go d.run(dl) - return d, nil -} - -func (d *displayLink) run(dl C.CFTypeRef) { - defer C.gio_releaseDisplayLink(dl) - displayLinks.Store(dl, d) - defer displayLinks.Delete(dl) - var stopTimer *time.Timer - var tchan <-chan time.Time - started := false - for { - select { - case <-tchan: - tchan = nil - started = false - C.gio_stopDisplayLink(dl) - case start := <-d.states: - switch { - case !start && tchan == nil: - // stopTimeout is the delay before stopping the display link to - // avoid the overhead of frequently starting and stopping the - // link thread. - const stopTimeout = 500 * time.Millisecond - if stopTimer == nil { - stopTimer = time.NewTimer(stopTimeout) - } else { - // stopTimer is always drained when tchan == nil. - stopTimer.Reset(stopTimeout) - } - tchan = stopTimer.C - atomic.StoreUint32(&d.running, 0) - case start: - if tchan != nil && !stopTimer.Stop() { - <-tchan - } - tchan = nil - atomic.StoreUint32(&d.running, 1) - if !started { - started = true - C.gio_startDisplayLink(dl) - } - } - case did := <-d.dids: - C.gio_setDisplayLinkDisplay(dl, C.uint64_t(did)) - case <-d.done: - return - } - } -} - -func (d *displayLink) Start() { - d.states <- true -} - -func (d *displayLink) Stop() { - d.states <- false -} - -func (d *displayLink) Close() { - close(d.done) -} - -func (d *displayLink) SetDisplayID(did uint64) { - d.dids <- did -} - -//export gio_onFrameCallback -func gio_onFrameCallback(dl C.CFTypeRef) { - if d, exists := displayLinks.Load(dl); exists { - d := d.(*displayLink) - if atomic.LoadUint32(&d.running) != 0 { - d.callback() - } - } -} diff --git a/vendor/gioui.org/app/internal/window/os_darwin.m b/vendor/gioui.org/app/internal/window/os_darwin.m deleted file mode 100644 index dc4f00b..0000000 --- a/vendor/gioui.org/app/internal/window/os_darwin.m +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -@import Dispatch; -@import Foundation; - -#include "_cgo_export.h" - -void gio_wakeupMainThread(void) { - dispatch_async(dispatch_get_main_queue(), ^{ - gio_dispatchMainFuncs(); - }); -} - -NSUInteger gio_nsstringLength(CFTypeRef cstr) { - NSString *str = (__bridge NSString *)cstr; - return [str length]; -} - -void gio_nsstringGetCharacters(CFTypeRef cstr, unichar *chars, NSUInteger loc, NSUInteger length) { - NSString *str = (__bridge NSString *)cstr; - [str getCharacters:chars range:NSMakeRange(loc, length)]; -} diff --git a/vendor/gioui.org/app/internal/window/os_ios.go b/vendor/gioui.org/app/internal/window/os_ios.go deleted file mode 100644 index 1865454..0000000 --- a/vendor/gioui.org/app/internal/window/os_ios.go +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,ios - -package window - -/* -#cgo CFLAGS: -DGLES_SILENCE_DEPRECATION -Werror -Wno-deprecated-declarations -fmodules -fobjc-arc -x objective-c - -#include <CoreGraphics/CoreGraphics.h> -#include <UIKit/UIKit.h> -#include <stdint.h> - -struct drawParams { - CGFloat dpi, sdpi; - CGFloat width, height; - CGFloat top, right, bottom, left; -}; - -__attribute__ ((visibility ("hidden"))) void gio_showTextInput(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) void gio_hideTextInput(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) void gio_addLayerToView(CFTypeRef viewRef, CFTypeRef layerRef); -__attribute__ ((visibility ("hidden"))) void gio_updateView(CFTypeRef viewRef, CFTypeRef layerRef); -__attribute__ ((visibility ("hidden"))) void gio_removeLayer(CFTypeRef layerRef); -__attribute__ ((visibility ("hidden"))) struct drawParams gio_viewDrawParams(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_readClipboard(void); -__attribute__ ((visibility ("hidden"))) void gio_writeClipboard(unichar *chars, NSUInteger length); -*/ -import "C" - -import ( - "image" - "runtime" - "runtime/debug" - "sync/atomic" - "time" - "unicode/utf16" - "unsafe" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" -) - -type window struct { - view C.CFTypeRef - w Callbacks - displayLink *displayLink - - layer C.CFTypeRef - visible atomic.Value - - pointerMap []C.CFTypeRef -} - -var mainWindow = newWindowRendezvous() - -var layerFactory func() uintptr - -var views = make(map[C.CFTypeRef]*window) - -func init() { - // Darwin requires UI operations happen on the main thread only. - runtime.LockOSThread() -} - -//export onCreate -func onCreate(view C.CFTypeRef) { - w := &window{ - view: view, - } - dl, err := NewDisplayLink(func() { - w.draw(false) - }) - if err != nil { - panic(err) - } - w.displayLink = dl - wopts := <-mainWindow.out - w.w = wopts.window - w.w.SetDriver(w) - w.visible.Store(false) - w.layer = C.CFTypeRef(layerFactory()) - C.gio_addLayerToView(view, w.layer) - views[view] = w - w.w.Event(system.StageEvent{Stage: system.StagePaused}) -} - -//export gio_onDraw -func gio_onDraw(view C.CFTypeRef) { - w := views[view] - w.draw(true) -} - -func (w *window) draw(sync bool) { - params := C.gio_viewDrawParams(w.view) - if params.width == 0 || params.height == 0 { - return - } - wasVisible := w.isVisible() - w.visible.Store(true) - C.gio_updateView(w.view, w.layer) - if !wasVisible { - w.w.Event(system.StageEvent{Stage: system.StageRunning}) - } - const inchPrDp = 1.0 / 163 - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: int(params.width + .5), - Y: int(params.height + .5), - }, - Insets: system.Insets{ - Top: unit.Px(float32(params.top)), - Right: unit.Px(float32(params.right)), - Bottom: unit.Px(float32(params.bottom)), - Left: unit.Px(float32(params.left)), - }, - Metric: unit.Metric{ - PxPerDp: float32(params.dpi) * inchPrDp, - PxPerSp: float32(params.sdpi) * inchPrDp, - }, - }, - Sync: sync, - }) -} - -//export onStop -func onStop(view C.CFTypeRef) { - w := views[view] - w.visible.Store(false) - w.w.Event(system.StageEvent{Stage: system.StagePaused}) -} - -//export onDestroy -func onDestroy(view C.CFTypeRef) { - w := views[view] - delete(views, view) - w.w.Event(system.DestroyEvent{}) - w.displayLink.Close() - C.gio_removeLayer(w.layer) - C.CFRelease(w.layer) - w.layer = 0 - w.view = 0 -} - -//export onFocus -func onFocus(view C.CFTypeRef, focus int) { - w := views[view] - w.w.Event(key.FocusEvent{Focus: focus != 0}) -} - -//export onLowMemory -func onLowMemory() { - runtime.GC() - debug.FreeOSMemory() -} - -//export onUpArrow -func onUpArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameUpArrow) -} - -//export onDownArrow -func onDownArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameDownArrow) -} - -//export onLeftArrow -func onLeftArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameLeftArrow) -} - -//export onRightArrow -func onRightArrow(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameRightArrow) -} - -//export onDeleteBackward -func onDeleteBackward(view C.CFTypeRef) { - views[view].onKeyCommand(key.NameDeleteBackward) -} - -//export onText -func onText(view C.CFTypeRef, str *C.char) { - w := views[view] - w.w.Event(key.EditEvent{ - Text: C.GoString(str), - }) -} - -//export onTouch -func onTouch(last C.int, view, touchRef C.CFTypeRef, phase C.NSInteger, x, y C.CGFloat, ti C.double) { - var typ pointer.Type - switch phase { - case C.UITouchPhaseBegan: - typ = pointer.Press - case C.UITouchPhaseMoved: - typ = pointer.Move - case C.UITouchPhaseEnded: - typ = pointer.Release - case C.UITouchPhaseCancelled: - typ = pointer.Cancel - default: - return - } - w := views[view] - t := time.Duration(float64(ti) * float64(time.Second)) - p := f32.Point{X: float32(x), Y: float32(y)} - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Touch, - PointerID: w.lookupTouch(last != 0, touchRef), - Position: p, - Time: t, - }) -} - -func (w *window) ReadClipboard() { - runOnMain(func() { - content := nsstringToString(C.gio_readClipboard()) - w.w.Event(system.ClipboardEvent{Text: content}) - }) -} - -func (w *window) WriteClipboard(s string) { - u16 := utf16.Encode([]rune(s)) - runOnMain(func() { - var chars *C.unichar - if len(u16) > 0 { - chars = (*C.unichar)(unsafe.Pointer(&u16[0])) - } - C.gio_writeClipboard(chars, C.NSUInteger(len(u16))) - }) -} - -func (w *window) SetAnimating(anim bool) { - v := w.view - if v == 0 { - return - } - if anim { - w.displayLink.Start() - } else { - w.displayLink.Stop() - } -} - -func (w *window) onKeyCommand(name string) { - w.w.Event(key.Event{ - Name: name, - }) -} - -// lookupTouch maps an UITouch pointer value to an index. If -// last is set, the map is cleared. -func (w *window) lookupTouch(last bool, touch C.CFTypeRef) pointer.ID { - id := -1 - for i, ref := range w.pointerMap { - if ref == touch { - id = i - break - } - } - if id == -1 { - id = len(w.pointerMap) - w.pointerMap = append(w.pointerMap, touch) - } - if last { - w.pointerMap = w.pointerMap[:0] - } - return pointer.ID(id) -} - -func (w *window) contextLayer() uintptr { - return uintptr(w.layer) -} - -func (w *window) isVisible() bool { - return w.visible.Load().(bool) -} - -func (w *window) ShowTextInput(show bool) { - v := w.view - if v == 0 { - return - } - C.CFRetain(v) - runOnMain(func() { - defer C.CFRelease(v) - if show { - C.gio_showTextInput(w.view) - } else { - C.gio_hideTextInput(w.view) - } - }) -} - -// Close the window. Not implemented for iOS. -func (w *window) Close() {} - -func NewWindow(win Callbacks, opts *Options) error { - mainWindow.in <- windowAndOptions{win, opts} - return <-mainWindow.errs -} - -func Main() { -} - -//export gio_runMain -func gio_runMain() { - runMain() -} diff --git a/vendor/gioui.org/app/internal/window/os_ios.m b/vendor/gioui.org/app/internal/window/os_ios.m deleted file mode 100644 index 66830e4..0000000 --- a/vendor/gioui.org/app/internal/window/os_ios.m +++ /dev/null @@ -1,328 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,ios - -@import UIKit; - -#include <stdint.h> -#include "_cgo_export.h" -#include "framework_ios.h" - -@interface GioView: UIView <UIKeyInput> -@end - -@implementation GioViewController - -CGFloat _keyboardHeight; - -- (void)loadView { - gio_runMain(); - - CGRect zeroFrame = CGRectMake(0, 0, 0, 0); - self.view = [[UIView alloc] initWithFrame:zeroFrame]; - self.view.layoutMargins = UIEdgeInsetsMake(0, 0, 0, 0); - UIView *drawView = [[GioView alloc] initWithFrame:zeroFrame]; - [self.view addSubview: drawView]; -#ifndef TARGET_OS_TV - drawView.multipleTouchEnabled = YES; -#endif - drawView.preservesSuperviewLayoutMargins = YES; - drawView.layoutMargins = UIEdgeInsetsMake(0, 0, 0, 0); - onCreate((__bridge CFTypeRef)drawView); - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillChange:) - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillChange:) - name:UIKeyboardWillChangeFrameNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver: self - selector: @selector(applicationDidEnterBackground:) - name: UIApplicationDidEnterBackgroundNotification - object: nil]; - [[NSNotificationCenter defaultCenter] addObserver: self - selector: @selector(applicationWillEnterForeground:) - name: UIApplicationWillEnterForegroundNotification - object: nil]; -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - UIView *drawView = self.view.subviews[0]; - if (drawView != nil) { - gio_onDraw((__bridge CFTypeRef)drawView); - } -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - UIView *drawView = self.view.subviews[0]; - if (drawView != nil) { - onStop((__bridge CFTypeRef)drawView); - } -} - -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; - CFTypeRef viewRef = (__bridge CFTypeRef)self.view.subviews[0]; - onDestroy(viewRef); -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - UIView *view = self.view.subviews[0]; - CGRect frame = self.view.bounds; - // Adjust view bounds to make room for the keyboard. - frame.size.height -= _keyboardHeight; - view.frame = frame; - gio_onDraw((__bridge CFTypeRef)view); -} - -- (void)didReceiveMemoryWarning { - onLowMemory(); - [super didReceiveMemoryWarning]; -} - -- (void)keyboardWillChange:(NSNotification *)note { - NSDictionary *userInfo = note.userInfo; - CGRect f = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - _keyboardHeight = f.size.height; - [self.view setNeedsLayout]; -} - -- (void)keyboardWillHide:(NSNotification *)note { - _keyboardHeight = 0.0; - [self.view setNeedsLayout]; -} -@end - -static void handleTouches(int last, UIView *view, NSSet<UITouch *> *touches, UIEvent *event) { - CGFloat scale = view.contentScaleFactor; - NSUInteger i = 0; - NSUInteger n = [touches count]; - CFTypeRef viewRef = (__bridge CFTypeRef)view; - for (UITouch *touch in touches) { - CFTypeRef touchRef = (__bridge CFTypeRef)touch; - i++; - NSArray<UITouch *> *coalescedTouches = [event coalescedTouchesForTouch:touch]; - NSUInteger j = 0; - NSUInteger m = [coalescedTouches count]; - for (UITouch *coalescedTouch in [event coalescedTouchesForTouch:touch]) { - CGPoint loc = [coalescedTouch locationInView:view]; - j++; - int lastTouch = last && i == n && j == m; - onTouch(lastTouch, viewRef, touchRef, touch.phase, loc.x*scale, loc.y*scale, [coalescedTouch timestamp]); - } - } -} - -@implementation GioView -NSArray<UIKeyCommand *> *_keyCommands; -+ (void)onFrameCallback:(CADisplayLink *)link { - gio_onFrameCallback((__bridge CFTypeRef)link); -} - -- (void)willMoveToWindow:(UIWindow *)newWindow { - if (self.window != nil) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIWindowDidBecomeKeyNotification - object:self.window]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIWindowDidResignKeyNotification - object:self.window]; - } - self.contentScaleFactor = newWindow.screen.nativeScale; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onWindowDidBecomeKey:) - name:UIWindowDidBecomeKeyNotification - object:newWindow]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onWindowDidResignKey:) - name:UIWindowDidResignKeyNotification - object:newWindow]; -} - -- (void)onWindowDidBecomeKey:(NSNotification *)note { - if (self.isFirstResponder) { - onFocus((__bridge CFTypeRef)self, YES); - } -} - -- (void)onWindowDidResignKey:(NSNotification *)note { - if (self.isFirstResponder) { - onFocus((__bridge CFTypeRef)self, NO); - } -} - -- (void)dealloc { -} - -- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { - handleTouches(0, self, touches, event); -} - -- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { - handleTouches(0, self, touches, event); -} - -- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { - handleTouches(1, self, touches, event); -} - -- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { - handleTouches(1, self, touches, event); -} - -- (void)insertText:(NSString *)text { - onText((__bridge CFTypeRef)self, (char *)text.UTF8String); -} - -- (BOOL)canBecomeFirstResponder { - return YES; -} - -- (BOOL)hasText { - return YES; -} - -- (void)deleteBackward { - onDeleteBackward((__bridge CFTypeRef)self); -} - -- (void)onUpArrow { - onUpArrow((__bridge CFTypeRef)self); -} - -- (void)onDownArrow { - onDownArrow((__bridge CFTypeRef)self); -} - -- (void)onLeftArrow { - onLeftArrow((__bridge CFTypeRef)self); -} - -- (void)onRightArrow { - onRightArrow((__bridge CFTypeRef)self); -} - -- (NSArray<UIKeyCommand *> *)keyCommands { - if (_keyCommands == nil) { - _keyCommands = @[ - [UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow - modifierFlags:0 - action:@selector(onUpArrow)], - [UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow - modifierFlags:0 - action:@selector(onDownArrow)], - [UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow - modifierFlags:0 - action:@selector(onLeftArrow)], - [UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow - modifierFlags:0 - action:@selector(onRightArrow)] - ]; - } - return _keyCommands; -} -@end - -void gio_writeClipboard(unichar *chars, NSUInteger length) { - @autoreleasepool { - NSString *s = [NSString string]; - if (length > 0) { - s = [NSString stringWithCharacters:chars length:length]; - } - UIPasteboard *p = UIPasteboard.generalPasteboard; - p.string = s; - } -} - -CFTypeRef gio_readClipboard(void) { - @autoreleasepool { - UIPasteboard *p = UIPasteboard.generalPasteboard; - return (__bridge_retained CFTypeRef)p.string; - } -} - -void gio_showTextInput(CFTypeRef viewRef) { - UIView *view = (__bridge UIView *)viewRef; - [view becomeFirstResponder]; -} - -void gio_hideTextInput(CFTypeRef viewRef) { - UIView *view = (__bridge UIView *)viewRef; - [view resignFirstResponder]; -} - -void gio_addLayerToView(CFTypeRef viewRef, CFTypeRef layerRef) { - UIView *view = (__bridge UIView *)viewRef; - CALayer *layer = (__bridge CALayer *)layerRef; - [view.layer addSublayer:layer]; -} - -void gio_updateView(CFTypeRef viewRef, CFTypeRef layerRef) { - UIView *view = (__bridge UIView *)viewRef; - CAEAGLLayer *layer = (__bridge CAEAGLLayer *)layerRef; - layer.contentsScale = view.contentScaleFactor; - layer.bounds = view.bounds; -} - -void gio_removeLayer(CFTypeRef layerRef) { - CALayer *layer = (__bridge CALayer *)layerRef; - [layer removeFromSuperlayer]; -} - -struct drawParams gio_viewDrawParams(CFTypeRef viewRef) { - UIView *v = (__bridge UIView *)viewRef; - struct drawParams params; - CGFloat scale = v.layer.contentsScale; - // Use 163 as the standard ppi on iOS. - params.dpi = 163*scale; - params.sdpi = params.dpi; - UIEdgeInsets insets = v.layoutMargins; - if (@available(iOS 11.0, tvOS 11.0, *)) { - UIFontMetrics *metrics = [UIFontMetrics defaultMetrics]; - params.sdpi = [metrics scaledValueForValue:params.sdpi]; - insets = v.safeAreaInsets; - } - params.width = v.bounds.size.width*scale; - params.height = v.bounds.size.height*scale; - params.top = insets.top*scale; - params.right = insets.right*scale; - params.bottom = insets.bottom*scale; - params.left = insets.left*scale; - return params; -} - -CFTypeRef gio_createDisplayLink(void) { - CADisplayLink *dl = [CADisplayLink displayLinkWithTarget:[GioView class] selector:@selector(onFrameCallback:)]; - dl.paused = YES; - NSRunLoop *runLoop = [NSRunLoop mainRunLoop]; - [dl addToRunLoop:runLoop forMode:[runLoop currentMode]]; - return (__bridge_retained CFTypeRef)dl; -} - -int gio_startDisplayLink(CFTypeRef dlref) { - CADisplayLink *dl = (__bridge CADisplayLink *)dlref; - dl.paused = NO; - return 0; -} - -int gio_stopDisplayLink(CFTypeRef dlref) { - CADisplayLink *dl = (__bridge CADisplayLink *)dlref; - dl.paused = YES; - return 0; -} - -void gio_releaseDisplayLink(CFTypeRef dlref) { - CADisplayLink *dl = (__bridge CADisplayLink *)dlref; - [dl invalidate]; - CFRelease(dlref); -} - -void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did) { - // Nothing to do on iOS. -} diff --git a/vendor/gioui.org/app/internal/window/os_js.go b/vendor/gioui.org/app/internal/window/os_js.go deleted file mode 100644 index 32235df..0000000 --- a/vendor/gioui.org/app/internal/window/os_js.go +++ /dev/null @@ -1,494 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -import ( - "image" - "strings" - "sync" - "syscall/js" - "time" - "unicode" - "unicode/utf8" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" -) - -type window struct { - window js.Value - clipboard js.Value - cnv js.Value - tarea js.Value - w Callbacks - redraw js.Func - clipboardCallback js.Func - requestAnimationFrame js.Value - cleanfuncs []func() - touches []js.Value - composing bool - - mu sync.Mutex - scale float32 - animating bool -} - -func NewWindow(win Callbacks, opts *Options) error { - doc := js.Global().Get("document") - cont := getContainer(doc) - cnv := createCanvas(doc) - cont.Call("appendChild", cnv) - tarea := createTextArea(doc) - cont.Call("appendChild", tarea) - w := &window{ - cnv: cnv, - tarea: tarea, - window: js.Global().Get("window"), - clipboard: js.Global().Get("navigator").Get("clipboard"), - } - w.requestAnimationFrame = w.window.Get("requestAnimationFrame") - w.redraw = w.funcOf(func(this js.Value, args []js.Value) interface{} { - w.animCallback() - return nil - }) - w.clipboardCallback = w.funcOf(func(this js.Value, args []js.Value) interface{} { - content := args[0].String() - win.Event(system.ClipboardEvent{Text: content}) - return nil - }) - w.addEventListeners() - w.w = win - go func() { - w.w.SetDriver(w) - w.focus() - w.w.Event(system.StageEvent{Stage: system.StageRunning}) - w.draw(true) - select {} - w.cleanup() - }() - return nil -} - -func getContainer(doc js.Value) js.Value { - cont := doc.Call("getElementById", "giowindow") - if !cont.IsNull() { - return cont - } - cont = doc.Call("createElement", "DIV") - doc.Get("body").Call("appendChild", cont) - return cont -} - -func createTextArea(doc js.Value) js.Value { - tarea := doc.Call("createElement", "input") - style := tarea.Get("style") - style.Set("width", "1px") - style.Set("height", "1px") - style.Set("opacity", "0") - style.Set("border", "0") - style.Set("padding", "0") - tarea.Set("autocomplete", "off") - tarea.Set("autocorrect", "off") - tarea.Set("autocapitalize", "off") - tarea.Set("spellcheck", false) - return tarea -} - -func createCanvas(doc js.Value) js.Value { - cnv := doc.Call("createElement", "canvas") - style := cnv.Get("style") - style.Set("position", "fixed") - style.Set("width", "100%") - style.Set("height", "100%") - return cnv -} - -func (w *window) cleanup() { - // Cleanup in the opposite order of - // construction. - for i := len(w.cleanfuncs) - 1; i >= 0; i-- { - w.cleanfuncs[i]() - } - w.cleanfuncs = nil -} - -func (w *window) addEventListeners() { - w.addEventListener(w.window, "resize", func(this js.Value, args []js.Value) interface{} { - w.draw(true) - return nil - }) - w.addEventListener(w.cnv, "mousemove", func(this js.Value, args []js.Value) interface{} { - w.pointerEvent(pointer.Move, 0, 0, args[0]) - return nil - }) - w.addEventListener(w.cnv, "mousedown", func(this js.Value, args []js.Value) interface{} { - w.pointerEvent(pointer.Press, 0, 0, args[0]) - return nil - }) - w.addEventListener(w.cnv, "mouseup", func(this js.Value, args []js.Value) interface{} { - w.pointerEvent(pointer.Release, 0, 0, args[0]) - return nil - }) - w.addEventListener(w.cnv, "wheel", func(this js.Value, args []js.Value) interface{} { - e := args[0] - dx, dy := e.Get("deltaX").Float(), e.Get("deltaY").Float() - mode := e.Get("deltaMode").Int() - switch mode { - case 0x01: // DOM_DELTA_LINE - dx *= 10 - dy *= 10 - case 0x02: // DOM_DELTA_PAGE - dx *= 120 - dy *= 120 - } - w.pointerEvent(pointer.Scroll, float32(dx), float32(dy), e) - return nil - }) - w.addEventListener(w.cnv, "touchstart", func(this js.Value, args []js.Value) interface{} { - w.touchEvent(pointer.Press, args[0]) - return nil - }) - w.addEventListener(w.cnv, "touchend", func(this js.Value, args []js.Value) interface{} { - w.touchEvent(pointer.Release, args[0]) - return nil - }) - w.addEventListener(w.cnv, "touchmove", func(this js.Value, args []js.Value) interface{} { - w.touchEvent(pointer.Move, args[0]) - return nil - }) - w.addEventListener(w.cnv, "touchcancel", func(this js.Value, args []js.Value) interface{} { - // Cancel all touches even if only one touch was cancelled. - for i := range w.touches { - w.touches[i] = js.Null() - } - w.touches = w.touches[:0] - w.w.Event(pointer.Event{ - Type: pointer.Cancel, - Source: pointer.Touch, - }) - return nil - }) - w.addEventListener(w.tarea, "focus", func(this js.Value, args []js.Value) interface{} { - w.w.Event(key.FocusEvent{Focus: true}) - return nil - }) - w.addEventListener(w.tarea, "blur", func(this js.Value, args []js.Value) interface{} { - w.w.Event(key.FocusEvent{Focus: false}) - return nil - }) - w.addEventListener(w.tarea, "keydown", func(this js.Value, args []js.Value) interface{} { - w.keyEvent(args[0]) - return nil - }) - w.addEventListener(w.tarea, "compositionstart", func(this js.Value, args []js.Value) interface{} { - w.composing = true - return nil - }) - w.addEventListener(w.tarea, "compositionend", func(this js.Value, args []js.Value) interface{} { - w.composing = false - w.flushInput() - return nil - }) - w.addEventListener(w.tarea, "input", func(this js.Value, args []js.Value) interface{} { - if w.composing { - return nil - } - w.flushInput() - return nil - }) -} - -func (w *window) flushInput() { - val := w.tarea.Get("value").String() - w.tarea.Set("value", "") - w.w.Event(key.EditEvent{Text: string(val)}) -} - -func (w *window) blur() { - w.tarea.Call("blur") -} - -func (w *window) focus() { - w.tarea.Call("focus") -} - -func (w *window) keyEvent(e js.Value) { - k := e.Get("key").String() - if n, ok := translateKey(k); ok { - cmd := key.Event{ - Name: n, - Modifiers: modifiersFor(e), - } - w.w.Event(cmd) - } -} - -// modifiersFor returns the modifier set for a DOM MouseEvent or -// KeyEvent. -func modifiersFor(e js.Value) key.Modifiers { - var mods key.Modifiers - if e.Call("getModifierState", "Alt").Bool() { - mods |= key.ModAlt - } - if e.Call("getModifierState", "Control").Bool() { - mods |= key.ModCtrl - } - if e.Call("getModifierState", "Shift").Bool() { - mods |= key.ModShift - } - return mods -} - -func (w *window) touchEvent(typ pointer.Type, e js.Value) { - e.Call("preventDefault") - t := time.Duration(e.Get("timeStamp").Int()) * time.Millisecond - changedTouches := e.Get("changedTouches") - n := changedTouches.Length() - rect := w.cnv.Call("getBoundingClientRect") - w.mu.Lock() - scale := w.scale - w.mu.Unlock() - var mods key.Modifiers - if e.Get("shiftKey").Bool() { - mods |= key.ModShift - } - if e.Get("altKey").Bool() { - mods |= key.ModAlt - } - if e.Get("ctrlKey").Bool() { - mods |= key.ModCtrl - } - for i := 0; i < n; i++ { - touch := changedTouches.Index(i) - pid := w.touchIDFor(touch) - x, y := touch.Get("clientX").Float(), touch.Get("clientY").Float() - x -= rect.Get("left").Float() - y -= rect.Get("top").Float() - pos := f32.Point{ - X: float32(x) * scale, - Y: float32(y) * scale, - } - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Touch, - Position: pos, - PointerID: pid, - Time: t, - Modifiers: modifiersFor(e), - }) - } -} - -func (w *window) touchIDFor(touch js.Value) pointer.ID { - id := touch.Get("identifier") - for i, id2 := range w.touches { - if id2.Equal(id) { - return pointer.ID(i) - } - } - pid := pointer.ID(len(w.touches)) - w.touches = append(w.touches, id) - return pid -} - -func (w *window) pointerEvent(typ pointer.Type, dx, dy float32, e js.Value) { - e.Call("preventDefault") - x, y := e.Get("clientX").Float(), e.Get("clientY").Float() - rect := w.cnv.Call("getBoundingClientRect") - x -= rect.Get("left").Float() - y -= rect.Get("top").Float() - w.mu.Lock() - scale := w.scale - w.mu.Unlock() - pos := f32.Point{ - X: float32(x) * scale, - Y: float32(y) * scale, - } - scroll := f32.Point{ - X: dx * scale, - Y: dy * scale, - } - t := time.Duration(e.Get("timeStamp").Int()) * time.Millisecond - jbtns := e.Get("buttons").Int() - var btns pointer.Buttons - if jbtns&1 != 0 { - btns |= pointer.ButtonLeft - } - if jbtns&2 != 0 { - btns |= pointer.ButtonRight - } - if jbtns&4 != 0 { - btns |= pointer.ButtonMiddle - } - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Mouse, - Buttons: btns, - Position: pos, - Scroll: scroll, - Time: t, - Modifiers: modifiersFor(e), - }) -} - -func (w *window) addEventListener(this js.Value, event string, f func(this js.Value, args []js.Value) interface{}) { - jsf := w.funcOf(f) - this.Call("addEventListener", event, jsf) - w.cleanfuncs = append(w.cleanfuncs, func() { - this.Call("removeEventListener", event, jsf) - }) -} - -// funcOf is like js.FuncOf but adds the js.Func to a list of -// functions to be released up. -func (w *window) funcOf(f func(this js.Value, args []js.Value) interface{}) js.Func { - jsf := js.FuncOf(f) - w.cleanfuncs = append(w.cleanfuncs, jsf.Release) - return jsf -} - -func (w *window) animCallback() { - w.mu.Lock() - anim := w.animating - if anim { - w.requestAnimationFrame.Invoke(w.redraw) - } - w.mu.Unlock() - if anim { - w.draw(false) - } -} - -func (w *window) SetAnimating(anim bool) { - w.mu.Lock() - defer w.mu.Unlock() - if anim && !w.animating { - w.requestAnimationFrame.Invoke(w.redraw) - } - w.animating = anim -} - -func (w *window) ReadClipboard() { - if w.clipboard.IsUndefined() { - return - } - if w.clipboard.Get("readText").IsUndefined() { - return - } - w.clipboard.Call("readText", w.clipboard).Call("then", w.clipboardCallback) -} - -func (w *window) WriteClipboard(s string) { - if w.clipboard.IsUndefined() { - return - } - if w.clipboard.Get("writeText").IsUndefined() { - return - } - w.clipboard.Call("writeText", s) -} - -func (w *window) ShowTextInput(show bool) { - // Run in a goroutine to avoid a deadlock if the - // focus change result in an event. - go func() { - if show { - w.focus() - } else { - w.blur() - } - }() -} - -// Close the window. Not implemented for js. -func (w *window) Close() {} - -func (w *window) draw(sync bool) { - width, height, scale, cfg := w.config() - if cfg == (unit.Metric{}) || width == 0 || height == 0 { - return - } - w.mu.Lock() - w.scale = float32(scale) - w.mu.Unlock() - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: width, - Y: height, - }, - Metric: cfg, - }, - Sync: sync, - }) -} - -func (w *window) config() (int, int, float32, unit.Metric) { - rect := w.cnv.Call("getBoundingClientRect") - width, height := rect.Get("width").Float(), rect.Get("height").Float() - scale := w.window.Get("devicePixelRatio").Float() - width *= scale - height *= scale - iw, ih := int(width+.5), int(height+.5) - // Adjust internal size of canvas if necessary. - if cw, ch := w.cnv.Get("width").Int(), w.cnv.Get("height").Int(); iw != cw || ih != ch { - w.cnv.Set("width", iw) - w.cnv.Set("height", ih) - } - return iw, ih, float32(scale), unit.Metric{ - PxPerDp: float32(scale), - PxPerSp: float32(scale), - } -} - -func Main() { - select {} -} - -func translateKey(k string) (string, bool) { - var n string - switch k { - case "ArrowUp": - n = key.NameUpArrow - case "ArrowDown": - n = key.NameDownArrow - case "ArrowLeft": - n = key.NameLeftArrow - case "ArrowRight": - n = key.NameRightArrow - case "Escape": - n = key.NameEscape - case "Enter": - n = key.NameReturn - case "Backspace": - n = key.NameDeleteBackward - case "Delete": - n = key.NameDeleteForward - case "Home": - n = key.NameHome - case "End": - n = key.NameEnd - case "PageUp": - n = key.NamePageUp - case "PageDown": - n = key.NamePageDown - case "Tab": - n = key.NameTab - case " ": - n = "Space" - case "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12": - n = k - default: - r, s := utf8.DecodeRuneInString(k) - // If there is exactly one printable character, return that. - if s == len(k) && unicode.IsPrint(r) { - return strings.ToUpper(k), true - } - return "", false - } - return n, true -} diff --git a/vendor/gioui.org/app/internal/window/os_macos.go b/vendor/gioui.org/app/internal/window/os_macos.go deleted file mode 100644 index ef95b70..0000000 --- a/vendor/gioui.org/app/internal/window/os_macos.go +++ /dev/null @@ -1,460 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,!ios - -package window - -import ( - "errors" - "image" - "runtime" - "time" - "unicode" - "unicode/utf16" - "unsafe" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" - - _ "gioui.org/app/internal/cocoainit" -) - -/* -#cgo CFLAGS: -DGL_SILENCE_DEPRECATION -Werror -Wno-deprecated-declarations -fmodules -fobjc-arc -x objective-c - -#include <AppKit/AppKit.h> - -#define GIO_MOUSE_MOVE 1 -#define GIO_MOUSE_UP 2 -#define GIO_MOUSE_DOWN 3 -#define GIO_MOUSE_SCROLL 4 - -__attribute__ ((visibility ("hidden"))) void gio_main(void); -__attribute__ ((visibility ("hidden"))) CGFloat gio_viewWidth(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) CGFloat gio_viewHeight(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) CGFloat gio_getViewBackingScale(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) CGFloat gio_getScreenBackingScale(void); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_readClipboard(void); -__attribute__ ((visibility ("hidden"))) void gio_writeClipboard(unichar *chars, NSUInteger length); -__attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight); -__attribute__ ((visibility ("hidden"))) void gio_makeKeyAndOrderFront(CFTypeRef windowRef); -__attribute__ ((visibility ("hidden"))) NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft); -__attribute__ ((visibility ("hidden"))) void gio_close(CFTypeRef windowRef); -*/ -import "C" - -func init() { - // Darwin requires that UI operations happen on the main thread only. - runtime.LockOSThread() -} - -type window struct { - view C.CFTypeRef - window C.CFTypeRef - w Callbacks - stage system.Stage - displayLink *displayLink - - scale float32 -} - -// viewMap is the mapping from Cocoa NSViews to Go windows. -var viewMap = make(map[C.CFTypeRef]*window) - -var viewFactory func() C.CFTypeRef - -// launched is closed when applicationDidFinishLaunching is called. -var launched = make(chan struct{}) - -// nextTopLeft is the offset to use for the next window's call to -// cascadeTopLeftFromPoint. -var nextTopLeft C.NSPoint - -// mustView is like lookoupView, except that it panics -// if the view isn't mapped. -func mustView(view C.CFTypeRef) *window { - w, ok := lookupView(view) - if !ok { - panic("no window for view") - } - return w -} - -func lookupView(view C.CFTypeRef) (*window, bool) { - w, exists := viewMap[view] - if !exists { - return nil, false - } - return w, true -} - -func deleteView(view C.CFTypeRef) { - delete(viewMap, view) -} - -func insertView(view C.CFTypeRef, w *window) { - viewMap[view] = w -} - -func (w *window) contextView() C.CFTypeRef { - return w.view -} - -func (w *window) ReadClipboard() { - runOnMain(func() { - content := nsstringToString(C.gio_readClipboard()) - w.w.Event(system.ClipboardEvent{Text: content}) - }) -} - -func (w *window) WriteClipboard(s string) { - u16 := utf16.Encode([]rune(s)) - runOnMain(func() { - var chars *C.unichar - if len(u16) > 0 { - chars = (*C.unichar)(unsafe.Pointer(&u16[0])) - } - C.gio_writeClipboard(chars, C.NSUInteger(len(u16))) - }) -} - -func (w *window) ShowTextInput(show bool) {} - -func (w *window) SetAnimating(anim bool) { - if anim { - w.displayLink.Start() - } else { - w.displayLink.Stop() - } -} - -func (w *window) Close() { - runOnMain(func() { - // Make sure the view is still valid. The window might've been closed - // during the switch to the main thread. - if w.view != 0 { - C.gio_close(w.window) - } - }) -} - -func (w *window) setStage(stage system.Stage) { - if stage == w.stage { - return - } - w.stage = stage - w.w.Event(system.StageEvent{Stage: stage}) -} - -//export gio_onKeys -func gio_onKeys(view C.CFTypeRef, cstr *C.char, ti C.double, mods C.NSUInteger) { - str := C.GoString(cstr) - kmods := convertMods(mods) - w := mustView(view) - for _, k := range str { - if n, ok := convertKey(k); ok { - w.w.Event(key.Event{ - Name: n, - Modifiers: kmods, - }) - } - } -} - -//export gio_onText -func gio_onText(view C.CFTypeRef, cstr *C.char) { - str := C.GoString(cstr) - w := mustView(view) - w.w.Event(key.EditEvent{Text: str}) -} - -//export gio_onMouse -func gio_onMouse(view C.CFTypeRef, cdir C.int, cbtns C.NSUInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) { - var typ pointer.Type - switch cdir { - case C.GIO_MOUSE_MOVE: - typ = pointer.Move - case C.GIO_MOUSE_UP: - typ = pointer.Release - case C.GIO_MOUSE_DOWN: - typ = pointer.Press - case C.GIO_MOUSE_SCROLL: - typ = pointer.Scroll - default: - panic("invalid direction") - } - var btns pointer.Buttons - if cbtns&(1<<0) != 0 { - btns |= pointer.ButtonLeft - } - if cbtns&(1<<1) != 0 { - btns |= pointer.ButtonRight - } - if cbtns&(1<<2) != 0 { - btns |= pointer.ButtonMiddle - } - t := time.Duration(float64(ti)*float64(time.Second) + .5) - w := mustView(view) - xf, yf := float32(x)*w.scale, float32(y)*w.scale - dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Mouse, - Time: t, - Buttons: btns, - Position: f32.Point{X: xf, Y: yf}, - Scroll: f32.Point{X: dxf, Y: dyf}, - Modifiers: convertMods(mods), - }) -} - -//export gio_onDraw -func gio_onDraw(view C.CFTypeRef) { - w := mustView(view) - w.draw() -} - -//export gio_onFocus -func gio_onFocus(view C.CFTypeRef, focus C.BOOL) { - w := mustView(view) - w.w.Event(key.FocusEvent{Focus: focus == C.YES}) -} - -//export gio_onChangeScreen -func gio_onChangeScreen(view C.CFTypeRef, did uint64) { - w := mustView(view) - w.displayLink.SetDisplayID(did) -} - -func (w *window) draw() { - w.scale = float32(C.gio_getViewBackingScale(w.view)) - wf, hf := float32(C.gio_viewWidth(w.view)), float32(C.gio_viewHeight(w.view)) - if wf == 0 || hf == 0 { - return - } - width := int(wf*w.scale + .5) - height := int(hf*w.scale + .5) - cfg := configFor(w.scale) - w.setStage(system.StageRunning) - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: width, - Y: height, - }, - Metric: cfg, - }, - Sync: true, - }) -} - -func configFor(scale float32) unit.Metric { - return unit.Metric{ - PxPerDp: scale, - PxPerSp: scale, - } -} - -//export gio_onClose -func gio_onClose(view C.CFTypeRef) { - w := mustView(view) - w.displayLink.Close() - deleteView(view) - w.w.Event(system.DestroyEvent{}) - C.CFRelease(w.view) - w.view = 0 - C.CFRelease(w.window) - w.window = 0 -} - -//export gio_onHide -func gio_onHide(view C.CFTypeRef) { - w := mustView(view) - w.setStage(system.StagePaused) -} - -//export gio_onShow -func gio_onShow(view C.CFTypeRef) { - w := mustView(view) - w.setStage(system.StageRunning) -} - -//export gio_onAppHide -func gio_onAppHide() { - for _, w := range viewMap { - w.setStage(system.StagePaused) - } -} - -//export gio_onAppShow -func gio_onAppShow() { - for _, w := range viewMap { - w.setStage(system.StageRunning) - } -} - -//export gio_onFinishLaunching -func gio_onFinishLaunching() { - close(launched) -} - -func NewWindow(win Callbacks, opts *Options) error { - <-launched - errch := make(chan error) - runOnMain(func() { - w, err := newWindow(opts) - if err != nil { - errch <- err - return - } - screenScale := float32(C.gio_getScreenBackingScale()) - cfg := configFor(screenScale) - width := cfg.Px(opts.Width) - height := cfg.Px(opts.Height) - // Window sizes is in unscaled screen coordinates, not device pixels. - width = int(float32(width) / screenScale) - height = int(float32(height) / screenScale) - minWidth := cfg.Px(opts.MinWidth) - minHeight := cfg.Px(opts.MinHeight) - minWidth = int(float32(minWidth) / screenScale) - minHeight = int(float32(minHeight) / screenScale) - maxWidth := cfg.Px(opts.MaxWidth) - maxHeight := cfg.Px(opts.MaxHeight) - maxWidth = int(float32(maxWidth) / screenScale) - maxHeight = int(float32(maxHeight) / screenScale) - title := C.CString(opts.Title) - defer C.free(unsafe.Pointer(title)) - errch <- nil - win.SetDriver(w) - w.w = win - w.window = C.gio_createWindow(w.view, title, C.CGFloat(width), C.CGFloat(height), - C.CGFloat(minWidth), C.CGFloat(minHeight), C.CGFloat(maxWidth), C.CGFloat(maxHeight)) - if nextTopLeft.x == 0 && nextTopLeft.y == 0 { - // cascadeTopLeftFromPoint treats (0, 0) as a no-op, - // and just returns the offset we need for the first window. - nextTopLeft = C.gio_cascadeTopLeftFromPoint(w.window, nextTopLeft) - } - nextTopLeft = C.gio_cascadeTopLeftFromPoint(w.window, nextTopLeft) - C.gio_makeKeyAndOrderFront(w.window) - }) - return <-errch -} - -func newWindow(opts *Options) (*window, error) { - view := viewFactory() - if view == 0 { - return nil, errors.New("CreateWindow: failed to create view") - } - scale := float32(C.gio_getViewBackingScale(view)) - w := &window{ - view: view, - scale: scale, - } - dl, err := NewDisplayLink(func() { - runOnMain(func() { - if w.view != 0 { - C.gio_setNeedsDisplay(w.view) - } - }) - }) - w.displayLink = dl - if err != nil { - C.CFRelease(view) - return nil, err - } - insertView(view, w) - return w, nil -} - -func Main() { - C.gio_main() -} - -func convertKey(k rune) (string, bool) { - var n string - switch k { - case 0x1b: - n = key.NameEscape - case C.NSLeftArrowFunctionKey: - n = key.NameLeftArrow - case C.NSRightArrowFunctionKey: - n = key.NameRightArrow - case C.NSUpArrowFunctionKey: - n = key.NameUpArrow - case C.NSDownArrowFunctionKey: - n = key.NameDownArrow - case 0xd: - n = key.NameReturn - case 0x3: - n = key.NameEnter - case C.NSHomeFunctionKey: - n = key.NameHome - case C.NSEndFunctionKey: - n = key.NameEnd - case 0x7f: - n = key.NameDeleteBackward - case C.NSDeleteFunctionKey: - n = key.NameDeleteForward - case C.NSPageUpFunctionKey: - n = key.NamePageUp - case C.NSPageDownFunctionKey: - n = key.NamePageDown - case C.NSF1FunctionKey: - n = "F1" - case C.NSF2FunctionKey: - n = "F2" - case C.NSF3FunctionKey: - n = "F3" - case C.NSF4FunctionKey: - n = "F4" - case C.NSF5FunctionKey: - n = "F5" - case C.NSF6FunctionKey: - n = "F6" - case C.NSF7FunctionKey: - n = "F7" - case C.NSF8FunctionKey: - n = "F8" - case C.NSF9FunctionKey: - n = "F9" - case C.NSF10FunctionKey: - n = "F10" - case C.NSF11FunctionKey: - n = "F11" - case C.NSF12FunctionKey: - n = "F12" - case 0x09, 0x19: - n = key.NameTab - case 0x20: - n = "Space" - default: - k = unicode.ToUpper(k) - if !unicode.IsPrint(k) { - return "", false - } - n = string(k) - } - return n, true -} - -func convertMods(mods C.NSUInteger) key.Modifiers { - var kmods key.Modifiers - if mods&C.NSAlternateKeyMask != 0 { - kmods |= key.ModAlt - } - if mods&C.NSControlKeyMask != 0 { - kmods |= key.ModCtrl - } - if mods&C.NSCommandKeyMask != 0 { - kmods |= key.ModCommand - } - if mods&C.NSShiftKeyMask != 0 { - kmods |= key.ModShift - } - return kmods -} diff --git a/vendor/gioui.org/app/internal/window/os_macos.m b/vendor/gioui.org/app/internal/window/os_macos.m deleted file mode 100644 index b8c0dee..0000000 --- a/vendor/gioui.org/app/internal/window/os_macos.m +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build darwin,!ios - -@import AppKit; - -#include "_cgo_export.h" - -@interface GioAppDelegate : NSObject<NSApplicationDelegate> -@end - -@interface GioWindowDelegate : NSObject<NSWindowDelegate> -@end - -@implementation GioWindowDelegate -- (void)windowWillMiniaturize:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - gio_onHide((__bridge CFTypeRef)window.contentView); -} -- (void)windowDidDeminiaturize:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - gio_onShow((__bridge CFTypeRef)window.contentView); -} -- (void)windowDidChangeScreen:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - CGDirectDisplayID dispID = [[[window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue]; - CFTypeRef view = (__bridge CFTypeRef)window.contentView; - gio_onChangeScreen(view, dispID); -} -- (void)windowDidBecomeKey:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - gio_onFocus((__bridge CFTypeRef)window.contentView, YES); -} -- (void)windowDidResignKey:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - gio_onFocus((__bridge CFTypeRef)window.contentView, NO); -} -- (void)windowWillClose:(NSNotification *)notification { - NSWindow *window = (NSWindow *)[notification object]; - window.delegate = nil; - gio_onClose((__bridge CFTypeRef)window.contentView); -} -@end - -// Delegates are weakly referenced from their peers. Nothing -// else holds a strong reference to our window delegate, so -// keep a single global reference instead. -static GioWindowDelegate *globalWindowDel; - -void gio_writeClipboard(unichar *chars, NSUInteger length) { - @autoreleasepool { - NSString *s = [NSString string]; - if (length > 0) { - s = [NSString stringWithCharacters:chars length:length]; - } - NSPasteboard *p = NSPasteboard.generalPasteboard; - [p declareTypes:@[NSPasteboardTypeString] owner:nil]; - [p setString:s forType:NSPasteboardTypeString]; - } -} - -CFTypeRef gio_readClipboard(void) { - @autoreleasepool { - NSPasteboard *p = NSPasteboard.generalPasteboard; - NSString *content = [p stringForType:NSPasteboardTypeString]; - return (__bridge_retained CFTypeRef)content; - } -} - -CGFloat gio_viewHeight(CFTypeRef viewRef) { - NSView *view = (__bridge NSView *)viewRef; - return [view bounds].size.height; -} - -CGFloat gio_viewWidth(CFTypeRef viewRef) { - NSView *view = (__bridge NSView *)viewRef; - return [view bounds].size.width; -} - -CGFloat gio_getScreenBackingScale(void) { - return [NSScreen.mainScreen backingScaleFactor]; -} - -CGFloat gio_getViewBackingScale(CFTypeRef viewRef) { - NSView *view = (__bridge NSView *)viewRef; - return [view.window backingScaleFactor]; -} - -static CVReturn displayLinkCallback(CVDisplayLinkRef dl, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { - gio_onFrameCallback(dl); - return kCVReturnSuccess; -} - -CFTypeRef gio_createDisplayLink(void) { - CVDisplayLinkRef dl; - CVDisplayLinkCreateWithActiveCGDisplays(&dl); - CVDisplayLinkSetOutputCallback(dl, displayLinkCallback, nil); - return dl; -} - -int gio_startDisplayLink(CFTypeRef dl) { - return CVDisplayLinkStart((CVDisplayLinkRef)dl); -} - -int gio_stopDisplayLink(CFTypeRef dl) { - return CVDisplayLinkStop((CVDisplayLinkRef)dl); -} - -void gio_releaseDisplayLink(CFTypeRef dl) { - CVDisplayLinkRelease((CVDisplayLinkRef)dl); -} - -void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did) { - CVDisplayLinkSetCurrentCGDisplay((CVDisplayLinkRef)dl, (CGDirectDisplayID)did); -} - -NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft) { - NSWindow *window = (__bridge NSWindow *)windowRef; - return [window cascadeTopLeftFromPoint:topLeft]; -} - -void gio_makeKeyAndOrderFront(CFTypeRef windowRef) { - NSWindow *window = (__bridge NSWindow *)windowRef; - [window makeKeyAndOrderFront:nil]; -} - -CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight) { - @autoreleasepool { - NSRect rect = NSMakeRect(0, 0, width, height); - NSUInteger styleMask = NSTitledWindowMask | - NSResizableWindowMask | - NSMiniaturizableWindowMask | - NSClosableWindowMask; - - NSWindow* window = [[NSWindow alloc] initWithContentRect:rect - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:NO]; - if (minWidth > 0 || minHeight > 0) { - window.contentMinSize = NSMakeSize(minWidth, minHeight); - } - if (maxWidth > 0 || maxHeight > 0) { - window.contentMaxSize = NSMakeSize(maxWidth, maxHeight); - } - [window setAcceptsMouseMovedEvents:YES]; - window.title = [NSString stringWithUTF8String: title]; - NSView *view = (__bridge NSView *)viewRef; - [window setContentView:view]; - [window makeFirstResponder:view]; - window.releasedWhenClosed = NO; - window.delegate = globalWindowDel; - return (__bridge_retained CFTypeRef)window; - } -} - -void gio_close(CFTypeRef windowRef) { - NSWindow* window = (__bridge NSWindow *)windowRef; - [window performClose:nil]; -} - -@implementation GioAppDelegate -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - [[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)]; - gio_onFinishLaunching(); -} -- (void)applicationDidHide:(NSNotification *)aNotification { - gio_onAppHide(); -} -- (void)applicationWillUnhide:(NSNotification *)notification { - gio_onAppShow(); -} -@end - -void gio_main() { - @autoreleasepool { - [NSApplication sharedApplication]; - GioAppDelegate *del = [[GioAppDelegate alloc] init]; - [NSApp setDelegate:del]; - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - - NSMenuItem *mainMenu = [NSMenuItem new]; - - NSMenu *menu = [NSMenu new]; - NSMenuItem *hideMenuItem = [[NSMenuItem alloc] initWithTitle:@"Hide" - action:@selector(hide:) - keyEquivalent:@"h"]; - [menu addItem:hideMenuItem]; - NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit" - action:@selector(terminate:) - keyEquivalent:@"q"]; - [menu addItem:quitMenuItem]; - [mainMenu setSubmenu:menu]; - NSMenu *menuBar = [NSMenu new]; - [menuBar addItem:mainMenu]; - [NSApp setMainMenu:menuBar]; - - globalWindowDel = [[GioWindowDelegate alloc] init]; - - [NSApp run]; - } -} diff --git a/vendor/gioui.org/app/internal/window/os_unix.go b/vendor/gioui.org/app/internal/window/os_unix.go deleted file mode 100644 index baaebb5..0000000 --- a/vendor/gioui.org/app/internal/window/os_unix.go +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android freebsd openbsd - -package window - -import ( - "errors" -) - -func Main() { - select {} -} - -// instead of creating files with build tags for each combination of wayland +/- x11 -// let each driver initialize these variables with their own version of createWindow. -var wlDriver, x11Driver func(Callbacks, *Options) error - -func NewWindow(window Callbacks, opts *Options) error { - var errFirst, err error - if wlDriver != nil { - if err = wlDriver(window, opts); err == nil { - return nil - } - errFirst = err - } - if x11Driver != nil { - if err = x11Driver(window, opts); err == nil { - return nil - } - if errFirst == nil { - errFirst = err - } - } - if errFirst != nil { - return errFirst - } - return errors.New("app: no window driver available") -} diff --git a/vendor/gioui.org/app/internal/window/os_wayland.c b/vendor/gioui.org/app/internal/window/os_wayland.c deleted file mode 100644 index 5c1c075..0000000 --- a/vendor/gioui.org/app/internal/window/os_wayland.c +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android,!nowayland freebsd - -#include <wayland-client.h> -#include "wayland_xdg_shell.h" -#include "wayland_text_input.h" -#include "_cgo_export.h" - -const struct wl_registry_listener gio_registry_listener = { - // Cast away const parameter. - .global = (void (*)(void *, struct wl_registry *, uint32_t, const char *, uint32_t))gio_onRegistryGlobal, - .global_remove = gio_onRegistryGlobalRemove -}; - -const struct wl_surface_listener gio_surface_listener = { - .enter = gio_onSurfaceEnter, - .leave = gio_onSurfaceLeave, -}; - -const struct xdg_surface_listener gio_xdg_surface_listener = { - .configure = gio_onXdgSurfaceConfigure, -}; - -const struct xdg_toplevel_listener gio_xdg_toplevel_listener = { - .configure = gio_onToplevelConfigure, - .close = gio_onToplevelClose, -}; - -static void xdg_wm_base_handle_ping(void *data, struct xdg_wm_base *wm, uint32_t serial) { - xdg_wm_base_pong(wm, serial); -} - -const struct xdg_wm_base_listener gio_xdg_wm_base_listener = { - .ping = xdg_wm_base_handle_ping, -}; - -const struct wl_callback_listener gio_callback_listener = { - .done = gio_onFrameDone, -}; - -const struct wl_output_listener gio_output_listener = { - // Cast away const parameter. - .geometry = (void (*)(void *, struct wl_output *, int32_t, int32_t, int32_t, int32_t, int32_t, const char *, const char *, int32_t))gio_onOutputGeometry, - .mode = gio_onOutputMode, - .done = gio_onOutputDone, - .scale = gio_onOutputScale, -}; - -const struct wl_seat_listener gio_seat_listener = { - .capabilities = gio_onSeatCapabilities, - // Cast away const parameter. - .name = (void (*)(void *, struct wl_seat *, const char *))gio_onSeatName, -}; - -const struct wl_pointer_listener gio_pointer_listener = { - .enter = gio_onPointerEnter, - .leave = gio_onPointerLeave, - .motion = gio_onPointerMotion, - .button = gio_onPointerButton, - .axis = gio_onPointerAxis, - .frame = gio_onPointerFrame, - .axis_source = gio_onPointerAxisSource, - .axis_stop = gio_onPointerAxisStop, - .axis_discrete = gio_onPointerAxisDiscrete, -}; - -const struct wl_touch_listener gio_touch_listener = { - .down = gio_onTouchDown, - .up = gio_onTouchUp, - .motion = gio_onTouchMotion, - .frame = gio_onTouchFrame, - .cancel = gio_onTouchCancel, -}; - -const struct wl_keyboard_listener gio_keyboard_listener = { - .keymap = gio_onKeyboardKeymap, - .enter = gio_onKeyboardEnter, - .leave = gio_onKeyboardLeave, - .key = gio_onKeyboardKey, - .modifiers = gio_onKeyboardModifiers, - .repeat_info = gio_onKeyboardRepeatInfo -}; - -const struct zwp_text_input_v3_listener gio_zwp_text_input_v3_listener = { - .enter = gio_onTextInputEnter, - .leave = gio_onTextInputLeave, - // Cast away const parameter. - .preedit_string = (void (*)(void *, struct zwp_text_input_v3 *, const char *, int32_t, int32_t))gio_onTextInputPreeditString, - .commit_string = (void (*)(void *, struct zwp_text_input_v3 *, const char *))gio_onTextInputCommitString, - .delete_surrounding_text = gio_onTextInputDeleteSurroundingText, - .done = gio_onTextInputDone -}; - -const struct wl_data_device_listener gio_data_device_listener = { - .data_offer = gio_onDataDeviceOffer, - .enter = gio_onDataDeviceEnter, - .leave = gio_onDataDeviceLeave, - .motion = gio_onDataDeviceMotion, - .drop = gio_onDataDeviceDrop, - .selection = gio_onDataDeviceSelection, -}; - -const struct wl_data_offer_listener gio_data_offer_listener = { - .offer = (void (*)(void *, struct wl_data_offer *, const char *))gio_onDataOfferOffer, - .source_actions = gio_onDataOfferSourceActions, - .action = gio_onDataOfferAction, -}; - -const struct wl_data_source_listener gio_data_source_listener = { - .target = (void (*)(void *, struct wl_data_source *, const char *))gio_onDataSourceTarget, - .send = (void (*)(void *, struct wl_data_source *, const char *, int32_t))gio_onDataSourceSend, - .cancelled = gio_onDataSourceCancelled, - .dnd_drop_performed = gio_onDataSourceDNDDropPerformed, - .dnd_finished = gio_onDataSourceDNDFinished, - .action = gio_onDataSourceAction, -}; diff --git a/vendor/gioui.org/app/internal/window/os_wayland.go b/vendor/gioui.org/app/internal/window/os_wayland.go deleted file mode 100644 index 4a456ce..0000000 --- a/vendor/gioui.org/app/internal/window/os_wayland.go +++ /dev/null @@ -1,1531 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android,!nowayland freebsd - -package window - -import ( - "bytes" - "errors" - "fmt" - "image" - "io" - "io/ioutil" - "math" - "os" - "os/exec" - "strconv" - "sync" - "time" - "unsafe" - - "gioui.org/app/internal/xkb" - "gioui.org/f32" - "gioui.org/internal/fling" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" - syscall "golang.org/x/sys/unix" -) - -// Use wayland-scanner to generate glue code for the xdg-shell and xdg-decoration extensions. -//go:generate wayland-scanner client-header /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml wayland_xdg_shell.h -//go:generate wayland-scanner private-code /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml wayland_xdg_shell.c - -//go:generate wayland-scanner client-header /usr/share/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml wayland_text_input.h -//go:generate wayland-scanner private-code /usr/share/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml wayland_text_input.c - -//go:generate wayland-scanner client-header /usr/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml wayland_xdg_decoration.h -//go:generate wayland-scanner private-code /usr/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml wayland_xdg_decoration.c - -//go:generate sed -i "1s;^;// +build linux,!android,!nowayland freebsd\\n\\n;" wayland_xdg_shell.c -//go:generate sed -i "1s;^;// +build linux,!android,!nowayland freebsd\\n\\n;" wayland_xdg_decoration.c -//go:generate sed -i "1s;^;// +build linux,!android,!nowayland freebsd\\n\\n;" wayland_text_input.c - -/* -#cgo linux pkg-config: wayland-client wayland-cursor -#cgo freebsd openbsd LDFLAGS: -lwayland-client -lwayland-cursor -#cgo freebsd CFLAGS: -I/usr/local/include -#cgo freebsd LDFLAGS: -L/usr/local/lib - -#include <stdlib.h> -#include <wayland-client.h> -#include <wayland-cursor.h> -#include "wayland_text_input.h" -#include "wayland_xdg_shell.h" -#include "wayland_xdg_decoration.h" - -extern const struct wl_registry_listener gio_registry_listener; -extern const struct wl_surface_listener gio_surface_listener; -extern const struct xdg_surface_listener gio_xdg_surface_listener; -extern const struct xdg_toplevel_listener gio_xdg_toplevel_listener; -extern const struct xdg_wm_base_listener gio_xdg_wm_base_listener; -extern const struct wl_callback_listener gio_callback_listener; -extern const struct wl_output_listener gio_output_listener; -extern const struct wl_seat_listener gio_seat_listener; -extern const struct wl_pointer_listener gio_pointer_listener; -extern const struct wl_touch_listener gio_touch_listener; -extern const struct wl_keyboard_listener gio_keyboard_listener; -extern const struct zwp_text_input_v3_listener gio_zwp_text_input_v3_listener; -extern const struct wl_data_device_listener gio_data_device_listener; -extern const struct wl_data_offer_listener gio_data_offer_listener; -extern const struct wl_data_source_listener gio_data_source_listener; -*/ -import "C" - -type wlDisplay struct { - disp *C.struct_wl_display - reg *C.struct_wl_registry - compositor *C.struct_wl_compositor - wm *C.struct_xdg_wm_base - imm *C.struct_zwp_text_input_manager_v3 - shm *C.struct_wl_shm - dataDeviceManager *C.struct_wl_data_device_manager - decor *C.struct_zxdg_decoration_manager_v1 - seat *wlSeat - xkb *xkb.Context - outputMap map[C.uint32_t]*C.struct_wl_output - outputConfig map[*C.struct_wl_output]*wlOutput - - // Notification pipe fds. - notify struct { - read, write int - } - - repeat repeatState -} - -type wlSeat struct { - disp *wlDisplay - seat *C.struct_wl_seat - name C.uint32_t - pointer *C.struct_wl_pointer - touch *C.struct_wl_touch - keyboard *C.struct_wl_keyboard - im *C.struct_zwp_text_input_v3 - - // The most recent input serial. - serial C.uint32_t - - pointerFocus *window - keyboardFocus *window - touchFoci map[C.int32_t]*window - - // Clipboard support. - dataDev *C.struct_wl_data_device - // offers is a map from active wl_data_offers to - // the list of mime types they support. - offers map[*C.struct_wl_data_offer][]string - // clipboard is the wl_data_offer for the clipboard. - clipboard *C.struct_wl_data_offer - // mimeType is the chosen mime type of clipboard. - mimeType string - // source represents the clipboard content of the most recent - // clipboard write, if any. - source *C.struct_wl_data_source - // content is the data belonging to source. - content []byte -} - -type repeatState struct { - rate int - delay time.Duration - - key uint32 - win Callbacks - stopC chan struct{} - - start time.Duration - last time.Duration - mu sync.Mutex - now time.Duration -} - -type window struct { - w Callbacks - disp *wlDisplay - surf *C.struct_wl_surface - wmSurf *C.struct_xdg_surface - topLvl *C.struct_xdg_toplevel - decor *C.struct_zxdg_toplevel_decoration_v1 - ppdp, ppsp float32 - scroll struct { - time time.Duration - steps image.Point - dist f32.Point - } - pointerBtns pointer.Buttons - lastPos f32.Point - lastTouch f32.Point - - cursor struct { - theme *C.struct_wl_cursor_theme - cursor *C.struct_wl_cursor - surf *C.struct_wl_surface - } - - fling struct { - yExtrapolation fling.Extrapolation - xExtrapolation fling.Extrapolation - anim fling.Animation - start bool - dir f32.Point - } - - stage system.Stage - dead bool - lastFrameCallback *C.struct_wl_callback - - mu sync.Mutex - animating bool - needAck bool - // The most recent configure serial waiting to be ack'ed. - serial C.uint32_t - width int - height int - newScale bool - scale int - // readClipboard tracks whether a ClipboardEvent is requested. - readClipboard bool - // writeClipboard is set whenever a clipboard write is requested. - writeClipboard *string -} - -type poller struct { - pollfds [2]syscall.PollFd - // buf is scratch space for draining the notification pipe. - buf [100]byte -} - -type wlOutput struct { - width int - height int - physWidth int - physHeight int - transform C.int32_t - scale int - windows []*window -} - -// callbackMap maps Wayland native handles to corresponding Go -// references. It is necessary because the the Wayland client API -// forces the use of callbacks and storing pointers to Go values -// in C is forbidden. -var callbackMap sync.Map - -// clipboardMimeTypes is a list of supported clipboard mime types, in -// order of preference. -var clipboardMimeTypes = []string{"text/plain;charset=utf8", "UTF8_STRING", "text/plain", "TEXT", "STRING"} - -func init() { - wlDriver = newWLWindow -} - -func newWLWindow(window Callbacks, opts *Options) error { - d, err := newWLDisplay() - if err != nil { - return err - } - w, err := d.createNativeWindow(opts) - if err != nil { - d.destroy() - return err - } - w.w = window - go func() { - defer d.destroy() - defer w.destroy() - w.w.SetDriver(w) - if err := w.loop(); err != nil { - panic(err) - } - }() - return nil -} - -func (d *wlDisplay) writeClipboard(content []byte) error { - s := d.seat - if s == nil { - return nil - } - // Clear old offer. - if s.source != nil { - C.wl_data_source_destroy(s.source) - s.source = nil - s.content = nil - } - if d.dataDeviceManager == nil || s.dataDev == nil { - return nil - } - s.content = content - s.source = C.wl_data_device_manager_create_data_source(d.dataDeviceManager) - C.wl_data_source_add_listener(s.source, &C.gio_data_source_listener, unsafe.Pointer(s.seat)) - for _, mime := range clipboardMimeTypes { - C.wl_data_source_offer(s.source, C.CString(mime)) - } - C.wl_data_device_set_selection(s.dataDev, s.source, s.serial) - return nil -} - -func (d *wlDisplay) readClipboard() (io.ReadCloser, error) { - s := d.seat - if s == nil { - return nil, nil - } - if s.clipboard == nil { - return nil, nil - } - r, w, err := os.Pipe() - if err != nil { - return nil, err - } - cmimeType := C.CString(s.mimeType) - defer C.free(unsafe.Pointer(cmimeType)) - C.wl_data_offer_receive(s.clipboard, cmimeType, C.int(w.Fd())) - return r, nil -} - -func (d *wlDisplay) createNativeWindow(opts *Options) (*window, error) { - if d.compositor == nil { - return nil, errors.New("wayland: no compositor available") - } - if d.wm == nil { - return nil, errors.New("wayland: no xdg_wm_base available") - } - if d.shm == nil { - return nil, errors.New("wayland: no wl_shm available") - } - if len(d.outputMap) == 0 { - return nil, errors.New("wayland: no outputs available") - } - var scale int - for _, conf := range d.outputConfig { - if s := conf.scale; s > scale { - scale = s - } - } - ppdp := detectUIScale() - - w := &window{ - disp: d, - scale: scale, - newScale: scale != 1, - ppdp: ppdp, - ppsp: ppdp, - } - w.surf = C.wl_compositor_create_surface(d.compositor) - if w.surf == nil { - w.destroy() - return nil, errors.New("wayland: wl_compositor_create_surface failed") - } - callbackStore(unsafe.Pointer(w.surf), w) - w.wmSurf = C.xdg_wm_base_get_xdg_surface(d.wm, w.surf) - if w.wmSurf == nil { - w.destroy() - return nil, errors.New("wayland: xdg_wm_base_get_xdg_surface failed") - } - w.topLvl = C.xdg_surface_get_toplevel(w.wmSurf) - if w.topLvl == nil { - w.destroy() - return nil, errors.New("wayland: xdg_surface_get_toplevel failed") - } - w.cursor.theme = C.wl_cursor_theme_load(nil, 32, d.shm) - if w.cursor.theme == nil { - w.destroy() - return nil, errors.New("wayland: wl_cursor_theme_load failed") - } - cname := C.CString("left_ptr") - defer C.free(unsafe.Pointer(cname)) - w.cursor.cursor = C.wl_cursor_theme_get_cursor(w.cursor.theme, cname) - if w.cursor.cursor == nil { - w.destroy() - return nil, errors.New("wayland: wl_cursor_theme_get_cursor failed") - } - w.cursor.surf = C.wl_compositor_create_surface(d.compositor) - if w.cursor.surf == nil { - w.destroy() - return nil, errors.New("wayland: wl_compositor_create_surface failed") - } - C.xdg_wm_base_add_listener(d.wm, &C.gio_xdg_wm_base_listener, unsafe.Pointer(w.surf)) - C.wl_surface_add_listener(w.surf, &C.gio_surface_listener, unsafe.Pointer(w.surf)) - C.xdg_surface_add_listener(w.wmSurf, &C.gio_xdg_surface_listener, unsafe.Pointer(w.surf)) - C.xdg_toplevel_add_listener(w.topLvl, &C.gio_xdg_toplevel_listener, unsafe.Pointer(w.surf)) - title := C.CString(opts.Title) - C.xdg_toplevel_set_title(w.topLvl, title) - C.free(unsafe.Pointer(title)) - - _, _, cfg := w.config() - w.width = cfg.Px(opts.Width) - w.height = cfg.Px(opts.Height) - if d.decor != nil { - // Request server side decorations. - w.decor = C.zxdg_decoration_manager_v1_get_toplevel_decoration(d.decor, w.topLvl) - C.zxdg_toplevel_decoration_v1_set_mode(w.decor, C.ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) - } - w.updateOpaqueRegion() - C.wl_surface_commit(w.surf) - return w, nil -} - -func callbackDelete(k unsafe.Pointer) { - callbackMap.Delete(k) -} - -func callbackStore(k unsafe.Pointer, v interface{}) { - callbackMap.Store(k, v) -} - -func callbackLoad(k unsafe.Pointer) interface{} { - v, exists := callbackMap.Load(k) - if !exists { - panic("missing callback entry") - } - return v -} - -//export gio_onSeatCapabilities -func gio_onSeatCapabilities(data unsafe.Pointer, seat *C.struct_wl_seat, caps C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - s.updateCaps(caps) -} - -// flushOffers remove all wl_data_offers that isn't the clipboard -// content. -func (s *wlSeat) flushOffers() { - for o := range s.offers { - if o == s.clipboard { - continue - } - // We're only interested in clipboard offers. - delete(s.offers, o) - callbackDelete(unsafe.Pointer(o)) - C.wl_data_offer_destroy(o) - } -} - -func (s *wlSeat) destroy() { - if s.source != nil { - C.wl_data_source_destroy(s.source) - s.source = nil - } - if s.im != nil { - C.zwp_text_input_v3_destroy(s.im) - s.im = nil - } - if s.pointer != nil { - C.wl_pointer_release(s.pointer) - } - if s.touch != nil { - C.wl_touch_release(s.touch) - } - if s.keyboard != nil { - C.wl_keyboard_release(s.keyboard) - } - s.clipboard = nil - s.flushOffers() - if s.dataDev != nil { - C.wl_data_device_release(s.dataDev) - } - if s.seat != nil { - callbackDelete(unsafe.Pointer(s.seat)) - C.wl_seat_release(s.seat) - } -} - -func (s *wlSeat) updateCaps(caps C.uint32_t) { - if s.im == nil && s.disp.imm != nil { - s.im = C.zwp_text_input_manager_v3_get_text_input(s.disp.imm, s.seat) - C.zwp_text_input_v3_add_listener(s.im, &C.gio_zwp_text_input_v3_listener, unsafe.Pointer(s.seat)) - } - switch { - case s.pointer == nil && caps&C.WL_SEAT_CAPABILITY_POINTER != 0: - s.pointer = C.wl_seat_get_pointer(s.seat) - C.wl_pointer_add_listener(s.pointer, &C.gio_pointer_listener, unsafe.Pointer(s.seat)) - case s.pointer != nil && caps&C.WL_SEAT_CAPABILITY_POINTER == 0: - C.wl_pointer_release(s.pointer) - s.pointer = nil - } - switch { - case s.touch == nil && caps&C.WL_SEAT_CAPABILITY_TOUCH != 0: - s.touch = C.wl_seat_get_touch(s.seat) - C.wl_touch_add_listener(s.touch, &C.gio_touch_listener, unsafe.Pointer(s.seat)) - case s.touch != nil && caps&C.WL_SEAT_CAPABILITY_TOUCH == 0: - C.wl_touch_release(s.touch) - s.touch = nil - } - switch { - case s.keyboard == nil && caps&C.WL_SEAT_CAPABILITY_KEYBOARD != 0: - s.keyboard = C.wl_seat_get_keyboard(s.seat) - C.wl_keyboard_add_listener(s.keyboard, &C.gio_keyboard_listener, unsafe.Pointer(s.seat)) - case s.keyboard != nil && caps&C.WL_SEAT_CAPABILITY_KEYBOARD == 0: - C.wl_keyboard_release(s.keyboard) - s.keyboard = nil - } -} - -//export gio_onSeatName -func gio_onSeatName(data unsafe.Pointer, seat *C.struct_wl_seat, name *C.char) { -} - -//export gio_onXdgSurfaceConfigure -func gio_onXdgSurfaceConfigure(data unsafe.Pointer, wmSurf *C.struct_xdg_surface, serial C.uint32_t) { - w := callbackLoad(data).(*window) - w.mu.Lock() - w.serial = serial - w.needAck = true - w.mu.Unlock() - w.setStage(system.StageRunning) - w.draw(true) -} - -//export gio_onToplevelClose -func gio_onToplevelClose(data unsafe.Pointer, topLvl *C.struct_xdg_toplevel) { - w := callbackLoad(data).(*window) - w.dead = true -} - -//export gio_onToplevelConfigure -func gio_onToplevelConfigure(data unsafe.Pointer, topLvl *C.struct_xdg_toplevel, width, height C.int32_t, states *C.struct_wl_array) { - w := callbackLoad(data).(*window) - if width != 0 && height != 0 { - w.mu.Lock() - defer w.mu.Unlock() - w.width = int(width) - w.height = int(height) - w.updateOpaqueRegion() - } -} - -//export gio_onOutputMode -func gio_onOutputMode(data unsafe.Pointer, output *C.struct_wl_output, flags C.uint32_t, width, height, refresh C.int32_t) { - if flags&C.WL_OUTPUT_MODE_CURRENT == 0 { - return - } - d := callbackLoad(data).(*wlDisplay) - c := d.outputConfig[output] - c.width = int(width) - c.height = int(height) -} - -//export gio_onOutputGeometry -func gio_onOutputGeometry(data unsafe.Pointer, output *C.struct_wl_output, x, y, physWidth, physHeight, subpixel C.int32_t, make, model *C.char, transform C.int32_t) { - d := callbackLoad(data).(*wlDisplay) - c := d.outputConfig[output] - c.transform = transform - c.physWidth = int(physWidth) - c.physHeight = int(physHeight) -} - -//export gio_onOutputScale -func gio_onOutputScale(data unsafe.Pointer, output *C.struct_wl_output, scale C.int32_t) { - d := callbackLoad(data).(*wlDisplay) - c := d.outputConfig[output] - c.scale = int(scale) -} - -//export gio_onOutputDone -func gio_onOutputDone(data unsafe.Pointer, output *C.struct_wl_output) { - d := callbackLoad(data).(*wlDisplay) - conf := d.outputConfig[output] - for _, w := range conf.windows { - w.draw(true) - } -} - -//export gio_onSurfaceEnter -func gio_onSurfaceEnter(data unsafe.Pointer, surf *C.struct_wl_surface, output *C.struct_wl_output) { - w := callbackLoad(data).(*window) - conf := w.disp.outputConfig[output] - var found bool - for _, w2 := range conf.windows { - if w2 == w { - found = true - break - } - } - if !found { - conf.windows = append(conf.windows, w) - } - w.updateOutputs() -} - -//export gio_onSurfaceLeave -func gio_onSurfaceLeave(data unsafe.Pointer, surf *C.struct_wl_surface, output *C.struct_wl_output) { - w := callbackLoad(data).(*window) - conf := w.disp.outputConfig[output] - for i, w2 := range conf.windows { - if w2 == w { - conf.windows = append(conf.windows[:i], conf.windows[i+1:]...) - break - } - } - w.updateOutputs() -} - -//export gio_onRegistryGlobal -func gio_onRegistryGlobal(data unsafe.Pointer, reg *C.struct_wl_registry, name C.uint32_t, cintf *C.char, version C.uint32_t) { - d := callbackLoad(data).(*wlDisplay) - switch C.GoString(cintf) { - case "wl_compositor": - d.compositor = (*C.struct_wl_compositor)(C.wl_registry_bind(reg, name, &C.wl_compositor_interface, 3)) - case "wl_output": - output := (*C.struct_wl_output)(C.wl_registry_bind(reg, name, &C.wl_output_interface, 2)) - C.wl_output_add_listener(output, &C.gio_output_listener, unsafe.Pointer(d.disp)) - d.outputMap[name] = output - d.outputConfig[output] = new(wlOutput) - case "wl_seat": - if d.seat != nil { - break - } - s := (*C.struct_wl_seat)(C.wl_registry_bind(reg, name, &C.wl_seat_interface, 5)) - if s == nil { - // No support for v5 protocol. - break - } - d.seat = &wlSeat{ - disp: d, - name: name, - seat: s, - offers: make(map[*C.struct_wl_data_offer][]string), - } - callbackStore(unsafe.Pointer(s), d.seat) - C.wl_seat_add_listener(s, &C.gio_seat_listener, unsafe.Pointer(s)) - if d.dataDeviceManager == nil { - break - } - d.seat.dataDev = C.wl_data_device_manager_get_data_device(d.dataDeviceManager, s) - if d.seat.dataDev == nil { - break - } - callbackStore(unsafe.Pointer(d.seat.dataDev), d.seat) - C.wl_data_device_add_listener(d.seat.dataDev, &C.gio_data_device_listener, unsafe.Pointer(d.seat.dataDev)) - case "wl_shm": - d.shm = (*C.struct_wl_shm)(C.wl_registry_bind(reg, name, &C.wl_shm_interface, 1)) - case "xdg_wm_base": - d.wm = (*C.struct_xdg_wm_base)(C.wl_registry_bind(reg, name, &C.xdg_wm_base_interface, 1)) - case "zxdg_decoration_manager_v1": - d.decor = (*C.struct_zxdg_decoration_manager_v1)(C.wl_registry_bind(reg, name, &C.zxdg_decoration_manager_v1_interface, 1)) - // TODO: Implement and test text-input support. - /*case "zwp_text_input_manager_v3": - d.imm = (*C.struct_zwp_text_input_manager_v3)(C.wl_registry_bind(reg, name, &C.zwp_text_input_manager_v3_interface, 1))*/ - case "wl_data_device_manager": - d.dataDeviceManager = (*C.struct_wl_data_device_manager)(C.wl_registry_bind(reg, name, &C.wl_data_device_manager_interface, 3)) - } -} - -//export gio_onDataOfferOffer -func gio_onDataOfferOffer(data unsafe.Pointer, offer *C.struct_wl_data_offer, mime *C.char) { - s := callbackLoad(data).(*wlSeat) - s.offers[offer] = append(s.offers[offer], C.GoString(mime)) -} - -//export gio_onDataOfferSourceActions -func gio_onDataOfferSourceActions(data unsafe.Pointer, offer *C.struct_wl_data_offer, acts C.uint32_t) { -} - -//export gio_onDataOfferAction -func gio_onDataOfferAction(data unsafe.Pointer, offer *C.struct_wl_data_offer, act C.uint32_t) { -} - -//export gio_onDataDeviceOffer -func gio_onDataDeviceOffer(data unsafe.Pointer, dataDev *C.struct_wl_data_device, id *C.struct_wl_data_offer) { - s := callbackLoad(data).(*wlSeat) - callbackStore(unsafe.Pointer(id), s) - C.wl_data_offer_add_listener(id, &C.gio_data_offer_listener, unsafe.Pointer(id)) - s.offers[id] = nil -} - -//export gio_onDataDeviceEnter -func gio_onDataDeviceEnter(data unsafe.Pointer, dataDev *C.struct_wl_data_device, serial C.uint32_t, surf *C.struct_wl_surface, x, y C.wl_fixed_t, id *C.struct_wl_data_offer) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - s.flushOffers() -} - -//export gio_onDataDeviceLeave -func gio_onDataDeviceLeave(data unsafe.Pointer, dataDev *C.struct_wl_data_device) { -} - -//export gio_onDataDeviceMotion -func gio_onDataDeviceMotion(data unsafe.Pointer, dataDev *C.struct_wl_data_device, t C.uint32_t, x, y C.wl_fixed_t) { -} - -//export gio_onDataDeviceDrop -func gio_onDataDeviceDrop(data unsafe.Pointer, dataDev *C.struct_wl_data_device) { -} - -//export gio_onDataDeviceSelection -func gio_onDataDeviceSelection(data unsafe.Pointer, dataDev *C.struct_wl_data_device, id *C.struct_wl_data_offer) { - s := callbackLoad(data).(*wlSeat) - defer s.flushOffers() - s.clipboard = nil -loop: - for _, want := range clipboardMimeTypes { - for _, got := range s.offers[id] { - if want != got { - continue - } - s.clipboard = id - s.mimeType = got - break loop - } - } -} - -//export gio_onRegistryGlobalRemove -func gio_onRegistryGlobalRemove(data unsafe.Pointer, reg *C.struct_wl_registry, name C.uint32_t) { - d := callbackLoad(data).(*wlDisplay) - if s := d.seat; s != nil && name == s.name { - s.destroy() - d.seat = nil - } - if output, exists := d.outputMap[name]; exists { - C.wl_output_destroy(output) - delete(d.outputMap, name) - delete(d.outputConfig, output) - } -} - -//export gio_onTouchDown -func gio_onTouchDown(data unsafe.Pointer, touch *C.struct_wl_touch, serial, t C.uint32_t, surf *C.struct_wl_surface, id C.int32_t, x, y C.wl_fixed_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := callbackLoad(unsafe.Pointer(surf)).(*window) - s.touchFoci[id] = w - w.lastTouch = f32.Point{ - X: fromFixed(x) * float32(w.scale), - Y: fromFixed(y) * float32(w.scale), - } - w.w.Event(pointer.Event{ - Type: pointer.Press, - Source: pointer.Touch, - Position: w.lastTouch, - PointerID: pointer.ID(id), - Time: time.Duration(t) * time.Millisecond, - Modifiers: w.disp.xkb.Modifiers(), - }) -} - -//export gio_onTouchUp -func gio_onTouchUp(data unsafe.Pointer, touch *C.struct_wl_touch, serial, t C.uint32_t, id C.int32_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := s.touchFoci[id] - delete(s.touchFoci, id) - w.w.Event(pointer.Event{ - Type: pointer.Release, - Source: pointer.Touch, - Position: w.lastTouch, - PointerID: pointer.ID(id), - Time: time.Duration(t) * time.Millisecond, - Modifiers: w.disp.xkb.Modifiers(), - }) -} - -//export gio_onTouchMotion -func gio_onTouchMotion(data unsafe.Pointer, touch *C.struct_wl_touch, t C.uint32_t, id C.int32_t, x, y C.wl_fixed_t) { - s := callbackLoad(data).(*wlSeat) - w := s.touchFoci[id] - w.lastTouch = f32.Point{ - X: fromFixed(x) * float32(w.scale), - Y: fromFixed(y) * float32(w.scale), - } - w.w.Event(pointer.Event{ - Type: pointer.Move, - Position: w.lastTouch, - Source: pointer.Touch, - PointerID: pointer.ID(id), - Time: time.Duration(t) * time.Millisecond, - Modifiers: w.disp.xkb.Modifiers(), - }) -} - -//export gio_onTouchFrame -func gio_onTouchFrame(data unsafe.Pointer, touch *C.struct_wl_touch) { -} - -//export gio_onTouchCancel -func gio_onTouchCancel(data unsafe.Pointer, touch *C.struct_wl_touch) { - s := callbackLoad(data).(*wlSeat) - for id, w := range s.touchFoci { - delete(s.touchFoci, id) - w.w.Event(pointer.Event{ - Type: pointer.Cancel, - Source: pointer.Touch, - }) - } -} - -//export gio_onPointerEnter -func gio_onPointerEnter(data unsafe.Pointer, pointer *C.struct_wl_pointer, serial C.uint32_t, surf *C.struct_wl_surface, x, y C.wl_fixed_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := callbackLoad(unsafe.Pointer(surf)).(*window) - s.pointerFocus = w - // Get images[0]. - img := *w.cursor.cursor.images - buf := C.wl_cursor_image_get_buffer(img) - if buf == nil { - return - } - C.wl_pointer_set_cursor(pointer, serial, w.cursor.surf, C.int32_t(img.hotspot_x), C.int32_t(img.hotspot_y)) - C.wl_surface_attach(w.cursor.surf, buf, 0, 0) - C.wl_surface_damage(w.cursor.surf, 0, 0, C.int32_t(img.width), C.int32_t(img.height)) - C.wl_surface_commit(w.cursor.surf) - w.lastPos = f32.Point{X: fromFixed(x), Y: fromFixed(y)} -} - -//export gio_onPointerLeave -func gio_onPointerLeave(data unsafe.Pointer, p *C.struct_wl_pointer, serial C.uint32_t, surface *C.struct_wl_surface) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial -} - -//export gio_onPointerMotion -func gio_onPointerMotion(data unsafe.Pointer, p *C.struct_wl_pointer, t C.uint32_t, x, y C.wl_fixed_t) { - s := callbackLoad(data).(*wlSeat) - w := s.pointerFocus - w.resetFling() - w.onPointerMotion(x, y, t) -} - -//export gio_onPointerButton -func gio_onPointerButton(data unsafe.Pointer, p *C.struct_wl_pointer, serial, t, wbtn, state C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := s.pointerFocus - // From linux-event-codes.h. - const ( - BTN_LEFT = 0x110 - BTN_RIGHT = 0x111 - BTN_MIDDLE = 0x112 - ) - var btn pointer.Buttons - switch wbtn { - case BTN_LEFT: - btn = pointer.ButtonLeft - case BTN_RIGHT: - btn = pointer.ButtonRight - case BTN_MIDDLE: - btn = pointer.ButtonMiddle - default: - return - } - var typ pointer.Type - switch state { - case 0: - w.pointerBtns &^= btn - typ = pointer.Release - case 1: - w.pointerBtns |= btn - typ = pointer.Press - } - w.flushScroll() - w.resetFling() - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Mouse, - Buttons: w.pointerBtns, - Position: w.lastPos, - Time: time.Duration(t) * time.Millisecond, - Modifiers: w.disp.xkb.Modifiers(), - }) -} - -//export gio_onPointerAxis -func gio_onPointerAxis(data unsafe.Pointer, p *C.struct_wl_pointer, t, axis C.uint32_t, value C.wl_fixed_t) { - s := callbackLoad(data).(*wlSeat) - w := s.pointerFocus - v := fromFixed(value) - w.resetFling() - if w.scroll.dist == (f32.Point{}) { - w.scroll.time = time.Duration(t) * time.Millisecond - } - switch axis { - case C.WL_POINTER_AXIS_HORIZONTAL_SCROLL: - w.scroll.dist.X += v - case C.WL_POINTER_AXIS_VERTICAL_SCROLL: - w.scroll.dist.Y += v - } -} - -//export gio_onPointerFrame -func gio_onPointerFrame(data unsafe.Pointer, p *C.struct_wl_pointer) { - s := callbackLoad(data).(*wlSeat) - w := s.pointerFocus - w.flushScroll() - w.flushFling() -} - -func (w *window) flushFling() { - if !w.fling.start { - return - } - w.fling.start = false - estx, esty := w.fling.xExtrapolation.Estimate(), w.fling.yExtrapolation.Estimate() - w.fling.xExtrapolation = fling.Extrapolation{} - w.fling.yExtrapolation = fling.Extrapolation{} - vel := float32(math.Sqrt(float64(estx.Velocity*estx.Velocity + esty.Velocity*esty.Velocity))) - _, _, c := w.config() - if !w.fling.anim.Start(c, time.Now(), vel) { - return - } - invDist := 1 / vel - w.fling.dir.X = estx.Velocity * invDist - w.fling.dir.Y = esty.Velocity * invDist - // Wake up the window loop. - w.disp.wakeup() -} - -//export gio_onPointerAxisSource -func gio_onPointerAxisSource(data unsafe.Pointer, pointer *C.struct_wl_pointer, source C.uint32_t) { -} - -//export gio_onPointerAxisStop -func gio_onPointerAxisStop(data unsafe.Pointer, p *C.struct_wl_pointer, t, axis C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - w := s.pointerFocus - w.fling.start = true -} - -//export gio_onPointerAxisDiscrete -func gio_onPointerAxisDiscrete(data unsafe.Pointer, p *C.struct_wl_pointer, axis C.uint32_t, discrete C.int32_t) { - s := callbackLoad(data).(*wlSeat) - w := s.pointerFocus - w.resetFling() - switch axis { - case C.WL_POINTER_AXIS_HORIZONTAL_SCROLL: - w.scroll.steps.X += int(discrete) - case C.WL_POINTER_AXIS_VERTICAL_SCROLL: - w.scroll.steps.Y += int(discrete) - } -} - -func (w *window) ReadClipboard() { - w.mu.Lock() - w.readClipboard = true - w.mu.Unlock() - w.disp.wakeup() -} - -func (w *window) WriteClipboard(s string) { - w.mu.Lock() - w.writeClipboard = &s - w.mu.Unlock() - w.disp.wakeup() -} - -func (w *window) resetFling() { - w.fling.start = false - w.fling.anim = fling.Animation{} -} - -//export gio_onKeyboardKeymap -func gio_onKeyboardKeymap(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, format C.uint32_t, fd C.int32_t, size C.uint32_t) { - defer syscall.Close(int(fd)) - s := callbackLoad(data).(*wlSeat) - s.disp.repeat.Stop(0) - s.disp.xkb.DestroyKeymapState() - if format != C.WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 { - return - } - if err := s.disp.xkb.LoadKeymap(int(format), int(fd), int(size)); err != nil { - // TODO: Do better. - panic(err) - } -} - -//export gio_onKeyboardEnter -func gio_onKeyboardEnter(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, serial C.uint32_t, surf *C.struct_wl_surface, keys *C.struct_wl_array) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := callbackLoad(unsafe.Pointer(surf)).(*window) - s.keyboardFocus = w - s.disp.repeat.Stop(0) - w.w.Event(key.FocusEvent{Focus: true}) -} - -//export gio_onKeyboardLeave -func gio_onKeyboardLeave(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, serial C.uint32_t, surf *C.struct_wl_surface) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - s.disp.repeat.Stop(0) - w := s.keyboardFocus - w.w.Event(key.FocusEvent{Focus: false}) -} - -//export gio_onKeyboardKey -func gio_onKeyboardKey(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, serial, timestamp, keyCode, state C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - w := s.keyboardFocus - t := time.Duration(timestamp) * time.Millisecond - s.disp.repeat.Stop(t) - w.resetFling() - if state != C.WL_KEYBOARD_KEY_STATE_PRESSED { - return - } - kc := mapXKBKeycode(uint32(keyCode)) - for _, e := range w.disp.xkb.DispatchKey(kc) { - w.w.Event(e) - } - if w.disp.xkb.IsRepeatKey(kc) { - w.disp.repeat.Start(w, kc, t) - } -} - -func mapXKBKeycode(keyCode uint32) uint32 { - // According to the xkb_v1 spec: "to determine the xkb keycode, clients must add 8 to the key event keycode." - return keyCode + 8 -} - -func (r *repeatState) Start(w *window, keyCode uint32, t time.Duration) { - if r.rate <= 0 { - return - } - stopC := make(chan struct{}) - r.start = t - r.last = 0 - r.now = 0 - r.stopC = stopC - r.key = keyCode - r.win = w.w - rate, delay := r.rate, r.delay - go func() { - timer := time.NewTimer(delay) - for { - select { - case <-timer.C: - case <-stopC: - close(stopC) - return - } - r.Advance(delay) - w.disp.wakeup() - delay = time.Second / time.Duration(rate) - timer.Reset(delay) - } - }() -} - -func (r *repeatState) Stop(t time.Duration) { - if r.stopC == nil { - return - } - r.stopC <- struct{}{} - <-r.stopC - r.stopC = nil - t -= r.start - if r.now > t { - r.now = t - } -} - -func (r *repeatState) Advance(dt time.Duration) { - r.mu.Lock() - defer r.mu.Unlock() - r.now += dt -} - -func (r *repeatState) Repeat(d *wlDisplay) { - if r.rate <= 0 { - return - } - r.mu.Lock() - now := r.now - r.mu.Unlock() - for { - var delay time.Duration - if r.last < r.delay { - delay = r.delay - } else { - delay = time.Second / time.Duration(r.rate) - } - if r.last+delay > now { - break - } - for _, e := range d.xkb.DispatchKey(r.key) { - r.win.Event(e) - } - r.last += delay - } -} - -//export gio_onFrameDone -func gio_onFrameDone(data unsafe.Pointer, callback *C.struct_wl_callback, t C.uint32_t) { - C.wl_callback_destroy(callback) - w := callbackLoad(data).(*window) - if w.lastFrameCallback == callback { - w.lastFrameCallback = nil - w.draw(false) - } -} - -func (w *window) loop() error { - var p poller - for { - if err := w.disp.dispatch(&p); err != nil { - return err - } - if w.dead { - w.w.Event(system.DestroyEvent{}) - break - } - w.process() - } - return nil -} - -func (w *window) process() { - w.mu.Lock() - readClipboard := w.readClipboard - writeClipboard := w.writeClipboard - w.readClipboard = false - w.writeClipboard = nil - w.mu.Unlock() - if readClipboard { - r, err := w.disp.readClipboard() - // Send empty responses on unavailable clipboards or errors. - if r == nil || err != nil { - w.w.Event(system.ClipboardEvent{}) - return - } - // Don't let slow clipboard transfers block event loop. - go func() { - defer r.Close() - data, _ := ioutil.ReadAll(r) - w.w.Event(system.ClipboardEvent{Text: string(data)}) - }() - } - if writeClipboard != nil { - w.disp.writeClipboard([]byte(*writeClipboard)) - } - // pass false to skip unnecessary drawing. - w.draw(false) -} - -func (d *wlDisplay) dispatch(p *poller) error { - dispfd := C.wl_display_get_fd(d.disp) - // Poll for events and notifications. - pollfds := append(p.pollfds[:0], - syscall.PollFd{Fd: int32(dispfd), Events: syscall.POLLIN | syscall.POLLERR}, - syscall.PollFd{Fd: int32(d.notify.read), Events: syscall.POLLIN | syscall.POLLERR}, - ) - dispFd := &pollfds[0] - if ret, err := C.wl_display_flush(d.disp); ret < 0 { - if err != syscall.EAGAIN { - return fmt.Errorf("wayland: wl_display_flush failed: %v", err) - } - // EAGAIN means the output buffer was full. Poll for - // POLLOUT to know when we can write again. - dispFd.Events |= syscall.POLLOUT - } - if _, err := syscall.Poll(pollfds, -1); err != nil && err != syscall.EINTR { - return fmt.Errorf("wayland: poll failed: %v", err) - } - // Clear notifications. - for { - _, err := syscall.Read(d.notify.read, p.buf[:]) - if err == syscall.EAGAIN { - break - } - if err != nil { - return fmt.Errorf("wayland: read from notify pipe failed: %v", err) - } - } - // Handle events - switch { - case dispFd.Revents&syscall.POLLIN != 0: - if ret, err := C.wl_display_dispatch(d.disp); ret < 0 { - return fmt.Errorf("wayland: wl_display_dispatch failed: %v", err) - } - case dispFd.Revents&(syscall.POLLERR|syscall.POLLHUP) != 0: - return errors.New("wayland: display file descriptor gone") - } - d.repeat.Repeat(d) - return nil -} - -func (w *window) SetAnimating(anim bool) { - w.mu.Lock() - w.animating = anim - w.mu.Unlock() - w.disp.wakeup() -} - -// Wakeup wakes up the event loop through the notification pipe. -func (d *wlDisplay) wakeup() { - oneByte := make([]byte, 1) - if _, err := syscall.Write(d.notify.write, oneByte); err != nil && err != syscall.EAGAIN { - panic(fmt.Errorf("failed to write to pipe: %v", err)) - } -} - -func (w *window) destroy() { - if w.cursor.surf != nil { - C.wl_surface_destroy(w.cursor.surf) - } - if w.cursor.theme != nil { - C.wl_cursor_theme_destroy(w.cursor.theme) - } - if w.topLvl != nil { - C.xdg_toplevel_destroy(w.topLvl) - } - if w.surf != nil { - C.wl_surface_destroy(w.surf) - } - if w.wmSurf != nil { - C.xdg_surface_destroy(w.wmSurf) - } - if w.decor != nil { - C.zxdg_toplevel_decoration_v1_destroy(w.decor) - } - callbackDelete(unsafe.Pointer(w.surf)) -} - -//export gio_onKeyboardModifiers -func gio_onKeyboardModifiers(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, serial, depressed, latched, locked, group C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial - d := s.disp - d.repeat.Stop(0) - if d.xkb == nil { - return - } - d.xkb.UpdateMask(uint32(depressed), uint32(latched), uint32(locked), uint32(group), uint32(group), uint32(group)) -} - -//export gio_onKeyboardRepeatInfo -func gio_onKeyboardRepeatInfo(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, rate, delay C.int32_t) { - s := callbackLoad(data).(*wlSeat) - d := s.disp - d.repeat.Stop(0) - d.repeat.rate = int(rate) - d.repeat.delay = time.Duration(delay) * time.Millisecond -} - -//export gio_onTextInputEnter -func gio_onTextInputEnter(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, surf *C.struct_wl_surface) { -} - -//export gio_onTextInputLeave -func gio_onTextInputLeave(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, surf *C.struct_wl_surface) { -} - -//export gio_onTextInputPreeditString -func gio_onTextInputPreeditString(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, ctxt *C.char, begin, end C.int32_t) { -} - -//export gio_onTextInputCommitString -func gio_onTextInputCommitString(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, ctxt *C.char) { -} - -//export gio_onTextInputDeleteSurroundingText -func gio_onTextInputDeleteSurroundingText(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, before, after C.uint32_t) { -} - -//export gio_onTextInputDone -func gio_onTextInputDone(data unsafe.Pointer, im *C.struct_zwp_text_input_v3, serial C.uint32_t) { - s := callbackLoad(data).(*wlSeat) - s.serial = serial -} - -//export gio_onDataSourceTarget -func gio_onDataSourceTarget(data unsafe.Pointer, source *C.struct_wl_data_source, mime *C.char) { -} - -//export gio_onDataSourceSend -func gio_onDataSourceSend(data unsafe.Pointer, source *C.struct_wl_data_source, mime *C.char, fd C.int32_t) { - s := callbackLoad(data).(*wlSeat) - content := s.content - go func() { - defer syscall.Close(int(fd)) - syscall.Write(int(fd), content) - }() -} - -//export gio_onDataSourceCancelled -func gio_onDataSourceCancelled(data unsafe.Pointer, source *C.struct_wl_data_source) { - s := callbackLoad(data).(*wlSeat) - if s.source == source { - s.content = nil - s.source = nil - } - C.wl_data_source_destroy(source) -} - -//export gio_onDataSourceDNDDropPerformed -func gio_onDataSourceDNDDropPerformed(data unsafe.Pointer, source *C.struct_wl_data_source) { -} - -//export gio_onDataSourceDNDFinished -func gio_onDataSourceDNDFinished(data unsafe.Pointer, source *C.struct_wl_data_source) { -} - -//export gio_onDataSourceAction -func gio_onDataSourceAction(data unsafe.Pointer, source *C.struct_wl_data_source, act C.uint32_t) { -} - -func (w *window) flushScroll() { - var fling f32.Point - if w.fling.anim.Active() { - dist := float32(w.fling.anim.Tick(time.Now())) - fling = w.fling.dir.Mul(dist) - } - // The Wayland reported scroll distance for - // discrete scroll axes is only 10 pixels, where - // 100 seems more appropriate. - const discreteScale = 10 - if w.scroll.steps.X != 0 { - w.scroll.dist.X *= discreteScale - } - if w.scroll.steps.Y != 0 { - w.scroll.dist.Y *= discreteScale - } - total := w.scroll.dist.Add(fling) - if total == (f32.Point{}) { - return - } - w.w.Event(pointer.Event{ - Type: pointer.Scroll, - Source: pointer.Mouse, - Buttons: w.pointerBtns, - Position: w.lastPos, - Scroll: total, - Time: w.scroll.time, - Modifiers: w.disp.xkb.Modifiers(), - }) - if w.scroll.steps == (image.Point{}) { - w.fling.xExtrapolation.SampleDelta(w.scroll.time, -w.scroll.dist.X) - w.fling.yExtrapolation.SampleDelta(w.scroll.time, -w.scroll.dist.Y) - } - w.scroll.dist = f32.Point{} - w.scroll.steps = image.Point{} -} - -func (w *window) onPointerMotion(x, y C.wl_fixed_t, t C.uint32_t) { - w.flushScroll() - w.lastPos = f32.Point{ - X: fromFixed(x) * float32(w.scale), - Y: fromFixed(y) * float32(w.scale), - } - w.w.Event(pointer.Event{ - Type: pointer.Move, - Position: w.lastPos, - Buttons: w.pointerBtns, - Source: pointer.Mouse, - Time: time.Duration(t) * time.Millisecond, - Modifiers: w.disp.xkb.Modifiers(), - }) -} - -func (w *window) updateOpaqueRegion() { - reg := C.wl_compositor_create_region(w.disp.compositor) - C.wl_region_add(reg, 0, 0, C.int32_t(w.width), C.int32_t(w.height)) - C.wl_surface_set_opaque_region(w.surf, reg) - C.wl_region_destroy(reg) -} - -func (w *window) updateOutputs() { - scale := 1 - var found bool - for _, conf := range w.disp.outputConfig { - for _, w2 := range conf.windows { - if w2 == w { - found = true - if conf.scale > scale { - scale = conf.scale - } - } - } - } - w.mu.Lock() - if found && scale != w.scale { - w.scale = scale - w.newScale = true - } - w.mu.Unlock() - if !found { - w.setStage(system.StagePaused) - } else { - w.setStage(system.StageRunning) - w.draw(true) - } -} - -func (w *window) config() (int, int, unit.Metric) { - width, height := w.width*w.scale, w.height*w.scale - return width, height, unit.Metric{ - PxPerDp: w.ppdp * float32(w.scale), - PxPerSp: w.ppsp * float32(w.scale), - } -} - -func (w *window) draw(sync bool) { - w.flushScroll() - w.mu.Lock() - anim := w.animating || w.fling.anim.Active() - dead := w.dead - w.mu.Unlock() - if dead || (!anim && !sync) { - return - } - width, height, cfg := w.config() - if cfg == (unit.Metric{}) { - return - } - if anim && w.lastFrameCallback == nil { - w.lastFrameCallback = C.wl_surface_frame(w.surf) - // Use the surface as listener data for gio_onFrameDone. - C.wl_callback_add_listener(w.lastFrameCallback, &C.gio_callback_listener, unsafe.Pointer(w.surf)) - } - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: width, - Y: height, - }, - Metric: cfg, - }, - Sync: sync, - }) -} - -func (w *window) setStage(s system.Stage) { - if s == w.stage { - return - } - w.stage = s - w.w.Event(system.StageEvent{s}) -} - -func (w *window) display() *C.struct_wl_display { - return w.disp.disp -} - -func (w *window) surface() (*C.struct_wl_surface, int, int) { - if w.needAck { - C.xdg_surface_ack_configure(w.wmSurf, w.serial) - w.needAck = false - } - width, height, scale := w.width, w.height, w.scale - if w.newScale { - C.wl_surface_set_buffer_scale(w.surf, C.int32_t(scale)) - w.newScale = false - } - return w.surf, width * scale, height * scale -} - -func (w *window) ShowTextInput(show bool) {} - -// Close the window. Not implemented for Wayland. -func (w *window) Close() {} - -// detectUIScale reports the system UI scale, or 1.0 if it fails. -func detectUIScale() float32 { - // TODO: What about other window environments? - out, err := exec.Command("gsettings", "get", "org.gnome.desktop.interface", "text-scaling-factor").Output() - if err != nil { - return 1.0 - } - scale, err := strconv.ParseFloat(string(bytes.TrimSpace(out)), 32) - if err != nil { - return 1.0 - } - return float32(scale) -} - -func newWLDisplay() (*wlDisplay, error) { - d := &wlDisplay{ - outputMap: make(map[C.uint32_t]*C.struct_wl_output), - outputConfig: make(map[*C.struct_wl_output]*wlOutput), - } - pipe := make([]int, 2) - if err := syscall.Pipe2(pipe, syscall.O_NONBLOCK|syscall.O_CLOEXEC); err != nil { - return nil, fmt.Errorf("wayland: failed to create pipe: %v", err) - } - d.notify.read = pipe[0] - d.notify.write = pipe[1] - xkb, err := xkb.New() - if err != nil { - d.destroy() - return nil, fmt.Errorf("wayland: %v", err) - } - d.xkb = xkb - d.disp, err = C.wl_display_connect(nil) - if d.disp == nil { - d.destroy() - return nil, fmt.Errorf("wayland: wl_display_connect failed: %v", err) - } - callbackMap.Store(unsafe.Pointer(d.disp), d) - d.reg = C.wl_display_get_registry(d.disp) - if d.reg == nil { - d.destroy() - return nil, errors.New("wayland: wl_display_get_registry failed") - } - C.wl_registry_add_listener(d.reg, &C.gio_registry_listener, unsafe.Pointer(d.disp)) - // Wait for the server to register all its globals to the - // registry listener (gio_onRegistryGlobal). - C.wl_display_roundtrip(d.disp) - // Configuration listeners are added to outputs by gio_onRegistryGlobal. - // We need another roundtrip to get the initial output configurations - // through the gio_onOutput* callbacks. - C.wl_display_roundtrip(d.disp) - return d, nil -} - -func (d *wlDisplay) destroy() { - if d.notify.write != 0 { - syscall.Close(d.notify.write) - d.notify.write = 0 - } - if d.notify.read != 0 { - syscall.Close(d.notify.read) - d.notify.read = 0 - } - d.repeat.Stop(0) - if d.xkb != nil { - d.xkb.Destroy() - d.xkb = nil - } - if d.seat != nil { - d.seat.destroy() - d.seat = nil - } - if d.imm != nil { - C.zwp_text_input_manager_v3_destroy(d.imm) - } - if d.decor != nil { - C.zxdg_decoration_manager_v1_destroy(d.decor) - } - if d.shm != nil { - C.wl_shm_destroy(d.shm) - } - if d.compositor != nil { - C.wl_compositor_destroy(d.compositor) - } - if d.wm != nil { - C.xdg_wm_base_destroy(d.wm) - } - for _, output := range d.outputMap { - C.wl_output_destroy(output) - } - if d.reg != nil { - C.wl_registry_destroy(d.reg) - } - if d.disp != nil { - C.wl_display_disconnect(d.disp) - callbackDelete(unsafe.Pointer(d.disp)) - } -} - -// fromFixed converts a Wayland wl_fixed_t 23.8 number to float32. -func fromFixed(v C.wl_fixed_t) float32 { - // Convert to float64 to avoid overflow. - // From wayland-util.h. - b := ((1023 + 44) << 52) + (1 << 51) + uint64(v) - f := math.Float64frombits(b) - (3 << 43) - return float32(f) -} diff --git a/vendor/gioui.org/app/internal/window/os_windows.go b/vendor/gioui.org/app/internal/window/os_windows.go deleted file mode 100644 index 247f10a..0000000 --- a/vendor/gioui.org/app/internal/window/os_windows.go +++ /dev/null @@ -1,642 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -import ( - "errors" - "fmt" - "image" - "reflect" - "runtime" - "sort" - "strings" - "sync" - "time" - "unicode" - "unicode/utf16" - "unsafe" - - syscall "golang.org/x/sys/windows" - - "gioui.org/app/internal/windows" - "gioui.org/unit" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" -) - -type winConstraints struct { - minWidth, minHeight int32 - maxWidth, maxHeight int32 -} - -type winDeltas struct { - width int32 - height int32 -} - -type window struct { - hwnd syscall.Handle - hdc syscall.Handle - w Callbacks - width int - height int - stage system.Stage - dead bool - pointerBtns pointer.Buttons - - mu sync.Mutex - animating bool - - minmax winConstraints - deltas winDeltas - opts *Options -} - -const _WM_REDRAW = windows.WM_USER + 0 - -type gpuAPI struct { - priority int - initializer func(w *window) (Context, error) -} - -// backends is the list of potential Context -// implementations. -var backends []gpuAPI - -// winMap maps win32 HWNDs to *windows. -var winMap sync.Map - -var resources struct { - once sync.Once - // handle is the module handle from GetModuleHandle. - handle syscall.Handle - // class is the Gio window class from RegisterClassEx. - class uint16 - // cursor is the arrow cursor resource - cursor syscall.Handle -} - -func Main() { - select {} -} - -func NewWindow(window Callbacks, opts *Options) error { - cerr := make(chan error) - go func() { - // Call win32 API from a single OS thread. - runtime.LockOSThread() - w, err := createNativeWindow(opts) - if err != nil { - cerr <- err - return - } - defer w.destroy() - cerr <- nil - winMap.Store(w.hwnd, w) - defer winMap.Delete(w.hwnd) - w.w = window - w.w.SetDriver(w) - defer w.w.Event(system.DestroyEvent{}) - windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT) - windows.SetForegroundWindow(w.hwnd) - windows.SetFocus(w.hwnd) - if err := w.loop(); err != nil { - panic(err) - } - }() - return <-cerr -} - -// initResources initializes the resources global. -func initResources() error { - windows.SetProcessDPIAware() - hInst, err := windows.GetModuleHandle() - if err != nil { - return err - } - resources.handle = hInst - curs, err := windows.LoadCursor(windows.IDC_ARROW) - if err != nil { - return err - } - resources.cursor = curs - wcls := windows.WndClassEx{ - CbSize: uint32(unsafe.Sizeof(windows.WndClassEx{})), - Style: windows.CS_HREDRAW | windows.CS_VREDRAW | windows.CS_OWNDC, - LpfnWndProc: syscall.NewCallback(windowProc), - HInstance: hInst, - HCursor: curs, - LpszClassName: syscall.StringToUTF16Ptr("GioWindow"), - } - cls, err := windows.RegisterClassEx(&wcls) - if err != nil { - return err - } - resources.class = cls - return nil -} - -func getWindowConstraints(cfg unit.Metric, opts *Options, d winDeltas) winConstraints { - var minmax winConstraints - minmax.minWidth = int32(cfg.Px(opts.MinWidth)) - minmax.minHeight = int32(cfg.Px(opts.MinHeight)) - minmax.maxWidth = int32(cfg.Px(opts.MaxWidth)) - minmax.maxHeight = int32(cfg.Px(opts.MaxHeight)) - return minmax -} - -func createNativeWindow(opts *Options) (*window, error) { - var resErr error - resources.once.Do(func() { - resErr = initResources() - }) - if resErr != nil { - return nil, resErr - } - cfg := configForDC() - wr := windows.Rect{ - Right: int32(cfg.Px(opts.Width)), - Bottom: int32(cfg.Px(opts.Height)), - } - dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW) - dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE) - deltas := winDeltas{ - width: wr.Right, - height: wr.Bottom, - } - windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle) - deltas.width = wr.Right - wr.Left - deltas.width - deltas.height = wr.Bottom - wr.Top - deltas.height - - hwnd, err := windows.CreateWindowEx(dwExStyle, - resources.class, - opts.Title, - dwStyle|windows.WS_CLIPSIBLINGS|windows.WS_CLIPCHILDREN, - windows.CW_USEDEFAULT, windows.CW_USEDEFAULT, - wr.Right-wr.Left, - wr.Bottom-wr.Top, - 0, - 0, - resources.handle, - 0) - if err != nil { - return nil, err - } - w := &window{ - hwnd: hwnd, - minmax: getWindowConstraints(cfg, opts, deltas), - deltas: deltas, - opts: opts, - } - w.hdc, err = windows.GetDC(hwnd) - if err != nil { - return nil, err - } - return w, nil -} - -func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr { - win, exists := winMap.Load(hwnd) - if !exists { - return windows.DefWindowProc(hwnd, msg, wParam, lParam) - } - - w := win.(*window) - - switch msg { - case windows.WM_UNICHAR: - if wParam == windows.UNICODE_NOCHAR { - // Tell the system that we accept WM_UNICHAR messages. - return 1 - } - fallthrough - case windows.WM_CHAR: - if r := rune(wParam); unicode.IsPrint(r) { - w.w.Event(key.EditEvent{Text: string(r)}) - } - // The message is processed. - return 1 - case windows.WM_DPICHANGED: - // Let Windows know we're prepared for runtime DPI changes. - return 1 - case windows.WM_ERASEBKGND: - // Avoid flickering between GPU content and background color. - return 1 - case windows.WM_KEYDOWN, windows.WM_SYSKEYDOWN: - if n, ok := convertKeyCode(wParam); ok { - w.w.Event(key.Event{Name: n, Modifiers: getModifiers()}) - } - case windows.WM_LBUTTONDOWN: - w.pointerButton(pointer.ButtonLeft, true, lParam, getModifiers()) - case windows.WM_LBUTTONUP: - w.pointerButton(pointer.ButtonLeft, false, lParam, getModifiers()) - case windows.WM_RBUTTONDOWN: - w.pointerButton(pointer.ButtonRight, true, lParam, getModifiers()) - case windows.WM_RBUTTONUP: - w.pointerButton(pointer.ButtonRight, false, lParam, getModifiers()) - case windows.WM_MBUTTONDOWN: - w.pointerButton(pointer.ButtonMiddle, true, lParam, getModifiers()) - case windows.WM_MBUTTONUP: - w.pointerButton(pointer.ButtonMiddle, false, lParam, getModifiers()) - case windows.WM_CANCELMODE: - w.w.Event(pointer.Event{ - Type: pointer.Cancel, - }) - case windows.WM_SETFOCUS: - w.w.Event(key.FocusEvent{Focus: true}) - case windows.WM_KILLFOCUS: - w.w.Event(key.FocusEvent{Focus: false}) - case windows.WM_MOUSEMOVE: - x, y := coordsFromlParam(lParam) - p := f32.Point{X: float32(x), Y: float32(y)} - w.w.Event(pointer.Event{ - Type: pointer.Move, - Source: pointer.Mouse, - Position: p, - Buttons: w.pointerBtns, - Time: windows.GetMessageTime(), - }) - case windows.WM_MOUSEWHEEL: - w.scrollEvent(wParam, lParam) - case windows.WM_DESTROY: - w.dead = true - case windows.WM_PAINT: - w.draw(true) - case windows.WM_SIZE: - switch wParam { - case windows.SIZE_MINIMIZED: - w.setStage(system.StagePaused) - case windows.SIZE_MAXIMIZED, windows.SIZE_RESTORED: - w.setStage(system.StageRunning) - } - case windows.WM_GETMINMAXINFO: - mm := (*windows.MinMaxInfo)(unsafe.Pointer(uintptr(lParam))) - if w.minmax.minWidth > 0 || w.minmax.minHeight > 0 { - mm.PtMinTrackSize = windows.Point{ - w.minmax.minWidth+w.deltas.width, - w.minmax.minHeight+w.deltas.height, - } - } - if w.minmax.maxWidth > 0 || w.minmax.maxHeight > 0 { - mm.PtMaxTrackSize = windows.Point{ - w.minmax.maxWidth+w.deltas.width, - w.minmax.maxHeight+w.deltas.height, - } - } - } - - return windows.DefWindowProc(hwnd, msg, wParam, lParam) -} - -func getModifiers() key.Modifiers { - var kmods key.Modifiers - if windows.GetKeyState(windows.VK_LWIN)&0x1000 != 0 || windows.GetKeyState(windows.VK_RWIN)&0x1000 != 0 { - kmods |= key.ModSuper - } - if windows.GetKeyState(windows.VK_MENU)&0x1000 != 0 { - kmods |= key.ModAlt - } - if windows.GetKeyState(windows.VK_CONTROL)&0x1000 != 0 { - kmods |= key.ModCtrl - } - if windows.GetKeyState(windows.VK_SHIFT)&0x1000 != 0 { - kmods |= key.ModShift - } - return kmods -} - -func (w *window) pointerButton(btn pointer.Buttons, press bool, lParam uintptr, kmods key.Modifiers) { - var typ pointer.Type - if press { - typ = pointer.Press - if w.pointerBtns == 0 { - windows.SetCapture(w.hwnd) - } - w.pointerBtns |= btn - } else { - typ = pointer.Release - w.pointerBtns &^= btn - if w.pointerBtns == 0 { - windows.ReleaseCapture() - } - } - x, y := coordsFromlParam(lParam) - p := f32.Point{X: float32(x), Y: float32(y)} - w.w.Event(pointer.Event{ - Type: typ, - Source: pointer.Mouse, - Position: p, - Buttons: w.pointerBtns, - Time: windows.GetMessageTime(), - Modifiers: kmods, - }) -} - -func coordsFromlParam(lParam uintptr) (int, int) { - x := int(int16(lParam & 0xffff)) - y := int(int16((lParam >> 16) & 0xffff)) - return x, y -} - -func (w *window) scrollEvent(wParam, lParam uintptr) { - x, y := coordsFromlParam(lParam) - // The WM_MOUSEWHEEL coordinates are in screen coordinates, in contrast - // to other mouse events. - np := windows.Point{X: int32(x), Y: int32(y)} - windows.ScreenToClient(w.hwnd, &np) - p := f32.Point{X: float32(np.X), Y: float32(np.Y)} - dist := float32(int16(wParam >> 16)) - w.w.Event(pointer.Event{ - Type: pointer.Scroll, - Source: pointer.Mouse, - Position: p, - Buttons: w.pointerBtns, - Scroll: f32.Point{Y: -dist}, - Time: windows.GetMessageTime(), - }) -} - -// Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20060126-00/?p=32513/ -func (w *window) loop() error { - msg := new(windows.Msg) - for !w.dead { - w.mu.Lock() - anim := w.animating - w.mu.Unlock() - if anim && !windows.PeekMessage(msg, w.hwnd, 0, 0, windows.PM_NOREMOVE) { - w.draw(false) - continue - } - windows.GetMessage(msg, w.hwnd, 0, 0) - if msg.Message == windows.WM_QUIT { - windows.PostQuitMessage(msg.WParam) - break - } - windows.TranslateMessage(msg) - windows.DispatchMessage(msg) - } - return nil -} - -func (w *window) SetAnimating(anim bool) { - w.mu.Lock() - w.animating = anim - w.mu.Unlock() - if anim { - w.postRedraw() - } -} - -func (w *window) postRedraw() { - if err := windows.PostMessage(w.hwnd, _WM_REDRAW, 0, 0); err != nil { - panic(err) - } -} - -func (w *window) setStage(s system.Stage) { - w.stage = s - w.w.Event(system.StageEvent{Stage: s}) -} - -func (w *window) draw(sync bool) { - var r windows.Rect - windows.GetClientRect(w.hwnd, &r) - w.width = int(r.Right - r.Left) - w.height = int(r.Bottom - r.Top) - if w.width == 0 || w.height == 0 { - return - } - cfg := configForDC() - w.minmax = getWindowConstraints(cfg, w.opts, w.deltas) - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: w.width, - Y: w.height, - }, - Metric: cfg, - }, - Sync: sync, - }) -} - -func (w *window) destroy() { - if w.hdc != 0 { - windows.ReleaseDC(w.hdc) - w.hdc = 0 - } - if w.hwnd != 0 { - windows.DestroyWindow(w.hwnd) - w.hwnd = 0 - } -} - -func (w *window) NewContext() (Context, error) { - sort.Slice(backends, func(i, j int) bool { - return backends[i].priority < backends[j].priority - }) - var errs []string - for _, b := range backends { - ctx, err := b.initializer(w) - if err == nil { - return ctx, nil - } - errs = append(errs, err.Error()) - } - if len(errs) > 0 { - return nil, fmt.Errorf("NewContext: failed to create a GPU device, tried: %s", strings.Join(errs, ", ")) - } - return nil, errors.New("NewContext: no available backends") -} - -func (w *window) ReadClipboard() { - w.readClipboard() -} - -func (w *window) readClipboard() error { - if err := windows.OpenClipboard(w.hwnd); err != nil { - return err - } - defer windows.CloseClipboard() - mem, err := windows.GetClipboardData(windows.CF_UNICODETEXT) - if err != nil { - return err - } - ptr, err := windows.GlobalLock(mem) - if err != nil { - return err - } - defer windows.GlobalUnlock(mem) - // Look for terminating null character. - n := 0 - for { - ch := *(*uint16)(unsafe.Pointer(ptr + uintptr(n)*2)) - if ch == 0 { - break - } - n++ - } - var u16 []uint16 - hdr := (*reflect.SliceHeader)(unsafe.Pointer(&u16)) - hdr.Data = ptr - hdr.Cap = n - hdr.Len = n - content := string(utf16.Decode(u16)) - go func() { - w.w.Event(system.ClipboardEvent{Text: content}) - }() - return nil -} - -func (w *window) WriteClipboard(s string) { - w.writeClipboard(s) -} - -func (w *window) writeClipboard(s string) error { - u16 := utf16.Encode([]rune(s)) - // Data must be null terminated. - u16 = append(u16, 0) - if err := windows.OpenClipboard(w.hwnd); err != nil { - return err - } - defer windows.CloseClipboard() - if err := windows.EmptyClipboard(); err != nil { - return err - } - n := len(u16) * int(unsafe.Sizeof(u16[0])) - mem, err := windows.GlobalAlloc(n) - if err != nil { - return err - } - ptr, err := windows.GlobalLock(mem) - if err != nil { - windows.GlobalFree(mem) - return err - } - var u16v []uint16 - hdr := (*reflect.SliceHeader)(unsafe.Pointer(&u16v)) - hdr.Data = ptr - hdr.Cap = len(u16) - hdr.Len = len(u16) - copy(u16v, u16) - windows.GlobalUnlock(mem) - if err := windows.SetClipboardData(windows.CF_UNICODETEXT, mem); err != nil { - windows.GlobalFree(mem) - return err - } - return nil -} - -func (w *window) ShowTextInput(show bool) {} - -func (w *window) HDC() syscall.Handle { - return w.hdc -} - -func (w *window) HWND() (syscall.Handle, int, int) { - return w.hwnd, w.width, w.height -} - -func (w *window) Close() { - windows.PostMessage(w.hwnd, windows.WM_CLOSE, 0, 0) -} - -func convertKeyCode(code uintptr) (string, bool) { - if '0' <= code && code <= '9' || 'A' <= code && code <= 'Z' { - return string(rune(code)), true - } - var r string - switch code { - case windows.VK_ESCAPE: - r = key.NameEscape - case windows.VK_LEFT: - r = key.NameLeftArrow - case windows.VK_RIGHT: - r = key.NameRightArrow - case windows.VK_RETURN: - r = key.NameReturn - case windows.VK_UP: - r = key.NameUpArrow - case windows.VK_DOWN: - r = key.NameDownArrow - case windows.VK_HOME: - r = key.NameHome - case windows.VK_END: - r = key.NameEnd - case windows.VK_BACK: - r = key.NameDeleteBackward - case windows.VK_DELETE: - r = key.NameDeleteForward - case windows.VK_PRIOR: - r = key.NamePageUp - case windows.VK_NEXT: - r = key.NamePageDown - case windows.VK_F1: - r = "F1" - case windows.VK_F2: - r = "F2" - case windows.VK_F3: - r = "F3" - case windows.VK_F4: - r = "F4" - case windows.VK_F5: - r = "F5" - case windows.VK_F6: - r = "F6" - case windows.VK_F7: - r = "F7" - case windows.VK_F8: - r = "F8" - case windows.VK_F9: - r = "F9" - case windows.VK_F10: - r = "F10" - case windows.VK_F11: - r = "F11" - case windows.VK_F12: - r = "F12" - case windows.VK_TAB: - r = key.NameTab - case windows.VK_SPACE: - r = "Space" - case windows.VK_OEM_1: - r = ";" - case windows.VK_OEM_PLUS: - r = "+" - case windows.VK_OEM_COMMA: - r = "," - case windows.VK_OEM_MINUS: - r = "-" - case windows.VK_OEM_PERIOD: - r = "." - case windows.VK_OEM_2: - r = "/" - case windows.VK_OEM_3: - r = "`" - case windows.VK_OEM_4: - r = "[" - case windows.VK_OEM_5, windows.VK_OEM_102: - r = "\\" - case windows.VK_OEM_6: - r = "]" - case windows.VK_OEM_7: - r = "'" - default: - return "", false - } - return r, true -} - -func configForDC() unit.Metric { - dpi := windows.GetSystemDPI() - const inchPrDp = 1.0 / 96.0 - ppdp := float32(dpi) * inchPrDp - return unit.Metric{ - PxPerDp: ppdp, - PxPerSp: ppdp, - } -} diff --git a/vendor/gioui.org/app/internal/window/os_x11.go b/vendor/gioui.org/app/internal/window/os_x11.go deleted file mode 100644 index 69108c6..0000000 --- a/vendor/gioui.org/app/internal/window/os_x11.go +++ /dev/null @@ -1,647 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build linux,!android,!nox11 freebsd openbsd - -package window - -/* -#cgo openbsd CFLAGS: -I/usr/X11R6/include -I/usr/local/include -#cgo openbsd LDFLAGS: -L/usr/X11R6/lib -L/usr/local/lib -#cgo freebsd openbsd LDFLAGS: -lX11 -lxkbcommon -lxkbcommon-x11 -lX11-xcb -#cgo linux pkg-config: x11 xkbcommon xkbcommon-x11 x11-xcb - -#include <stdlib.h> -#include <locale.h> -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> -#include <X11/Xresource.h> -#include <X11/XKBlib.h> -#include <X11/Xlib-xcb.h> -#include <xkbcommon/xkbcommon-x11.h> - -*/ -import "C" -import ( - "errors" - "fmt" - "image" - "os" - "path/filepath" - "strconv" - "sync" - "time" - "unsafe" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" - - "gioui.org/app/internal/xkb" - syscall "golang.org/x/sys/unix" -) - -type x11Window struct { - w Callbacks - x *C.Display - xkb *xkb.Context - xkbEventBase C.int - xw C.Window - - atoms struct { - // "UTF8_STRING". - utf8string C.Atom - // "TARGETS" - targets C.Atom - // "CLIPBOARD". - clipboard C.Atom - // "CLIPBOARD_CONTENT", the clipboard destination property. - clipboardContent C.Atom - // "WM_DELETE_WINDOW" - evDelWindow C.Atom - // "ATOM" - atom C.Atom - } - stage system.Stage - cfg unit.Metric - width int - height int - notify struct { - read, write int - } - dead bool - - mu sync.Mutex - animating bool - - pointerBtns pointer.Buttons - - clipboard struct { - read bool - write *string - content []byte - } -} - -func (w *x11Window) SetAnimating(anim bool) { - w.mu.Lock() - w.animating = anim - w.mu.Unlock() - if anim { - w.wakeup() - } -} - -func (w *x11Window) ReadClipboard() { - w.mu.Lock() - w.clipboard.read = true - w.mu.Unlock() - w.wakeup() -} - -func (w *x11Window) WriteClipboard(s string) { - w.mu.Lock() - w.clipboard.write = &s - w.mu.Unlock() - w.wakeup() -} - -func (w *x11Window) ShowTextInput(show bool) {} - -// Close the window. -func (w *x11Window) Close() { - w.mu.Lock() - defer w.mu.Unlock() - - var xev C.XEvent - ev := (*C.XClientMessageEvent)(unsafe.Pointer(&xev)) - *ev = C.XClientMessageEvent{ - _type: C.ClientMessage, - display: w.x, - window: w.xw, - message_type: w.atom("WM_PROTOCOLS", true), - format: 32, - } - arr := (*[5]C.long)(unsafe.Pointer(&ev.data)) - arr[0] = C.long(w.atoms.evDelWindow) - arr[1] = C.CurrentTime - C.XSendEvent(w.x, w.xw, C.False, C.NoEventMask, &xev) -} - -var x11OneByte = make([]byte, 1) - -func (w *x11Window) wakeup() { - if _, err := syscall.Write(w.notify.write, x11OneByte); err != nil && err != syscall.EAGAIN { - panic(fmt.Errorf("failed to write to pipe: %v", err)) - } -} - -func (w *x11Window) display() *C.Display { - return w.x -} - -func (w *x11Window) window() (C.Window, int, int) { - return w.xw, w.width, w.height -} - -func (w *x11Window) setStage(s system.Stage) { - if s == w.stage { - return - } - w.stage = s - w.w.Event(system.StageEvent{s}) -} - -func (w *x11Window) loop() { - h := x11EventHandler{w: w, xev: new(C.XEvent), text: make([]byte, 4)} - xfd := C.XConnectionNumber(w.x) - - // Poll for events and notifications. - pollfds := []syscall.PollFd{ - {Fd: int32(xfd), Events: syscall.POLLIN | syscall.POLLERR}, - {Fd: int32(w.notify.read), Events: syscall.POLLIN | syscall.POLLERR}, - } - xEvents := &pollfds[0].Revents - // Plenty of room for a backlog of notifications. - buf := make([]byte, 100) - -loop: - for !w.dead { - var syn, anim bool - // Check for pending draw events before checking animation or blocking. - // This fixes an issue on Xephyr where on startup XPending() > 0 but - // poll will still block. This also prevents no-op calls to poll. - if syn = h.handleEvents(); !syn { - w.mu.Lock() - anim = w.animating - w.mu.Unlock() - if !anim { - // Clear poll events. - *xEvents = 0 - // Wait for X event or gio notification. - if _, err := syscall.Poll(pollfds, -1); err != nil && err != syscall.EINTR { - panic(fmt.Errorf("x11 loop: poll failed: %w", err)) - } - switch { - case *xEvents&syscall.POLLIN != 0: - syn = h.handleEvents() - if w.dead { - break loop - } - case *xEvents&(syscall.POLLERR|syscall.POLLHUP) != 0: - break loop - } - } - } - // Clear notifications. - for { - _, err := syscall.Read(w.notify.read, buf) - if err == syscall.EAGAIN { - break - } - if err != nil { - panic(fmt.Errorf("x11 loop: read from notify pipe failed: %w", err)) - } - } - - if anim || syn { - w.w.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: w.width, - Y: w.height, - }, - Metric: w.cfg, - }, - Sync: syn, - }) - } - w.mu.Lock() - readClipboard := w.clipboard.read - writeClipboard := w.clipboard.write - w.clipboard.read = false - w.clipboard.write = nil - w.mu.Unlock() - if readClipboard { - C.XDeleteProperty(w.x, w.xw, w.atoms.clipboardContent) - C.XConvertSelection(w.x, w.atoms.clipboard, w.atoms.utf8string, w.atoms.clipboardContent, w.xw, C.CurrentTime) - } - if writeClipboard != nil { - w.clipboard.content = []byte(*writeClipboard) - C.XSetSelectionOwner(w.x, w.atoms.clipboard, w.xw, C.CurrentTime) - } - } - w.w.Event(system.DestroyEvent{Err: nil}) -} - -func (w *x11Window) destroy() { - if w.notify.write != 0 { - syscall.Close(w.notify.write) - w.notify.write = 0 - } - if w.notify.read != 0 { - syscall.Close(w.notify.read) - w.notify.read = 0 - } - if w.xkb != nil { - w.xkb.Destroy() - w.xkb = nil - } - C.XDestroyWindow(w.x, w.xw) - C.XCloseDisplay(w.x) -} - -// atom is a wrapper around XInternAtom. Callers should cache the result -// in order to limit round-trips to the X server. -// -func (w *x11Window) atom(name string, onlyIfExists bool) C.Atom { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - flag := C.Bool(C.False) - if onlyIfExists { - flag = C.True - } - return C.XInternAtom(w.x, cname, flag) -} - -// x11EventHandler wraps static variables for the main event loop. -// Its sole purpose is to prevent heap allocation and reduce clutter -// in x11window.loop. -// -type x11EventHandler struct { - w *x11Window - text []byte - xev *C.XEvent -} - -// handleEvents returns true if the window needs to be redrawn. -// -func (h *x11EventHandler) handleEvents() bool { - w := h.w - xev := h.xev - redraw := false - for C.XPending(w.x) != 0 { - C.XNextEvent(w.x, xev) - if C.XFilterEvent(xev, C.None) == C.True { - continue - } - switch _type := (*C.XAnyEvent)(unsafe.Pointer(xev))._type; _type { - case h.w.xkbEventBase: - xkbEvent := (*C.XkbAnyEvent)(unsafe.Pointer(xev)) - switch xkbEvent.xkb_type { - case C.XkbNewKeyboardNotify, C.XkbMapNotify: - if err := h.w.updateXkbKeymap(); err != nil { - panic(err) - } - case C.XkbStateNotify: - state := (*C.XkbStateNotifyEvent)(unsafe.Pointer(xev)) - h.w.xkb.UpdateMask(uint32(state.base_mods), uint32(state.latched_mods), uint32(state.locked_mods), - uint32(state.base_group), uint32(state.latched_group), uint32(state.locked_group)) - } - case C.KeyPress: - kevt := (*C.XKeyPressedEvent)(unsafe.Pointer(xev)) - for _, e := range h.w.xkb.DispatchKey(uint32(kevt.keycode)) { - w.w.Event(e) - } - case C.KeyRelease: - case C.ButtonPress, C.ButtonRelease: - bevt := (*C.XButtonEvent)(unsafe.Pointer(xev)) - ev := pointer.Event{ - Type: pointer.Press, - Source: pointer.Mouse, - Position: f32.Point{ - X: float32(bevt.x), - Y: float32(bevt.y), - }, - Time: time.Duration(bevt.time) * time.Millisecond, - Modifiers: w.xkb.Modifiers(), - } - if bevt._type == C.ButtonRelease { - ev.Type = pointer.Release - } - var btn pointer.Buttons - const scrollScale = 10 - switch bevt.button { - case C.Button1: - btn = pointer.ButtonLeft - case C.Button2: - btn = pointer.ButtonMiddle - case C.Button3: - btn = pointer.ButtonRight - case C.Button4: - // scroll up - ev.Type = pointer.Scroll - ev.Scroll.Y = -scrollScale - case C.Button5: - // scroll down - ev.Type = pointer.Scroll - ev.Scroll.Y = +scrollScale - default: - continue - } - switch _type { - case C.ButtonPress: - w.pointerBtns |= btn - case C.ButtonRelease: - w.pointerBtns &^= btn - } - ev.Buttons = w.pointerBtns - w.w.Event(ev) - case C.MotionNotify: - mevt := (*C.XMotionEvent)(unsafe.Pointer(xev)) - w.w.Event(pointer.Event{ - Type: pointer.Move, - Source: pointer.Mouse, - Buttons: w.pointerBtns, - Position: f32.Point{ - X: float32(mevt.x), - Y: float32(mevt.y), - }, - Time: time.Duration(mevt.time) * time.Millisecond, - Modifiers: w.xkb.Modifiers(), - }) - case C.Expose: // update - // redraw only on the last expose event - redraw = (*C.XExposeEvent)(unsafe.Pointer(xev)).count == 0 - case C.FocusIn: - w.w.Event(key.FocusEvent{Focus: true}) - case C.FocusOut: - w.w.Event(key.FocusEvent{Focus: false}) - case C.ConfigureNotify: // window configuration change - cevt := (*C.XConfigureEvent)(unsafe.Pointer(xev)) - w.width = int(cevt.width) - w.height = int(cevt.height) - // redraw will be done by a later expose event - case C.SelectionNotify: - cevt := (*C.XSelectionEvent)(unsafe.Pointer(xev)) - prop := w.atoms.clipboardContent - if cevt.property != prop { - break - } - if cevt.selection != w.atoms.clipboard { - break - } - var text C.XTextProperty - if st := C.XGetTextProperty(w.x, w.xw, &text, prop); st == 0 { - // Failed; ignore. - break - } - if text.format != 8 || text.encoding != w.atoms.utf8string { - // Ignore non-utf-8 encoded strings. - break - } - str := C.GoStringN((*C.char)(unsafe.Pointer(text.value)), C.int(text.nitems)) - w.w.Event(system.ClipboardEvent{Text: str}) - case C.SelectionRequest: - cevt := (*C.XSelectionRequestEvent)(unsafe.Pointer(xev)) - if cevt.selection != w.atoms.clipboard || cevt.property == C.None { - // Unsupported clipboard or obsolete requestor. - break - } - notify := func() { - var xev C.XEvent - ev := (*C.XSelectionEvent)(unsafe.Pointer(&xev)) - *ev = C.XSelectionEvent{ - _type: C.SelectionNotify, - display: cevt.display, - requestor: cevt.requestor, - selection: cevt.selection, - target: cevt.target, - property: cevt.property, - time: cevt.time, - } - C.XSendEvent(w.x, cevt.requestor, 0, 0, &xev) - } - switch cevt.target { - case w.atoms.targets: - // The requestor wants the supported clipboard - // formats. First write the formats... - formats := []uint32{uint32(w.atoms.utf8string)} - C.XChangeProperty(w.x, cevt.requestor, cevt.property, w.atoms.atom, - 32 /* bitwidth of formats */, C.PropModeReplace, - (*C.uchar)(unsafe.Pointer(&formats[0])), C.int(len(formats)), - ) - // ...then notify the requestor. - notify() - case w.atoms.utf8string: - content := w.clipboard.content - var ptr *C.uchar - if len(content) > 0 { - ptr = (*C.uchar)(unsafe.Pointer(&content[0])) - } - C.XChangeProperty(w.x, cevt.requestor, cevt.property, w.atoms.utf8string, - 8 /* bitwidth */, C.PropModeReplace, - ptr, C.int(len(content)), - ) - notify() - } - case C.ClientMessage: // extensions - cevt := (*C.XClientMessageEvent)(unsafe.Pointer(xev)) - switch *(*C.long)(unsafe.Pointer(&cevt.data)) { - case C.long(w.atoms.evDelWindow): - w.dead = true - return false - } - } - } - return redraw -} - -var ( - x11Threads sync.Once -) - -func init() { - x11Driver = newX11Window -} - -func newX11Window(gioWin Callbacks, opts *Options) error { - var err error - - pipe := make([]int, 2) - if err := syscall.Pipe2(pipe, syscall.O_NONBLOCK|syscall.O_CLOEXEC); err != nil { - return fmt.Errorf("NewX11Window: failed to create pipe: %w", err) - } - - x11Threads.Do(func() { - if C.XInitThreads() == 0 { - err = errors.New("x11: threads init failed") - } - C.XrmInitialize() - }) - if err != nil { - return err - } - dpy := C.XOpenDisplay(nil) - if dpy == nil { - return errors.New("x11: cannot connect to the X server") - } - var major, minor C.int = C.XkbMajorVersion, C.XkbMinorVersion - var xkbEventBase C.int - if C.XkbQueryExtension(dpy, nil, &xkbEventBase, nil, &major, &minor) != C.True { - C.XCloseDisplay(dpy) - return errors.New("x11: XkbQueryExtension failed") - } - const bits = C.uint(C.XkbNewKeyboardNotifyMask | C.XkbMapNotifyMask | C.XkbStateNotifyMask) - if C.XkbSelectEvents(dpy, C.XkbUseCoreKbd, bits, bits) != C.True { - C.XCloseDisplay(dpy) - return errors.New("x11: XkbSelectEvents failed") - } - xkb, err := xkb.New() - if err != nil { - C.XCloseDisplay(dpy) - return fmt.Errorf("x11: %v", err) - } - - ppsp := x11DetectUIScale(dpy) - cfg := unit.Metric{PxPerDp: ppsp, PxPerSp: ppsp} - swa := C.XSetWindowAttributes{ - event_mask: C.ExposureMask | C.FocusChangeMask | // update - C.KeyPressMask | C.KeyReleaseMask | // keyboard - C.ButtonPressMask | C.ButtonReleaseMask | // mouse clicks - C.PointerMotionMask | // mouse movement - C.StructureNotifyMask, // resize - background_pixmap: C.None, - override_redirect: C.False, - } - win := C.XCreateWindow(dpy, C.XDefaultRootWindow(dpy), - 0, 0, C.uint(cfg.Px(opts.Width)), C.uint(cfg.Px(opts.Height)), - 0, C.CopyFromParent, C.InputOutput, nil, - C.CWEventMask|C.CWBackPixmap|C.CWOverrideRedirect, &swa) - - w := &x11Window{ - w: gioWin, x: dpy, xw: win, - width: cfg.Px(opts.Width), - height: cfg.Px(opts.Height), - cfg: cfg, - xkb: xkb, - xkbEventBase: xkbEventBase, - } - w.notify.read = pipe[0] - w.notify.write = pipe[1] - - if err := w.updateXkbKeymap(); err != nil { - w.destroy() - return err - } - - var hints C.XWMHints - hints.input = C.True - hints.flags = C.InputHint - C.XSetWMHints(dpy, win, &hints) - - var shints C.XSizeHints - if opts.MinWidth.V != 0 || opts.MinHeight.V != 0 { - shints.min_width = C.int(cfg.Px(opts.MinWidth)) - shints.min_height = C.int(cfg.Px(opts.MinHeight)) - shints.flags = C.PMinSize - } - if opts.MaxWidth.V != 0 || opts.MaxHeight.V != 0 { - shints.max_width = C.int(cfg.Px(opts.MaxWidth)) - shints.max_height = C.int(cfg.Px(opts.MaxHeight)) - shints.flags = shints.flags | C.PMaxSize - } - if shints.flags != 0 { - C.XSetWMNormalHints(dpy, win, &shints) - } - - name := C.CString(filepath.Base(os.Args[0])) - defer C.free(unsafe.Pointer(name)) - wmhints := C.XClassHint{name, name} - C.XSetClassHint(dpy, win, &wmhints) - - w.atoms.utf8string = w.atom("UTF8_STRING", false) - w.atoms.evDelWindow = w.atom("WM_DELETE_WINDOW", false) - w.atoms.clipboard = w.atom("CLIPBOARD", false) - w.atoms.clipboardContent = w.atom("CLIPBOARD_CONTENT", false) - w.atoms.atom = w.atom("ATOM", false) - w.atoms.targets = w.atom("TARGETS", false) - - // set the name - ctitle := C.CString(opts.Title) - defer C.free(unsafe.Pointer(ctitle)) - C.XStoreName(dpy, win, ctitle) - // set _NET_WM_NAME as well for UTF-8 support in window title. - C.XSetTextProperty(dpy, win, - &C.XTextProperty{ - value: (*C.uchar)(unsafe.Pointer(ctitle)), - encoding: w.atoms.utf8string, - format: 8, - nitems: C.ulong(len(opts.Title)), - }, - w.atom("_NET_WM_NAME", false)) - - // extensions - C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1) - - // make the window visible on the screen - C.XMapWindow(dpy, win) - - go func() { - w.w.SetDriver(w) - w.setStage(system.StageRunning) - w.loop() - w.destroy() - }() - return nil -} - -// detectUIScale reports the system UI scale, or 1.0 if it fails. -func x11DetectUIScale(dpy *C.Display) float32 { - // default fixed DPI value used in most desktop UI toolkits - const defaultDesktopDPI = 96 - var scale float32 = 1.0 - - // Get actual DPI from X resource Xft.dpi (set by GTK and Qt). - // This value is entirely based on user preferences and conflates both - // screen (UI) scaling and font scale. - rms := C.XResourceManagerString(dpy) - if rms != nil { - db := C.XrmGetStringDatabase(rms) - if db != nil { - var ( - t *C.char - v C.XrmValue - ) - if C.XrmGetResource(db, (*C.char)(unsafe.Pointer(&[]byte("Xft.dpi\x00")[0])), - (*C.char)(unsafe.Pointer(&[]byte("Xft.Dpi\x00")[0])), &t, &v) != C.False { - if t != nil && C.GoString(t) == "String" { - f, err := strconv.ParseFloat(C.GoString(v.addr), 32) - if err == nil { - scale = float32(f) / defaultDesktopDPI - } - } - } - C.XrmDestroyDatabase(db) - } - } - - return scale -} - -func (w *x11Window) updateXkbKeymap() error { - w.xkb.DestroyKeymapState() - ctx := (*C.struct_xkb_context)(unsafe.Pointer(w.xkb.Ctx)) - xcb := C.XGetXCBConnection(w.x) - if xcb == nil { - return errors.New("x11: XGetXCBConnection failed") - } - xkbDevID := C.xkb_x11_get_core_keyboard_device_id(xcb) - if xkbDevID == -1 { - return errors.New("x11: xkb_x11_get_core_keyboard_device_id failed") - } - keymap := C.xkb_x11_keymap_new_from_device(ctx, xcb, xkbDevID, C.XKB_KEYMAP_COMPILE_NO_FLAGS) - if keymap == nil { - return errors.New("x11: xkb_x11_keymap_new_from_device failed") - } - state := C.xkb_x11_state_new_from_device(keymap, xcb, xkbDevID) - if state == nil { - C.xkb_keymap_unref(keymap) - return errors.New("x11: xkb_x11_keymap_new_from_device failed") - } - w.xkb.SetKeymap(unsafe.Pointer(keymap), unsafe.Pointer(state)) - return nil -} diff --git a/vendor/gioui.org/app/internal/window/runmain.go b/vendor/gioui.org/app/internal/window/runmain.go deleted file mode 100644 index f9de5d0..0000000 --- a/vendor/gioui.org/app/internal/window/runmain.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// +build android darwin,ios - -package window - -// Android only supports non-Java programs as c-shared libraries. -// Unfortunately, Go does not run a program's main function in -// library mode. To make Gio programs simpler and uniform, we'll -// link to the main function here and call it from Java. - -import ( - "sync" - _ "unsafe" // for go:linkname -) - -//go:linkname mainMain main.main -func mainMain() - -var runMainOnce sync.Once - -func runMain() { - runMainOnce.Do(func() { - // Indirect call, since the linker does not know the address of main when - // laying down this package. - fn := mainMain - fn() - }) -} diff --git a/vendor/gioui.org/app/internal/window/wayland_text_input.c b/vendor/gioui.org/app/internal/window/wayland_text_input.c deleted file mode 100644 index a69af09..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_text_input.c +++ /dev/null @@ -1,98 +0,0 @@ -// +build linux,!android,!nowayland freebsd - -/* Generated by wayland-scanner 1.17.0 */ - -/* - * Copyright © 2012, 2013 Intel Corporation - * Copyright © 2015, 2016 Jan Arne Petersen - * Copyright © 2017, 2018 Red Hat, Inc. - * Copyright © 2018 Purism SPC - * - * Permission to use, copy, modify, distribute, and sell this - * software and its documentation for any purpose is hereby granted - * without fee, provided that the above copyright notice appear in - * all copies and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of - * the copyright holders not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - * THIS SOFTWARE. - */ - -#include <stdlib.h> -#include <stdint.h> -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_seat_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface zwp_text_input_v3_interface; - -static const struct wl_interface *types[] = { - NULL, - NULL, - NULL, - NULL, - &wl_surface_interface, - &wl_surface_interface, - &zwp_text_input_v3_interface, - &wl_seat_interface, -}; - -static const struct wl_message zwp_text_input_v3_requests[] = { - { "destroy", "", types + 0 }, - { "enable", "", types + 0 }, - { "disable", "", types + 0 }, - { "set_surrounding_text", "sii", types + 0 }, - { "set_text_change_cause", "u", types + 0 }, - { "set_content_type", "uu", types + 0 }, - { "set_cursor_rectangle", "iiii", types + 0 }, - { "commit", "", types + 0 }, -}; - -static const struct wl_message zwp_text_input_v3_events[] = { - { "enter", "o", types + 4 }, - { "leave", "o", types + 5 }, - { "preedit_string", "?sii", types + 0 }, - { "commit_string", "?s", types + 0 }, - { "delete_surrounding_text", "uu", types + 0 }, - { "done", "u", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zwp_text_input_v3_interface = { - "zwp_text_input_v3", 1, - 8, zwp_text_input_v3_requests, - 6, zwp_text_input_v3_events, -}; - -static const struct wl_message zwp_text_input_manager_v3_requests[] = { - { "destroy", "", types + 0 }, - { "get_text_input", "no", types + 6 }, -}; - -WL_PRIVATE const struct wl_interface zwp_text_input_manager_v3_interface = { - "zwp_text_input_manager_v3", 1, - 2, zwp_text_input_manager_v3_requests, - 0, NULL, -}; - diff --git a/vendor/gioui.org/app/internal/window/wayland_text_input.h b/vendor/gioui.org/app/internal/window/wayland_text_input.h deleted file mode 100644 index 8a6f8dd..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_text_input.h +++ /dev/null @@ -1,819 +0,0 @@ -/* Generated by wayland-scanner 1.17.0 */ - -#ifndef TEXT_INPUT_UNSTABLE_V3_CLIENT_PROTOCOL_H -#define TEXT_INPUT_UNSTABLE_V3_CLIENT_PROTOCOL_H - -#include <stdint.h> -#include <stddef.h> -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_text_input_unstable_v3 The text_input_unstable_v3 protocol - * Protocol for composing text - * - * @section page_desc_text_input_unstable_v3 Description - * - * This protocol allows compositors to act as input methods and to send text - * to applications. A text input object is used to manage state of what are - * typically text entry fields in the application. - * - * This document adheres to the RFC 2119 when using words like "must", - * "should", "may", etc. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - * - * @section page_ifaces_text_input_unstable_v3 Interfaces - * - @subpage page_iface_zwp_text_input_v3 - text input - * - @subpage page_iface_zwp_text_input_manager_v3 - text input manager - * @section page_copyright_text_input_unstable_v3 Copyright - * <pre> - * - * Copyright © 2012, 2013 Intel Corporation - * Copyright © 2015, 2016 Jan Arne Petersen - * Copyright © 2017, 2018 Red Hat, Inc. - * Copyright © 2018 Purism SPC - * - * Permission to use, copy, modify, distribute, and sell this - * software and its documentation for any purpose is hereby granted - * without fee, provided that the above copyright notice appear in - * all copies and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of - * the copyright holders not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - * THIS SOFTWARE. - * </pre> - */ -struct wl_seat; -struct wl_surface; -struct zwp_text_input_manager_v3; -struct zwp_text_input_v3; - -/** - * @page page_iface_zwp_text_input_v3 zwp_text_input_v3 - * @section page_iface_zwp_text_input_v3_desc Description - * - * The zwp_text_input_v3 interface represents text input and input methods - * associated with a seat. It provides enter/leave events to follow the - * text input focus for a seat. - * - * Requests are used to enable/disable the text-input object and set - * state information like surrounding and selected text or the content type. - * The information about the entered text is sent to the text-input object - * via the preedit_string and commit_string events. - * - * Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices - * must not point to middle bytes inside a code point: they must either - * point to the first byte of a code point or to the end of the buffer. - * Lengths must be measured between two valid indices. - * - * Focus moving throughout surfaces will result in the emission of - * zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused - * surface must commit zwp_text_input_v3.enable and - * zwp_text_input_v3.disable requests as the keyboard focus moves across - * editable and non-editable elements of the UI. Those two requests are not - * expected to be paired with each other, the compositor must be able to - * handle consecutive series of the same request. - * - * State is sent by the state requests (set_surrounding_text, - * set_content_type and set_cursor_rectangle) and a commit request. After an - * enter event or disable request all state information is invalidated and - * needs to be resent by the client. - * @section page_iface_zwp_text_input_v3_api API - * See @ref iface_zwp_text_input_v3. - */ -/** - * @defgroup iface_zwp_text_input_v3 The zwp_text_input_v3 interface - * - * The zwp_text_input_v3 interface represents text input and input methods - * associated with a seat. It provides enter/leave events to follow the - * text input focus for a seat. - * - * Requests are used to enable/disable the text-input object and set - * state information like surrounding and selected text or the content type. - * The information about the entered text is sent to the text-input object - * via the preedit_string and commit_string events. - * - * Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices - * must not point to middle bytes inside a code point: they must either - * point to the first byte of a code point or to the end of the buffer. - * Lengths must be measured between two valid indices. - * - * Focus moving throughout surfaces will result in the emission of - * zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused - * surface must commit zwp_text_input_v3.enable and - * zwp_text_input_v3.disable requests as the keyboard focus moves across - * editable and non-editable elements of the UI. Those two requests are not - * expected to be paired with each other, the compositor must be able to - * handle consecutive series of the same request. - * - * State is sent by the state requests (set_surrounding_text, - * set_content_type and set_cursor_rectangle) and a commit request. After an - * enter event or disable request all state information is invalidated and - * needs to be resent by the client. - */ -extern const struct wl_interface zwp_text_input_v3_interface; -/** - * @page page_iface_zwp_text_input_manager_v3 zwp_text_input_manager_v3 - * @section page_iface_zwp_text_input_manager_v3_desc Description - * - * A factory for text-input objects. This object is a global singleton. - * @section page_iface_zwp_text_input_manager_v3_api API - * See @ref iface_zwp_text_input_manager_v3. - */ -/** - * @defgroup iface_zwp_text_input_manager_v3 The zwp_text_input_manager_v3 interface - * - * A factory for text-input objects. This object is a global singleton. - */ -extern const struct wl_interface zwp_text_input_manager_v3_interface; - -#ifndef ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_ENUM -#define ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_ENUM -/** - * @ingroup iface_zwp_text_input_v3 - * text change reason - * - * Reason for the change of surrounding text or cursor posision. - */ -enum zwp_text_input_v3_change_cause { - /** - * input method caused the change - */ - ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD = 0, - /** - * something else than the input method caused the change - */ - ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER = 1, -}; -#endif /* ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_ENUM */ - -#ifndef ZWP_TEXT_INPUT_V3_CONTENT_HINT_ENUM -#define ZWP_TEXT_INPUT_V3_CONTENT_HINT_ENUM -/** - * @ingroup iface_zwp_text_input_v3 - * content hint - * - * Content hint is a bitmask to allow to modify the behavior of the text - * input. - */ -enum zwp_text_input_v3_content_hint { - /** - * no special behavior - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE = 0x0, - /** - * suggest word completions - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_COMPLETION = 0x1, - /** - * suggest word corrections - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK = 0x2, - /** - * switch to uppercase letters at the start of a sentence - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION = 0x4, - /** - * prefer lowercase letters - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_LOWERCASE = 0x8, - /** - * prefer uppercase letters - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_UPPERCASE = 0x10, - /** - * prefer casing for titles and headings (can be language dependent) - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_TITLECASE = 0x20, - /** - * characters should be hidden - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_HIDDEN_TEXT = 0x40, - /** - * typed text should not be stored - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA = 0x80, - /** - * just Latin characters should be entered - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_LATIN = 0x100, - /** - * the text input is multiline - */ - ZWP_TEXT_INPUT_V3_CONTENT_HINT_MULTILINE = 0x200, -}; -#endif /* ZWP_TEXT_INPUT_V3_CONTENT_HINT_ENUM */ - -#ifndef ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ENUM -#define ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ENUM -/** - * @ingroup iface_zwp_text_input_v3 - * content purpose - * - * The content purpose allows to specify the primary purpose of a text - * input. - * - * This allows an input method to show special purpose input panels with - * extra characters or to disallow some characters. - */ -enum zwp_text_input_v3_content_purpose { - /** - * default input, allowing all characters - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL = 0, - /** - * allow only alphabetic characters - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ALPHA = 1, - /** - * allow only digits - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS = 2, - /** - * input a number (including decimal separator and sign) - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER = 3, - /** - * input a phone number - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE = 4, - /** - * input an URL - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL = 5, - /** - * input an email address - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL = 6, - /** - * input a name of a person - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NAME = 7, - /** - * input a password (combine with sensitive_data hint) - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PASSWORD = 8, - /** - * input is a numeric password (combine with sensitive_data hint) - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN = 9, - /** - * input a date - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE = 10, - /** - * input a time - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TIME = 11, - /** - * input a date and time - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME = 12, - /** - * input for a terminal - */ - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL = 13, -}; -#endif /* ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ENUM */ - -/** - * @ingroup iface_zwp_text_input_v3 - * @struct zwp_text_input_v3_listener - */ -struct zwp_text_input_v3_listener { - /** - * enter event - * - * Notification that this seat's text-input focus is on a certain - * surface. - * - * When the seat has the keyboard capability the text-input focus - * follows the keyboard focus. This event sets the current surface - * for the text-input object. - */ - void (*enter)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - struct wl_surface *surface); - /** - * leave event - * - * Notification that this seat's text-input focus is no longer on - * a certain surface. The client should reset any preedit string - * previously set. - * - * The leave notification clears the current surface. It is sent - * before the enter notification for the new focus. - * - * When the seat has the keyboard capability the text-input focus - * follows the keyboard focus. - */ - void (*leave)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - struct wl_surface *surface); - /** - * pre-edit - * - * Notify when a new composing text (pre-edit) should be set at - * the current cursor position. Any previously set composing text - * must be removed. Any previously existing selected text must be - * removed. - * - * The argument text contains the pre-edit string buffer. - * - * The parameters cursor_begin and cursor_end are counted in bytes - * relative to the beginning of the submitted text buffer. Cursor - * should be hidden when both are equal to -1. - * - * They could be represented by the client as a line if both values - * are the same, or as a text highlight otherwise. - * - * Values set with this event are double-buffered. They must be - * applied and reset to initial on the next zwp_text_input_v3.done - * event. - * - * The initial value of text is an empty string, and cursor_begin, - * cursor_end and cursor_hidden are all 0. - */ - void (*preedit_string)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - const char *text, - int32_t cursor_begin, - int32_t cursor_end); - /** - * text commit - * - * Notify when text should be inserted into the editor widget. - * The text to commit could be either just a single character after - * a key press or the result of some composing (pre-edit). - * - * Values set with this event are double-buffered. They must be - * applied and reset to initial on the next zwp_text_input_v3.done - * event. - * - * The initial value of text is an empty string. - */ - void (*commit_string)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - const char *text); - /** - * delete surrounding text - * - * Notify when the text around the current cursor position should - * be deleted. - * - * Before_length and after_length are the number of bytes before - * and after the current cursor index (excluding the selection) to - * delete. - * - * If a preedit text is present, in effect before_length is counted - * from the beginning of it, and after_length from its end (see - * done event sequence). - * - * Values set with this event are double-buffered. They must be - * applied and reset to initial on the next zwp_text_input_v3.done - * event. - * - * The initial values of both before_length and after_length are 0. - * @param before_length length of text before current cursor position - * @param after_length length of text after current cursor position - */ - void (*delete_surrounding_text)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - uint32_t before_length, - uint32_t after_length); - /** - * apply changes - * - * Instruct the application to apply changes to state requested - * by the preedit_string, commit_string and delete_surrounding_text - * events. The state relating to these events is double-buffered, - * and each one modifies the pending state. This event replaces the - * current state with the pending state. - * - * The application must proceed by evaluating the changes in the - * following order: - * - * 1. Replace existing preedit string with the cursor. 2. Delete - * requested surrounding text. 3. Insert commit string with the - * cursor at its end. 4. Calculate surrounding text to send. 5. - * Insert new preedit text in cursor position. 6. Place cursor - * inside preedit text. - * - * The serial number reflects the last state of the - * zwp_text_input_v3 object known to the compositor. The value of - * the serial argument must be equal to the number of commit - * requests already issued on that object. When the client receives - * a done event with a serial different than the number of past - * commit requests, it must proceed as normal, except it should not - * change the current state of the zwp_text_input_v3 object. - */ - void (*done)(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - uint32_t serial); -}; - -/** - * @ingroup iface_zwp_text_input_v3 - */ -static inline int -zwp_text_input_v3_add_listener(struct zwp_text_input_v3 *zwp_text_input_v3, - const struct zwp_text_input_v3_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zwp_text_input_v3, - (void (**)(void)) listener, data); -} - -#define ZWP_TEXT_INPUT_V3_DESTROY 0 -#define ZWP_TEXT_INPUT_V3_ENABLE 1 -#define ZWP_TEXT_INPUT_V3_DISABLE 2 -#define ZWP_TEXT_INPUT_V3_SET_SURROUNDING_TEXT 3 -#define ZWP_TEXT_INPUT_V3_SET_TEXT_CHANGE_CAUSE 4 -#define ZWP_TEXT_INPUT_V3_SET_CONTENT_TYPE 5 -#define ZWP_TEXT_INPUT_V3_SET_CURSOR_RECTANGLE 6 -#define ZWP_TEXT_INPUT_V3_COMMIT 7 - -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_ENTER_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_LEAVE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_PREEDIT_STRING_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_COMMIT_STRING_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_DELETE_SURROUNDING_TEXT_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_DONE_SINCE_VERSION 1 - -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_ENABLE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_DISABLE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_SET_SURROUNDING_TEXT_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_SET_TEXT_CHANGE_CAUSE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_SET_CONTENT_TYPE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_SET_CURSOR_RECTANGLE_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_v3 - */ -#define ZWP_TEXT_INPUT_V3_COMMIT_SINCE_VERSION 1 - -/** @ingroup iface_zwp_text_input_v3 */ -static inline void -zwp_text_input_v3_set_user_data(struct zwp_text_input_v3 *zwp_text_input_v3, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_text_input_v3, user_data); -} - -/** @ingroup iface_zwp_text_input_v3 */ -static inline void * -zwp_text_input_v3_get_user_data(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_text_input_v3); -} - -static inline uint32_t -zwp_text_input_v3_get_version(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_text_input_v3); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Destroy the wp_text_input object. Also disables all surfaces enabled - * through this wp_text_input object. - */ -static inline void -zwp_text_input_v3_destroy(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) zwp_text_input_v3); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Requests text input on the surface previously obtained from the enter - * event. - * - * This request must be issued every time the active text input changes - * to a new one, including within the current surface. Use - * zwp_text_input_v3.disable when there is no longer any input focus on - * the current surface. - * - * This request resets all state associated with previous enable, disable, - * set_surrounding_text, set_text_change_cause, set_content_type, and - * set_cursor_rectangle requests, as well as the state associated with - * preedit_string, commit_string, and delete_surrounding_text events. - * - * The set_surrounding_text, set_content_type and set_cursor_rectangle - * requests must follow if the text input supports the necessary - * functionality. - * - * State set with this request is double-buffered. It will get applied on - * the next zwp_text_input_v3.commit request, and stay valid until the - * next committed enable or disable request. - * - * The changes must be applied by the compositor after issuing a - * zwp_text_input_v3.commit request. - */ -static inline void -zwp_text_input_v3_enable(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_ENABLE); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Explicitly disable text input on the current surface (typically when - * there is no focus on any text entry inside the surface). - * - * State set with this request is double-buffered. It will get applied on - * the next zwp_text_input_v3.commit request. - */ -static inline void -zwp_text_input_v3_disable(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_DISABLE); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Sets the surrounding plain text around the input, excluding the preedit - * text. - * - * The client should notify the compositor of any changes in any of the - * values carried with this request, including changes caused by handling - * incoming text-input events as well as changes caused by other - * mechanisms like keyboard typing. - * - * If the client is unaware of the text around the cursor, it should not - * issue this request, to signify lack of support to the compositor. - * - * Text is UTF-8 encoded, and should include the cursor position, the - * complete selection and additional characters before and after them. - * There is a maximum length of wayland messages, so text can not be - * longer than 4000 bytes. - * - * Cursor is the byte offset of the cursor within text buffer. - * - * Anchor is the byte offset of the selection anchor within text buffer. - * If there is no selected text, anchor is the same as cursor. - * - * If any preedit text is present, it is replaced with a cursor for the - * purpose of this event. - * - * Values set with this request are double-buffered. They will get applied - * on the next zwp_text_input_v3.commit request, and stay valid until the - * next committed enable or disable request. - * - * The initial state for affected fields is empty, meaning that the text - * input does not support sending surrounding text. If the empty values - * get applied, subsequent attempts to change them may have no effect. - */ -static inline void -zwp_text_input_v3_set_surrounding_text(struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor, int32_t anchor) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_SET_SURROUNDING_TEXT, text, cursor, anchor); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Tells the compositor why the text surrounding the cursor changed. - * - * Whenever the client detects an external change in text, cursor, or - * anchor posision, it must issue this request to the compositor. This - * request is intended to give the input method a chance to update the - * preedit text in an appropriate way, e.g. by removing it when the user - * starts typing with a keyboard. - * - * cause describes the source of the change. - * - * The value set with this request is double-buffered. It must be applied - * and reset to initial at the next zwp_text_input_v3.commit request. - * - * The initial value of cause is input_method. - */ -static inline void -zwp_text_input_v3_set_text_change_cause(struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t cause) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_SET_TEXT_CHANGE_CAUSE, cause); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Sets the content purpose and content hint. While the purpose is the - * basic purpose of an input field, the hint flags allow to modify some of - * the behavior. - * - * Values set with this request are double-buffered. They will get applied - * on the next zwp_text_input_v3.commit request. - * Subsequent attempts to update them may have no effect. The values - * remain valid until the next committed enable or disable request. - * - * The initial value for hint is none, and the initial value for purpose - * is normal. - */ -static inline void -zwp_text_input_v3_set_content_type(struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t hint, uint32_t purpose) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_SET_CONTENT_TYPE, hint, purpose); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Marks an area around the cursor as a x, y, width, height rectangle in - * surface local coordinates. - * - * Allows the compositor to put a window with word suggestions near the - * cursor, without obstructing the text being input. - * - * If the client is unaware of the position of edited text, it should not - * issue this request, to signify lack of support to the compositor. - * - * Values set with this request are double-buffered. They will get applied - * on the next zwp_text_input_v3.commit request, and stay valid until the - * next committed enable or disable request. - * - * The initial values describing a cursor rectangle are empty. That means - * the text input does not support describing the cursor area. If the - * empty values get applied, subsequent attempts to change them may have - * no effect. - */ -static inline void -zwp_text_input_v3_set_cursor_rectangle(struct zwp_text_input_v3 *zwp_text_input_v3, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_SET_CURSOR_RECTANGLE, x, y, width, height); -} - -/** - * @ingroup iface_zwp_text_input_v3 - * - * Atomically applies state changes recently sent to the compositor. - * - * The commit request establishes and updates the state of the client, and - * must be issued after any changes to apply them. - * - * Text input state (enabled status, content purpose, content hint, - * surrounding text and change cause, cursor rectangle) is conceptually - * double-buffered within the context of a text input, i.e. between a - * committed enable request and the following committed enable or disable - * request. - * - * Protocol requests modify the pending state, as opposed to the current - * state in use by the input method. A commit request atomically applies - * all pending state, replacing the current state. After commit, the new - * pending state is as documented for each related request. - * - * Requests are applied in the order of arrival. - * - * Neither current nor pending state are modified unless noted otherwise. - * - * The compositor must count the number of commit requests coming from - * each zwp_text_input_v3 object and use the count as the serial in done - * events. - */ -static inline void -zwp_text_input_v3_commit(struct zwp_text_input_v3 *zwp_text_input_v3) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_v3, - ZWP_TEXT_INPUT_V3_COMMIT); -} - -#define ZWP_TEXT_INPUT_MANAGER_V3_DESTROY 0 -#define ZWP_TEXT_INPUT_MANAGER_V3_GET_TEXT_INPUT 1 - - -/** - * @ingroup iface_zwp_text_input_manager_v3 - */ -#define ZWP_TEXT_INPUT_MANAGER_V3_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zwp_text_input_manager_v3 - */ -#define ZWP_TEXT_INPUT_MANAGER_V3_GET_TEXT_INPUT_SINCE_VERSION 1 - -/** @ingroup iface_zwp_text_input_manager_v3 */ -static inline void -zwp_text_input_manager_v3_set_user_data(struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zwp_text_input_manager_v3, user_data); -} - -/** @ingroup iface_zwp_text_input_manager_v3 */ -static inline void * -zwp_text_input_manager_v3_get_user_data(struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zwp_text_input_manager_v3); -} - -static inline uint32_t -zwp_text_input_manager_v3_get_version(struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3) -{ - return wl_proxy_get_version((struct wl_proxy *) zwp_text_input_manager_v3); -} - -/** - * @ingroup iface_zwp_text_input_manager_v3 - * - * Destroy the wp_text_input_manager object. - */ -static inline void -zwp_text_input_manager_v3_destroy(struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3) -{ - wl_proxy_marshal((struct wl_proxy *) zwp_text_input_manager_v3, - ZWP_TEXT_INPUT_MANAGER_V3_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) zwp_text_input_manager_v3); -} - -/** - * @ingroup iface_zwp_text_input_manager_v3 - * - * Creates a new text-input object for a given seat. - */ -static inline struct zwp_text_input_v3 * -zwp_text_input_manager_v3_get_text_input(struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3, struct wl_seat *seat) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) zwp_text_input_manager_v3, - ZWP_TEXT_INPUT_MANAGER_V3_GET_TEXT_INPUT, &zwp_text_input_v3_interface, NULL, seat); - - return (struct zwp_text_input_v3 *) id; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.c b/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.c deleted file mode 100644 index fa13d7c..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.c +++ /dev/null @@ -1,77 +0,0 @@ -// +build linux,!android,!nowayland freebsd - -/* Generated by wayland-scanner 1.17.0 */ - -/* - * Copyright © 2018 Simon Ser - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <stdlib.h> -#include <stdint.h> -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface xdg_toplevel_interface; -extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; - -static const struct wl_interface *types[] = { - NULL, - &zxdg_toplevel_decoration_v1_interface, - &xdg_toplevel_interface, -}; - -static const struct wl_message zxdg_decoration_manager_v1_requests[] = { - { "destroy", "", types + 0 }, - { "get_toplevel_decoration", "no", types + 1 }, -}; - -WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = { - "zxdg_decoration_manager_v1", 1, - 2, zxdg_decoration_manager_v1_requests, - 0, NULL, -}; - -static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = { - { "destroy", "", types + 0 }, - { "set_mode", "u", types + 0 }, - { "unset_mode", "", types + 0 }, -}; - -static const struct wl_message zxdg_toplevel_decoration_v1_events[] = { - { "configure", "u", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = { - "zxdg_toplevel_decoration_v1", 1, - 3, zxdg_toplevel_decoration_v1_requests, - 1, zxdg_toplevel_decoration_v1_events, -}; - diff --git a/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.h b/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.h deleted file mode 100644 index 044ea2e..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_xdg_decoration.h +++ /dev/null @@ -1,376 +0,0 @@ -/* Generated by wayland-scanner 1.17.0 */ - -#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H -#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H - -#include <stdint.h> -#include <stddef.h> -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol - * @section page_ifaces_xdg_decoration_unstable_v1 Interfaces - * - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager - * - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface - * @section page_copyright_xdg_decoration_unstable_v1 Copyright - * <pre> - * - * Copyright © 2018 Simon Ser - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * </pre> - */ -struct xdg_toplevel; -struct zxdg_decoration_manager_v1; -struct zxdg_toplevel_decoration_v1; - -/** - * @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1 - * @section page_iface_zxdg_decoration_manager_v1_desc Description - * - * This interface allows a compositor to announce support for server-side - * decorations. - * - * A window decoration is a set of window controls as deemed appropriate by - * the party managing them, such as user interface components used to move, - * resize and change a window's state. - * - * A client can use this protocol to request being decorated by a supporting - * compositor. - * - * If compositor and client do not negotiate the use of a server-side - * decoration using this protocol, clients continue to self-decorate as they - * see fit. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - * @section page_iface_zxdg_decoration_manager_v1_api API - * See @ref iface_zxdg_decoration_manager_v1. - */ -/** - * @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface - * - * This interface allows a compositor to announce support for server-side - * decorations. - * - * A window decoration is a set of window controls as deemed appropriate by - * the party managing them, such as user interface components used to move, - * resize and change a window's state. - * - * A client can use this protocol to request being decorated by a supporting - * compositor. - * - * If compositor and client do not negotiate the use of a server-side - * decoration using this protocol, clients continue to self-decorate as they - * see fit. - * - * Warning! The protocol described in this file is experimental and - * backward incompatible changes may be made. Backward compatible changes - * may be added together with the corresponding interface version bump. - * Backward incompatible changes are done by bumping the version number in - * the protocol and interface names and resetting the interface version. - * Once the protocol is to be declared stable, the 'z' prefix and the - * version number in the protocol and interface names are removed and the - * interface version number is reset. - */ -extern const struct wl_interface zxdg_decoration_manager_v1_interface; -/** - * @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1 - * @section page_iface_zxdg_toplevel_decoration_v1_desc Description - * - * The decoration object allows the compositor to toggle server-side window - * decorations for a toplevel surface. The client can request to switch to - * another mode. - * - * The xdg_toplevel_decoration object must be destroyed before its - * xdg_toplevel. - * @section page_iface_zxdg_toplevel_decoration_v1_api API - * See @ref iface_zxdg_toplevel_decoration_v1. - */ -/** - * @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface - * - * The decoration object allows the compositor to toggle server-side window - * decorations for a toplevel surface. The client can request to switch to - * another mode. - * - * The xdg_toplevel_decoration object must be destroyed before its - * xdg_toplevel. - */ -extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; - -#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0 -#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1 - - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - */ -#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_decoration_manager_v1 - */ -#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1 - -/** @ingroup iface_zxdg_decoration_manager_v1 */ -static inline void -zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data); -} - -/** @ingroup iface_zxdg_decoration_manager_v1 */ -static inline void * -zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1); -} - -static inline uint32_t -zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1); -} - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - * - * Destroy the decoration manager. This doesn't destroy objects created - * with the manager. - */ -static inline void -zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1) -{ - wl_proxy_marshal((struct wl_proxy *) zxdg_decoration_manager_v1, - ZXDG_DECORATION_MANAGER_V1_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) zxdg_decoration_manager_v1); -} - -/** - * @ingroup iface_zxdg_decoration_manager_v1 - * - * Create a new decoration object associated with the given toplevel. - * - * Creating an xdg_toplevel_decoration from an xdg_toplevel which has a - * buffer attached or committed is a client error, and any attempts by a - * client to attach or manipulate a buffer prior to the first - * xdg_toplevel_decoration.configure event must also be treated as - * errors. - */ -static inline struct zxdg_toplevel_decoration_v1 * -zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) zxdg_decoration_manager_v1, - ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, NULL, toplevel); - - return (struct zxdg_toplevel_decoration_v1 *) id; -} - -#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM -#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM -enum zxdg_toplevel_decoration_v1_error { - /** - * xdg_toplevel has a buffer attached before configure - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0, - /** - * xdg_toplevel already has a decoration object - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1, - /** - * xdg_toplevel destroyed before the decoration object - */ - ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2, -}; -#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */ - -#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM -#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * window decoration modes - * - * These values describe window decoration modes. - */ -enum zxdg_toplevel_decoration_v1_mode { - /** - * no server-side window decoration - */ - ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1, - /** - * server-side window decoration - */ - ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2, -}; -#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */ - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * @struct zxdg_toplevel_decoration_v1_listener - */ -struct zxdg_toplevel_decoration_v1_listener { - /** - * suggest a surface change - * - * The configure event asks the client to change its decoration - * mode. The configured state should not be applied immediately. - * Clients must send an ack_configure in response to this event. - * See xdg_surface.configure and xdg_surface.ack_configure for - * details. - * - * A configure event can be sent at any time. The specified mode - * must be obeyed by the client. - * @param mode the decoration mode - */ - void (*configure)(void *data, - struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, - uint32_t mode); -}; - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -static inline int -zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, - const struct zxdg_toplevel_decoration_v1_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1, - (void (**)(void)) listener, data); -} - -#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0 -#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1 -#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2 - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1 - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1 -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - */ -#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1 - -/** @ingroup iface_zxdg_toplevel_decoration_v1 */ -static inline void -zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data); -} - -/** @ingroup iface_zxdg_toplevel_decoration_v1 */ -static inline void * -zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1); -} - -static inline uint32_t -zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Switch back to a mode without any server-side decorations at the next - * commit. - */ -static inline void -zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - wl_proxy_marshal((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) zxdg_toplevel_decoration_v1); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Set the toplevel surface decoration mode. This informs the compositor - * that the client prefers the provided decoration mode. - * - * After requesting a decoration mode, the compositor will respond by - * emitting a xdg_surface.configure event. The client should then update - * its content, drawing it without decorations if the received mode is - * server-side decorations. The client must also acknowledge the configure - * when committing the new content (see xdg_surface.ack_configure). - * - * The compositor can decide not to use the client's mode and enforce a - * different mode instead. - * - * Clients whose decoration mode depend on the xdg_toplevel state may send - * a set_mode request in response to a xdg_surface.configure event and wait - * for the next xdg_surface.configure event to prevent unwanted state. - * Such clients are responsible for preventing configure loops and must - * make sure not to send multiple successive set_mode requests with the - * same decoration mode. - */ -static inline void -zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode) -{ - wl_proxy_marshal((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, mode); -} - -/** - * @ingroup iface_zxdg_toplevel_decoration_v1 - * - * Unset the toplevel surface decoration mode. This informs the compositor - * that the client doesn't prefer a particular decoration mode. - * - * This request has the same semantics as set_mode. - */ -static inline void -zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1) -{ - wl_proxy_marshal((struct wl_proxy *) zxdg_toplevel_decoration_v1, - ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/vendor/gioui.org/app/internal/window/wayland_xdg_shell.c b/vendor/gioui.org/app/internal/window/wayland_xdg_shell.c deleted file mode 100644 index 1947847..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_xdg_shell.c +++ /dev/null @@ -1,176 +0,0 @@ -// +build linux,!android,!nowayland freebsd - -/* Generated by wayland-scanner 1.17.0 */ - -/* - * Copyright © 2008-2013 Kristian Høgsberg - * Copyright © 2013 Rafael Antognolli - * Copyright © 2013 Jasper St. Pierre - * Copyright © 2010-2013 Intel Corporation - * Copyright © 2015-2017 Samsung Electronics Co., Ltd - * Copyright © 2015-2017 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <stdlib.h> -#include <stdint.h> -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_seat_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface xdg_popup_interface; -extern const struct wl_interface xdg_positioner_interface; -extern const struct wl_interface xdg_surface_interface; -extern const struct wl_interface xdg_toplevel_interface; - -static const struct wl_interface *types[] = { - NULL, - NULL, - NULL, - NULL, - &xdg_positioner_interface, - &xdg_surface_interface, - &wl_surface_interface, - &xdg_toplevel_interface, - &xdg_popup_interface, - &xdg_surface_interface, - &xdg_positioner_interface, - &xdg_toplevel_interface, - &wl_seat_interface, - NULL, - NULL, - NULL, - &wl_seat_interface, - NULL, - &wl_seat_interface, - NULL, - NULL, - &wl_output_interface, - &wl_seat_interface, - NULL, -}; - -static const struct wl_message xdg_wm_base_requests[] = { - { "destroy", "", types + 0 }, - { "create_positioner", "n", types + 4 }, - { "get_xdg_surface", "no", types + 5 }, - { "pong", "u", types + 0 }, -}; - -static const struct wl_message xdg_wm_base_events[] = { - { "ping", "u", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_wm_base_interface = { - "xdg_wm_base", 2, - 4, xdg_wm_base_requests, - 1, xdg_wm_base_events, -}; - -static const struct wl_message xdg_positioner_requests[] = { - { "destroy", "", types + 0 }, - { "set_size", "ii", types + 0 }, - { "set_anchor_rect", "iiii", types + 0 }, - { "set_anchor", "u", types + 0 }, - { "set_gravity", "u", types + 0 }, - { "set_constraint_adjustment", "u", types + 0 }, - { "set_offset", "ii", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_positioner_interface = { - "xdg_positioner", 2, - 7, xdg_positioner_requests, - 0, NULL, -}; - -static const struct wl_message xdg_surface_requests[] = { - { "destroy", "", types + 0 }, - { "get_toplevel", "n", types + 7 }, - { "get_popup", "n?oo", types + 8 }, - { "set_window_geometry", "iiii", types + 0 }, - { "ack_configure", "u", types + 0 }, -}; - -static const struct wl_message xdg_surface_events[] = { - { "configure", "u", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_surface_interface = { - "xdg_surface", 2, - 5, xdg_surface_requests, - 1, xdg_surface_events, -}; - -static const struct wl_message xdg_toplevel_requests[] = { - { "destroy", "", types + 0 }, - { "set_parent", "?o", types + 11 }, - { "set_title", "s", types + 0 }, - { "set_app_id", "s", types + 0 }, - { "show_window_menu", "ouii", types + 12 }, - { "move", "ou", types + 16 }, - { "resize", "ouu", types + 18 }, - { "set_max_size", "ii", types + 0 }, - { "set_min_size", "ii", types + 0 }, - { "set_maximized", "", types + 0 }, - { "unset_maximized", "", types + 0 }, - { "set_fullscreen", "?o", types + 21 }, - { "unset_fullscreen", "", types + 0 }, - { "set_minimized", "", types + 0 }, -}; - -static const struct wl_message xdg_toplevel_events[] = { - { "configure", "iia", types + 0 }, - { "close", "", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_toplevel_interface = { - "xdg_toplevel", 2, - 14, xdg_toplevel_requests, - 2, xdg_toplevel_events, -}; - -static const struct wl_message xdg_popup_requests[] = { - { "destroy", "", types + 0 }, - { "grab", "ou", types + 22 }, -}; - -static const struct wl_message xdg_popup_events[] = { - { "configure", "iiii", types + 0 }, - { "popup_done", "", types + 0 }, -}; - -WL_PRIVATE const struct wl_interface xdg_popup_interface = { - "xdg_popup", 2, - 2, xdg_popup_requests, - 2, xdg_popup_events, -}; - diff --git a/vendor/gioui.org/app/internal/window/wayland_xdg_shell.h b/vendor/gioui.org/app/internal/window/wayland_xdg_shell.h deleted file mode 100644 index 1f4bfb5..0000000 --- a/vendor/gioui.org/app/internal/window/wayland_xdg_shell.h +++ /dev/null @@ -1,1842 +0,0 @@ -/* Generated by wayland-scanner 1.17.0 */ - -#ifndef XDG_SHELL_CLIENT_PROTOCOL_H -#define XDG_SHELL_CLIENT_PROTOCOL_H - -#include <stdint.h> -#include <stddef.h> -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_xdg_shell The xdg_shell protocol - * @section page_ifaces_xdg_shell Interfaces - * - @subpage page_iface_xdg_wm_base - create desktop-style surfaces - * - @subpage page_iface_xdg_positioner - child surface positioner - * - @subpage page_iface_xdg_surface - desktop user interface surface base interface - * - @subpage page_iface_xdg_toplevel - toplevel surface - * - @subpage page_iface_xdg_popup - short-lived, popup surfaces for menus - * @section page_copyright_xdg_shell Copyright - * <pre> - * - * Copyright © 2008-2013 Kristian Høgsberg - * Copyright © 2013 Rafael Antognolli - * Copyright © 2013 Jasper St. Pierre - * Copyright © 2010-2013 Intel Corporation - * Copyright © 2015-2017 Samsung Electronics Co., Ltd - * Copyright © 2015-2017 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * </pre> - */ -struct wl_output; -struct wl_seat; -struct wl_surface; -struct xdg_popup; -struct xdg_positioner; -struct xdg_surface; -struct xdg_toplevel; -struct xdg_wm_base; - -/** - * @page page_iface_xdg_wm_base xdg_wm_base - * @section page_iface_xdg_wm_base_desc Description - * - * The xdg_wm_base interface is exposed as a global object enabling clients - * to turn their wl_surfaces into windows in a desktop environment. It - * defines the basic functionality needed for clients and the compositor to - * create windows that can be dragged, resized, maximized, etc, as well as - * creating transient windows such as popup menus. - * @section page_iface_xdg_wm_base_api API - * See @ref iface_xdg_wm_base. - */ -/** - * @defgroup iface_xdg_wm_base The xdg_wm_base interface - * - * The xdg_wm_base interface is exposed as a global object enabling clients - * to turn their wl_surfaces into windows in a desktop environment. It - * defines the basic functionality needed for clients and the compositor to - * create windows that can be dragged, resized, maximized, etc, as well as - * creating transient windows such as popup menus. - */ -extern const struct wl_interface xdg_wm_base_interface; -/** - * @page page_iface_xdg_positioner xdg_positioner - * @section page_iface_xdg_positioner_desc Description - * - * The xdg_positioner provides a collection of rules for the placement of a - * child surface relative to a parent surface. Rules can be defined to ensure - * the child surface remains within the visible area's borders, and to - * specify how the child surface changes its position, such as sliding along - * an axis, or flipping around a rectangle. These positioner-created rules are - * constrained by the requirement that a child surface must intersect with or - * be at least partially adjacent to its parent surface. - * - * See the various requests for details about possible rules. - * - * At the time of the request, the compositor makes a copy of the rules - * specified by the xdg_positioner. Thus, after the request is complete the - * xdg_positioner object can be destroyed or reused; further changes to the - * object will have no effect on previous usages. - * - * For an xdg_positioner object to be considered complete, it must have a - * non-zero size set by set_size, and a non-zero anchor rectangle set by - * set_anchor_rect. Passing an incomplete xdg_positioner object when - * positioning a surface raises an error. - * @section page_iface_xdg_positioner_api API - * See @ref iface_xdg_positioner. - */ -/** - * @defgroup iface_xdg_positioner The xdg_positioner interface - * - * The xdg_positioner provides a collection of rules for the placement of a - * child surface relative to a parent surface. Rules can be defined to ensure - * the child surface remains within the visible area's borders, and to - * specify how the child surface changes its position, such as sliding along - * an axis, or flipping around a rectangle. These positioner-created rules are - * constrained by the requirement that a child surface must intersect with or - * be at least partially adjacent to its parent surface. - * - * See the various requests for details about possible rules. - * - * At the time of the request, the compositor makes a copy of the rules - * specified by the xdg_positioner. Thus, after the request is complete the - * xdg_positioner object can be destroyed or reused; further changes to the - * object will have no effect on previous usages. - * - * For an xdg_positioner object to be considered complete, it must have a - * non-zero size set by set_size, and a non-zero anchor rectangle set by - * set_anchor_rect. Passing an incomplete xdg_positioner object when - * positioning a surface raises an error. - */ -extern const struct wl_interface xdg_positioner_interface; -/** - * @page page_iface_xdg_surface xdg_surface - * @section page_iface_xdg_surface_desc Description - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides a base set of functionality required to construct user - * interface elements requiring management by the compositor, such as - * toplevel windows, menus, etc. The types of functionality are split into - * xdg_surface roles. - * - * Creating an xdg_surface does not set the role for a wl_surface. In order - * to map an xdg_surface, the client must create a role-specific object - * using, e.g., get_toplevel, get_popup. The wl_surface for any given - * xdg_surface can have at most one role, and may not be assigned any role - * not based on xdg_surface. - * - * A role must be assigned before any other requests are made to the - * xdg_surface object. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_surface state to take effect. - * - * Creating an xdg_surface from a wl_surface which has a buffer attached or - * committed is a client error, and any attempts by a client to attach or - * manipulate a buffer prior to the first xdg_surface.configure call must - * also be treated as errors. - * - * Mapping an xdg_surface-based role surface is defined as making it - * possible for the surface to be shown by the compositor. Note that - * a mapped surface is not guaranteed to be visible once it is mapped. - * - * For an xdg_surface to be mapped by the compositor, the following - * conditions must be met: - * (1) the client has assigned an xdg_surface-based role to the surface - * (2) the client has set and committed the xdg_surface state and the - * role-dependent state to the surface - * (3) the client has committed a buffer to the surface - * - * A newly-unmapped surface is considered to have met condition (1) out - * of the 3 required conditions for mapping a surface if its role surface - * has not been destroyed. - * @section page_iface_xdg_surface_api API - * See @ref iface_xdg_surface. - */ -/** - * @defgroup iface_xdg_surface The xdg_surface interface - * - * An interface that may be implemented by a wl_surface, for - * implementations that provide a desktop-style user interface. - * - * It provides a base set of functionality required to construct user - * interface elements requiring management by the compositor, such as - * toplevel windows, menus, etc. The types of functionality are split into - * xdg_surface roles. - * - * Creating an xdg_surface does not set the role for a wl_surface. In order - * to map an xdg_surface, the client must create a role-specific object - * using, e.g., get_toplevel, get_popup. The wl_surface for any given - * xdg_surface can have at most one role, and may not be assigned any role - * not based on xdg_surface. - * - * A role must be assigned before any other requests are made to the - * xdg_surface object. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_surface state to take effect. - * - * Creating an xdg_surface from a wl_surface which has a buffer attached or - * committed is a client error, and any attempts by a client to attach or - * manipulate a buffer prior to the first xdg_surface.configure call must - * also be treated as errors. - * - * Mapping an xdg_surface-based role surface is defined as making it - * possible for the surface to be shown by the compositor. Note that - * a mapped surface is not guaranteed to be visible once it is mapped. - * - * For an xdg_surface to be mapped by the compositor, the following - * conditions must be met: - * (1) the client has assigned an xdg_surface-based role to the surface - * (2) the client has set and committed the xdg_surface state and the - * role-dependent state to the surface - * (3) the client has committed a buffer to the surface - * - * A newly-unmapped surface is considered to have met condition (1) out - * of the 3 required conditions for mapping a surface if its role surface - * has not been destroyed. - */ -extern const struct wl_interface xdg_surface_interface; -/** - * @page page_iface_xdg_toplevel xdg_toplevel - * @section page_iface_xdg_toplevel_desc Description - * - * This interface defines an xdg_surface role which allows a surface to, - * among other things, set window-like properties such as maximize, - * fullscreen, and minimize, set application-specific metadata like title and - * id, and well as trigger user interactive operations such as interactive - * resize and move. - * - * Unmapping an xdg_toplevel means that the surface cannot be shown - * by the compositor until it is explicitly mapped again. - * All active operations (e.g., move, resize) are canceled and all - * attributes (e.g. title, state, stacking, ...) are discarded for - * an xdg_toplevel surface when it is unmapped. - * - * Attaching a null buffer to a toplevel unmaps the surface. - * @section page_iface_xdg_toplevel_api API - * See @ref iface_xdg_toplevel. - */ -/** - * @defgroup iface_xdg_toplevel The xdg_toplevel interface - * - * This interface defines an xdg_surface role which allows a surface to, - * among other things, set window-like properties such as maximize, - * fullscreen, and minimize, set application-specific metadata like title and - * id, and well as trigger user interactive operations such as interactive - * resize and move. - * - * Unmapping an xdg_toplevel means that the surface cannot be shown - * by the compositor until it is explicitly mapped again. - * All active operations (e.g., move, resize) are canceled and all - * attributes (e.g. title, state, stacking, ...) are discarded for - * an xdg_toplevel surface when it is unmapped. - * - * Attaching a null buffer to a toplevel unmaps the surface. - */ -extern const struct wl_interface xdg_toplevel_interface; -/** - * @page page_iface_xdg_popup xdg_popup - * @section page_iface_xdg_popup_desc Description - * - * A popup surface is a short-lived, temporary surface. It can be used to - * implement for example menus, popovers, tooltips and other similar user - * interface concepts. - * - * A popup can be made to take an explicit grab. See xdg_popup.grab for - * details. - * - * When the popup is dismissed, a popup_done event will be sent out, and at - * the same time the surface will be unmapped. See the xdg_popup.popup_done - * event for details. - * - * Explicitly destroying the xdg_popup object will also dismiss the popup and - * unmap the surface. Clients that want to dismiss the popup when another - * surface of their own is clicked should dismiss the popup using the destroy - * request. - * - * A newly created xdg_popup will be stacked on top of all previously created - * xdg_popup surfaces associated with the same xdg_toplevel. - * - * The parent of an xdg_popup must be mapped (see the xdg_surface - * description) before the xdg_popup itself. - * - * The x and y arguments passed when creating the popup object specify - * where the top left of the popup should be placed, relative to the - * local surface coordinates of the parent surface. See - * xdg_surface.get_popup. An xdg_popup must intersect with or be at least - * partially adjacent to its parent surface. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_popup state to take effect. - * @section page_iface_xdg_popup_api API - * See @ref iface_xdg_popup. - */ -/** - * @defgroup iface_xdg_popup The xdg_popup interface - * - * A popup surface is a short-lived, temporary surface. It can be used to - * implement for example menus, popovers, tooltips and other similar user - * interface concepts. - * - * A popup can be made to take an explicit grab. See xdg_popup.grab for - * details. - * - * When the popup is dismissed, a popup_done event will be sent out, and at - * the same time the surface will be unmapped. See the xdg_popup.popup_done - * event for details. - * - * Explicitly destroying the xdg_popup object will also dismiss the popup and - * unmap the surface. Clients that want to dismiss the popup when another - * surface of their own is clicked should dismiss the popup using the destroy - * request. - * - * A newly created xdg_popup will be stacked on top of all previously created - * xdg_popup surfaces associated with the same xdg_toplevel. - * - * The parent of an xdg_popup must be mapped (see the xdg_surface - * description) before the xdg_popup itself. - * - * The x and y arguments passed when creating the popup object specify - * where the top left of the popup should be placed, relative to the - * local surface coordinates of the parent surface. See - * xdg_surface.get_popup. An xdg_popup must intersect with or be at least - * partially adjacent to its parent surface. - * - * The client must call wl_surface.commit on the corresponding wl_surface - * for the xdg_popup state to take effect. - */ -extern const struct wl_interface xdg_popup_interface; - -#ifndef XDG_WM_BASE_ERROR_ENUM -#define XDG_WM_BASE_ERROR_ENUM -enum xdg_wm_base_error { - /** - * given wl_surface has another role - */ - XDG_WM_BASE_ERROR_ROLE = 0, - /** - * xdg_wm_base was destroyed before children - */ - XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1, - /** - * the client tried to map or destroy a non-topmost popup - */ - XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2, - /** - * the client specified an invalid popup parent surface - */ - XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3, - /** - * the client provided an invalid surface state - */ - XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4, - /** - * the client provided an invalid positioner - */ - XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5, -}; -#endif /* XDG_WM_BASE_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_wm_base - * @struct xdg_wm_base_listener - */ -struct xdg_wm_base_listener { - /** - * check if the client is alive - * - * The ping event asks the client if it's still alive. Pass the - * serial specified in the event back to the compositor by sending - * a "pong" request back with the specified serial. See - * xdg_wm_base.pong. - * - * Compositors can use this to determine if the client is still - * alive. It's unspecified what will happen if the client doesn't - * respond to the ping request, or in what timeframe. Clients - * should try to respond in a reasonable amount of time. - * - * A compositor is free to ping in any way it wants, but a client - * must always respond to any xdg_wm_base object it created. - * @param serial pass this to the pong request - */ - void (*ping)(void *data, - struct xdg_wm_base *xdg_wm_base, - uint32_t serial); -}; - -/** - * @ingroup iface_xdg_wm_base - */ -static inline int -xdg_wm_base_add_listener(struct xdg_wm_base *xdg_wm_base, - const struct xdg_wm_base_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_wm_base, - (void (**)(void)) listener, data); -} - -#define XDG_WM_BASE_DESTROY 0 -#define XDG_WM_BASE_CREATE_POSITIONER 1 -#define XDG_WM_BASE_GET_XDG_SURFACE 2 -#define XDG_WM_BASE_PONG 3 - -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_PING_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_CREATE_POSITIONER_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_GET_XDG_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_wm_base - */ -#define XDG_WM_BASE_PONG_SINCE_VERSION 1 - -/** @ingroup iface_xdg_wm_base */ -static inline void -xdg_wm_base_set_user_data(struct xdg_wm_base *xdg_wm_base, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_wm_base, user_data); -} - -/** @ingroup iface_xdg_wm_base */ -static inline void * -xdg_wm_base_get_user_data(struct xdg_wm_base *xdg_wm_base) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_wm_base); -} - -static inline uint32_t -xdg_wm_base_get_version(struct xdg_wm_base *xdg_wm_base) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_wm_base); -} - -/** - * @ingroup iface_xdg_wm_base - * - * Destroy this xdg_wm_base object. - * - * Destroying a bound xdg_wm_base object while there are surfaces - * still alive created by this xdg_wm_base object instance is illegal - * and will result in a protocol error. - */ -static inline void -xdg_wm_base_destroy(struct xdg_wm_base *xdg_wm_base) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) xdg_wm_base); -} - -/** - * @ingroup iface_xdg_wm_base - * - * Create a positioner object. A positioner object is used to position - * surfaces relative to some parent surface. See the interface description - * and xdg_surface.get_popup for details. - */ -static inline struct xdg_positioner * -xdg_wm_base_create_positioner(struct xdg_wm_base *xdg_wm_base) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_CREATE_POSITIONER, &xdg_positioner_interface, NULL); - - return (struct xdg_positioner *) id; -} - -/** - * @ingroup iface_xdg_wm_base - * - * This creates an xdg_surface for the given surface. While xdg_surface - * itself is not a role, the corresponding surface may only be assigned - * a role extending xdg_surface, such as xdg_toplevel or xdg_popup. - * - * This creates an xdg_surface for the given surface. An xdg_surface is - * used as basis to define a role to a given surface, such as xdg_toplevel - * or xdg_popup. It also manages functionality shared between xdg_surface - * based surface roles. - * - * See the documentation of xdg_surface for more details about what an - * xdg_surface is and how it is used. - */ -static inline struct xdg_surface * -xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_GET_XDG_SURFACE, &xdg_surface_interface, NULL, surface); - - return (struct xdg_surface *) id; -} - -/** - * @ingroup iface_xdg_wm_base - * - * A client must respond to a ping event with a pong request or - * the client may be deemed unresponsive. See xdg_wm_base.ping. - */ -static inline void -xdg_wm_base_pong(struct xdg_wm_base *xdg_wm_base, uint32_t serial) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_wm_base, - XDG_WM_BASE_PONG, serial); -} - -#ifndef XDG_POSITIONER_ERROR_ENUM -#define XDG_POSITIONER_ERROR_ENUM -enum xdg_positioner_error { - /** - * invalid input provided - */ - XDG_POSITIONER_ERROR_INVALID_INPUT = 0, -}; -#endif /* XDG_POSITIONER_ERROR_ENUM */ - -#ifndef XDG_POSITIONER_ANCHOR_ENUM -#define XDG_POSITIONER_ANCHOR_ENUM -enum xdg_positioner_anchor { - XDG_POSITIONER_ANCHOR_NONE = 0, - XDG_POSITIONER_ANCHOR_TOP = 1, - XDG_POSITIONER_ANCHOR_BOTTOM = 2, - XDG_POSITIONER_ANCHOR_LEFT = 3, - XDG_POSITIONER_ANCHOR_RIGHT = 4, - XDG_POSITIONER_ANCHOR_TOP_LEFT = 5, - XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6, - XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7, - XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8, -}; -#endif /* XDG_POSITIONER_ANCHOR_ENUM */ - -#ifndef XDG_POSITIONER_GRAVITY_ENUM -#define XDG_POSITIONER_GRAVITY_ENUM -enum xdg_positioner_gravity { - XDG_POSITIONER_GRAVITY_NONE = 0, - XDG_POSITIONER_GRAVITY_TOP = 1, - XDG_POSITIONER_GRAVITY_BOTTOM = 2, - XDG_POSITIONER_GRAVITY_LEFT = 3, - XDG_POSITIONER_GRAVITY_RIGHT = 4, - XDG_POSITIONER_GRAVITY_TOP_LEFT = 5, - XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6, - XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7, - XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8, -}; -#endif /* XDG_POSITIONER_GRAVITY_ENUM */ - -#ifndef XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM -#define XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM -/** - * @ingroup iface_xdg_positioner - * vertically resize the surface - * - * Resize the surface vertically so that it is completely unconstrained. - */ -enum xdg_positioner_constraint_adjustment { - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, -}; -#endif /* XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_ENUM */ - -#define XDG_POSITIONER_DESTROY 0 -#define XDG_POSITIONER_SET_SIZE 1 -#define XDG_POSITIONER_SET_ANCHOR_RECT 2 -#define XDG_POSITIONER_SET_ANCHOR 3 -#define XDG_POSITIONER_SET_GRAVITY 4 -#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT 5 -#define XDG_POSITIONER_SET_OFFSET 6 - - -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_ANCHOR_RECT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_ANCHOR_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_GRAVITY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_positioner - */ -#define XDG_POSITIONER_SET_OFFSET_SINCE_VERSION 1 - -/** @ingroup iface_xdg_positioner */ -static inline void -xdg_positioner_set_user_data(struct xdg_positioner *xdg_positioner, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_positioner, user_data); -} - -/** @ingroup iface_xdg_positioner */ -static inline void * -xdg_positioner_get_user_data(struct xdg_positioner *xdg_positioner) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_positioner); -} - -static inline uint32_t -xdg_positioner_get_version(struct xdg_positioner *xdg_positioner) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_positioner); -} - -/** - * @ingroup iface_xdg_positioner - * - * Notify the compositor that the xdg_positioner will no longer be used. - */ -static inline void -xdg_positioner_destroy(struct xdg_positioner *xdg_positioner) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) xdg_positioner); -} - -/** - * @ingroup iface_xdg_positioner - * - * Set the size of the surface that is to be positioned with the positioner - * object. The size is in surface-local coordinates and corresponds to the - * window geometry. See xdg_surface.set_window_geometry. - * - * If a zero or negative size is set the invalid_input error is raised. - */ -static inline void -xdg_positioner_set_size(struct xdg_positioner *xdg_positioner, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_SIZE, width, height); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify the anchor rectangle within the parent surface that the child - * surface will be placed relative to. The rectangle is relative to the - * window geometry as defined by xdg_surface.set_window_geometry of the - * parent surface. - * - * When the xdg_positioner object is used to position a child surface, the - * anchor rectangle may not extend outside the window geometry of the - * positioned child's parent surface. - * - * If a negative size is set the invalid_input error is raised. - */ -static inline void -xdg_positioner_set_anchor_rect(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_ANCHOR_RECT, x, y, width, height); -} - -/** - * @ingroup iface_xdg_positioner - * - * Defines the anchor point for the anchor rectangle. The specified anchor - * is used derive an anchor point that the child surface will be - * positioned relative to. If a corner anchor is set (e.g. 'top_left' or - * 'bottom_right'), the anchor point will be at the specified corner; - * otherwise, the derived anchor point will be centered on the specified - * edge, or in the center of the anchor rectangle if no edge is specified. - */ -static inline void -xdg_positioner_set_anchor(struct xdg_positioner *xdg_positioner, uint32_t anchor) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_ANCHOR, anchor); -} - -/** - * @ingroup iface_xdg_positioner - * - * Defines in what direction a surface should be positioned, relative to - * the anchor point of the parent surface. If a corner gravity is - * specified (e.g. 'bottom_right' or 'top_left'), then the child surface - * will be placed towards the specified gravity; otherwise, the child - * surface will be centered over the anchor point on any axis that had no - * gravity specified. - */ -static inline void -xdg_positioner_set_gravity(struct xdg_positioner *xdg_positioner, uint32_t gravity) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_GRAVITY, gravity); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify how the window should be positioned if the originally intended - * position caused the surface to be constrained, meaning at least - * partially outside positioning boundaries set by the compositor. The - * adjustment is set by constructing a bitmask describing the adjustment to - * be made when the surface is constrained on that axis. - * - * If no bit for one axis is set, the compositor will assume that the child - * surface should not change its position on that axis when constrained. - * - * If more than one bit for one axis is set, the order of how adjustments - * are applied is specified in the corresponding adjustment descriptions. - * - * The default adjustment is none. - */ -static inline void -xdg_positioner_set_constraint_adjustment(struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_CONSTRAINT_ADJUSTMENT, constraint_adjustment); -} - -/** - * @ingroup iface_xdg_positioner - * - * Specify the surface position offset relative to the position of the - * anchor on the anchor rectangle and the anchor on the surface. For - * example if the anchor of the anchor rectangle is at (x, y), the surface - * has the gravity bottom|right, and the offset is (ox, oy), the calculated - * surface position will be (x + ox, y + oy). The offset position of the - * surface is the one used for constraint testing. See - * set_constraint_adjustment. - * - * An example use case is placing a popup menu on top of a user interface - * element, while aligning the user interface element of the parent surface - * with some user interface element placed somewhere in the popup surface. - */ -static inline void -xdg_positioner_set_offset(struct xdg_positioner *xdg_positioner, int32_t x, int32_t y) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_positioner, - XDG_POSITIONER_SET_OFFSET, x, y); -} - -#ifndef XDG_SURFACE_ERROR_ENUM -#define XDG_SURFACE_ERROR_ENUM -enum xdg_surface_error { - XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1, - XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2, - XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3, -}; -#endif /* XDG_SURFACE_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_surface - * @struct xdg_surface_listener - */ -struct xdg_surface_listener { - /** - * suggest a surface change - * - * The configure event marks the end of a configure sequence. A - * configure sequence is a set of one or more events configuring - * the state of the xdg_surface, including the final - * xdg_surface.configure event. - * - * Where applicable, xdg_surface surface roles will during a - * configure sequence extend this event as a latched state sent as - * events before the xdg_surface.configure event. Such events - * should be considered to make up a set of atomically applied - * configuration states, where the xdg_surface.configure commits - * the accumulated state. - * - * Clients should arrange their surface for the new states, and - * then send an ack_configure request with the serial sent in this - * configure event at some point before committing the new surface. - * - * If the client receives multiple configure events before it can - * respond to one, it is free to discard all but the last event it - * received. - * @param serial serial of the configure event - */ - void (*configure)(void *data, - struct xdg_surface *xdg_surface, - uint32_t serial); -}; - -/** - * @ingroup iface_xdg_surface - */ -static inline int -xdg_surface_add_listener(struct xdg_surface *xdg_surface, - const struct xdg_surface_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_surface, - (void (**)(void)) listener, data); -} - -#define XDG_SURFACE_DESTROY 0 -#define XDG_SURFACE_GET_TOPLEVEL 1 -#define XDG_SURFACE_GET_POPUP 2 -#define XDG_SURFACE_SET_WINDOW_GEOMETRY 3 -#define XDG_SURFACE_ACK_CONFIGURE 4 - -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_CONFIGURE_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_GET_TOPLEVEL_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_GET_POPUP_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_SET_WINDOW_GEOMETRY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_surface - */ -#define XDG_SURFACE_ACK_CONFIGURE_SINCE_VERSION 1 - -/** @ingroup iface_xdg_surface */ -static inline void -xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data); -} - -/** @ingroup iface_xdg_surface */ -static inline void * -xdg_surface_get_user_data(struct xdg_surface *xdg_surface) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface); -} - -static inline uint32_t -xdg_surface_get_version(struct xdg_surface *xdg_surface) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_surface); -} - -/** - * @ingroup iface_xdg_surface - * - * Destroy the xdg_surface object. An xdg_surface must only be destroyed - * after its role object has been destroyed. - */ -static inline void -xdg_surface_destroy(struct xdg_surface *xdg_surface) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_surface, - XDG_SURFACE_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) xdg_surface); -} - -/** - * @ingroup iface_xdg_surface - * - * This creates an xdg_toplevel object for the given xdg_surface and gives - * the associated wl_surface the xdg_toplevel role. - * - * See the documentation of xdg_toplevel for more details about what an - * xdg_toplevel is and how it is used. - */ -static inline struct xdg_toplevel * -xdg_surface_get_toplevel(struct xdg_surface *xdg_surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_surface, - XDG_SURFACE_GET_TOPLEVEL, &xdg_toplevel_interface, NULL); - - return (struct xdg_toplevel *) id; -} - -/** - * @ingroup iface_xdg_surface - * - * This creates an xdg_popup object for the given xdg_surface and gives - * the associated wl_surface the xdg_popup role. - * - * If null is passed as a parent, a parent surface must be specified using - * some other protocol, before committing the initial state. - * - * See the documentation of xdg_popup for more details about what an - * xdg_popup is and how it is used. - */ -static inline struct xdg_popup * -xdg_surface_get_popup(struct xdg_surface *xdg_surface, struct xdg_surface *parent, struct xdg_positioner *positioner) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_surface, - XDG_SURFACE_GET_POPUP, &xdg_popup_interface, NULL, parent, positioner); - - return (struct xdg_popup *) id; -} - -/** - * @ingroup iface_xdg_surface - * - * The window geometry of a surface is its "visible bounds" from the - * user's perspective. Client-side decorations often have invisible - * portions like drop-shadows which should be ignored for the - * purposes of aligning, placing and constraining windows. - * - * The window geometry is double buffered, and will be applied at the - * time wl_surface.commit of the corresponding wl_surface is called. - * - * When maintaining a position, the compositor should treat the (x, y) - * coordinate of the window geometry as the top left corner of the window. - * A client changing the (x, y) window geometry coordinate should in - * general not alter the position of the window. - * - * Once the window geometry of the surface is set, it is not possible to - * unset it, and it will remain the same until set_window_geometry is - * called again, even if a new subsurface or buffer is attached. - * - * If never set, the value is the full bounds of the surface, - * including any subsurfaces. This updates dynamically on every - * commit. This unset is meant for extremely simple clients. - * - * The arguments are given in the surface-local coordinate space of - * the wl_surface associated with this xdg_surface. - * - * The width and height must be greater than zero. Setting an invalid size - * will raise an error. When applied, the effective window geometry will be - * the set window geometry clamped to the bounding rectangle of the - * combined geometry of the surface of the xdg_surface and the associated - * subsurfaces. - */ -static inline void -xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_surface, - XDG_SURFACE_SET_WINDOW_GEOMETRY, x, y, width, height); -} - -/** - * @ingroup iface_xdg_surface - * - * When a configure event is received, if a client commits the - * surface in response to the configure event, then the client - * must make an ack_configure request sometime before the commit - * request, passing along the serial of the configure event. - * - * For instance, for toplevel surfaces the compositor might use this - * information to move a surface to the top left only when the client has - * drawn itself for the maximized or fullscreen state. - * - * If the client receives multiple configure events before it - * can respond to one, it only has to ack the last configure event. - * - * A client is not required to commit immediately after sending - * an ack_configure request - it may even ack_configure several times - * before its next surface commit. - * - * A client may send multiple ack_configure requests before committing, but - * only the last request sent before a commit indicates which configure - * event the client really is responding to. - */ -static inline void -xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_surface, - XDG_SURFACE_ACK_CONFIGURE, serial); -} - -#ifndef XDG_TOPLEVEL_RESIZE_EDGE_ENUM -#define XDG_TOPLEVEL_RESIZE_EDGE_ENUM -/** - * @ingroup iface_xdg_toplevel - * edge values for resizing - * - * These values are used to indicate which edge of a surface - * is being dragged in a resize operation. - */ -enum xdg_toplevel_resize_edge { - XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0, - XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2, - XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4, - XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6, - XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8, - XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9, - XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10, -}; -#endif /* XDG_TOPLEVEL_RESIZE_EDGE_ENUM */ - -#ifndef XDG_TOPLEVEL_STATE_ENUM -#define XDG_TOPLEVEL_STATE_ENUM -/** - * @ingroup iface_xdg_toplevel - * the surface is tiled - * - * The window is currently in a tiled layout and the bottom edge is - * considered to be adjacent to another part of the tiling grid. - */ -enum xdg_toplevel_state { - /** - * the surface is maximized - */ - XDG_TOPLEVEL_STATE_MAXIMIZED = 1, - /** - * the surface is fullscreen - */ - XDG_TOPLEVEL_STATE_FULLSCREEN = 2, - /** - * the surface is being resized - */ - XDG_TOPLEVEL_STATE_RESIZING = 3, - /** - * the surface is now activated - */ - XDG_TOPLEVEL_STATE_ACTIVATED = 4, - /** - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_LEFT = 5, - /** - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_RIGHT = 6, - /** - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_TOP = 7, - /** - * @since 2 - */ - XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8, -}; -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_TOP_SINCE_VERSION 2 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2 -#endif /* XDG_TOPLEVEL_STATE_ENUM */ - -/** - * @ingroup iface_xdg_toplevel - * @struct xdg_toplevel_listener - */ -struct xdg_toplevel_listener { - /** - * suggest a surface change - * - * This configure event asks the client to resize its toplevel - * surface or to change its state. The configured state should not - * be applied immediately. See xdg_surface.configure for details. - * - * The width and height arguments specify a hint to the window - * about how its surface should be resized in window geometry - * coordinates. See set_window_geometry. - * - * If the width or height arguments are zero, it means the client - * should decide its own window dimension. This may happen when the - * compositor needs to configure the state of the surface but - * doesn't have any information about any previous or expected - * dimension. - * - * The states listed in the event specify how the width/height - * arguments should be interpreted, and possibly how it should be - * drawn. - * - * Clients must send an ack_configure in response to this event. - * See xdg_surface.configure and xdg_surface.ack_configure for - * details. - */ - void (*configure)(void *data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states); - /** - * surface wants to be closed - * - * The close event is sent by the compositor when the user wants - * the surface to be closed. This should be equivalent to the user - * clicking the close button in client-side decorations, if your - * application has any. - * - * This is only a request that the user intends to close the - * window. The client may choose to ignore this request, or show a - * dialog to ask the user to save their data, etc. - */ - void (*close)(void *data, - struct xdg_toplevel *xdg_toplevel); -}; - -/** - * @ingroup iface_xdg_toplevel - */ -static inline int -xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel, - const struct xdg_toplevel_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel, - (void (**)(void)) listener, data); -} - -#define XDG_TOPLEVEL_DESTROY 0 -#define XDG_TOPLEVEL_SET_PARENT 1 -#define XDG_TOPLEVEL_SET_TITLE 2 -#define XDG_TOPLEVEL_SET_APP_ID 3 -#define XDG_TOPLEVEL_SHOW_WINDOW_MENU 4 -#define XDG_TOPLEVEL_MOVE 5 -#define XDG_TOPLEVEL_RESIZE 6 -#define XDG_TOPLEVEL_SET_MAX_SIZE 7 -#define XDG_TOPLEVEL_SET_MIN_SIZE 8 -#define XDG_TOPLEVEL_SET_MAXIMIZED 9 -#define XDG_TOPLEVEL_UNSET_MAXIMIZED 10 -#define XDG_TOPLEVEL_SET_FULLSCREEN 11 -#define XDG_TOPLEVEL_UNSET_FULLSCREEN 12 -#define XDG_TOPLEVEL_SET_MINIMIZED 13 - -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_CLOSE_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_PARENT_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_TITLE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_APP_ID_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SHOW_WINDOW_MENU_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_MOVE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_RESIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MAX_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MIN_SIZE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MAXIMIZED_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_UNSET_MAXIMIZED_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_FULLSCREEN_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_UNSET_FULLSCREEN_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_toplevel - */ -#define XDG_TOPLEVEL_SET_MINIMIZED_SINCE_VERSION 1 - -/** @ingroup iface_xdg_toplevel */ -static inline void -xdg_toplevel_set_user_data(struct xdg_toplevel *xdg_toplevel, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_toplevel, user_data); -} - -/** @ingroup iface_xdg_toplevel */ -static inline void * -xdg_toplevel_get_user_data(struct xdg_toplevel *xdg_toplevel) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_toplevel); -} - -static inline uint32_t -xdg_toplevel_get_version(struct xdg_toplevel *xdg_toplevel) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_toplevel); -} - -/** - * @ingroup iface_xdg_toplevel - * - * This request destroys the role surface and unmaps the surface; - * see "Unmapping" behavior in interface section for details. - */ -static inline void -xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) xdg_toplevel); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set the "parent" of this surface. This surface should be stacked - * above the parent surface and all other ancestor surfaces. - * - * Parent windows should be set on dialogs, toolboxes, or other - * "auxiliary" surfaces, so that the parent is raised when the dialog - * is raised. - * - * Setting a null parent for a child window removes any parent-child - * relationship for the child. Setting a null parent for a window which - * currently has no parent is a no-op. - * - * If the parent is unmapped then its children are managed as - * though the parent of the now-unmapped parent has become the - * parent of this surface. If no parent exists for the now-unmapped - * parent then the children are managed as though they have no - * parent surface. - */ -static inline void -xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_PARENT, parent); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a short title for the surface. - * - * This string may be used to identify the surface in a task bar, - * window list, or other user interface elements provided by the - * compositor. - * - * The string must be encoded in UTF-8. - */ -static inline void -xdg_toplevel_set_title(struct xdg_toplevel *xdg_toplevel, const char *title) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_TITLE, title); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set an application identifier for the surface. - * - * The app ID identifies the general class of applications to which - * the surface belongs. The compositor can use this to group multiple - * surfaces together, or to determine how to launch a new application. - * - * For D-Bus activatable applications, the app ID is used as the D-Bus - * service name. - * - * The compositor shell will try to group application surfaces together - * by their app ID. As a best practice, it is suggested to select app - * ID's that match the basename of the application's .desktop file. - * For example, "org.freedesktop.FooViewer" where the .desktop file is - * "org.freedesktop.FooViewer.desktop". - * - * Like other properties, a set_app_id request can be sent after the - * xdg_toplevel has been mapped to update the property. - * - * See the desktop-entry specification [0] for more details on - * application identifiers and how they relate to well-known D-Bus - * names and .desktop files. - * - * [0] http://standards.freedesktop.org/desktop-entry-spec/ - */ -static inline void -xdg_toplevel_set_app_id(struct xdg_toplevel *xdg_toplevel, const char *app_id) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_APP_ID, app_id); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Clients implementing client-side decorations might want to show - * a context menu when right-clicking on the decorations, giving the - * user a menu that they can use to maximize or minimize the window. - * - * This request asks the compositor to pop up such a window menu at - * the given position, relative to the local surface coordinates of - * the parent surface. There are no guarantees as to what menu items - * the window menu contains. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. - */ -static inline void -xdg_toplevel_show_window_menu(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SHOW_WINDOW_MENU, seat, serial, x, y); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Start an interactive, user-driven move of the surface. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. The passed - * serial is used to determine the type of interactive move (touch, - * pointer, etc). - * - * The server may ignore move requests depending on the state of - * the surface (e.g. fullscreen or maximized), or if the passed serial - * is no longer valid. - * - * If triggered, the surface will lose the focus of the device - * (wl_pointer, wl_touch, etc) used for the move. It is up to the - * compositor to visually indicate that the move is taking place, such as - * updating a pointer cursor, during the move. There is no guarantee - * that the device focus will return when the move is completed. - */ -static inline void -xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_MOVE, seat, serial); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Start a user-driven, interactive resize of the surface. - * - * This request must be used in response to some sort of user action - * like a button press, key press, or touch down event. The passed - * serial is used to determine the type of interactive resize (touch, - * pointer, etc). - * - * The server may ignore resize requests depending on the state of - * the surface (e.g. fullscreen or maximized). - * - * If triggered, the client will receive configure events with the - * "resize" state enum value and the expected sizes. See the "resize" - * enum value for more details about what is required. The client - * must also acknowledge configure events using "ack_configure". After - * the resize is completed, the client will receive another "configure" - * event without the resize state. - * - * If triggered, the surface also will lose the focus of the device - * (wl_pointer, wl_touch, etc) used for the resize. It is up to the - * compositor to visually indicate that the resize is taking place, - * such as updating a pointer cursor, during the resize. There is no - * guarantee that the device focus will return when the resize is - * completed. - * - * The edges parameter specifies how the surface should be resized, - * and is one of the values of the resize_edge enum. The compositor - * may use this information to update the surface position for - * example when dragging the top left corner. The compositor may also - * use this information to adapt its behavior, e.g. choose an - * appropriate cursor image. - */ -static inline void -xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_RESIZE, seat, serial, edges); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a maximum size for the window. - * - * The client can specify a maximum size so that the compositor does - * not try to configure the window beyond this size. - * - * The width and height arguments are in window geometry coordinates. - * See xdg_surface.set_window_geometry. - * - * Values set in this way are double-buffered. They will get applied - * on the next commit. - * - * The compositor can use this information to allow or disallow - * different states like maximize or fullscreen and draw accurate - * animations. - * - * Similarly, a tiling window manager may use this information to - * place and resize client windows in a more effective way. - * - * The client should not rely on the compositor to obey the maximum - * size. The compositor may decide to ignore the values set by the - * client and request a larger size. - * - * If never set, or a value of zero in the request, means that the - * client has no expected maximum size in the given dimension. - * As a result, a client wishing to reset the maximum size - * to an unspecified state can use zero for width and height in the - * request. - * - * Requesting a maximum size to be smaller than the minimum size of - * a surface is illegal and will result in a protocol error. - * - * The width and height must be greater than or equal to zero. Using - * strictly negative values for width and height will result in a - * protocol error. - */ -static inline void -xdg_toplevel_set_max_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MAX_SIZE, width, height); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Set a minimum size for the window. - * - * The client can specify a minimum size so that the compositor does - * not try to configure the window below this size. - * - * The width and height arguments are in window geometry coordinates. - * See xdg_surface.set_window_geometry. - * - * Values set in this way are double-buffered. They will get applied - * on the next commit. - * - * The compositor can use this information to allow or disallow - * different states like maximize or fullscreen and draw accurate - * animations. - * - * Similarly, a tiling window manager may use this information to - * place and resize client windows in a more effective way. - * - * The client should not rely on the compositor to obey the minimum - * size. The compositor may decide to ignore the values set by the - * client and request a smaller size. - * - * If never set, or a value of zero in the request, means that the - * client has no expected minimum size in the given dimension. - * As a result, a client wishing to reset the minimum size - * to an unspecified state can use zero for width and height in the - * request. - * - * Requesting a minimum size to be larger than the maximum size of - * a surface is illegal and will result in a protocol error. - * - * The width and height must be greater than or equal to zero. Using - * strictly negative values for width and height will result in a - * protocol error. - */ -static inline void -xdg_toplevel_set_min_size(struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MIN_SIZE, width, height); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Maximize the surface. - * - * After requesting that the surface should be maximized, the compositor - * will respond by emitting a configure event. Whether this configure - * actually sets the window maximized is subject to compositor policies. - * The client must then update its content, drawing in the configured - * state. The client must also acknowledge the configure when committing - * the new content (see ack_configure). - * - * It is up to the compositor to decide how and where to maximize the - * surface, for example which output and what region of the screen should - * be used. - * - * If the surface was already maximized, the compositor will still emit - * a configure event with the "maximized" state. - * - * If the surface is in a fullscreen state, this request has no direct - * effect. It may alter the state the surface is returned to when - * unmaximized unless overridden by the compositor. - */ -static inline void -xdg_toplevel_set_maximized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MAXIMIZED); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Unmaximize the surface. - * - * After requesting that the surface should be unmaximized, the compositor - * will respond by emitting a configure event. Whether this actually - * un-maximizes the window is subject to compositor policies. - * If available and applicable, the compositor will include the window - * geometry dimensions the window had prior to being maximized in the - * configure event. The client must then update its content, drawing it in - * the configured state. The client must also acknowledge the configure - * when committing the new content (see ack_configure). - * - * It is up to the compositor to position the surface after it was - * unmaximized; usually the position the surface had before maximizing, if - * applicable. - * - * If the surface was already not maximized, the compositor will still - * emit a configure event without the "maximized" state. - * - * If the surface is in a fullscreen state, this request has no direct - * effect. It may alter the state the surface is returned to when - * unmaximized unless overridden by the compositor. - */ -static inline void -xdg_toplevel_unset_maximized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_UNSET_MAXIMIZED); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Make the surface fullscreen. - * - * After requesting that the surface should be fullscreened, the - * compositor will respond by emitting a configure event. Whether the - * client is actually put into a fullscreen state is subject to compositor - * policies. The client must also acknowledge the configure when - * committing the new content (see ack_configure). - * - * The output passed by the request indicates the client's preference as - * to which display it should be set fullscreen on. If this value is NULL, - * it's up to the compositor to choose which display will be used to map - * this surface. - * - * If the surface doesn't cover the whole output, the compositor will - * position the surface in the center of the output and compensate with - * with border fill covering the rest of the output. The content of the - * border fill is undefined, but should be assumed to be in some way that - * attempts to blend into the surrounding area (e.g. solid black). - * - * If the fullscreened surface is not opaque, the compositor must make - * sure that other screen content not part of the same surface tree (made - * up of subsurfaces, popups or similarly coupled surfaces) are not - * visible below the fullscreened surface. - */ -static inline void -xdg_toplevel_set_fullscreen(struct xdg_toplevel *xdg_toplevel, struct wl_output *output) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_FULLSCREEN, output); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Make the surface no longer fullscreen. - * - * After requesting that the surface should be unfullscreened, the - * compositor will respond by emitting a configure event. - * Whether this actually removes the fullscreen state of the client is - * subject to compositor policies. - * - * Making a surface unfullscreen sets states for the surface based on the following: - * * the state(s) it may have had before becoming fullscreen - * * any state(s) decided by the compositor - * * any state(s) requested by the client while the surface was fullscreen - * - * The compositor may include the previous window geometry dimensions in - * the configure event, if applicable. - * - * The client must also acknowledge the configure when committing the new - * content (see ack_configure). - */ -static inline void -xdg_toplevel_unset_fullscreen(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_UNSET_FULLSCREEN); -} - -/** - * @ingroup iface_xdg_toplevel - * - * Request that the compositor minimize your surface. There is no - * way to know if the surface is currently minimized, nor is there - * any way to unset minimization on this surface. - * - * If you are looking to throttle redrawing when minimized, please - * instead use the wl_surface.frame event for this, as this will - * also work with live previews on windows in Alt-Tab, Expose or - * similar compositor features. - */ -static inline void -xdg_toplevel_set_minimized(struct xdg_toplevel *xdg_toplevel) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_toplevel, - XDG_TOPLEVEL_SET_MINIMIZED); -} - -#ifndef XDG_POPUP_ERROR_ENUM -#define XDG_POPUP_ERROR_ENUM -enum xdg_popup_error { - /** - * tried to grab after being mapped - */ - XDG_POPUP_ERROR_INVALID_GRAB = 0, -}; -#endif /* XDG_POPUP_ERROR_ENUM */ - -/** - * @ingroup iface_xdg_popup - * @struct xdg_popup_listener - */ -struct xdg_popup_listener { - /** - * configure the popup surface - * - * This event asks the popup surface to configure itself given - * the configuration. The configured state should not be applied - * immediately. See xdg_surface.configure for details. - * - * The x and y arguments represent the position the popup was - * placed at given the xdg_positioner rule, relative to the upper - * left corner of the window geometry of the parent surface. - * @param x x position relative to parent surface window geometry - * @param y y position relative to parent surface window geometry - * @param width window geometry width - * @param height window geometry height - */ - void (*configure)(void *data, - struct xdg_popup *xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height); - /** - * popup interaction is done - * - * The popup_done event is sent out when a popup is dismissed by - * the compositor. The client should destroy the xdg_popup object - * at this point. - */ - void (*popup_done)(void *data, - struct xdg_popup *xdg_popup); -}; - -/** - * @ingroup iface_xdg_popup - */ -static inline int -xdg_popup_add_listener(struct xdg_popup *xdg_popup, - const struct xdg_popup_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) xdg_popup, - (void (**)(void)) listener, data); -} - -#define XDG_POPUP_DESTROY 0 -#define XDG_POPUP_GRAB 1 - -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_POPUP_DONE_SINCE_VERSION 1 - -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_DESTROY_SINCE_VERSION 1 -/** - * @ingroup iface_xdg_popup - */ -#define XDG_POPUP_GRAB_SINCE_VERSION 1 - -/** @ingroup iface_xdg_popup */ -static inline void -xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data); -} - -/** @ingroup iface_xdg_popup */ -static inline void * -xdg_popup_get_user_data(struct xdg_popup *xdg_popup) -{ - return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup); -} - -static inline uint32_t -xdg_popup_get_version(struct xdg_popup *xdg_popup) -{ - return wl_proxy_get_version((struct wl_proxy *) xdg_popup); -} - -/** - * @ingroup iface_xdg_popup - * - * This destroys the popup. Explicitly destroying the xdg_popup - * object will also dismiss the popup, and unmap the surface. - * - * If this xdg_popup is not the "topmost" popup, a protocol error - * will be sent. - */ -static inline void -xdg_popup_destroy(struct xdg_popup *xdg_popup) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_popup, - XDG_POPUP_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) xdg_popup); -} - -/** - * @ingroup iface_xdg_popup - * - * This request makes the created popup take an explicit grab. An explicit - * grab will be dismissed when the user dismisses the popup, or when the - * client destroys the xdg_popup. This can be done by the user clicking - * outside the surface, using the keyboard, or even locking the screen - * through closing the lid or a timeout. - * - * If the compositor denies the grab, the popup will be immediately - * dismissed. - * - * This request must be used in response to some sort of user action like a - * button press, key press, or touch down event. The serial number of the - * event should be passed as 'serial'. - * - * The parent of a grabbing popup must either be an xdg_toplevel surface or - * another xdg_popup with an explicit grab. If the parent is another - * xdg_popup it means that the popups are nested, with this popup now being - * the topmost popup. - * - * Nested popups must be destroyed in the reverse order they were created - * in, e.g. the only popup you are allowed to destroy at all times is the - * topmost one. - * - * When compositors choose to dismiss a popup, they may dismiss every - * nested grabbing popup as well. When a compositor dismisses popups, it - * will follow the same dismissing order as required from the client. - * - * The parent of a grabbing popup must either be another xdg_popup with an - * active explicit grab, or an xdg_popup or xdg_toplevel, if there are no - * explicit grabs already taken. - * - * If the topmost grabbing popup is destroyed, the grab will be returned to - * the parent of the popup, if that parent previously had an explicit grab. - * - * If the parent is a grabbing popup which has already been dismissed, this - * popup will be immediately dismissed. If the parent is a popup that did - * not take an explicit grab, an error will be raised. - * - * During a popup grab, the client owning the grab will receive pointer - * and touch events for all their surfaces as normal (similar to an - * "owner-events" grab in X11 parlance), while the top most grabbing popup - * will always have keyboard focus. - */ -static inline void -xdg_popup_grab(struct xdg_popup *xdg_popup, struct wl_seat *seat, uint32_t serial) -{ - wl_proxy_marshal((struct wl_proxy *) xdg_popup, - XDG_POPUP_GRAB, seat, serial); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/vendor/gioui.org/app/internal/window/window.go b/vendor/gioui.org/app/internal/window/window.go deleted file mode 100644 index 30ba360..0000000 --- a/vendor/gioui.org/app/internal/window/window.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -// Package window implements platform specific windows -// and GPU contexts. -package window - -import ( - "errors" - - "gioui.org/gpu/backend" - "gioui.org/io/event" - "gioui.org/io/system" - "gioui.org/unit" -) - -type Options struct { - Width, Height unit.Value - MinWidth, MinHeight unit.Value - MaxWidth, MaxHeight unit.Value - Title string -} - -type FrameEvent struct { - system.FrameEvent - - Sync bool -} - -type Callbacks interface { - SetDriver(d Driver) - Event(e event.Event) -} - -type Context interface { - Backend() (backend.Device, error) - Present() error - MakeCurrent() error - Release() - Lock() - Unlock() -} - -// ErrDeviceLost is returned from Context.Present when -// the underlying GPU device is gone and should be -// recreated. -var ErrDeviceLost = errors.New("GPU device lost") - -// Driver is the interface for the platform implementation -// of a window. -type Driver interface { - // SetAnimating sets the animation flag. When the window is animating, - // FrameEvents are delivered as fast as the display can handle them. - SetAnimating(anim bool) - // ShowTextInput updates the virtual keyboard state. - ShowTextInput(show bool) - NewContext() (Context, error) - - // ReadClipboard requests the clipboard content. - ReadClipboard() - // WriteClipboard requests a clipboard write. - WriteClipboard(s string) - - // Close the window. - Close() -} - -type windowRendezvous struct { - in chan windowAndOptions - out chan windowAndOptions - errs chan error -} - -type windowAndOptions struct { - window Callbacks - opts *Options -} - -func newWindowRendezvous() *windowRendezvous { - wr := &windowRendezvous{ - in: make(chan windowAndOptions), - out: make(chan windowAndOptions), - errs: make(chan error), - } - go func() { - var main windowAndOptions - var out chan windowAndOptions - for { - select { - case w := <-wr.in: - var err error - if main.window != nil { - err = errors.New("multiple windows are not supported") - } - wr.errs <- err - main = w - out = wr.out - case out <- main: - } - } - }() - return wr -} |