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 }