Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw directly on the desktop?

Tags:

c

x11

cairo

I'm wondering how to draw directly on the root window in an X11 environment with Cairo (in C), in order to make widgets. I've copied some parts of the code of tint2, but it's quite enormous, and the only result I have is not satisfying. I would be pleased to have a complete working sample code, or at least some tips or little programs to study. Thank you guys !

like image 500
Dylar Avatar asked Aug 23 '11 17:08

Dylar


People also ask

How do I draw directly on my screen Windows 10?

Select Windows Ink Workspace from the taskbar to open it. From here, you can select Whiteboard or Fullscreen Snip. (You can also select More and Learn more about pen or access Pen settings .) Tip: Press the top button on your pen once to quickly open Microsoft Whiteboard, or double-press it to open Snip & Sketch.

What is used to draw directly on the computer screen?

The correct answer is a Light pen. A light pen is a computer input device in the form of a light-sensitive wand used in conjunction with a computer's cathode-ray tube (CRT) display.


1 Answers

The "bottom" window is the root window. The problem is that in some desktop environments we have windows on top of the root window, so if you change the root window, you won't see your changes: you need to change the window that's on the top.

This program does what you ask for: draw on the root window. To test it, I suggest you to:

  • ctrl+alt+f1
  • login as root
  • stop your desktop environment ("/etc/init.d/gdm stop", "/etc/init.d/kdm stop" or whatever is needed in your distro)
  • X -noreset -retro &
  • DISPLAY=:0.0 xterm &
  • DISPLAY=:0.0 metacity &

Then, go back to X (ctrl+alt+f7 or maybe f8) and run the program.

If you want to draw on Nautilus' top window, you will need to find out its window ID and then use it as the "w" variable. The "xwininfo" command might help you testing...

#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;
}
like image 192
pzanoni Avatar answered Nov 05 '22 15:11

pzanoni