I am developing plugin for Pidgin. I want to share one of my windows that are open on my computer with other user via VNC. When I select the window to be shared and press the button, Pidgin freezes and closes.
Here is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
static void
send_button_cb(GtkButton *button, PidginConversation *gtkconv)
{
gchar *url_vnc;
gchar *url_http;
gchar *joinstr;
int std_out[2];
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", "-shared", "-gui", "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);
}
There is a problem in here. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
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);
}
This function to fill combobox with opened windows names
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);
}
First function is working well: opening vnc connection and sends Port name to other users. (but this one for sharing all of screen.)
Second function has problem. When I click to button which is calling this function program crashes when you click the button.(this function for sharing one of my windows that are open on my computer.)
Third function to fill combobox with opened windows' names.