自定义pidgin插件崩溃(C上的GTK库和GLib) 我正在为洋泾浜开发插件。我想通过VNC与其他用户共享在我的计算机上打开的一个窗口。当我选择要共享的窗口并按下按钮时,Pidgin冻结并关闭。

自定义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

这里工作得很好:打开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_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);
}