用gdk实现抓屏与X Window ID

用gdk实现抓屏与X Window ID

最近看GDK,看到一段抓屏的代码还不错,所以贴出来分享。
环境:Ubuntu 8.04
编译:gcc -o capture capture.c `pkg-config --libs --cflags gtk+-2.0`
执行:capture [-options...],不带参数延迟3秒,输出文件名为当前时间.jpg
    -o outputfilename 
    -s delayseconds
 
除了这段代码外,还有几点相关的知识点:
1. GDK_WINDOW_XID(GdkWindow)或GDK_DRAWABLE_XID(GdkDrawable)可以将 GdkWindow/GdkDrawable转化为X window id,如果是GtkWindow,这么转:GTK_WIDGET(GtkWindow)->window
注意: windows id必须在show(比如gtk_widget_show)以后才能得到id的,否则会报warning并返回0
2. 在Ubuntu里测试的结果root window是0x41,而桌面的id往往是0X12000xx,桌面背景覆盖在root窗口上,所以root window你在GNOME环境下看不见,不过如果开机启动到控制台然后执行xinit(或者有些机器在进入GNOME加载显卡驱动前)你看到的灰色网格背景的窗口就是root window了;
3. 你可以自己新建一个窗口让mplayer的video输出到这个窗口上:mplayer -wid 0Xxxxx xxx.avi
4. 参考Ubuntu下的一个工具xwininfo,可以抓窗口的id,位置,大小等信息
usage:  xwininfo [-options ...]
where options include:
    -help                print this message
    -display host:dpy    X server to contact
    -root                use the root window
    -id windowid         use the window with the specified id
    -name windowname     use the window with the specified name
    -int                 print window id in decimal
    -children            print parent and child identifiers
    -tree                print children identifiers recursively
    -stats               print window geometry [DEFAULT]
    -bits                print window pixel information
    -events              print events selected for on window
    -size                print size hints
    -wm                  print window manager hints
    -shape               print shape extents
    -frame               don't ignore window manager frames
    -english             print sizes in english units
    -metric              print sizes in metric units
    -all                 -tree, -stats, -bits, -events, -wm, -size, -shape

 
/*--------------Begin:capture.c------------------*/
#include <gtk/gtk.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <gdk/gdkx.h>
void do_capture_screenshot (char *file, int sec)
{
 gint x, y;
 GdkScreen* cur_screen = NULL;
 GdkWindow* window = NULL;
 GdkPixbuf* pixbuf_screenshot = NULL;
 GdkRectangle rect;
 GdkRectangle screen_rect;
 g_printf("ready to capture.....\r\n");
 sleep(sec);
 if (cur_screen == NULL)
 cur_screen = gdk_screen_get_default (); //get screen
 screen_rect.x = 0;
 screen_rect.y = 0;
 screen_rect.width = gdk_screen_get_width (cur_screen); //get screen width
 screen_rect.height = gdk_screen_get_height (cur_screen); //get screen height
 g_print("screen_rect: x=%d,y=%d,w=%d,h=%d\n",screen_rect.x,screen_rect.y,screen_rect.width,screen_rect.height);
 window = gdk_screen_get_root_window (cur_screen); //get window by screen
 //Window xwin = GDK_WINDOW_XID(window);  //get window id
 //g_print("xwindow id is %x\n",xwin);
 gdk_window_get_origin (window, &x, &y); //get origin point
 rect.x = x;
 rect.y = y;
 gdk_drawable_get_size (GDK_DRAWABLE (window), &rect.width,&rect.height); //get drawable size
 g_print("rect: x=%d,y=%d,w=%d,h=%d\n",rect.x,rect.y,rect.width,rect.height);
 if (! gdk_rectangle_intersect (&rect, &screen_rect, &rect)) { //obtain the intersect area from rect and screen_rect
 g_print("Capture failed!...\r\n");
 return;
 }
 g_print("capture rect: x=%d,y=%d,w=%d,h=%d\n",rect.x,rect.y,rect.width,rect.height);
 pixbuf_screenshot = gdk_pixbuf_get_from_drawable (NULL, window,
 NULL,rect.x - x, rect.y - y, 0, 0,
 rect.width, rect.height); //get pixbuf from drawable widget
  gdk_pixbuf_save (pixbuf_screenshot, file, "jpeg", NULL, "quality","100", NULL); //save pixbuf to jpeg format file
 g_object_unref (pixbuf_screenshot);  //free pixbuf
 g_print("Capture saved!!!\r\n");
 return;
}
int main( int argc, char *argv[])
{
 int cmd, sec;
 char *file = NULL;
 time_t tt;
 struct tm *tm_ptr = NULL;
 file = (char *)malloc(32);
 time(&tt);
 tm_ptr = localtime(&tt);
 strftime(file, 32, "%Y%m%d%H%M%S", tm_ptr);
 strcat(file, ".jpg");
 sec = 3;
 gtk_init (&argc, &argv);
 while ((cmd = getopt(argc, argv, "o:s:")) != -1) {
 switch (cmd) {
 case 'o':
 file = optarg;
 break;
 case 's':
 sec = atoi(optarg);
 break;
 default:
 break;
 }
}
do_capture_screenshot(file, sec);
return 0;
}
 

 

你可能感兴趣的:(xWindow)