sample image:

The PNG file needs to be square (equal width and height), I think it also has to be 16*16, 32*32, 64*64 etc, only. Any transparent pixels in the PNG will be transparent in the cursor, also only black and white colors are allowed.
Code: Select all
Procedure.i Cursor_From_PNG(pngfile.s, hx, hy)
;hx and hy are the "hot spot" for the pointer.
png = LoadImage(#PB_Any, pngfile.s)
w = ImageWidth(png)
h = ImageHeight(png)
*pngsrc = AllocateMemory(w*h/8) ;the source (1 bit per pixel, 1 byte for 8 pixels)
*pngmsk = AllocateMemory(w*h/8) ;image mask for the source
StartDrawing(ImageOutput(png))
DrawingMode(#PB_2DDrawing_AlphaBlend) ;we need the alpha chanel to make the mask.
For a = 1 To w * h Step 8
srcbyte.s = "" ;reset the binary strings
mskbyte.s = ""
For b = 0 To 7 ; 8 pixels
x = (a + b) % w : If x = 0 : x = w : EndIf ;calculate x
y = (a + b) / w : If x <> w : y + 1 : EndIf ;calculate y
c.l = Point(x-1, y-1)
If Alpha(c) <> 0 ;this is solid?
;we are assuming that this image is only black and white, so we'll use the red value to check color.
If Red(c) <> 0
srcbyte.s + "1"
Else
srcbyte.s + "0"
EndIf
mskbyte.s + "1"
Else
srcbyte + "0"
mskbyte + "0"
EndIf
Next
;fix endian problem
srcbyte.s = ReverseString(srcbyte.s)
mskbyte.s = ReverseString(mskbyte.s)
;byte = binary string
sbyte.b = Val("%" + srcbyte.s)
mbyte.b = Val("%" + mskbyte.s)
;write the byte to the pointer
PokeB(*pngsrc + (a / 8), sbyte.b)
PokeB(*pngmsk + (a / 8), mbyte.b)
Next
StopDrawing()
fg.GdkColor ;white color
fg\red = 65535
fg\green = 65535
fg\blue = 65535
bg.GdkColor ;black color
src = gdk_bitmap_create_from_data_(#Null, *pngsrc, w, h)
msk = gdk_bitmap_create_from_data_(#Null, *pngmsk, w, h)
*mycursor = gdk_cursor_new_from_pixmap_(src, msk, @fg, @bg, hx, hy)
ProcedureReturn *mycursor
EndProcedure
Main_Window = OpenWindow(#PB_Any, 50, 50, 512, 512, "Cursor Test")
;create a Gdk Pointer to the Widget\Window
*Widget.GtkWidget = WindowID(Main_Window)
*GdkWindow = *Widget\Window
*cur_sword = Cursor_From_PNG("sword.png", 0, 0)
;set the cursor
gdk_window_set_cursor_(*GdkWindow , *cur_sword)
Repeat
WE = WaitWindowEvent()
Delay(10)
Until WE = #PB_Event_CloseWindow