[Linux] Cursor_From_PNG
Posted: Mon Feb 22, 2010 1:57 am
To make it easier to have custom cursors in a Linux game I'm working on, I decided to write my own Procedure which does so from a PNG file.
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.
Feel free to post any alterations you feel may be beneficial to the Linux PB community.
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