mssh-window.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <gdk/gdkkeysyms.h>
  4. #include "mssh-window.h"
  5. G_DEFINE_TYPE(MSSHWindow, mssh_window, GTK_TYPE_WINDOW)
  6. static void mssh_window_sendhost(GtkWidget *widget, gpointer data)
  7. {
  8. int i;
  9. MSSHWindow *window = MSSH_WINDOW(data);
  10. for(i = 0; i < window->num_servers; i++)
  11. {
  12. if(window->terms[i] != NULL)
  13. {
  14. if(gtk_check_menu_item_get_active(
  15. GTK_CHECK_MENU_ITEM(window->items[i])))
  16. {
  17. vte_terminal_feed_child(VTE_TERMINAL(window->terms[i]),
  18. window->servers[i], strlen(window->servers[i]));
  19. }
  20. }
  21. }
  22. }
  23. static void mssh_window_destroy(GtkWidget *widget, gpointer data)
  24. {
  25. MSSHWindow *window = MSSH_WINDOW(data);
  26. free(window->terms);
  27. free(window->items);
  28. gtk_main_quit();
  29. }
  30. GtkWidget* mssh_window_new(void)
  31. {
  32. return g_object_new(MSSH_TYPE_WINDOW, NULL);
  33. }
  34. gboolean key_press(GtkWidget *widget, GdkEventKey *event,
  35. gpointer user_data)
  36. {
  37. int i;
  38. gboolean dummy;
  39. MSSHWindow *window = MSSH_WINDOW(user_data);
  40. for(i = 0; i < window->num_servers; i++)
  41. {
  42. if(window->terms[i] != NULL)
  43. {
  44. if(gtk_check_menu_item_get_active(
  45. GTK_CHECK_MENU_ITEM(window->items[i])))
  46. {
  47. g_signal_emit_by_name(window->terms[i], "key-press-event",
  48. event, &dummy);
  49. }
  50. }
  51. }
  52. return TRUE;
  53. }
  54. void vte_child_exited(VteTerminal *vte, gpointer user_data)
  55. {
  56. int i;
  57. char data[] = "\n[Child Exited]";
  58. MSSHWindow *window = MSSH_WINDOW(user_data);
  59. vte_terminal_feed(vte, data, strlen(data));
  60. for(i = 0; i < window->num_servers; i++)
  61. {
  62. if(window->terms[i] == GTK_WIDGET(vte))
  63. {
  64. window->terms[i] = NULL;
  65. break;
  66. }
  67. }
  68. }
  69. static void mssh_window_init(MSSHWindow* window)
  70. {
  71. GtkAccelGroup *accel_group;
  72. accel_group = gtk_accel_group_new();
  73. window->vbox = gtk_vbox_new(FALSE, 0);
  74. window->entry = gtk_entry_new();
  75. window->menu_bar = gtk_menu_bar_new();
  76. window->server_menu = gtk_menu_new();
  77. window->file_menu = gtk_menu_new();
  78. window->server_item = gtk_menu_item_new_with_label("Servers");
  79. window->file_item = gtk_menu_item_new_with_label("File");
  80. window->file_quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,
  81. NULL);
  82. window->file_sendhost = gtk_image_menu_item_new_with_label(
  83. "Send hostname");
  84. gtk_menu_item_set_submenu(GTK_MENU_ITEM(window->file_item),
  85. window->file_menu);
  86. gtk_menu_item_set_submenu(GTK_MENU_ITEM(window->server_item),
  87. window->server_menu);
  88. gtk_menu_shell_append(GTK_MENU_SHELL(window->file_menu),
  89. window->file_sendhost);
  90. gtk_menu_shell_append(GTK_MENU_SHELL(window->file_menu),
  91. window->file_quit);
  92. g_signal_connect(G_OBJECT(window->file_sendhost), "activate",
  93. G_CALLBACK(mssh_window_sendhost), window);
  94. g_signal_connect(G_OBJECT(window->file_quit), "activate",
  95. G_CALLBACK(mssh_window_destroy), window);
  96. gtk_widget_add_accelerator(window->file_quit, "activate", accel_group,
  97. GDK_W, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
  98. gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
  99. gtk_menu_bar_append(GTK_MENU_BAR(window->menu_bar),
  100. window->file_item);
  101. gtk_menu_bar_append(GTK_MENU_BAR(window->menu_bar),
  102. window->server_item);
  103. g_signal_connect(G_OBJECT(window->entry), "key-press-event",
  104. G_CALLBACK(key_press), window);
  105. gtk_box_pack_start(GTK_BOX(window->vbox), window->menu_bar,
  106. FALSE, TRUE, 0);
  107. gtk_box_pack_start(GTK_BOX(window->vbox), window->entry,
  108. FALSE, TRUE, 2);
  109. gtk_container_add(GTK_CONTAINER(window), window->vbox);
  110. gtk_widget_set_size_request(GTK_WIDGET(window), 1024, 768);
  111. gtk_window_set_title(GTK_WINDOW(window), "MSSH");
  112. }
  113. void mssh_window_new_session(MSSHWindow* window, char **env,
  114. int num_servers, char **servers)
  115. {
  116. char *args[3] = { NULL, NULL, NULL };
  117. int i, j, k;
  118. int rows = num_servers/2 + num_servers%2;
  119. window->env = env;
  120. window->num_servers = num_servers;
  121. window->servers = servers;
  122. window->items = malloc(sizeof(GtkWidget) * num_servers);
  123. window->terms = malloc(sizeof(GtkWidget) * num_servers);
  124. memset(window->items, 0, sizeof(GtkWidget) * num_servers);
  125. memset(window->terms, 0, sizeof(GtkWidget) * num_servers);
  126. args[0] = strdup("ssh");
  127. window->table = gtk_table_new(rows, 2, TRUE);
  128. gtk_box_pack_start(GTK_BOX(window->vbox), window->table,
  129. TRUE, TRUE, 0);
  130. for(i = 0; i < rows; i++)
  131. {
  132. for(j = 0; j < 2; j++)
  133. {
  134. k = j + i*2;
  135. if(k < num_servers)
  136. {
  137. args[1] = window->servers[k];
  138. window->terms[k] = vte_terminal_new();
  139. g_signal_connect(G_OBJECT(window->terms[k]),
  140. "child-exited", G_CALLBACK(vte_child_exited), window);
  141. vte_terminal_fork_command(VTE_TERMINAL(window->terms[k]),
  142. "ssh", args, window->env, NULL, FALSE, FALSE,
  143. FALSE);
  144. if((k == num_servers - 1) && (num_servers % 2 == 1))
  145. {
  146. gtk_table_attach(GTK_TABLE(window->table),
  147. window->terms[k], j, j+2, i, i+1,
  148. GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2,
  149. 2);
  150. }
  151. else
  152. {
  153. gtk_table_attach(GTK_TABLE(window->table),
  154. window->terms[k], j, j+1, i, i+1,
  155. GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2,
  156. 2);
  157. }
  158. window->items[k] = gtk_check_menu_item_new_with_label(
  159. window->servers[k]);
  160. gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
  161. window->items[k]), TRUE);
  162. gtk_menu_shell_append(GTK_MENU_SHELL(window->server_menu),
  163. window->items[k]);
  164. }
  165. }
  166. }
  167. free(args[0]);
  168. }
  169. static void mssh_window_class_init(MSSHWindowClass *klass)
  170. {
  171. }