J'ai besoin de dessiner une forme directement sur l'écran (une petite flèche) dans X11, elle sert de superposition. Je cherche environ une heure non sans de bons résultats. Quelqu'un pourrait-il me fournir un bon point d'entrée pour ce dont j'ai besoin? Les technologies que je peux utiliser sont cairo, gtk ou XLib. Tout ce que j'ai trouvé jusqu'ici dépend de la composition, qui n'est pas toujours disponible, ou crée une forme blanche derrière ma flèche (rectangle, une fenêtre).X11: Dessiner une superposition/Supprimer des dessins d'une superposition
EDIT: Je suis maintenant capable de dessiner une superposition X11 en utilisant Composite et Cairo. Je le fais de cette façon (Note: Ceci est un exemple minimal, il y a peu ou pas de vérification d'erreur !!!). Commencez à partir du terminal pour pouvoir le quitter!
// COMPILE WITH: g++ -o overlay overlay.cc -lXfixes -lXcomposite -lX11 `pkg-config --cflags --libs cairo`
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <stdio.h>
#include <unistd.h>
Display *display_;
int old_x_, old_y_;
cairo_surface_t *surf_;
Window overlay_;
int screen_;
int height_;
int width_;
cairo_t *cr_;
void paint_cursor(int new_x, int new_y, bool first = false)
{
if (!first)
{
cairo_set_operator(cr_, CAIRO_OPERATOR_CLEAR);
cairo_rectangle(cr_, old_x_, old_y_, 20, 20);
cairo_fill(cr_);
}
old_x_ = new_x;
old_y_ = new_y;
cairo_set_operator(cr_, CAIRO_OPERATOR_SOURCE);
cairo_move_to(cr_, new_x, new_y);
cairo_line_to(cr_, new_x + 0, new_y + 16);
cairo_line_to(cr_, new_x + 4, new_y + 13);
cairo_line_to(cr_, new_x + 7, new_y + 18);
cairo_line_to(cr_, new_x + 9, new_y + 17);
cairo_line_to(cr_, new_x + 6, new_y + 12);
cairo_line_to(cr_, new_x + 11, new_y + 12);
cairo_line_to(cr_, new_x + 0, new_y + 0);
cairo_set_source_rgba(cr_, 0.0, 0.0, 0.0, 0.5);
cairo_stroke_preserve(cr_);
cairo_set_source_rgba(cr_, 0.0, 1.0, 0.0, 0.5);
cairo_fill(cr_);
}
int main()
{
display_ = ::XOpenDisplay(0);
if (!display_)
{
return -1;
}
screen_ = ::XDefaultScreen(display_);
Window root = RootWindow(display_, screen_);
::XCompositeRedirectSubwindows(display_, root, CompositeRedirectAutomatic);
::XSelectInput(display_, root, SubstructureNotifyMask);
overlay_ = ::XCompositeGetOverlayWindow(display_, root);
XserverRegion region = ::XFixesCreateRegion(display_, 0, 0);
::XFixesSetWindowShapeRegion(display_, overlay_, ShapeBounding, 0, 0, 0);
::XFixesSetWindowShapeRegion(display_, overlay_, ShapeInput, 0, 0, region);
::XFixesDestroyRegion(display_, region);
width_ = DisplayWidth(display_, screen_);
height_ = DisplayHeight(display_, screen_);
surf_ = ::cairo_xlib_surface_create(display_, overlay_, DefaultVisual(display_, screen_), width_, height_);
cr_ = ::cairo_create(surf_);
::XSelectInput(display_, overlay_, ExposureMask);
old_x_ = 0;
old_y_ = 0;
paint_cursor(0, 0, true);
XEvent ev;
Window root_return, child_return;
int root_x_return, root_y_return;
int win_x_return, win_y_return;
unsigned int mask;
for (;;)
{
XQueryPointer(display_, root, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask);
paint_cursor(root_x_return, root_y_return);
printf("Paint\n");
}
return 0;
}
La question qui reste: Comment supprimer l'ancien curseur qui a été dessiné? J'ai essayé XClearArea, j'ai essayé de peindre avec Cairo, j'ai essayé l'opérateur Cairo Clear, etc. Rien n'a fonctionné. Quelqu'un peut-il me pointer ici dans la bonne direction?
Core X11 ne fait pas cela, vous aurez besoin d'une sorte d'extension. Vous pouvez utiliser l'extension Composite ou Shape. La forme est plus facilement disponible que Composite. Vous pouvez également utiliser un visuel de superposition si disponible (nécessite une prise en charge OpenGL et overlay dans le matériel). –
Vous pouvez également dessiner directement sur des fenêtres existantes, mais cela n'est pas recommandé. Si un autre programme essaie de repeindre en même temps, le résultat peut ne pas s'afficher correctement. –
Regardez la source de xeyes. Ancien mais fonctionne. –