LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Mouse simulating movement and click (https://www.linuxquestions.org/questions/programming-9/mouse-simulating-movement-and-click-4175663604/)

AlMeu 11-03-2019 04:53 AM

Mouse simulating movement and click
 
At @pan64 recomandation I open this new tread for my request.
I found here a nice code for simulating mouse movement and click without using additional Linux tools installed.

Code:

#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>

// Simulate mouse click
void
click (Display *display, int button)
{
  // Create and setting up the event
  XEvent event;
  memset (&event, 0, sizeof (event));
  event.xbutton.button = button;
  event.xbutton.same_screen = True;
  event.xbutton.subwindow = DefaultRootWindow (display);
  while (event.xbutton.subwindow)
    {
      event.xbutton.window = event.xbutton.subwindow;
      XQueryPointer (display, event.xbutton.window,
                    &event.xbutton.root, &event.xbutton.subwindow,
                    &event.xbutton.x_root, &event.xbutton.y_root,
                    &event.xbutton.x, &event.xbutton.y,
                    &event.xbutton.state);
    }
  // Press
  event.type = ButtonPress;
  if (XSendEvent (display, PointerWindow, True, ButtonPressMask, &event) == 0)
    fprintf (stderr, "Error to send the event!\n");
  XFlush (display);
  usleep (1);
  // Release
  event.type = ButtonRelease;
  if (XSendEvent (display, PointerWindow, True, ButtonReleaseMask, &event) == 0)
    fprintf (stderr, "Error to send the event!\n");
  XFlush (display);
  usleep (1);
}

// Get mouse coordinates
void
coords (Display *display, int *x, int *y)
{
  XEvent event;
  XQueryPointer (display, DefaultRootWindow (display),
                &event.xbutton.root, &event.xbutton.window,
                &event.xbutton.x_root, &event.xbutton.y_root,
                &event.xbutton.x, &event.xbutton.y,
                &event.xbutton.state);
  *x = event.xbutton.x;
  *y = event.xbutton.y;
}

// Move mouse pointer (relative)
void
move (Display *display, int x, int y)
{
  XWarpPointer (display, None, None, 0,0,0,0, x, y);
  XFlush (display);
  usleep (1);
}

// Move mouse pointer (absolute)
void
move_to (Display *display, int x, int y)
{
  int cur_x, cur_y;
  coords (display, &cur_x, &cur_y);
  XWarpPointer (display, None, None, 0,0,0,0, -cur_x, -cur_y);
  XWarpPointer (display, None, None, 0,0,0,0, x, y);
  usleep (1);
}

// Get pixel color at coordinates x,y
void
pixel_color (Display *display, int x, int y, XColor *color)
{
  XImage *image;
  image = XGetImage (display, DefaultRootWindow (display), x, y, 1, 1, AllPlanes, XYPixmap);
  color->pixel = XGetPixel (image, 0, 0);
  XFree (image);
  XQueryColor (display, DefaultColormap(display, DefaultScreen (display)), color);
}

// START HERE
int
main (int argc, char *argv[])
{
  int starting = 3;
  int x = 0;
  int y = 0;

  // Open X display
  Display *display = XOpenDisplay (NULL);
  if (display == NULL)
    {
      fprintf (stderr, "Can't open display!\n");
      return -1;
    }
 
  // Wait 3 seconds to start
  printf ("Starting in  ");
  fflush (stdout);
  while (starting > 0)
    {
      printf ("\b\b\b %d...", starting);
      fflush (stdout);
      sleep (1);
      starting--;
    }
  printf ("\n");

  // Start
  while (1)
    {
      click (display, Button1);
      //move (display, x, y);
      //coords (dispaly, &x, &y);
      sleep (1);
    }

  // Close X display and exit
  XCloseDisplay (display);
  return 0;
}

I compiled with:
Code:

gcc -o autoclick autoclick.c -lX11
I tried run and I get:

./autoclick 50, 50, 1
Starting in 3 2 1...

and that it's all. I try change the coordinates but nothing happen or button.
What I do wrong?

GazL 11-03-2019 05:34 AM

Works here. That is, it works after fixing the compiler warnings due to missing headers:
Code:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

Always compile with -Wall.

AlMeu 11-03-2019 05:42 AM

Thanks for answer.
I added the header you give me, recompiled and run it again.
It happen the same, don't do anything with command:

./autoclick 50, 50, 1
Starting in 3 2 1...

I tried change the coordinates and button, nothing change!!!
If I understood well button 1, 2, 3 should be mouse buttons left, middle and right?

By the way, it will be good also a parameter for time to keep pressed.


Thanks again

GazL 11-03-2019 05:49 AM

On my system it generates a click every 1 second. What are you putting your mouse over in order to check it?

GazL 11-03-2019 05:51 AM

Quote:

Originally Posted by AlMeu (Post 6053529)
It happen the same, don't do anything with command:

./autoclick 50, 50, 1

it won't because your main() function doesn't use any of the args, it just clicks wherever the mouse is.

AlMeu 11-03-2019 06:20 AM

Eeee is not what I expect do....
OK.
I found now another one which seams it clicks where I want.

Code:

#include <X11/Xlib.h>
#include<stdio.h>
#include<unistd.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

void mouseClick(int button)
{
    Display *display = XOpenDisplay(NULL);

    XEvent event;

    if(display == NULL)
    {
        fprintf(stderr, "Errore nell'apertura del Display !!!\n");
        exit(EXIT_FAILURE);
    }

    memset(&event, 0x00, sizeof(event));

    event.type = ButtonPress;
    event.xbutton.button = button;
    event.xbutton.same_screen = True;

    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);

    event.xbutton.subwindow = event.xbutton.window;

    while(event.xbutton.subwindow)
    {
        event.xbutton.window = event.xbutton.subwindow;

        XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
    }

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    usleep(100000);

    event.type = ButtonRelease;
    event.xbutton.state = 0x100;

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    XCloseDisplay(display);
}
int main(int argc,char * argv[])
{
    int i=0;
    int x , y;
    x=atoi(argv[1]);
    y=atoi(argv[2]);
    Display *display = XOpenDisplay(0);
    Window root = DefaultRootWindow(display);

    XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);

    mouseClick(Button1);
    XFlush(display);


    XCloseDisplay(display);
    return 0;
}

Still I don't understand at this new cod if I set button 1 as third argument don't do anything. If I set 2 or 3 is acting like a click with left button!!
I try to add also a time argument and create a function:

Code:

click(){
  # where mouseclick is the code up
  $dir/mouseclick $1, $2, $3
  sleep $4
}

#call later as
$click 710,450,2,1

It iS OK like that?
Question: in this situation if I want set 1.5s ...?

Or perhaps is better call like that
Code:

click(){
  # where mouseclick is the code up
  $dir/mouseclick $1, $2, $3
}

#call later as
$click 710,450,2
sleep 1.5

Thanks again.

pan64 11-03-2019 12:47 PM

the Button parameter is still not handled by the c code you posted. You need to take care about the third argument and pass it to the function mouseClick.

The last code you posted is probably a shell script, but I'm not really sure, because syntactically incorrect. I don't really understand what do you want to achieve.

also someone suggested xdotool probably that will be much easier for you: https://theembeddedlab.com/tutorials...-raspberry-pi/

dugan 11-03-2019 01:23 PM

Just curious:

Do you already know about xdotool?

AlMeu 11-03-2019 01:30 PM

I am not running the code in a regular distribution of Linux. It's true that I tested on Ubuntu. But there is an embedded distribution Yocto, if I don't mistake which can't have these tools and update online as I want and there I want play with this.
As much I understand from code of moving mouse and click me too I don't see making difference on button. But running with choise of button 2, 3 it's clicking.
Yes the last pieces of code are shell script where I want call and use.
xdotool must be installed before run.
If you see what is incorrect and advice me to fix, I will be happy.
If is regarding call:

click 710,450,2

I already realized that is mistake.


Thanks @pan64

pan64 11-03-2019 01:44 PM

if you want to validate your shell script please try www.shellcheck.net
what I can see is: the $ is not required before click, but obviously it is not the full script, so there can be other problems too.

I don't know, but probably xdotool is also available on your embedded system (so probably you can install it easily).

Also, you must not add comma (,) between arguments, space is enough

AlMeu 11-08-2019 10:08 AM

Hi guys,
This is the code I want run:

Code:

#!/bin/bash
#
#

# Define the paths
dir2=$(tail -n 1 /etc/mtab)
dir=${dir2:10:20}

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$dir/utils

# Log file
logfile="$dir/MICOM.txt"

# Save message log to file
flog(){
    # Timestamp
    local tstamp=$(date +"%m/%d/%Y ""%T")
    echo -ne "$tstamp - $1\r\n" >> "$logfile"
}

# Show image and wait a touch on screen
show_screen(){
  "$dir"/utils/showScreen "$dir/screens/$1"
}

# Click & wait
click(){
  "$dir"/utils/mouseclick "$1" "$2" "$3"
  sleep "$4"
}

# Main part of script

# Mount the directory for read/write
#mount -uw $dir
mount -o remount,rw "$dir"
/bin/sync

# Shows script starting screen
show_screen "3Read_Config.png"

# Remove the old file if exists
  rm -f "$logfile"
flog "*****************AutorunLog MICOM*****************"
flog "USB mounted in $dir"

#check if autorun.sh file exist
f="$dir/autorun_bavn/autorun.sh"
if [ -f "$f" ]
then

# Popup list choise
zenity --list --text="Choose your favorite" --column="Name:" Opt1 Opt2 Opt3

# Activate menu
#Click on Settings
click 620 325 2 1.2
#Click on System
click 710 450 2 1
#Click on down arrow
click 750 330 2 1
#Click on System Version
click 200 150 2 1
#Activate cod interface
click 120 30 2 0.5
click 200 450 2 0.5   
click 700 30 2 0.5
click 410 80 2 0.5
click 750 450 2 1.5


else
  # Show already installed screen
    flog "autorun.sh not found, path is invalid"

  # Shows final screen
    show_screen "3Script_Error.png"
       
  # Exit from script
    exit 0
fi
/bin/sync

I analyzed with ShelCheck, but mouseclick which in Ubuntu run in this Yocto distribution seams doesn't want do anything!!
Even the other command show_screen doesn't execute.
I insert even zenity command for test and also don't execute.
I do something wrong?
Any ideea?

pan64 11-09-2019 05:00 AM

looks like your program does not find the display. Does the variable DISPLAY set correctly?
You have no error handling in your scripts and also you could write some [more] info in a logfile to see what's happening and what went wrong.

AlMeu 12-02-2019 12:26 PM

In Ubuntu after compilation the command mouseclick generated works well.
But I want use it in other distribution Poky (Yocto) and here seams doesn't react at all. Here I don't see the terminal and I lunch it trough a bash script but I don't see any reaction!!!!
Perhaps don't find Display, but how to adjust for check what's going wrong?


All times are GMT -5. The time now is 03:06 PM.