gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/app/os_unix.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  //go:build (linux && !android) || freebsd || openbsd
     4  // +build linux,!android freebsd openbsd
     5  
     6  package app
     7  
     8  import (
     9  	"errors"
    10  	"unsafe"
    11  
    12  	"gioui.org/io/event"
    13  	"gioui.org/io/pointer"
    14  )
    15  
    16  type X11ViewEvent struct {
    17  	// Display is a pointer to the X11 Display created by XOpenDisplay.
    18  	Display unsafe.Pointer
    19  	// Window is the X11 window ID as returned by XCreateWindow.
    20  	Window uintptr
    21  }
    22  
    23  func (X11ViewEvent) implementsViewEvent() {}
    24  func (X11ViewEvent) ImplementsEvent()     {}
    25  
    26  type WaylandViewEvent struct {
    27  	// Display is the *wl_display returned by wl_display_connect.
    28  	Display unsafe.Pointer
    29  	// Surface is the *wl_surface returned by wl_compositor_create_surface.
    30  	Surface unsafe.Pointer
    31  }
    32  
    33  func (WaylandViewEvent) implementsViewEvent() {}
    34  func (WaylandViewEvent) ImplementsEvent()     {}
    35  
    36  func osMain() {
    37  	select {}
    38  }
    39  
    40  type windowDriver func(*callbacks, []Option) error
    41  
    42  // Instead of creating files with build tags for each combination of wayland +/- x11
    43  // let each driver initialize these variables with their own version of createWindow.
    44  var wlDriver, x11Driver windowDriver
    45  
    46  func newWindow(window *callbacks, options []Option) {
    47  	var errFirst error
    48  	for _, d := range []windowDriver{wlDriver, x11Driver} {
    49  		if d == nil {
    50  			continue
    51  		}
    52  		err := d(window, options)
    53  		if err == nil {
    54  			return
    55  		}
    56  		if errFirst == nil {
    57  			errFirst = err
    58  		}
    59  	}
    60  	window.SetDriver(&dummyDriver{
    61  		win:     window,
    62  		wakeups: make(chan event.Event, 1),
    63  	})
    64  	if errFirst == nil {
    65  		errFirst = errors.New("app: no window driver available")
    66  	}
    67  	window.ProcessEvent(DestroyEvent{Err: errFirst})
    68  }
    69  
    70  type dummyDriver struct {
    71  	win     *callbacks
    72  	wakeups chan event.Event
    73  }
    74  
    75  func (d *dummyDriver) Event() event.Event {
    76  	if e, ok := d.win.nextEvent(); ok {
    77  		return e
    78  	}
    79  	return <-d.wakeups
    80  }
    81  
    82  func (d *dummyDriver) Invalidate() {
    83  	select {
    84  	case d.wakeups <- wakeupEvent{}:
    85  	default:
    86  	}
    87  }
    88  
    89  // xCursor contains mapping from pointer.Cursor to XCursor.
    90  var xCursor = [...]string{
    91  	pointer.CursorDefault:                  "left_ptr",
    92  	pointer.CursorNone:                     "",
    93  	pointer.CursorText:                     "xterm",
    94  	pointer.CursorVerticalText:             "vertical-text",
    95  	pointer.CursorPointer:                  "hand2",
    96  	pointer.CursorCrosshair:                "crosshair",
    97  	pointer.CursorAllScroll:                "fleur",
    98  	pointer.CursorColResize:                "sb_h_double_arrow",
    99  	pointer.CursorRowResize:                "sb_v_double_arrow",
   100  	pointer.CursorGrab:                     "hand1",
   101  	pointer.CursorGrabbing:                 "move",
   102  	pointer.CursorNotAllowed:               "crossed_circle",
   103  	pointer.CursorWait:                     "watch",
   104  	pointer.CursorProgress:                 "left_ptr_watch",
   105  	pointer.CursorNorthWestResize:          "top_left_corner",
   106  	pointer.CursorNorthEastResize:          "top_right_corner",
   107  	pointer.CursorSouthWestResize:          "bottom_left_corner",
   108  	pointer.CursorSouthEastResize:          "bottom_right_corner",
   109  	pointer.CursorNorthSouthResize:         "sb_v_double_arrow",
   110  	pointer.CursorEastWestResize:           "sb_h_double_arrow",
   111  	pointer.CursorWestResize:               "left_side",
   112  	pointer.CursorEastResize:               "right_side",
   113  	pointer.CursorNorthResize:              "top_side",
   114  	pointer.CursorSouthResize:              "bottom_side",
   115  	pointer.CursorNorthEastSouthWestResize: "fd_double_arrow",
   116  	pointer.CursorNorthWestSouthEastResize: "bd_double_arrow",
   117  }