github.com/jmigpin/editor@v1.6.0/driver/xdriver/xcursors/cursors.go (about)

     1  package xcursors
     2  
     3  import (
     4  	"image/color"
     5  
     6  	"github.com/BurntSushi/xgb"
     7  	"github.com/BurntSushi/xgb/xproto"
     8  	"github.com/jmigpin/editor/util/imageutil"
     9  )
    10  
    11  // https://tronche.com/gui/x/xlib/appendix/b/
    12  
    13  type Cursors struct {
    14  	conn *xgb.Conn
    15  	win  xproto.Window
    16  	m    map[Cursor]xproto.Cursor
    17  }
    18  
    19  func NewCursors(conn *xgb.Conn, win xproto.Window) (*Cursors, error) {
    20  	cs := &Cursors{
    21  		conn: conn,
    22  		win:  win,
    23  		m:    make(map[Cursor]xproto.Cursor),
    24  	}
    25  	return cs, nil
    26  }
    27  func (cs *Cursors) SetCursor(c Cursor) error {
    28  	xc, ok := cs.m[c]
    29  	if !ok {
    30  		xc2, err := cs.loadCursor(c)
    31  		if err != nil {
    32  			return err
    33  		}
    34  		cs.m[c] = xc2
    35  		xc = xc2
    36  	}
    37  	mask := uint32(xproto.CwCursor)
    38  	values := []uint32{uint32(xc)}
    39  	_ = xproto.ChangeWindowAttributes(cs.conn, cs.win, mask, values)
    40  	return nil
    41  }
    42  func (cs *Cursors) loadCursor(c Cursor) (xproto.Cursor, error) {
    43  	return cs.loadCursor2(c, color.Black, color.White)
    44  }
    45  func (cs *Cursors) loadCursor2(c Cursor, fg, bg color.Color) (xproto.Cursor, error) {
    46  	if c == XCNone {
    47  		return 0, nil
    48  	}
    49  	fontId, err := xproto.NewFontId(cs.conn)
    50  	if err != nil {
    51  		return 0, err
    52  	}
    53  	cursor, err := xproto.NewCursorId(cs.conn)
    54  	if err != nil {
    55  		return 0, err
    56  	}
    57  	name := "cursor"
    58  	err = xproto.OpenFontChecked(cs.conn, fontId, uint16(len(name)), name).Check()
    59  	if err != nil {
    60  		return 0, err
    61  	}
    62  
    63  	// colors
    64  	ur, ug, ub, _ := imageutil.ColorUint16s(fg)
    65  	vr, vg, vb, _ := imageutil.ColorUint16s(bg)
    66  
    67  	err = xproto.CreateGlyphCursorChecked(
    68  		cs.conn, cursor,
    69  		fontId, fontId,
    70  		uint16(c), uint16(c)+1,
    71  		ur, ug, ub,
    72  		vr, vg, vb).Check()
    73  	if err != nil {
    74  		return 0, err
    75  	}
    76  
    77  	err = xproto.CloseFontChecked(cs.conn, fontId).Check()
    78  	if err != nil {
    79  		return 0, err
    80  	}
    81  
    82  	return cursor, nil
    83  }
    84  
    85  type Cursor uint16
    86  
    87  // Just to distinguish from the other cursors (uint16) to reset to parent window cursor. Value after last x cursor at 152.
    88  const XCNone = 200
    89  
    90  const (
    91  	XCursor           = 0
    92  	Arrow             = 2
    93  	BasedArrowDown    = 4
    94  	BasedArrowUp      = 6
    95  	Boat              = 8
    96  	Bogosity          = 10
    97  	BottomLeftCorner  = 12
    98  	BottomRightCorner = 14
    99  	BottomSide        = 16
   100  	BottomTee         = 18
   101  	BoxSpiral         = 20
   102  	CenterPtr         = 22
   103  	Circle            = 24
   104  	Clock             = 26
   105  	CoffeeMug         = 28
   106  	Cross             = 30
   107  	CrossReverse      = 32
   108  	Crosshair         = 34
   109  	DiamondCross      = 36
   110  	Dot               = 38
   111  	DotBoxMask        = 40
   112  	DoubleArrow       = 42
   113  	DraftLarge        = 44
   114  	DraftSmall        = 46
   115  	DrapedBox         = 48
   116  	Exchange          = 50
   117  	Fleur             = 52
   118  	Gobbler           = 54
   119  	Gumby             = 56
   120  	Hand1             = 58
   121  	Hand2             = 60
   122  	Heart             = 62
   123  	Icon              = 64
   124  	IronCross         = 66
   125  	LeftPtr           = 68
   126  	LeftSide          = 70
   127  	LeftTee           = 72
   128  	LeftButton        = 74
   129  	LLAngle           = 76
   130  	LRAngle           = 78
   131  	Man               = 80
   132  	MiddleButton      = 82
   133  	Mouse             = 84
   134  	Pencil            = 86
   135  	Pirate            = 88
   136  	Plus              = 90
   137  	QuestionArrow     = 92
   138  	RightPtr          = 94
   139  	RightSide         = 96
   140  	RightTee          = 98
   141  	RightButton       = 100
   142  	RtlLogo           = 102
   143  	Sailboat          = 104
   144  	SBDownArrow       = 106
   145  	SBHDoubleArrow    = 108
   146  	SBLeftArrow       = 110
   147  	SBRightArrow      = 112
   148  	SBUpArrow         = 114
   149  	SBVDoubleArrow    = 116
   150  	Shuttle           = 118
   151  	Sizing            = 120
   152  	Spider            = 122
   153  	Spraycan          = 124
   154  	Star              = 126
   155  	Target            = 128
   156  	TCross            = 130
   157  	TopLeftArrow      = 132
   158  	TopLeftCorner     = 134
   159  	TopRightCorner    = 136
   160  	TopSide           = 138
   161  	TopTee            = 140
   162  	Trek              = 142
   163  	ULAngle           = 144
   164  	Umbrella          = 146
   165  	URAngle           = 148
   166  	Watch             = 150
   167  	XTerm             = 152
   168  )