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 }