自定义pidgin插件崩溃(C上的GTK库和GLib) 我正在为洋泾浜开发插件。我想通过VNC与其他用户共享在我的计算机上打开的一个窗口。当我选择要共享的窗口并按下按钮时,Pidgin冻结并关闭。
这里工作得很好:打开vnc连接并将端口名发送给其他用户。(但这一个用于共享所有屏幕。)自定义pidgin插件崩溃(C上的GTK库和GLib) 我正在为洋泾浜开发插件。我想通过VNC与其他用户共享在我的计算机上打开的一个窗口。当我选择要共享的窗口并按下按钮时,Pidgin冻结并关闭。,c,gtk,glib,vnc,pidgin,C,Gtk,Glib,Vnc,Pidgin,这里工作得很好:打开vnc连接并将端口名发送给其他用户。(但这一个用于共享所有屏幕。) 静态无效 发送按钮(GTK按钮*按钮,PIDGIN对话*gtkconv) { gchar*url_vnc; gchar*url_http; gchar*joinstr; int std_out[2]; int autoport=purple\u prefs\u get\u bool(PREF\u autoport); char x11vnc_端口[10]=“0”; if(purple_prefs_get_bo
静态无效
发送按钮(GTK按钮*按钮,PIDGIN对话*gtkconv)
{
gchar*url_vnc;
gchar*url_http;
gchar*joinstr;
int std_out[2];
int autoport=purple\u prefs\u get\u bool(PREF\u autoport);
char x11vnc_端口[10]=“0”;
if(purple_prefs_get_bool(PREF_X11VNC)&((X11VNC_pid==0)|(kill(X11VNC_pid,0)!=0)))
{
如果(紫色优先权优先权优先权优先权)
{
readableRandomString(密码,4);
}
其他的
{
strcpy(密码,紫色的prefs_get_字符串(PREF_PASSWD));
}
sprintf(x11vnc_端口,“%d”,5900+紫色_prefs_get_int(PREF_端口));
管道(标准输出);
如果((x11vnc_pid=fork())==0)
{
关闭(1);
关闭(标准输出[0]);
dup2(标准输出[1],1);
关闭(标准输出[1]);
int-ret=execlp(“x11vnc”、“x11vnc”、“共享”、“-gui”、“托盘”、“-http”、“-viewonly”、“-passwd”、密码、((自动端口)?“-autoport”:“-rfbport”)、x11vnc_端口、NULL);
佩罗尔(pidgin_vnc:x11vnc);
出口(ret);
}
关闭(标准输出[1]);
端口号=x11vnc端口;
如果(fd=fdopen(标准输出[0],“r”))
{
而(!feof(fd))
{
如果(fscanf(fd,“端口=%d”和端口数量))
打破
}
端口号-=5900;
//关闭(fd);
printf(“FINI\n”);
}
其他的
{
端口号=x11vnc端口;
}
}
常量字符*ip;
PurpleStunNatDiscovery*stunn\u res=purple\u stunn\u discover(NULL);
如果(晕眩恢复和晕眩恢复->状态==紫色晕眩恢复状态)
{
printf(“昏迷模式%d%d\n”,昏迷状态->状态,昏迷状态->类型);
ip=紫色网络获取我的ip(-1);
}
其他的
{
ip=purple_upnp_get_public_ip();
如果(ip==NULL)
{
printf(“本地模式”);
ip=紫色网络获取我的ip(-1);
}
其他的
{
printf(“UPNP模式\n”);
}
}
url_http=g_strdup_printf(“http://%s:%d/”,ip,5800+端口号);
url_vnc=g_strdup_printf(“vnc://invitation:%s@%s:%d”,密码,ip,端口号);
g_log(g_log_域、g_log_级调试、url_vnc);
joinstr=g_strdup_printf(“%s.\ntry\nor.Password=%s”、紫色的prefs_get_字符串(PREF_TEXT)、url_vnc、url_vnc、url_http、url_http、密码);
gtk_imhtml_append_text(gtk_imhtml(gtkconv->entry),joinstr,FALSE);
g_log(g_log_域,g_log_级别调试,“imhtml显示vnc\n”);
g_信号按名称发出(gtkconv->输入,“消息发送”);
g_log(g_log_域,g_log_级别调试,“已发送消息”);
g_free(url_vnc);
g_免费(url_http);
g_free(joinstr);
}
这里有个问题。当我单击按钮调用此函数时,当您单击该按钮时,程序崩溃。(此函数用于共享我的计算机上打开的一个窗口。)
静态无效
发送按钮(GTK按钮*按钮,PIDGIN对话*gtkconv)
{
gchar*url_vnc;
gchar*url_http;
gchar*joinstr;
int std_out[2];
int comboBoxSelectedRow=gtk_combo_box_get_active(combo_box));
char*selectedId[1]={0};
selectedId[0]=ekranIds[0][comboBoxSelectedRow];
int autoport=purple\u prefs\u get\u bool(PREF\u autoport);
char x11vnc_端口[10]=“0”;
if(purple_prefs_get_bool(PREF_X11VNC)&((X11VNC_pid==0)|(kill(X11VNC_pid,0)!=0)))
{
如果(紫色优先权优先权优先权优先权)
{
readableRandomString(密码,4);
}
其他的
{
strcpy(密码,紫色的prefs_get_字符串(PREF_PASSWD));
}
sprintf(x11vnc_端口,“%d”,5900+紫色_prefs_get_int(PREF_端口));
管道(标准输出);
如果((x11vnc_pid=fork())==0)
{
关闭(1);
关闭(标准输出[0]);
dup2(标准输出[1],1);
关闭(标准输出[1]);
int ret=execlp(“x11vnc”、“x11vnc”、“-id”、selectedId[0]、“-gui”、“-shared”、“tray”、“-http”、“-viewonly”、“-passwd”、password、((自动端口)?“-autoport”:“-rfbport”)、x11vnc_端口,NULL);
佩罗尔(pidgin_vnc:x11vnc);
出口(ret);
}
关闭(标准输出[1]);
端口号=x11vnc端口;
如果(fd=fdopen(标准输出[0],“r”))
{
而(!feof(fd))
{
如果(fscanf(fd,“端口=%d”和端口数量))
打破
}
端口号-=5900;
//关闭(fd);
printf(“FINI\n”);
}
其他的
{
端口号=x11vnc端口;
}
}
常量字符*ip;
PurpleStunNatDiscovery*stunn\u res=purple\u stunn\u discover(NULL);
如果(晕眩恢复和晕眩恢复->状态==紫色晕眩恢复状态)
{
printf(“昏迷模式%d%d\n”,昏迷状态->状态,昏迷状态->类型);
ip=紫色网络获取我的ip(-1);
}
其他的
{
ip=purple_upnp_get_public_ip();
如果(ip==NULL)
{
printf(“本地模式”);
ip=紫色网络获取我的ip(-1);
}
其他的
{
printf(“UPNP模式\n”);
}
}
url_http=g_strdup_printf(“http://%s:%d/”,ip,5800+端口号);
url_vnc=g_strdup_printf(“vnc://invitation:%s@%s:%d”,密码,ip,端口号);
g_log(g_log_域、g_log_级调试、url_vnc);
joinstr=g_strdup_printf(“%s.\ntry\nor.Password=%s”、紫色的prefs_get_字符串(PREF_TEXT)、url_vnc、url_vnc、url_http、url_http、密码);
gtk_imhtml_append_text(gtk_imhtml(gtkconv->entry),joinstr,FALSE);
g_log(g_log_域,g_log_级别调试,“imhtml显示vnc\n”);
g_信号按名称发出(gtkconv->输入,“消息发送”);
g_log(g_log_域,g_log_级别调试,“已发送消息”);
g_free(url_vnc);
g_免费(url_http);
g_free(joinstr);
gtk_小部件_全部显示(按钮);
}
此函数用于用打开的窗口名称填充组合框
static void
refresh_combo_box(GtkWidget *widget, PidginConversation *gtkconv)
{
FILE *fp1;
FILE *fp2;
char path[1035];
char path2[1035];
char sum[1035];
/* Open the command for reading. */
fp1 = popen("xprop -root | grep '_NET_CLIENT_LIST_STACKING(WINDOW)'", "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path) - 1, fp1) != NULL)
{
// printf("%s", path);
strcat(sum, path);
}
char *splitter = strtok(sum, "#");
splitter = strtok(NULL, "#");
char *virgulSplitter = strtok(splitter, ", ");
ekranIds[0][0] = strdup(virgulSplitter);
int a = 1;
while (virgulSplitter != NULL)
{
virgulSplitter = strtok(NULL, ",");
if (virgulSplitter != NULL)
{
ekranIds[0][a] = strdup(virgulSplitter);
a++;
}
}
for (int x = 0; x < a; x++)
{
ekranIds[0][a - 1][strcspn(ekranIds[0][a - 1], "\n")] = 0;
char tmp[500] = {0};
//here is get window names by id
sprintf(tmp, "xprop -id %s | grep '^WM_NAME'", ekranIds[0][x]);
fp2 = popen(tmp, "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
// Read the output a line at a time - output it.
while (fgets(path2, sizeof(path2) - 1, fp2) != NULL)
{
char *windowSplitter = strtok(path2, "=");
windowSplitter = strtok(NULL, "=");
ekranIds[1][x] = strdup(windowSplitter);
}
}
pclose(fp2);
pclose(fp1);
char *combobox_source[30];
for (int yf = 0; yf < 30; yf++)
{
if (ekranIds[1][yf] != NULL)
{
combobox_source[yf] = strdup(ekranIds[1][yf]);
}
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combo_box)));
for (int i = 0; i < G_N_ELEMENTS(combobox_source); i++)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), combobox_source[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
gtk_widget_show_all(combo_box);
}
静态无效
刷新组合框(GtkWidget*小部件、PidginConversation*gtkconv)
{
文件*fp1;
文件*fp2;
字符路径[1035];
char-path2[1035];
字符和[1035];
/*打开命令进行读取*/
fp1=popen(“xprop-ro
static void
send_button_cb_win(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
int comboBoxSelectedRow = gtk_combo_box_get_active(combo_box);
char *selectedId[1] = {0};
selectedId[0] = ekranIds[0][comboBoxSelectedRow];
int autoport = purple_prefs_get_bool(PREF_AUTOPORT);
char x11vnc_port[10] = "0";
if (purple_prefs_get_bool(PREF_X11VNC) && ((x11vnc_pid == 0) || (kill(x11vnc_pid, 0) != 0)))
{
if (purple_prefs_get_bool(PREF_GENPASSWD))
{
readableRandomString(password, 4);
}
else
{
strcpy(password, purple_prefs_get_string(PREF_PASSWD));
}
sprintf(x11vnc_port, "%d", 5900 + purple_prefs_get_int(PREF_PORT));
pipe(std_out);
if((x11vnc_pid = fork()) == 0)
{
close(1);
close(std_out[0]);
dup2(std_out[1], 1);
close(std_out[1]);
int ret = execlp("x11vnc", "x11vnc", "-id", selectedId[0], "-gui", "-shared", "tray", "-http", "-viewonly", "-passwd", password, ((autoport) ? "-autoport" : "-rfbport"), x11vnc_port, NULL);
perror("pidgin_vnc:x11vnc");
exit(ret);
}
close(std_out[1]);
port_num = x11vnc_port;
if (fd = fdopen(std_out[0], "r"))
{
while (!feof(fd))
{
if (fscanf(fd, "PORT=%d", &port_num))
break;
}
port_num -= 5900;
//close (fd);
printf("FINI\n");
}
else
{
port_num = x11vnc_port;
}
}
const char *ip;
PurpleStunNatDiscovery *stun_res = purple_stun_discover(NULL);
if (stun_res && stun_res->status == PURPLE_STUN_STATUS_DISCOVERED)
{
printf("STUN mode %d %d\n", stun_res->status, stun_res->type);
ip = purple_network_get_my_ip(-1);
}
else
{
ip = purple_upnp_get_public_ip();
if (ip == NULL)
{
printf("LOCAL mode\n");
ip = purple_network_get_my_ip(-1);
}
else
{
printf("UPNP mode\n");
}
}
url_http = g_strdup_printf("http://%s:%d/", ip, 5800 + port_num);
url_vnc = g_strdup_printf("vnc://invitation:%s@%s:%d", password, ip, port_num);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, url_vnc);
joinstr = g_strdup_printf("%s.\ntry <a href=\"%s\">%s</a>\nor <a href=\"%s\">%s</a>. Password=%s", purple_prefs_get_string(PREF_TEXT), url_vnc, url_vnc, url_http, url_http, password);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->entry), joinstr, FALSE);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "imhtml display vnc\n");
g_signal_emit_by_name(gtkconv->entry, "message_send");
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message sent\n");
g_free(url_vnc);
g_free(url_http);
g_free(joinstr);
gtk_widget_show_all(button);
}
static void
refresh_combo_box(GtkWidget *widget, PidginConversation *gtkconv)
{
FILE *fp1;
FILE *fp2;
char path[1035];
char path2[1035];
char sum[1035];
/* Open the command for reading. */
fp1 = popen("xprop -root | grep '_NET_CLIENT_LIST_STACKING(WINDOW)'", "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path) - 1, fp1) != NULL)
{
// printf("%s", path);
strcat(sum, path);
}
char *splitter = strtok(sum, "#");
splitter = strtok(NULL, "#");
char *virgulSplitter = strtok(splitter, ", ");
ekranIds[0][0] = strdup(virgulSplitter);
int a = 1;
while (virgulSplitter != NULL)
{
virgulSplitter = strtok(NULL, ",");
if (virgulSplitter != NULL)
{
ekranIds[0][a] = strdup(virgulSplitter);
a++;
}
}
for (int x = 0; x < a; x++)
{
ekranIds[0][a - 1][strcspn(ekranIds[0][a - 1], "\n")] = 0;
char tmp[500] = {0};
//here is get window names by id
sprintf(tmp, "xprop -id %s | grep '^WM_NAME'", ekranIds[0][x]);
fp2 = popen(tmp, "r");
if (fp1 == NULL)
{
printf("Failed to run command\n" );
exit(1);
}
// Read the output a line at a time - output it.
while (fgets(path2, sizeof(path2) - 1, fp2) != NULL)
{
char *windowSplitter = strtok(path2, "=");
windowSplitter = strtok(NULL, "=");
ekranIds[1][x] = strdup(windowSplitter);
}
}
pclose(fp2);
pclose(fp1);
char *combobox_source[30];
for (int yf = 0; yf < 30; yf++)
{
if (ekranIds[1][yf] != NULL)
{
combobox_source[yf] = strdup(ekranIds[1][yf]);
}
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combo_box)));
for (int i = 0; i < G_N_ELEMENTS(combobox_source); i++)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), combobox_source[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
gtk_widget_show_all(combo_box);
}