github.com/rajveermalviya/gamen@v0.1.2-0.20220930195403-9be15877c1aa/internal/xcb/cursor.go (about)

     1  //go:build linux && !android
     2  
     3  package xcb
     4  
     5  /*
     6  
     7  #include <stdlib.h>
     8  #include <X11/Xlib-xcb.h>
     9  #include <xcb/xcb_image.h>
    10  #include <X11/Xcursor/Xcursor.h>
    11  
    12  */
    13  import "C"
    14  import (
    15  	"unsafe"
    16  
    17  	"github.com/rajveermalviya/gamen/cursors"
    18  	"github.com/rajveermalviya/gamen/internal/common/xcursor"
    19  )
    20  
    21  func (d *Display) createEmptyCursor() C.xcb_cursor_t {
    22  	var buf [32]C.uint8_t
    23  
    24  	root := d.screens[0].xcbScreen.root
    25  
    26  	source := d.l.xcb_create_pixmap_from_bitmap_data(d.xcbConn,
    27  		root,
    28  		(*C.uint8_t)(unsafe.Pointer(&buf)),
    29  		16, 16,
    30  		1,
    31  		0, 0,
    32  		nil,
    33  	)
    34  	defer d.l.xcb_free_pixmap(d.xcbConn, source)
    35  
    36  	mask := d.l.xcb_create_pixmap_from_bitmap_data(d.xcbConn,
    37  		root,
    38  		(*C.uint8_t)(unsafe.Pointer(&buf)),
    39  		16, 16,
    40  		1,
    41  		0, 0,
    42  		nil,
    43  	)
    44  	defer d.l.xcb_free_pixmap(d.xcbConn, mask)
    45  
    46  	cursorId := d.l.xcb_generate_id(d.xcbConn)
    47  	d.l.xcb_create_cursor(d.xcbConn,
    48  		cursorId,
    49  		source, mask,
    50  		0, 0, 0,
    51  		0xFFFF, 0xFFFF, 0xFFFF,
    52  		8, 8,
    53  	)
    54  	return cursorId
    55  }
    56  
    57  func (d *Display) loadXCursor(name string) C.xcb_cursor_t {
    58  	nameStr := C.CString(name)
    59  	defer C.free(unsafe.Pointer(nameStr))
    60  
    61  	cursor := d.l.XcursorLibraryLoadCursor(d.xlibDisp, nameStr)
    62  	return C.xcb_cursor_t(cursor)
    63  }
    64  
    65  func (d *Display) loadCursorIcon(icon cursors.Icon) C.xcb_cursor_t {
    66  	d.mu.Lock()
    67  	defer d.mu.Unlock()
    68  
    69  	c, ok := d.cursors[icon]
    70  	if ok {
    71  		return c
    72  	}
    73  
    74  	if icon == 0 {
    75  		c = d.createEmptyCursor()
    76  		d.cursors[icon] = c
    77  		return c
    78  	}
    79  
    80  	for _, name := range xcursor.ToXcursorName(icon) {
    81  		c = d.loadXCursor(name)
    82  		if c != 0 {
    83  			break
    84  		}
    85  	}
    86  
    87  	d.cursors[icon] = c
    88  	return c
    89  }