2011-08-23 9 views
6

Tôi đang tự hỏi làm thế nào để vẽ trực tiếp trên cửa sổ gốc trong một môi trường X11 với Cairo (trong C), để làm cho các vật dụng. Tôi đã sao chép một số phần của mã của tint2, nhưng nó khá lớn, và kết quả duy nhất tôi có là không thỏa mãn. Tôi rất vui khi có một mã mẫu làm việc hoàn chỉnh, hoặc ít nhất một số mẹo hoặc chương trình nhỏ để học. Cảm ơn các bạn!Làm cách nào để vẽ trực tiếp trên màn hình?

+0

Tôi không biết nếu vẽ trực tiếp trên màn hình nền là cách tốt nhất để thực hiện việc này. Bạn biết bạn có thể có các cửa sổ không có viền/thanh tiêu đề trong X11 và đặt chúng thành không bao giờ thu nhỏ .. và nằm ở cuối ngăn xếp. Tôi nghĩ đó là những gì hầu hết các vật dụng làm. –

+0

Đây là một chủ đề tương tự có liên kết trợ giúp của tôi: http://stackoverflow.com/questions/1934442/drawing-on-the-x-root-window – CommonSense

+0

nhưng nếu đó là những gì bạn muốn xem xosd và xsnow .. mặc dù họ không sử dụng cairo, chỉ cần xlib. –

Trả lời

6

Cửa sổ "dưới cùng" là cửa sổ gốc. Vấn đề là trong một số môi trường máy tính để bàn, chúng ta có cửa sổ ở trên cùng của cửa sổ gốc, vì vậy nếu bạn thay đổi cửa sổ gốc, bạn sẽ không thấy thay đổi của mình: bạn cần thay đổi cửa sổ ở trên cùng.

Chương trình này thực hiện những gì bạn yêu cầu: vẽ trên cửa sổ gốc gốc. Để kiểm tra nó, tôi đề nghị bạn:

  • ctrl + alt + f1
  • đăng nhập như là người chủ
  • dừng môi trường máy tính để bàn của bạn ("/etc/init.d/gdm dừng", "/ etc/init.d/kdm dừng" hoặc bất cứ điều gì là cần thiết trong distro của bạn)
  • X -noreset -retro &
  • DISPLAY =: 0.0 xterm &
  • DISPLAY =: 0.0 metacity &

Sau đó, quay lại X (ctrl + alt + f7 hoặc có thể f8) và chạy chương trình.

Nếu bạn muốn vẽ trên cửa sổ trên cùng của Nautilus, bạn sẽ cần phải tìm ID cửa sổ của nó và sau đó sử dụng nó làm biến "w". Lệnh "xwininfo" có thể giúp bạn thử nghiệm ...

#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

Điều này làm việc cho tôi. Tôi có thể vẽ trên cửa sổ khác (Sublime Text) bằng cách sử dụng xwininfo để lấy ID cửa sổ, sau đó thay đổi dòng RootWindow() thành: 'Window w = (Window) 0x2400041;', sử dụng giá trị của riêng bạn cho ID của khóa học . Một điều tôi nhận thấy là nó không hoạt động cho mọi cửa sổ. Sử dụng ID cho Máy tính để bàn và cho Chrome không hoạt động. Bạn có ý kiến ​​gì không? – gsingh2011

+0

Thực ra, đủ thú vị, tôi thấy hình vuông màu đỏ trên Chrome khi tôi thay đổi tab và ngay sau đó nó biến mất ... – gsingh2011

+0

Đoán của tôi là ứng dụng chỉ vẽ trên đầu hình chữ nhật của bạn. Bạn thực sự không thể bắt đầu vẽ trên cửa sổ của ứng dụng khác vì bạn không biết khi nào họ sẽ vẽ lại trên đầu những thứ bạn đã làm. Nếu bạn muốn làm những điều kỳ lạ với nền máy tính để bàn thì tôi khuyên bạn nên xem mã nguồn của bất kỳ ứng dụng nào có trách nhiệm vẽ ở đó và sau đó thay đổi nó. Hoặc chỉ cần giết nó :) – pzanoni