Как нарисовать прямо на рабочем столе? - PullRequest
7 голосов
/ 23 августа 2011

Мне интересно, как рисовать непосредственно в корневом окне в среде X11 с Cairo (в C), чтобы создавать виджеты. Я скопировал некоторые части кода tint2, но он довольно огромный, и единственный результат, который у меня есть, не удовлетворяет. Я был бы рад иметь полный рабочий пример кода или хотя бы несколько советов или небольших программ для изучения. Спасибо, ребята!

1 Ответ

7 голосов
/ 07 октября 2011

«Нижнее» окно - это корневое окно. Проблема в том, что в некоторых средах рабочего стола у нас есть окна поверх корневого окна, поэтому, если вы измените корневое окно, вы не увидите свои изменения: вам нужно изменить окно, которое находится сверху.

Эта программа делает то, что вы просите: нарисовать в корневом окне . Чтобы проверить это, я предлагаю вам:

  • Ctrl + Alt + f1
  • войдите как root
  • остановка среды рабочего стола ("/etc/init.d/gdm stop", "/etc/init.d/kdm stop" или все, что нужно в вашем дистрибутиве)
  • X -noreset -retro &
  • DISPLAY =: 0,0 xterm &
  • DISPLAY =: 0,0 метасити &

Затем вернитесь к X (Ctrl + Alt + F7 или, возможно, F8) и запустите программу.

Если вы хотите рисовать в верхнем окне Наутилуса, вам нужно узнать его идентификатор окна, а затем использовать его в качестве переменной "w". Команда "xwininfo" может помочь вам в тестировании ...

#include <assert.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <cairo.h>
#include <cairo-xlib.h>

int width, height;

void draw(cairo_t *cr) {
    int quarter_w = width / 4;
    int quarter_h = height / 4;
    cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
    cairo_rectangle(cr, quarter_w, quarter_h, quarter_w * 2, quarter_h * 2);
    cairo_fill(cr);
}

int main() {
    Display *d = XOpenDisplay(NULL);
    assert(d);

    int s = DefaultScreen(d);
    Window w = RootWindow(d, s);
    width = DisplayWidth(d, s);
    height = DisplayHeight(d, s);

    cairo_surface_t *surf = cairo_xlib_surface_create(d, w,
                                  DefaultVisual(d, s),
                                  width, height);
    cairo_t *cr = cairo_create(surf);

    XSelectInput(d, w, ExposureMask);

    draw(cr);

    XEvent ev;
    while (1) {
    XNextEvent(d, &ev);
        printf("Event!\n");
        if (ev.type == Expose) {
            draw(cr);
        }
    }

    cairo_destroy(cr);
    cairo_surface_destroy(surf);
    XCloseDisplay(d);
    return 0;
}
...