X11에서 화면에 직접 모양을 그려야합니다 (작은 화살표). 오버레이로 사용됩니다. 나는 좋은 결과가없는 한 시간 정도를 찾고 있습니다. 누구든지 내가 필요한 것을 얻을 수있는 좋은 진입 점을 제공 할 수 있습니까? 내가 사용할 수있는 기술은 카이로, gtk 또는 XLib입니다.X11 : 오버레이 그리기/오버레이에서 도면 제거
내가 지금까지 찾은 모든 것이 항상 사용할 수있는 것은 아니지만, 내 화살표 (사각형, 창) 뒤에 흰색 모양을 만듭니다.
편집 : 이제 Composite와 Cairo를 사용하여 X11 오버레이를 그릴 수 있습니다. 나는 그것을 이렇게한다 (참고 : 이것은 최소한의 예이다. 에러 체크가 거의 없다. !!!). 터미널에서 시작하여 종료 할 수 있습니다!
// 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;
}
왼쪽에있는 질문 : 그려진 이전 커서를 제거하는 방법은 무엇입니까? 나는 XClearArea를 시험해 보았고, 나는 카이로를 overpaint하려고 시도했다. 나는 Cairo Clear operator를 시도했다. 아무것도하지 않았다. 누군가가 올바른 방향으로 나를 가리킬 수 있습니까?
Core X11에서는이 작업을 수행하지 않으므로 일부 확장자가 필요합니다. 복합 또는 모양 확장을 사용할 수 있습니다. 모양은 컴포지트보다 쉽게 사용할 수 있습니다. 사용 가능한 경우 오버레이 비주얼을 사용할 수도 있습니다 (하드웨어에서 OpenGL 및 오버레이 지원 필요). –
기존 창 바로 위에 그릴 수도 있지만 권장하지는 않습니다. 다른 프로그램이 동시에 다시 그리기를 시도하면 결과가 제대로 표시되지 않을 수 있습니다. –
xeyes의 근원을보십시오. 고대지만 작동합니다. –