国嵌实时监控系统代码笔记(四)采集端 gtk

<span style="font-size:14px;">#include "wcam.h"


__u64 clock_get_time_us()
{
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    return (__u64)ts.tv_sec * 1000000LL + (__u64)ts.tv_nsec / 1000LL;
}

void draw_video_frame(const void *p, int size, void *arg)//该显示函数用于net.c中
{
    struct wcam_win *c      = arg;
    GdkPixbufLoader *pixbuf_loader;
    GdkPixbuf       *pixbuf;
    GdkPixbuf       *pixbuf4fullscreen = NULL;
    GdkScreen       *screen;
    cairo_t         *cr;
    gchar           outstr[100];
    gfloat          fps; 
    guint64         now_us;

    gdk_threads_enter();
    
    /* update frame size label */
    sprintf(outstr, "%d 瀛楄妭", size);
    gtk_label_set_text(GTK_LABEL(c->frmsize_label), outstr);

    /* update fps label */
    c->frm_cnt++;
    if (c->frm_cnt == 1) {
        c->last_twenty_frm_us = clock_get_time_us();
    } else if (c->frm_cnt > 10) {
        now_us = clock_get_time_us();
        fps = 10.0 * 1000000.0 / (now_us - c->last_twenty_frm_us);
        c->frm_cnt = 0;
        sprintf(outstr, "%2.1f 甯?绉?, fps);
        gtk_label_set_text(GTK_LABEL(c->fps_label), outstr);
    }

    /* update video */
    pixbuf_loader = gdk_pixbuf_loader_new(); 		
    gdk_pixbuf_loader_write(pixbuf_loader, p, size, NULL); //将图像写入pixbuf_loader中
    gdk_pixbuf_loader_close(pixbuf_loader, NULL); 
    pixbuf = gdk_pixbuf_loader_get_pixbuf(pixbuf_loader);  //将图像写入pixbuf中

    /*创建cairo*/
    cr = gdk_cairo_create(c->video_area->window);//创建一个图像显示窗口
    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);//将pixbuf中的图像导入显示窗口

    cairo_paint(cr);//绘制图像到窗口上
    cairo_destroy(cr);

    g_object_unref(pixbuf_loader);
    if (pixbuf4fullscreen)
        g_object_unref(pixbuf4fullscreen);
        
	gdk_threads_leave();

    if (c->need_snapshot) {     /* Maybe we should open a file_save_dialog here */
        char img_path[100];     /* or maybe we should make the image_storage_path Configurable */ 
        FILE *fp;               
        time_t t;
        struct tm *tmp;
        t = time(NULL);
        tmp = localtime(&t);

        strftime(outstr, sizeof(outstr), "%F-%T", tmp);
        printf(SNAPSHOT_PATH"/webcam-%s.jpg\n", outstr);
        printf(SNAPSHOT_PATH"/webcam-%s.jpg", outstr);
        sprintf(img_path, SNAPSHOT_PATH"/webcam-%s.jpg", outstr);
        fp = fopen(img_path, "w");        
        fwrite(p, size, 1, fp);
        fclose(fp);
        c->need_snapshot = FALSE;
    }
}


static void connect_handler(GtkButton *button, gpointer data) 
{
    	struct entry_win *c = data;
    
        const gchar      *ip;
    	gint16           port;

	ip   = gtk_entry_get_text(GTK_ENTRY(c->ip_entry));//获取ip地址
	port = atoi(gtk_entry_get_text(GTK_ENTRY(c->port_entry)));//获取端口
	
	c->sock = tcp_init_net(ip,port);//连接ip和端口并返回sock描述符
    
        c->connected = TRUE;
        gtk_main_quit();	    //窗口退出
}


static gboolean logo_draw(struct entry_win *c, GtkWidget* box)
{
	gtk_box_pack_start_defaults(GTK_BOX(box), gtk_image_new_from_file(LOGO_IMG));//logo在wcam.h有地址
	gtk_box_pack_start_defaults(GTK_BOX(box), gtk_image_new_from_file(LOGO_IMG1));//修改很方便
	return TRUE;
}

static gboolean entry_area_draw(struct entry_win *c, GtkWidget* box)
{
	GtkWidget *label;	
	GtkWidget *entry;	

    /* Connect to */
	label = gtk_label_new("杩炴帴鍒?");//窗口边的serverip字符,"杩炴帴鍒?"不知是什么原因改变了
    gtk_box_pack_start_defaults(GTK_BOX(box), label);
	
	entry = gtk_entry_new();//创建窗口
	gtk_entry_set_text(GTK_ENTRY(entry), DEF_CONN_IP);//创建entry标签text,DEF_CONN_IP在wcam.h中定义好了
	gtk_entry_set_max_length(GTK_ENTRY(entry), 15);//文本entry最大长度

    gtk_box_pack_start_defaults(GTK_BOX(box), entry);//把创建好的文本框放到水平容器上
    c->ip_entry = entry;	//ip_entry取entry字符串
	
    /* Port */
	label = gtk_label_new("绔彛:");
    gtk_box_pack_start_defaults(GTK_BOX(box), label);	

	entry = gtk_entry_new();
	gtk_entry_set_text(GTK_ENTRY(entry), DEF_PORT);
	gtk_entry_set_max_length(GTK_ENTRY(entry), 5);

    gtk_box_pack_start_defaults(GTK_BOX(box), entry);	
    c->port_entry = entry;	

	return TRUE;
}

static gboolean
button_area_draw(struct entry_win *c, GtkWidget* box)//ok和退出按钮
{
	GtkWidget *button;
	
	/* Connect Button */
	button = gtk_button_new_with_label("杩炴帴");  
    gtk_box_pack_start_defaults(GTK_BOX(box), button);
    c->connect_button = button;
	//按钮关联事件
    g_signal_connect(button, "clicked", G_CALLBACK(connect_handler), c);		

	/* Quit Button */
	button = gtk_button_new_with_label("閫€鍑?);  
    gtk_box_pack_start_defaults(GTK_BOX(box), button);
	
    g_signal_connect(button, "clicked", G_CALLBACK(gtk_main_quit), NULL);	

	return TRUE;
}


static gboolean entry_win_draw_face(struct entry_win *c)//入口界面
{
    GtkWidget *vbox;
    GtkWidget *hbox;	

    vbox = gtk_vbox_new(FALSE, 5);
    gtk_container_add(GTK_CONTAINER(c->win), vbox);          
 	
    /* logo */
    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
	
	logo_draw(c, hbox);//draw函数是关键

	/* entry */
	hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
	entry_area_draw(c, hbox);

	/* button */
	hbox = gtk_hbutton_box_new();
	gtk_box_set_spacing(GTK_BOX(hbox), 5);
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);	
    gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
	button_area_draw(c, hbox);

    return TRUE;
}

static gboolean key_press_func(GtkWidget* widget, GdkEventKey* key, gpointer data)
{
#define KEY_ENTER 0xff0d
#define KEY_ESC   0xff1b
    struct entry_win *c = data;
    if (KEY_ENTER == key->keyval) 
    {
	connect_handler(GTK_BUTTON(c->connect_button), c); 
        return TRUE;
    } else if (KEY_ESC == key->keyval) 
    {
	c->connected = FALSE; 
        gtk_main_quit();
        return TRUE;
    }
	return FALSE;
} 

entry_win_t login_create()
{
    struct entry_win *c = calloc(1, sizeof(struct entry_win));
    if (!c) {
		perror("entry_win_create");
		return NULL;
	}
    c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);     
 
    gtk_window_set_title(GTK_WINDOW(c->win), WIN_TITLE);                
    gtk_window_set_icon(GTK_WINDOW(c->win), 
                        gdk_pixbuf_new_from_file(WIN_ICON, NULL));
    gtk_window_set_position(GTK_WINDOW(c->win), GTK_WIN_POS_CENTER); 
    gtk_window_set_resizable(GTK_WINDOW(c->win), FALSE);       
    gtk_container_set_border_width(GTK_CONTAINER(c->win), 0); 

    g_signal_connect(GTK_OBJECT(c->win), "destroy",
                     G_CALLBACK(gtk_main_quit), NULL);

    g_signal_connect(G_OBJECT(c->win), "key_press_event",
                     G_CALLBACK(key_press_func), c);
	
    
    gtk_widget_set_app_paintable(c->win, TRUE);

	entry_win_draw_face(c);
	
    gtk_widget_show_all(c->win);
    return c;
}

int login_run(entry_win_t win)
{
    struct entry_win *c = win; 
    gtk_main();//启动入口界面
    return c->connected == TRUE ? 0 : -1;
}

void login_hide(entry_win_t win)
{
    struct entry_win *c = win; 
    
    /*隐藏登录窗口*/
    gtk_widget_hide_all(c->win);
}



/*------------主窗口-------------------*/

int entry_win_get_ip(entry_win_t win, char *ip)
{
    struct entry_win *c = win; 
    if (c->connected == FALSE)
        return -1;
    strcpy(ip, gtk_entry_get_text(GTK_ENTRY(c->ip_entry)));//将ip_entry字符串化拷贝到ip
    return 0;
}

int entry_win_get_port(entry_win_t win, char *port)
{
    struct entry_win *c = win; 
    if (c->connected == FALSE)
        return -1;
    strcpy(port, gtk_entry_get_text(GTK_ENTRY(c->port_entry)));
    return 0;
}

void main_quit(GtkWidget *Object, gpointer data) 
{
    gtk_main_quit();
}

static gboolean
draw_area_draw(struct wcam_win *c, GtkWidget *box)
{
    c->video_area = gtk_drawing_area_new();
    gtk_widget_set_size_request(c->video_area, c->video_width, c->video_height);
	gtk_box_pack_start(GTK_BOX(box), c->video_area, FALSE, FALSE, 0);
	
    gtk_widget_add_events(c->video_area, GDK_BUTTON_PRESS_MASK);

	return TRUE;
}

static gboolean info_area_draw(struct wcam_win *c, GtkWidget *box)
{
	GtkWidget   *frame;
	GtkWidget   *table;
	GtkWidget   *label;
	GtkWidget   *align;
	GtkWidget   *separator;
    gchar       buf[256];

	frame = gtk_frame_new("淇℃伅鍖?);
    c->info_area = frame;
	gtk_box_pack_start_defaults(GTK_BOX(box), frame);

	table = gtk_table_new(9, 2, FALSE);
	gtk_container_add(GTK_CONTAINER(frame), table);
	
    /* VERSION & HOMEPAGE */
    label = gtk_label_new("涓婚〉:");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_link_button_new_with_label(WCAM_HOMEPAGE, "www.enjoylinux.cn");
    align = gtk_alignment_new(0, 0, 0, 0);	            /* 宸﹀榻?*/
    gtk_container_add(GTK_CONTAINER(align), label);	
    gtk_table_attach(GTK_TABLE(table), align, 1, 2, 0, 1,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_label_new("鐗堟湰:");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_label_new(WCAM_VERSION);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2,
                     GTK_FILL, GTK_SHRINK, 8, 1);

    /* IP & PORT */
    label = gtk_label_new("鏈嶅姟鍣?");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_label_new(c->ipaddr);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3,
                     GTK_FILL, GTK_SHRINK, 8, 1);

    separator = gtk_hseparator_new(); 
    gtk_table_attach(GTK_TABLE(table), separator, 0, 1, 3, 4,
                     GTK_FILL, GTK_SHRINK, 1, 1);
    separator = gtk_hseparator_new(); 
    gtk_table_attach(GTK_TABLE(table), separator, 1, 2, 3, 4,
                     GTK_FILL | GTK_EXPAND, GTK_SHRINK, 1, 1);

    /* Frame Format */
    label = gtk_label_new("甯ф牸寮?");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    sprintf(buf, "%c%c%c%c", (c->video_format)&0xFF,
                             (c->video_format>>8)&0xFF,
                             (c->video_format>>16)&0xFF,
                             (c->video_format>>24)&0xFF);
    label = gtk_label_new(buf);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 4, 5,
                     GTK_FILL, GTK_SHRINK, 8, 1);

    /* Frame width x height */
    label = gtk_label_new("甯у昂瀵?");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    sprintf(buf, "%d x %d", c->video_width, c->video_height); 
    label = gtk_label_new(buf);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 5, 6,
                     GTK_FILL, GTK_SHRINK, 8, 1);

    /* Frame Size */
    label = gtk_label_new("甯уぇ灏?");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_label_new("0");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 6, 7,
                     GTK_FILL, GTK_SHRINK, 8, 1);
    c->frmsize_label = label;

    /* FPS */
    label = gtk_label_new("甯ч€熺巼:");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8,
                     GTK_FILL, GTK_SHRINK, 1, 1);

    label = gtk_label_new("0");
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 1, 2, 7, 8,
                     GTK_FILL, GTK_SHRINK, 8, 1);
    c->fps_label = label;

    /* hseparator */
    separator = gtk_hseparator_new(); 
    gtk_table_attach(GTK_TABLE(table), separator, 0, 1, 8, 9,
                     GTK_FILL, GTK_SHRINK, 1, 1);
    separator = gtk_hseparator_new(); 
    gtk_table_attach(GTK_TABLE(table), separator, 1, 2, 8, 9,
                     GTK_FILL, GTK_SHRINK, 1, 1);

	return TRUE;
}

static gboolean main_button_area_draw(struct wcam_win *c, GtkWidget *box)
{
	GtkWidget *buttonbox;		
	GtkWidget *button;		
	GtkWidget *hbox;		
	GtkWidget *label;	
	GtkWidget *image;	

	buttonbox = gtk_hbutton_box_new();
    gtk_box_pack_start(GTK_BOX(box), buttonbox, FALSE, FALSE, 0);
    c->button_area = buttonbox;
 	/* control button */
	image = gtk_image_new_from_file(SETTING_BUTTON_IMG);
	label = gtk_label_new("鏄剧ず鎺у埗椤?");
	hbox = gtk_hbox_new(FALSE, 5);
	gtk_box_pack_start_defaults(GTK_BOX(hbox), image);
	gtk_box_pack_start_defaults(GTK_BOX(hbox), label);

	button = gtk_check_button_new();	
	gtk_container_add(GTK_CONTAINER(button), hbox);
    c->control_area_button = button;
	
	gtk_box_pack_start_defaults(GTK_BOX(buttonbox), button);	
	
 	/* snapshot button */
	image = gtk_image_new_from_file(SNAP_BUTTON_IMG);
	label = gtk_label_new("蹇収");
	hbox  = gtk_hbox_new(FALSE, 5);
	gtk_box_pack_start_defaults(GTK_BOX(hbox), image);
	gtk_box_pack_start_defaults(GTK_BOX(hbox), label);

	button = gtk_button_new();	
	gtk_container_add(GTK_CONTAINER(button), hbox);
	
	gtk_box_pack_start_defaults(GTK_BOX(buttonbox), button);
  

	return TRUE;
}

static gboolean main_win_draw_face(struct wcam_win *c)
{
    GtkWidget *box;
    GtkWidget *hbox;	
    GtkWidget *hseparator;	

    box = gtk_vbox_new(FALSE, 5);
    gtk_container_add(GTK_CONTAINER(c->win), box);          

 	/* draw_area & info_area */
    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, TRUE, 0);
	draw_area_draw(c, hbox);
    info_area_draw(c, hbox);	

 	/* hseparator */
	hseparator=gtk_hseparator_new(); 
    gtk_box_pack_start(GTK_BOX(box), hseparator, FALSE, TRUE, 0);
    
 	/* button_area */
    main_button_area_draw(c, box);

 	/* control_area */
   // control_area_draw(c, box);

    return TRUE;
}

static gboolean main_create(struct wcam_win *c)
{
    int len;
    /*------------初始化----------------*/
    c->video_width = 640;
    c->video_height = 480;

    /* 全屏 */
    c->video_fullscreen = FALSE;
    
    /* ip & port */
    entry_win_get_ip(c->entry_win, c->ipaddr);

    len = strlen(c->ipaddr);

    c->ipaddr[len] = ':';
    entry_win_get_port(c->entry_win, &c->ipaddr[len+1]);
	
	
    c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
 	
    /* 璁剧疆绐楀彛鏍囬 */
    gtk_window_set_title(GTK_WINDOW(c->win), WIN_TITLE);                

    gtk_window_set_icon(GTK_WINDOW(c->win), 
                        gdk_pixbuf_new_from_file(WIN_ICON, NULL));
    
    /* 绐楀彛杈规澶у皬璁剧疆涓? */
    gtk_container_set_border_width(GTK_CONTAINER(c->win), 0); 
    
    g_signal_connect(c->win, "destroy",
                     G_CALLBACK(main_quit), c);
    gtk_widget_set_app_paintable(c->win, TRUE);

	main_win_draw_face(c);

    gtk_widget_show_all(c->win);
    
    gtk_widget_hide(c->win);
    gtk_window_set_position(GTK_WINDOW(c->win), GTK_WIN_POS_CENTER); 
    gtk_widget_show(c->win);

    return TRUE;
}

void main_run( )
{
    gtk_main();
}

gint main(gint argc,gchar* argv[])
{	
    int res;
    	
    gtk_init(&argc, &argv);
    	
    g_thread_init(NULL);
    
    gdk_threads_init();
    

    struct wcam_win *c = calloc(1, sizeof(struct wcam_win));

    c->entry_win = login_create();
    
    res = login_run(c->entry_win);//启动入口界面
    if (res == -1) {
        goto err_win;
    }
    
    login_hide(c->entry_win);//关闭入口界面
    
    net_sys_init(c);//开始接收图像数据
  
    main_create(c);//创建主界面
    
    main_run();//启动主窗口

err_win:
    free(c->entry_win);
    free(c);

    return 0;
}
</span>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值