Segnalatore del puntatore del mouse sullo schermo usando le funzioni esterne del API di X11

Da Gambas-it.org - Wikipedia.

Il seguente programma a riga di comando produrrà uno speciale effetto grafico di cerchi concentrici rispetto al puntatore del mouse ovunque venga spostato e ovunque si trovi sul desktop.
Il programma potrà essere terminato nelle modalità consuete. E' preferibile, anche al fine di liberare la memoria occupata dalle risorse della libreria di X11, di premere - dopo aver cliccato nella console/Terminale - il tasto "Invio" della tastiera.

Mostriamo un esempio pratico.
(Qualora si dovesse riscontrare qualche problema nella definizione del disegno della pulsazione, si può provare ad aumentare o diminuire il valore della Costante "RITARDO".)

Private tempus As Timer
Private dsp As Pointer
Private grcnt As Pointer
Private win As Integer
Private Const RITARDO As Short = 1000
Private Const SPESSORE As Byte = 3          ' Imposta lo spessore della circonferenza dei cerchi concentrici
Private Const DISTANZA_CERCHI As Byte = 40  ' Imposta la distanza fra i cerchi concentrici


Library "libX11:6.4.0"

Private Const IncludeInferiors As Integer = 1
Private Const CapButt As Integer = 1
Private Const LineSolid As Integer = 0
Private Const JoinRound As Integer = 1
Private Const GXxor As Integer = 6

' Display *XOpenDisplay(char *display_name)
' Opens a connection to the X server that controls a display.
Private Extern XOpenDisplay(display_name As Pointer) As Pointer

' int XDefaultScreen (Display *display)
' Returns the default screen number referenced by the XOpenDisplay function.
Private Extern XDefaultScreen(display As Pointer) As Integer

' Window XRootWindow(Display *display, int screen_number)
' Returns the root window.
Private Extern XRootWindow(display As Pointer, screen_number As Integer) As Integer

' GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values)
' Creates a graphics context and returns a GC.
Private Extern XCreateGC(display As Pointer, d As Integer, valuemask As Long, values As Pointer) As Pointer

' XSetForeground (Display *display, GC gc, unsigned long foreground)
' Sets the foreground.
Private Extern XSetForeground(display As Pointer, gc As Pointer, foreground As Long)

' XSetSubwindowMode(Display *display, GC gc, int subwindow_mode)
' Sets the subwindow mode in the specified GC.
Private Extern XSetSubwindowMode(display As Pointer, gc As Pointer, subwindow_mode As Integer)

' XSetLineAttributes(Display *display, GC gc, unsigned int spessore, int line_style, int cap_style, int join_style)
' Sets the line drawing components in the specified GC.
Private Extern XSetLineAttributes(display As Pointer, gc As Pointer, spessore As Integer, line_style As Integer, cap_style As Integer, join_style As Integer)

' int XSetFunction(Display *display, GC gc, int function)
' Sets a specified value in the specified GC.
Private Extern XSetFunction(display As Pointer, gc As Pointer, ifunction As Integer) As Integer

' int XGrabServer(Display *display)
' Disables processing of requests and close downs on all other connections than the one this request arrived on.
Private Extern XGrabServer(display As Pointer) As Integer

' int XDrawArc(Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height, int angle1, int angle2)
' Draws a single circular or elliptical arc.
Private Extern XDrawArc(display As Pointer, d As Integer, gc As Pointer, x As Integer, y As Integer, width As Integer, height As Integer, angle1 As Integer, angle2 As Integer) As Integer

' Bool XQueryPointer(Display *display, Window w, Window *root_return, Window *child_return, int *root_x_return, int *root_y_return, int *win_x_return, int *win_y_return, unsigned int *mask_return)
' Returns the root window the pointer is logically on and the pointer coordinates relative to the root window's origin.
Private Extern XQueryPointer(display As Pointer, w As Integer, root_return As Pointer, child_return As Pointer, root_x_return As Pointer, root_y_return As Pointer, win_x_return As Pointer, win_y_return As Pointer, mask_return As Pointer) As Boolean

' int XFlush(Display *display)
' Flushes the output buffer.
Private Extern XFlush(display As Pointer) As Integer

' int XUngrabServer(Display *display)
' Restarts processing of requests and close downs on other connections.
Private Extern XUngrabServer(display As Pointer) As Integer

' int XCloseDisplay(Display *display)
' Closes the connection to the X server for the display specified in the Display structure and destroys all windows.
Private Extern XCloseDisplay(display As Pointer) As Integer


Public Sub Main()

 Dim scr As Integer
 
 dsp = XOpenDisplay(0)
 If dsp == 0 Then Error.Raise("Impossibile connettersi al server X !")
   
 scr = XDefaultScreen(dsp)
 win = XRootWindow(dsp, scr)

' Crea un contesto grafico X:
 grcnt = XCreateGC(dsp, win, 0, 0)
 If grcnt == 0 Then Error.Raise("Impossibile creare un contesto grafico X !")

 XSetForeground(dsp, grcnt, &0000FFFF)
 XSetSubwindowMode(dsp, grcnt, IncludeInferiors)
 XSetLineAttributes(dsp, grcnt, SPESSORE, LineSolid, CapButt, JoinRound)
 XSetFunction(dsp, grcnt, GXxor)

 With tempus = New Timer As "Tempus"
   .Delay = RITARDO
   .Start
 End With

End

Public Sub Tempus_Timer()

 Dim rag, raggio, dist_archi As Integer
 Dim rr, cr, x, y, xr, yr, mr As Integer
 Dim sh As Short

' Imposta il raggio del cerchio più esterno:
 raggio = 400

 Repeat
   raggio -= DISTANZA_CERCHI
   If rag Then
     XDrawArc(dsp, win, grcnt, x - rag / 2, y - rag / 2, rag, rag, 0, 360 * 64)
   Endif
  If raggio > 0 Then
     XQueryPointer(dsp, win, VarPtr(rr), VarPtr(cr), VarPtr(x), VarPtr(y), VarPtr(xr), VarPtr(yr), VarPtr(mr))
     XDrawArc(dsp, win, grcnt, x - raggio / 2, y - raggio / 2, raggio, raggio, 0, 360 * 64)
   Endif
   XFlush(dsp)
   Wait 0.016
   rag = raggio
   XUngrabServer(dsp)  
   Inc sh
   If sh == RITARDO Then
     sh = 0
     XGrabServer(dsp)
   Endif
 Until raggio < 0

End

Public Sub Application_Read()

 XUngrabServer(dsp)
 XCloseDisplay(dsp)
 Quit

End