Ncurses mvwprintw doesnt print - c++

I have a simple program that has a main window and a small window on the bottom like (without the lines, thats just so you can see the two windows:
+------------------+
| |
| |
| |
+------------------+
| |
+------------------+
I want the bottom area to be a place where you can type in, and here is my source code:
#include <termios.h>
#include <bits/stdc++.h>
#include <ncurses.h>
int main()
{
int scrx;
int scry;
initscr();
cbreak();
noecho();
clear();
raw();
getmaxyx(stdscr, scrx, scry);
WINDOW* input = newwin(1, scrx, scry, 0);
std::string cmdbuf;
while(true)
{
int newx;
int newy;
getmaxyx(stdscr, newx, newy);
if(newx != scrx || newy != scry)
{
// do stuff;
}
char c = wgetch(input);
cmdbuf.push_back(c);
werase(input);
mvwprintw(input, 0, 0, cmdbuf.c_str());
refresh();
wrefresh(input);
}
}
However, it doesn't seem to print anything, just move my cursor (which gets suck halfway across the screen). How can I make it so that text actually gets printed and that my cursor actually moves across the full screen?

Tidied it up for you a bit. Press 'q' to quit. You get the idea.
#include <termios.h>
#include <bits/stdc++.h>
#include <ncurses.h>
int main()
{
int scrx, scry;
initscr();
getmaxyx(stdscr, scry, scrx);
WINDOW *w = newwin(1, scrx, scry - 1, 0);
std::string cmdbuf {};
char c = '\0';
while (c != 'q')
{
int newx, newy;
getmaxyx(stdscr, newx, newy);
if(newx != scrx || newy != scry)
{
// do stuff;
}
c = wgetch(w);
cmdbuf += c;
mvwprintw(w, 0, 0, "%s", cmdbuf.c_str());
wrefresh(w);
}
delwin(w);
endwin();
}

The refresh is overwriting the mvwprintw because they're different windows. For the given example, there's no reason to refresh stdscr because nothing (except for the initscr call) has updated that window. Moving refresh out of the loop would help (but the "do stuff" can obviously interfere with that).
The newx/newy logic is too fragmentary to comment on (I'd use getbegyx ...).

The declaration of newwin is:
WINDOW *newwin(
int nlines, int ncols,
int begin_y, int begin_x);
You are calling:
newwin(1,scry,scrx,0)
Which sets the size of you window to 1 tall and scry wide, and puts it at coordinates (0,srcx). What you want is:
newwin(1,scry,scrx-1,0)
Where 1 is the height of the window.
Also, cbreak overrides raw, so there is no point to calling both.

Related

FLTK: Clearing a graph when drawing another

I wrote a simple FLTK program to draw a circle when clicking on the "Draw Circle" button and to draw a line when clicking on the "Draw Line" button. I supposed to have only one graph. But I got two graphs in the panel. I want only one showing and the other disappearing. The following is the code:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
}
else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() *3/ 4);
y1 = (int)(h() *3/ 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H) {}
};
Drawing* d;
void circle_cb(Fl_Widget*, void*) {
flag = 1;
fl_overlay_clear();
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget*, void*) {
flag = -1;
fl_overlay_clear();
d->redraw();
} // end clear_cb
int main(int argc, char** argv) {
Fl_Window* window = new Fl_Window(600, 550); // create a window, originally(400,400)
Drawing dr(0, 0, 600, 600);
d = &dr;
Fl_Button *b, *c;
b = new Fl_Button(150, 80, 100, 25, "&Draw Circle");
b->callback(circle_cb);
c = new Fl_Button(350, 80, 100, 25, "&Draw Line");
c->callback(line_cb);
window->end(); //show the window
window->show(argc, argv);
return Fl::run();
}
I have used fl_overlay_clear() to clear graph. However it is not working. Any help will be appreciated.
There are several issues that need to be fixed in your program, but first of all using the draw() method as you did is basically correct. However, using fl_overlay_clear(); is useless, you can remove it.
My solution: your widget doesn't have a solid background (boxtype), i.e. your draw method draws over the background over and over again w/o clearing it. There are several ways to solve this, but if you want to learn what happens, try this first: add window->resizable(window); before window->show(argc, argv);, run the program again and resize the window. You'll notice that the previous drawing disappears and only one drawing stays. That's because the background is cleared when you resize the widget.
Next step: add a solid boxtype:
d = &dr;
d->box(FL_DOWN_BOX);
and add Fl_Box::draw(); right at the beginning of your draw() method.
If you do that you may notice that your button(s) disappear when you click one of them - because your buttons are inside the area of your Drawing. The last thing(s) I fixed was to correct the coordinates of buttons and to enlarge the window (it was too small anyway to cover the entire Drawing). Here's my complete result:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
Fl_Box::draw();
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
} else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() * 3 / 4);
y1 = (int)(h() * 3 / 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H)
: Fl_Box(X, Y, W, H) {}
};
Drawing *d;
void circle_cb(Fl_Widget *, void *) {
flag = 1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget *, void *) {
flag = -1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end clear_cb
int main(int argc, char **argv) {
Fl_Window *window = new Fl_Window(600, 660); // create a window, originally(400,400)
Drawing dr(0, 60, 600, 600); // FIXED
d = &dr;
d->box(FL_DOWN_BOX); // ADDED
Fl_Button *b, *c;
b = new Fl_Button(150, 20, 100, 25, "&Draw Circle"); // FIXED
b->callback(circle_cb);
c = new Fl_Button(350, 20, 100, 25, "&Draw Line"); // FIXED
c->callback(line_cb);
window->end(); // show the window
window->resizable(window); // ADDED
window->show(argc, argv);
return Fl::run();
}
I believe this does what you want.
PS: the official FLTK support forum can be found on our website https://www.fltk.org/ and the direct link to the user forum (Google Groups) is https://groups.google.com/g/fltkgeneral
Just a quick addition to what Albrecht put so perfectly: FLTK drawing coordinates are relative to the window, not relative to the widget. You probably want to offset your drawing by the x() and y() coordinates of your widget.
In your handle() methods line_cb() , circle_cb() should call window()->make_current() and then fl_overlay_rect() after FL_DRAG events, and should call fl_overlay_clear() after a FL_RELEASE event. Refer for more details

Ncurses wrefresh not showing window borders

I am experimenting with some C++ using ncurses and am having trouble showing the window borders, but am having trouble with the following programs.
#include <cstdio>
#include <cstdlib>
#include <ncurses.h>
int main(int argc, char **argv)
{
if(argc != 5)
{
printf("not enough arguments\n");
exit(1);
}
int height = atoi(argv[1]);
int width = atoi(argv[2]);
int y = atoi(argv[3]);
int x = atoi(argv[4]);
initscr();
WINDOW *win = newwin(height, width, y, x);
box(win, 0, 0);
wrefresh(win);
int py, px;
getparyx(win, py, px);
mvprintw(LINES-2, 0, "getparyx: (%d, %d)", py, px);
int by, bx;
getbegyx(win, by, bx);
mvprintw(LINES-1, 0, "getbegyx: (%d, %d)", by, bx);
getch();
delwin(win);
endwin();
}
In the program above I draw the border using box and refresh using wrefresh, but it doesn't show anything. The other stuff that I print to stdscr, however, does show.
In another program however I was able to get the border working.
#include <ncurses.h>
int main()
{
const int height = 6, width = 8;
WINDOW *win;
int starty, startx;
int ch;
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
starty = (LINES - height) / 2;
startx = (COLS - width) / 2;
win = newwin(height, width, starty, startx);
box(win, 0, 0);
wrefresh(win);
while((ch = getch()) != KEY_F(1))
{
wborder(win, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
wrefresh(win);
delwin(win);
switch(ch)
{
case KEY_UP:
win = newwin(height, width, --starty, startx);
break;
case KEY_DOWN:
win = newwin(height, width, ++starty, startx);
break;
case KEY_LEFT:
win = newwin(height, width, starty, --startx);
break;
case KEY_RIGHT:
win = newwin(height, width, starty, ++startx);
break;
}
move(starty + (height / 2) - 1, startx + (width / 2) - 1);
box(win, 0, 0);
wrefresh(win);
}
delwin(win);
endwin();
}
The thing is that the border only appears in the loop. In other words the border does not start to show until I press buttons, meaning the initial wrefresh did not work.
After doing some research I this thread which suggested to call refresh after initscr (or at least before wrefresh()) but that did not work. So what am I missing that the border does not show in the first program?
For my tests, that initial refresh() is certainly what is missing. I checked some old code I wrote, and it indeed calls refresh() as part of the ncurses initialisation. Adding this to your code made it work for me. A lot of the curses documentation is still constrained to books, it never really made it onto the web.
initscr();
refresh(); // <-- HERE
WINDOW *win = newwin( height, width, y, x );
box( win, 0, 0 );
wrefresh(win);
I don't think the windowing model is fully initialised until after that first refresh() is called. But I could not find any documentation on exactly why that would be the case.
So not much detail in this answer, sorry... but I hope it helps.
The manual pages answer the question:
initscr
initscr also causes the first call to refresh(3x)
to clear the screen.
getch
If the window is not a pad, and it has been moved or modified since the
last call to wrefresh, wrefresh will be called before another character
is read.
The initscr (clear) and the mvprintw calls update stdscr, which is finally refreshed when you call getch. stdscr is a window, and as noted in the discussion of wrefresh, the physical screen is updated in the order that refreshes are applied (that is, it overlaps with the other window, and if you want the other window to appear, you should refresh stdscr first, to handle the clearing operation).

Xlib - window is not rendering

I am creating library for Xlib (like gtk/qt, but simplified). And i don't see window at my desktop. GDB says nothing. What i must do to fix this bug? Already tried to move display declaration to main function. Used -g flag as compiling (to check with GDB). And no window! Seriously, it's awesome glitch!
FXL++ library:
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
using namespace std;
class fxlpp{
public:
void init(){
disp = XOpenDisplay(NULL);
if(disp == NULL){ //error 1 if can't open display
cerr << "Can't open display" << endl;
exit(1);
}
screen = DefaultScreen(disp);
}
void mkWin(int winID, int x1, int y1, unsigned x2, unsigned y2){
win[winID] = XCreateSimpleWindow(disp, RootWindow(disp, screen), x1, y1, x2, y2, 0, BlackPixel(disp, screen), WhitePixel(disp, screen));
XSelectInput(disp, win[winID], ExposureMask | KeyPressMask);
XMapWindow(disp, win[winID]);
}
void mkCWin(int cWinID, int pWinID, int x1, int y1, int x2, int y2){
cWin[pWinID][cWinID] = XCreateSimpleWindow(disp, win[pWinID], x1, y1, x2, y2, 1, BlackPixel(disp, screen), WhitePixel(disp, screen));
XSelectInput(disp, cWin[pWinID][cWinID], ExposureMask | KeyPressMask);
XMapWindow(disp, cWin[pWinID][cWinID]);
}
protected:
Display *disp; //declare display pointer
int screen; //declare display num integer
Window win[129]; //declare window
Window cWin[129][129]; //declare child win array
XEvent event; //declare event handler
};
Code to test library:
#include <iostream>
#include "fxlpp.hpp"
using namespace std;
int main(){
class fxlpp fxlpp;
fxlpp.init();
fxlpp.mkWin(1, 100, 100, 500, 300);
sleep(2);
return 0;
}
As I wrote before, there's a lot more to X11 than just create a window, paint some lines on it and expect output. You must setup the X event loop to receive events, handle at a minumum exposure events, but also keyboard, mouse, etc. in the proper way. So I'm afraid it's not a bug, it's a design flaw in your program.
For a short tutorial, see here.
Although event loop is important most times, in this simple case you just need to call XFlush() after drawing.

How to automate mouse actions

I need to automate some mouse actions.
I need to do
mousemove1, lbuttondown1, wait1, mousemove1, lbuttonup1, wait1,
mousemove2, lbuttondown2, wait2, mousemove2, lbuttonup2, wait2,
...
The actions have to work regarding screen coordinates. The window which have to accept an event is the top window at this point.
There is a file with data.
For example
500 450 1000 500 300 2000
600 450 1000 600 300 5000
What did I try to do
#include <fstream>
#include <vector>
#include <windows.h>
struct A
{
POINT point1;
unsigned sleep1;
POINT point2;
unsigned sleep2;
A() { point1.x = point1.y = sleep1 = point2.x = point2.y = sleep2 = 0; }
};
void f(const A &a)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, a.point1.x, a.point1.y, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, a.point1.x, a.point1.y, 0, 0);
Sleep(a.sleep1);
mouse_event(MOUSEEVENTF_LEFTUP, a.point2.x, a.point2.y, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, a.point2.x, a.point2.y, 0, 0);
Sleep(a.sleep2);
}
int main()
{
std::vector<A> as;
std::ifstream fin("params.txt");
if (fin) {
A a;
while (fin.good()) {
fin >> a.point1.x;
fin >> a.point1.y;
fin >> a.sleep1;
fin >> a.point2.x;
fin >> a.point2.y;
fin >> a.sleep2;
if (fin.eof()) {
break;
}
as.push_back(a);
}
}
for (;;) {
for (const A &a : as) {
f(a);
}
}
}
Something is happening but I can not understand what is and where is a mistake.
A problem with your code is that you are using mouse_event with screen coordinates rather than normalized absolute coordinates. Normalized absolute coordinates always range between (0,0) in the top-left corner to (65535,65535) in the bottom-right corner, no matter what the desktop size happens to be.
The MouseTo function in the example below accepts screen coordinates as inputs, then uses the dekstop window's size to convert to normalized absolute coordinates. This example uses SendInput, which supersedes mouse_event, but they both use the same coordinates. I'm not sure if mouse_event can take the MOUSEEVENTF_VIRTUALDESK flag, but this is for supporting multi-monitor desktops.
If you wish build this example, start with a new Win32 Console application.
#include <Windows.h>
#include <cmath>
void MouseTo(int x, int y) {
RECT desktop_rect;
GetClientRect(GetDesktopWindow(), &desktop_rect);
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags =
MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
input.mi.dx = x * 65536 / desktop_rect.right;
input.mi.dy = y * 65536 / desktop_rect.bottom;
SendInput(1, &input, sizeof(input));
}
void MouseLButton(bool tf_down_up) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = tf_down_up ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(input));
}
void MouseLButtonDown() { MouseLButton(true); }
void MouseLButtonUp() { MouseLButton(false); }
void AnimatedDrag(const POINT& from, const POINT& to) {
static const double iteration_dist = 20;
static const DWORD iteration_delay_ms = 1;
const double dx = to.x - from.x;
const double dy = to.y - from.y;
const double dist = sqrt(dx*dx + dy*dy);
const int count = static_cast<int>(dist / iteration_dist);
MouseTo(from.x, from.y);
MouseLButtonDown();
for(int i=1; i<count; ++i) {
const int x = from.x + static_cast<int>(dx * i / count);
const int y = from.y + static_cast<int>(dy * i / count);
MouseTo(x, y);
Sleep(iteration_delay_ms);
}
MouseTo(to.x, to.y);
MouseLButtonUp();
}
int main() {
// minimize console window
ShowWindow(GetConsoleWindow(), SW_SHOWMINNOACTIVE);
Sleep(500);
// Drag whatever is at the window coordinates in "from" to "to"
const POINT from = {300, 100};
const POINT to = {900, 600};
AnimatedDrag(from, to);
}
Christopher's answer should suffice, but might be a little intimidating to anyone not well-versed with C++, and just trying to hack together a click-utility. This should be easy enough to hack away at for most newbies.
Pardon the use of macros; I'm using them to make the intent of the code a little more English-friendly.
It should right-click on your primary display (unless you changed the X coordinate line as-commented) then shift a few pixels over and left-click to close the Right-click menu prompt, if one was created. You can see what else is available on MSDN for your own custom requirements.
I kept click / unclick / move as seperate actions, so things like drag & drop should be fairly intuitive to perform when starting with all the right ingredients.
#include <Windows.h>
// Uses absolute coords where the primary display starts at 0,0
// That works well with enumerated monitors structures and their reported coords.
#define QUEUE_MV_MOUSE ip.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
#define QUEUE_RC_START_MOUSE ip.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
#define QUEUE_RC_END_MOUSE ip.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
#define QUEUE_LC_START_MOUSE ip.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
#define QUEUE_LC_END_MOUSE ip.mi.dwFlags = MOUSEEVENTF_LEFTUP;
#define SEND_IT SendInput(1, &ip, sizeof(ip));
#define VIRTUAL_X_MODIFIER (65536 / GetSystemMetrics(SM_CXSCREEN));
#define VIRTUAL_Y_MODIFIER (65536 / GetSystemMetrics(SM_CYSCREEN));
int main()
{
INPUT ip;
ip.type = INPUT_MOUSE;
ip.mi.mouseData = 0;
// Change 500 to -500 for a left-hand extended display.
ip.mi.dx = 500 * VIRTUAL_X_MODIFIER;
ip.mi.dy = 1000 * VIRTUAL_Y_MODIFIER;
// Un-comment this Sleep timer if you're debugging in an IDE and need a quick pause.
// Sleep(500);
QUEUE_MV_MOUSE;
SEND_IT;
// Various users advise brief Sleep pauses between queued mouse and keyboard events.
// 500 milliseconds is probably overkill for your automation requirements.
Sleep(500);
QUEUE_RC_START_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_RC_END_MOUSE;
SEND_IT;
Sleep(500);
ip.mi.dx -= 10 * VIRTUAL_X_MODIFIER;
ip.mi.dx -= 10 * VIRTUAL_Y_MODIFIER;
QUEUE_MV_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_LC_START_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_LC_END_MOUSE;
SEND_IT;
return 0;
}

How to simulate a mouse movement

How can I simulate a mouse event causing the pointer to move 500 pixels to the left, then click using C++. How would I do something like this?
Here's some modified Win32 code I had lying around:
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#define X 123
#define Y 123
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 800
void MouseSetup(INPUT *buffer)
{
buffer->type = INPUT_MOUSE;
buffer->mi.dx = (0 * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (0 * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.mouseData = 0;
buffer->mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
buffer->mi.time = 0;
buffer->mi.dwExtraInfo = 0;
}
void MouseMoveAbsolute(INPUT *buffer, int x, int y)
{
buffer->mi.dx = (x * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (y * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
SendInput(1, buffer, sizeof(INPUT));
}
void MouseClick(INPUT *buffer)
{
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
SendInput(1, buffer, sizeof(INPUT));
Sleep(10);
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP);
SendInput(1, buffer, sizeof(INPUT));
}
int main(int argc, char *argv[])
{
INPUT buffer[1];
MouseSetup(&buffer);
MouseMoveAbsolute(&buffer, X, Y);
MouseClick(&buffer);
return 0;
}
You'll need to call MouseSetup() to each INPUT buffer before you use it.
Resources
MSDN - SendInput()
MSDN - INPUT
MSDN - MOUSEINPUT
Here is a solution using Xlib for those who use Linux :
#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 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;
}
Just Build it and then to simulate a click at x ,y do:
$ ./a.out x y
i.e.
$g++ -lX11 sgmousesim2.cpp
$./a.out 123 13
Use SendInput to generate the input you want to simulate. From MSDN documentation:
Synthesizes keystrokes, mouse motions, and button clicks.
I have never did this using C++. Nevertheless, there is a Java class called Robot which is able to produce mouse events. I used this back on Java version 1.4 but it does still work. I tried the example from this Simulate a physical mouse move in Mac OS X. It runs smoothly with Oracle Java 1.6.0_26 on MacOSX Lion. The good about Java is that it is platform independent.
import java.awt.AWTException;
import java.awt.Robot;
public final class MovingMouseDemo
{
public static void main(String[] args) throws AWTException
{
Robot robot = new Robot();
robot.setAutoDelay(5);
robot.setAutoWaitForIdle(true);
//put mouse in the top left of the screen
robot.mouseMove(0, 0);
//wait so that you can see the result
robot.delay(1000);
//put the mouse 200 pixels away from the top
//10 pixels away from the left
robot.mouseMove(200, 10);
robot.delay(1000);
robot.mouseMove(40, 130);
}
}
You can still use JNI to bind it with C++.
I hope it helps
C++ alone can't do this. It has no concept of a "mouse", let alone a "click".
You need some sort of library which talks to your windowing system. For example, QT. Then it's a matter of searching through the API and making the right C++ calls.
Use the mouse_event function.