Intercettare i dati del mouse dai file-device mouse, mice, event
E' possibile intercettare i dati del mouse dai file-device:
- /dev/input/mouse(n)
- /dev/input/mice
- /dev/input/event(n)
laddove (n) è un numero d'indice.
Questa modalità ci consente di raccogliere i dati del mouse, pur stando con il suo puntatore al di fuori del Form del programma.gambas, oppure nel caso in cui lanciamo un'applicazione Gambas "a riga di comando" dal Terminale.
Bisogna ricordare che, essendo i predetti file-device del mouse protetti, dovremo ottenere preliminarmente i necessari permessi per la loro gestione.
Indice
Gestione mediante il file-device /dev/input/mouseN
Apertura del file-device mediante la Classe Process
Una modalità prevede l'apertura e la gestione del file-device /dev/input/mouseN mediante la Classe Process; laddove la "N" finale del file-device qui posta, rappresenta un numero progressivo.
Dopo aver lanciato il seguente codice, spostando molto lentamente il mouse senza cliccare alcun tasto, si vedrà spostare il Form coerentemente al verso dello spostamento del mouse. Tale azione verrà rilevata nella Label posta sul Form.
Se si clicca su un tasto, tale azione verrà rilevata nella Label. In particolare, rilasciando un qualsiasi tasto del mouse, si otterrà la chiusura del programma.
Private pr As Process Public Sub Form_Open() ' Se i permessi del file-device del mouse non consentono almeno la lettura del file-device... If Stat("/dev/input/mouse0").Auth <> "rwsrwxrwx" Then ' ...allora li modifichiamo. E' necessario passare la nostra PASSWORD: Shell "echo " & InputBox("Immettere la propria password !") & " | sudo -S chmod 444 '/dev/input/mouse0'" Wait Endif ' Modificati i permessi, potremo accedere al file-device del mouse e gestirlo in "lettura": pr = Shell "cat /dev/input/mouse0" For Read As "Processo" End Public Sub Processo_Read() Dim s As String Dim i As Integer ' Leggiamo non più di 4 dati-carattere dal file-device del mouse. ' Il segno negativo impedisce di causare l'errore "Fine del file". Read #pr, s, -4 ' Poiché una variabile stringa è comunque un puntatore ad un'area riservata, dereferenziamo detta variabile con l'apposita funzione di dereferenziazione che restituisce un tipo "Intero", e ne andiamo a leggere il valore: i = Int@(s) Select Case i ' [Nota 1] Case 16711720 ' spostamento in basso Label1.Alignment = Align.Bottom Label1.Text = "in basso" Case 65544 ' spostamento in alto Label1.Alignment = Align.Top Label1.Text = "in alto" Case 264 ' spostamento a destra Label1.Alignment = Align.Right Label1.Text = "a destra" Case 65304 ' spostamento a sinistra Label1.Alignment = Align.Left Label1.Text = "a sinistra" Case 9 ' premuto tasto sinistro Label1.Alignment = Align.Center Label1.Text = "tasto Sinistro" Case 10 ' premuto tasto destro Label1.Alignment = Align.Center Label1.Text = "tasto Destro" Case 12 ' premuto tasto centrale Label1.Alignment = Align.Center Label1.Text = "tasto Centrale" Case 8 ' qualsiasi tasto rilasciato Label1.Alignment = Align.Center Label1.Text = "tasto Rilasciato" Me.Close Return End Select Me.Move(Mouse.ScreenX - (Me.W / 2), Mouse.ScreenY - (Me.H / 2)) End
Un altro esempio analogo (nel quale si intende già eliminata la protezione del file-device relativo al mouse).
Se si cliccherà sul Form con il tasto sinistro del mouse, si provocherà la chiusura del programma.
Private Label1 As Label Private topo As Process Private n As Byte Private bb[3] As Byte Public Sub Form_Open() With Me .Width = 220 .Height = 150 .Center .Arrangement = Arrange.Fill End With Label1 = New Label(Me) As "Label1" End Public Sub Label1_Enter() topo = Shell "cat /dev/input/mouse0" For Read As "Topo" End Public Sub Label1_Leave() topo.kill End Public Sub Topo_Read() Dim b As Byte Repeat Read #topo, b If b == 9 Then Me.Close Return Endif bb[n] = b Inc n Until n == 3 Select Case bb[0] Case 40 ' spostamento in basso Label1.Alignment = Align.Bottom Label1.Text = "in basso" Case 8 Select Case bb[2] Case 1 ' spostamento in alto Label1.Alignment = Align.Top Label1.Text = "in alto" Case 0 ' spostamento a destra Label1.Alignment = Align.Right Label1.Text = "a destra" End Select Case 24 ' spostamento a sinistra Label1.Alignment = Align.Left Label1.Text = "a sinistra" End Select Me.Move(Mouse.ScreenX - (Me.W / 2), Mouse.ScreenY - (Me.H / 2)) n = 0 End
Apertura del file-device con Open.....For Read Watch
Quest'altra modalità prevede l'apertura e la gestione del file-device mediante l'istruzione Open.....For Read Watch.
Da precisare che, differentemente agli esempi sopra descritti, rilasciando un qualsiasi tasto del mouse, si otterrà lo spostamento a sinistra del Form per consentire all'utente eventualmente la chiusura del programma.
Private Label1 As Label Private fl As File Public Sub Form_Open() ' Se i permessi del file-device del mouse non consentono almeno la lettura del file-device... If Stat("/dev/input/mouse0").Auth <> "rwsrwxrwx" Then ' ...allora li modifichiamo. E' necessario scrivere nell'istruzione seguente la nostra password. ' Modificati i permessi, potremo accedere al file-device protetto del mouse: Shell "echo " & InputBox("Immettere la propria password !") & " | sudo -S chmod 444 '/dev/input/mouse0'" Wait Endif With Me .Width = 220 .Height = 150 .Center .Arrangement = Arrange.Fill End With Label1 = New Label(Me) As "Label1" End Public Sub Label1_Enter() fl = Open "/dev/input/mouse0" For Read Watch End Public Sub Label1_Leave() fl.Close End Public Sub File_Read() Dim s As String Dim i As Integer ' Legge non più di 4 dati-carattere dal file-device del mouse. ' Il segno negativo impedisce di causare l'errore "Fine del file". Read #fl, s, -4 ' Poiché una variabile stringa è comunque un puntatore ad un'area riservata, dereferenziamo detta variabile con l'apposita funzione di dereferenziazione che restituisce un tipo "Intero", e ne andiamo a leggere il valore: i = Int@(s) Select Case i ' [Nota 1] Case 16711720 ' spostamento in basso Label1.Alignment = Align.Bottom Label1.Text = "in basso" Case 65544 ' spostamento in alto Label1.Alignment = Align.Top Label1.Text = "in alto" Case 264 ' spostamento a destra Label1.Alignment = Align.Right Label1.Text = "a destra" Case 65304 ' spostamento a sinistra Label1.Alignment = Align.Left Label1.Text = "a sinistra" Case 9 ' premuto tasto sinistro Label1.Alignment = Align.Center Label1.Text = "tasto Sinistro" Case 10 ' premuto tasto destro Label1.Alignment = Align.Center Label1.Text = "tasto Destro" Case 12 ' premuto tasto centrale Label1.Alignment = Align.Center Label1.Text = "tasto Centrale" Case 8 ' qualsiasi tasto rilasciato Label1.Alignment = Align.Center Label1.Text = "tasto Rilasciato" Me.X = Me.X - (Me.W * 0.55) Return End Select Me.Move(Mouse.ScreenX - (Me.W / 2), Mouse.ScreenY - (Me.H / 2)) End
...un'applicazione pratica con Process
Come applicazione pratica di quanto descritto nella presente pagina, tenendo premuto con i tasti del mouse su una qualsiasi finestra di un programma esterno al nostro che appare sullo schermo, individueremo la finestra medesima e vi applicheremo alcuni comandi. Inoltre al rilascio di un qualunque pulsante conosceremo le coordinate assolute del puntatore del mouse in quel momento sullo schermo (anche se si è cliccato al di fuori di una finestra, semplicemente sulla Scrivania).
Si dovrà avere l'accortezza di inserire nel Form una TextArea, e di aprire le varie finestre, sulle quali testare il seguente codice, prima dell'applicativo.
E' necessario altresì attivare anche i Componenti "gb.desktop" e "gb.desktop.x11".
Private tp As Process Public Sub Form_Open() If Stat("/dev/input/mouse0").Auth <> "rwsrwxrwx" Then Shell "echo " & InputBox("Immettere la propria password !") & " | sudo -S chmod 444 '/dev/input/mouse0'" Wait Endif tp = Shell "cat /dev/input/mouse0" For Read As "tp" End Public Sub tp_Read() Dim s As String Dim i As Integer Dim b As Byte Dim dw As DesktopWindow ' Leggiamo i dati dal file-device del mouse... Read #tp, s, -4 i = Int@(s) ' Al rilascio di un qualunque tasto conosceremo le coordinate assolute del puntatore del mouse in quel momento sullo schermo (anche se si è cliccato al di fuori di una finestra). ' Se si vuole, invece, conoscere ad ogni spostamento del mouse le coordinate x,y del suo puntatore sullo schermo, allora basterà eliminare la sola parte dell'istruzione "IF", qui appresso. If i = 8 Then TextArea1.Text = "\nScreenX = " & Mouse.ScreenX & "\nScreenY = " & Mouse.ScreenY Endif For b = 1 To Desktop.Windows.Count - 1 dw = New DesktopWindow(Desktop.Windows[b].Id) ' Esclude ogni azione sulla finestra dell'applicazione Gambas previste per le finestre degli altri programmi dalle successive istruzioni: se il nome visibile della finestra elencata è uguale al nome dell'applicazione Gambas contenente il presente codice, allora salta al giro successivo: If Desktop.Windows[b].VisibleName = Application.Name Then Continue ' Se invece l'Id della finestra "attiva" è uguale all'Id della finestra cliccata (e quindi resa appunto "attiva", sollevata) di un programma esterno... If Desktop.ActiveWindow = Desktop.Windows[b].Id Then ' ...allora verifica quale tasto del mouse è stato premuto: Select Case i Case 9 ' tasto Sinistro ' Vengono mostrate nella "TextArea" alcune proprietà della finestra cliccata (va rilevato che i valori vengono mostrati nella "TextArea" per il solo tempo in cui il mouse viene matenuto cliccato. Pertanto, per poter vedere agevolmente i suddetti risultati, suggeriamo di mantenere cliccato sulla finestra del programma esterno per qualche secondo). With dw TextArea1.Text = .Name & "\n" TextArea1.Text &= "Id finestra: &h" & .Id & "\n" TextArea1.Text &= "Coord. X: " & .X & "\n" TextArea1.Text &= "Coord. Y: " & .Y & "\n" TextArea1.Text &= "Larghezza: " & .W & "\n" TextArea1.Text &= "Altezza: " & .H & "\n" End With Case 10 ' tasto Destro ' Se si clicca sulla finestra con il tasto destro del mouse, allora la finestra viene chiusa: dw.Close Case 12 ' tasto Centrale (rotellina) ' Se si clicca con il tasto centrale del mouse, la finestra viene spostata in altre coordinate dello schermo: dw.Move(500, 300) End Select Endif Next End
Gestione mediante il file-device: /dev/input/event...
L'esempio che riportiamo prevede la gestione dei dati del mouse intercettandoli dal suo file-device /dev/input/event... in un'applicazione "a riga di comando" lanciata da Terminale.
Bisognerà individuare l'esatto file-device del mouse il cui nome termina (sopra abbiamo sostituito l'ultimo carattere con tre puntini) con un numero.
Private fl As File Private n As Integer Public Sub Main() Dim s, pw As String ' Individua esattamente il file-device del mouse: s = File.Load("/proc/bus/input/devices") For Each s In Split(s, "\n") ' Individua la riga contenente la parola "mouse": If InStr(s, "mouse") > 0 Then ' Individua la parola "event" (corrispondente al file-device del mouse) e raccoglie il numero posto alla fine di tale parola: s = Scan(s, "*event* *")[1] Break Endif Next ' Per leggere il file-device individuato, bisogna avere i necessari permessi. ' Si dovrà passare la propria PASSWORD di sistema, scrivendola all'interno della consol o del terminale, e premere il tasto "Invio" della tastiera. Print "\e[31mImmettere la propria password...\e[0m" Input pw ' Se non sono stati modificati i permessi del file-device, devono essere modificati (sarà passata la propria password prima introdotta): Shell "echo " & pw & " | sudo -S chmod 444 /dev/input/event" & s Wait ' Apriamo il file-device in lettura e restiamo in attesa che arrivi qualche evento dal mouse: fl = Open "/dev/input/event" & s For Read Watch End Public Sub File_Read() Dim s As String Dim p As Pointer Dim l1, l2, l3, l4 As Long Dim sh1, sh2, sh3, sh4 As Short Dim i1, i2 As Integer ' Non appena giunge dal file-device qualche dato, lo leggiamo. ' Ogni evento che giunge dal mouse con-porta un flusso di più dati contemporaneamente. ' Per una più efficace ed intera intercettazione dell'intero fusso, lo leggiamo come stringa: Read #fl, s, -256 ' Per poter successivamente scomporre i vari dati dall'unica stringa, creiamo da quella stringa un puntatore: p = Alloc(s) ' Quindi dereferenzia il Puntatore con le apposite funzioni di dereferenziazione, e lo legge valore per valore: l1 = Long@(p) ' Secondi l2 = Long@(p + 8) ' Microsecondi sh1 = Short@(p + 16) ' Tipo di evento mouse sh2 = Short@(p + 18) ' Sotto-tipo di evento i1 = Int@(p + 20) ' Valore l3 = Long@(p + 24) ' Secondi l4 = Long@(p + 32) ' Microsecondi sh3 = Short@(p + 40) ' Tipo di evento mouse sh4 = Short@(p + 42) ' Sotto-tipo di evento i2 = Int@(p + 44) ' Valore ' Sfruttando il valore dei "secondi" riportati dalla variabile "l1" (o anche da "l3") mostriamo nel Terminale il numero di secondi trascorsi dal momento in cui l'applicativo è stato lanciato: If n = 0 Then n = l1 ' Andiamo a vedere in console/Terminale alcuni dati: Print sh1 & " " & sh2 & " " & i1 & " " & sh3 & " | " & sh4 & " " & i2 & " | " & Str(Time(0, 0, 0, (l1 - n) * 1000)) & Space(10) End
Sulla base della stampa della stringa in console/terminale, appena sopra riportata, agendo sul mouse, si vedrà una stringa composta in "astratto" come segue:
A B C D | E F | hh:mm:ss
Laddove:
- A = Tipo di evento mouse
se A = 2 --> spostamento mouse o rotazione rotellina; se 4 --> clic su tasto o sulla rotellina.
- B = Sotto-tipo di evento
se B = 0 --> spostamento mouse orizzontale; 1 --> spostamento verticale; 4 --> clic su tasto o sulla rotellina; 8 --> rotazione rotellina.
- C = Valore
se C = 589825 --> tasto sinistro cliccato; 589826 --> tasto destro cliccato; 589827 --> rotellina cliccata; con mouse fermo, se C < 0 ---> rotazione in basso della rotellina; se > 0 ---> rotazione in alto della rotellina. con mouse in movimento, se C = < 0 --> spostamento a sinistra o in alto; > 0 --> spostamento a destra o in basso.
- D = Tipo di evento mouse
se D = 0 spostamento mouse; 1 clic su tasto o su rotellina; 2 cambio di orientamento nello spostamento del mouse o rotazione della rotellina.
- E = Sotto-tipo di evento
se E = 1 --> cambio di orientamento nello spostamento del mouse; 11 --> rotazione della rotellina; 272 --> clic su tasto sinistro del mouse; 273 --> clic su tasto destro; 274 --> clic sulla rotellina.
- F = Valore
se F = 0 --> Spostamento del mouse o rilascio del tasto o della rotellina; < 0 cambio di orientamento in alto a destra o in alto a sinistra nello spostamento del mouse; > 0 cambio di orientamento in basso a destra o in basso a sinistra nello spostamento del mouse; 1 Clic su tasto o su rotellina.
Note
[1] Per maggiore completezza riportiamo i tre valori intercettati dal file-device /dev/input/mouse0 del mouse con la modalità sopra mostrata negli esempi (testato con Ubuntu), che prevedono la gestione mediante il file-device /dev/input/mouse0, in base all'azione applicata sul mouse medesimo:
- | 65544 | = spostamento verso l'alto; | ||
- | 65545 | = spostamento verso l'alto con tasto sinistro contemporaneamente premuto; | ||
- | 65546 | = spostamento verso l'alto con tasto destro contemporaneamente premuto; | ||
- | 65547 | = spostamento verso l'alto con tasti destro e sinistro contemporaneamente premuti; | ||
- | 65548 | = spostamento verso l'alto con tasto centrale contemporaneamente premuto; | ||
- | 65549 | = spostamento verso l'alto con tasti sinistro e centrale contemporaneamente premuti; | ||
- | 65550 | = spostamento verso l'alto con tasti centrale e destro contemporaneamente premuti; | ||
- | ||||
- | 16711720 | = spostamento verso il basso; | ||
- | 16711721 | = spostamento verso il basso con tasto sinistro contemporaneamente premuto; | ||
- | 16711722 | = spostamento verso il basso con tasto destro contemporaneamente premuto; | ||
- | 16711723 | = spostamento verso il basso con tasti destro e sinistro contemporaneamente premuti; | ||
- | 16711724 | = spostamento verso il basso con tasto centrale contemporaneamente premuto; | ||
- | 16711725 | = spostamento verso il basso con tasti sinistro e centrale contemporaneamente premuti; | ||
- | 16711726 | = spostamento verso il basso con tasti centrale e destro contemporaneamente premuti; | ||
- | ||||
- | 264 | = spostamento verso destra; | ||
- | 265 | = spostamento verso destra con tasto sinistro contemporaneamente premuto; | ||
- | 266 | = spostamento verso destra con tasto destro contemporaneamente premuto; | ||
- | 267 | = spostamento verso destra con tasti destro e sinistro contemporaneamente premuti; | ||
- | 268 | = spostamento verso destra con tasto centrale contemporaneamente premuto; | ||
- | 269 | = spostamento verso destra con tasti sinistro e centrale contemporaneamente premuti; | ||
- | 270 | = spostamento verso destra con tasti centrale e destro contemporaneamente premuti; | ||
- | ||||
- | 65304 | = spostamento verso sinistra; | ||
- | 65305 | = spostamento verso sinistra con tasto sinistro contemporaneamente premuto; | ||
- | 65306 | = spostamento verso sinistra con tasto destro contemporaneamente premuto; | ||
- | 65307 | = spostamento verso sinistra con tasti destro e sinistro contemporaneamente premuti; | ||
- | 65308 | = spostamento verso sinistra con tasto centrale contemporaneamente premuto; | ||
- | 65309 | = spostamento verso sinistra con tasti sinistro e centrale contemporaneamente premuti; | ||
- | 65310 | = spostamento verso sinistra con tasti centrale e destro contemporaneamente premuti; | ||
- | ||||
- | 8 | = qualsiasi tasto rilasciato. | ||
- | 9 | = tasto sinistro premuto; | ||
- | 10 | = tasto destro premuto; | ||
- | 11 | = tasti sinistro e destro contemporaneamente premuti; | ||
- | 12 | = tasto centrale premuto; | ||
- | 13 | = tasti sinistro e centrale contemporaneamente premuti; | ||
- | 14 | = tasti centrale e destro contemporaneamente premuti; |