2011-08-23 14 views
6

Me pregunto cómo dibujar directamente en la ventana raíz en un entorno X11 con El Cairo (en C), para hacer widgets. He copiado algunas partes del código de tint2, pero es bastante enorme, y el único resultado que tengo no es satisfactorio. Estaría encantado de tener un código de muestra de trabajo completo, o al menos algunos consejos o pequeños programas para estudiar. ¡Gracias chicos!¿Cómo dibujar directamente en el escritorio?

+0

No sé si dibujar directamente en el escritorio es la mejor manera de hacerlo. Sabes que puedes tener ventanas sin bordes/barras de título en X11 y configurarlas para que nunca se minimicen ... y estar en la parte inferior de la pila. Creo que eso es lo que hacen la mayoría de los widgets. –

+0

Aquí hay un hilo similar con un enlace que mi ayuda: http://stackoverflow.com/questions/1934442/drawing-on-the-x-root-window – CommonSense

+0

pero si eso es lo que quiere mirar y xosd xnow ... aunque no usan cairo, solo xlib. –

Respuesta

6

La ventana "inferior" es la ventana raíz. El problema es que en algunos entornos de escritorio tenemos ventanas en la parte superior de la ventana raíz, por lo que si cambia la ventana raíz, no verá los cambios: debe cambiar la ventana que está en la parte superior.

Este programa hace lo que pide: dibujar en la ventana raíz . Para probarlo, lo que sugeriría:

  • ctrl + alt + f1
  • inicio de sesión como root
  • detener su entorno de escritorio ("parada /etc/init.d/gdm", "/ etc/init.d/parada de KDM" o lo que se necesita en su distribución)
  • X -noreset -retro &
  • DISPLAY =: 0.0 xterm &
  • DISPLAY =: 0.0 metaciudad &

Luego, regrese a X (ctrl + alt + f7 o tal vez f8) y ejecute el programa.

Si desea dibujar en la ventana superior de Nautilus, necesitará encontrar su ID de ventana y luego usarla como la variable "w". El comando "xwininfo" podría ayudarlo a probar ...

#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; 
} 
+0

Esto funcionó para mí. Pude dibujar en otra ventana (Sublime Text) usando xwininfo para obtener el ID de la ventana, luego cambié la línea RootWindow() a: 'Window w = (Window) 0x2400041;', usando su propio valor para el ID por supuesto. . Una cosa que noté es que no funciona para todas las ventanas. Usar la ID para Desktop y Chrome no funcionó. ¿Tienes alguna idea de por qué? – gsingh2011

+0

En realidad, curiosamente, veo el cuadrado rojo en Chrome cuando cambio las pestañas, y un instante después desaparece ... – gsingh2011

+0

Supongo que la aplicación simplemente dibuja en la parte superior de su rectángulo. Realmente no puede comenzar a dibujar en la ventana de otra aplicación ya que no sabe cuándo van a dibujar nuevamente sobre las cosas que hizo. Si desea hacer cosas extravagantes con el fondo del escritorio, le sugiero que mire el código fuente de la aplicación que sea responsable de dibujar allí y luego cambiarla. O simplemente mátalo :) – pzanoni

Cuestiones relacionadas