mssh-window.c 4.9 KB

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