transmit_dialog.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:12k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  * Bill May  wmay@cisco.com
  21.  */
  22. #define __STDC_LIMIT_MACROS
  23. #include "mp4live.h"
  24. #include "mp4live_gui.h"
  25. #include <sys/socket.h>
  26. #include <netinet/in.h>
  27. #include <arpa/inet.h>
  28. #include <netdb.h>
  29. #include "rtp_transmitter.h"
  30. static GtkWidget *dialog;
  31. static GtkWidget *unicast_button;
  32. static GtkWidget *mcast_button;
  33. static GtkWidget *address_entry;
  34. static bool address_modified;
  35. static GtkWidget *video_port_entry;
  36. static bool video_port_modified;
  37. static GtkWidget *audio_port_entry;
  38. static bool audio_port_modified;
  39. static GtkWidget *mcast_ttl_menu;
  40. static GtkWidget *sdp_file_entry;
  41. static GtkWidget *address_generate_button;
  42. static GtkWidget *sdp_generate_button;
  43. static u_int8_t ttlValues[] = {
  44. 1, 15, 63, 127
  45. };
  46. static char* ttlNames[] = {
  47. "LAN - 1", "Organization - 15", "Regional - 63", "Worldwide - 127"
  48. };
  49. static u_int8_t ttlIndex;
  50. static void on_destroy_dialog (GtkWidget *widget, gpointer *data)
  51. {
  52. gtk_grab_remove(dialog);
  53. gtk_widget_destroy(dialog);
  54. dialog = NULL;
  55. static void on_unicast (GtkWidget *widget, gpointer *data)
  56. {
  57. bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  58. gtk_widget_set_sensitive(GTK_WIDGET(address_generate_button), !enabled);
  59. gtk_widget_set_sensitive(GTK_WIDGET(mcast_ttl_menu), !enabled);
  60. }
  61. static void on_changed (GtkWidget *widget, gpointer *data)
  62. {
  63. if (widget == address_entry) {
  64. address_modified = true;
  65. } else if (widget == video_port_entry) {
  66. video_port_modified = true;
  67. } else if (widget == audio_port_entry) {
  68. audio_port_modified = true;
  69. }
  70. }
  71. bool ValidateAddress(GtkWidget* widget)
  72. {
  73. const char* address = gtk_entry_get_text(GTK_ENTRY(widget));
  74. struct in_addr in;
  75. if (inet_pton(AF_INET, address, &in) > 0) {
  76. return true;
  77. }
  78. struct in6_addr in6;
  79. if (inet_pton(AF_INET6, address, &in6) > 0) {
  80. return true;
  81. }
  82. // Might have a DNS address...
  83. if (gethostbyname(address) != NULL) {
  84. return true;
  85. }
  86. ShowMessage("Transmission Address", "Invalid address entered");
  87. return false;
  88. }
  89. static void on_address_leave(GtkWidget *widget, gpointer *data)
  90. {
  91. if (!address_modified) {
  92. return;
  93. }
  94. ValidateAddress(widget);
  95. }
  96. bool ValidatePort(GtkWidget* entry, u_int16_t* port)
  97. {
  98. int value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(entry));
  99. if (value < 1024 || value > 65534 || (value & 1)) {
  100. ShowMessage("Transmission Port Number",
  101. "Please enter an even number between 1024 and 65534");
  102. // TBD gtk_widget_grab_focus(widget);
  103. return false;
  104. }
  105. if (port) {
  106. *port = value;
  107. }
  108. return true;
  109. }
  110. static void on_port_leave(GtkWidget *widget, gpointer *data)
  111. {
  112. if (widget == video_port_entry) {
  113. if (!video_port_modified) {
  114. return;
  115. }
  116. } else { // widget == audio_port_entry
  117. if (!audio_port_modified) {
  118. return;
  119. }
  120. }
  121. ValidatePort(widget, NULL);
  122. }
  123. static void on_ttl_menu_activate (GtkWidget *widget, gpointer data)
  124. {
  125. ttlIndex = (unsigned int)data & 0xFF;
  126. }
  127. static void on_address_generate (GtkWidget *widget, gpointer *data)
  128. {
  129. struct in_addr in;
  130. in.s_addr = CRtpTransmitter::GetRandomMcastAddress();
  131. gtk_entry_set_text(GTK_ENTRY(address_entry), inet_ntoa(in));
  132. u_int16_t portBlock = CRtpTransmitter::GetRandomPortBlock();
  133. gtk_spin_button_set_value(GTK_SPIN_BUTTON(video_port_entry), portBlock);
  134. gtk_spin_button_set_value(GTK_SPIN_BUTTON(audio_port_entry), portBlock + 2);
  135. }
  136. static bool ValidateAndSave(void)
  137. {
  138. if (!ValidateAddress(address_entry)) {
  139. return false;
  140. }
  141. u_int16_t videoPort;
  142.   if (!ValidatePort(video_port_entry, &videoPort)) {
  143. return false;
  144. }
  145. u_int16_t audioPort;
  146.   if (!ValidatePort(audio_port_entry, &audioPort)) {
  147. return false;
  148. }
  149. if (videoPort == audioPort) {
  150. ShowMessage("Port Error", 
  151. "Video and audio ports must be different");
  152. return false;
  153. }
  154. // copy new values to config
  155. MyConfig->SetStringValue(CONFIG_RTP_DEST_ADDRESS, 
  156. gtk_entry_get_text(GTK_ENTRY(address_entry)));
  157. MyConfig->SetIntegerValue(CONFIG_RTP_VIDEO_DEST_PORT, videoPort);
  158. MyConfig->SetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT, audioPort);
  159. MyConfig->SetIntegerValue(CONFIG_RTP_MCAST_TTL, ttlValues[ttlIndex]);
  160. MyConfig->SetStringValue(CONFIG_SDP_FILE_NAME,
  161. gtk_entry_get_text(GTK_ENTRY(sdp_file_entry)));
  162. DisplayTransmitSettings();  // display settings in main window
  163. return true;
  164. }
  165. static void on_sdp_generate (GtkWidget *widget, gpointer *data)
  166. {
  167. // check and save values
  168. if (!ValidateAndSave()) {
  169. return;
  170. }
  171. if (GenerateSdpFile(MyConfig)) {
  172. char buffer[256];
  173. snprintf(buffer, sizeof(buffer), "SDP file %s written",
  174. MyConfig->GetStringValue(CONFIG_SDP_FILE_NAME));
  175. ShowMessage("Generate SDP file", buffer); 
  176. } else {
  177. ShowMessage("Generate SDP file", 
  178. "SDP file couldn't be written, check file name");
  179. }
  180. }
  181. static void on_ok_button (GtkWidget *widget, gpointer *data)
  182. {
  183. // check and save values
  184. if (!ValidateAndSave()) {
  185. return;
  186. }
  187.     on_destroy_dialog(NULL, NULL);
  188. }
  189. static void on_cancel_button (GtkWidget *widget, gpointer *data)
  190. {
  191. on_destroy_dialog(NULL, NULL);
  192. }
  193. void CreateTransmitDialog (void) 
  194. {
  195. GtkWidget* hbox;
  196. GtkWidget* vbox;
  197. GSList* radioGroup;
  198. GtkWidget* label;
  199. GtkWidget* button;
  200. GtkObject* adjustment;
  201. dialog = gtk_dialog_new();
  202. gtk_signal_connect(GTK_OBJECT(dialog),
  203. "destroy",
  204. GTK_SIGNAL_FUNC(on_destroy_dialog),
  205. &dialog);
  206. gtk_window_set_title(GTK_WINDOW(dialog), "Transmission Settings");
  207. hbox = gtk_hbox_new(TRUE, 1);
  208. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
  209. FALSE, FALSE, 5);
  210. gtk_widget_show(hbox);
  211. // Unicast/Multicast radio
  212. bool isMcast = true;
  213. if (MyConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS) != NULL) {
  214. struct in_addr in;
  215. if (inet_aton(MyConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS), &in)) {
  216. isMcast = IN_MULTICAST(ntohl(in.s_addr));
  217. } else {
  218. isMcast = false;
  219. }
  220. }
  221. unicast_button = gtk_radio_button_new_with_label(NULL, "Unicast");
  222. gtk_widget_show(unicast_button);
  223. gtk_signal_connect(GTK_OBJECT(unicast_button), 
  224. "toggled",
  225.  GTK_SIGNAL_FUNC(on_unicast),
  226.  NULL);
  227. gtk_box_pack_start(GTK_BOX(hbox), unicast_button,
  228. FALSE, FALSE, 5);
  229. radioGroup = gtk_radio_button_group(GTK_RADIO_BUTTON(unicast_button));
  230. mcast_button = gtk_radio_button_new_with_label(radioGroup, "Multicast");
  231. gtk_widget_show(mcast_button);
  232. gtk_box_pack_start(GTK_BOX(hbox), mcast_button,
  233. FALSE, FALSE, 5);
  234. hbox = gtk_hbox_new(FALSE, 1);
  235. gtk_widget_show(hbox);
  236. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
  237. FALSE, FALSE, 5);
  238. vbox = gtk_vbox_new(TRUE, 1);
  239. gtk_widget_show(vbox);
  240. gtk_box_pack_start(GTK_BOX(hbox), vbox,
  241. FALSE, FALSE, 5);
  242. label = gtk_label_new(" Address:");
  243. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  244. gtk_widget_show(label);
  245. gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
  246. label = gtk_label_new(" Video Port:");
  247. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  248. gtk_widget_show(label);
  249. gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
  250. label = gtk_label_new(" Audio Port:");
  251. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  252. gtk_widget_show(label);
  253. gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
  254. label = gtk_label_new(" TTL:");
  255. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  256. gtk_widget_show(label);
  257. gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
  258. label = gtk_label_new(" SDP File:");
  259. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  260. gtk_widget_show(label);
  261. gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
  262. vbox = gtk_vbox_new(TRUE, 1);
  263. gtk_widget_show(vbox);
  264. gtk_box_pack_start(GTK_BOX(hbox), vbox,
  265. TRUE, TRUE, 5);
  266. address_entry = gtk_entry_new_with_max_length(128);
  267. gtk_entry_set_text(GTK_ENTRY(address_entry), 
  268. MyConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS));
  269. address_modified = false;
  270. SetEntryValidator(GTK_OBJECT(address_entry),
  271. GTK_SIGNAL_FUNC(on_changed),
  272. GTK_SIGNAL_FUNC(on_address_leave));
  273. gtk_widget_show(address_entry);
  274. gtk_box_pack_start(GTK_BOX(vbox), address_entry, TRUE, TRUE, 0);
  275. adjustment = gtk_adjustment_new(
  276. MyConfig->GetIntegerValue(CONFIG_RTP_VIDEO_DEST_PORT),
  277. 1024, 65534, 2, 0, 0);
  278. video_port_entry = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 2, 0);
  279. video_port_modified = false;
  280. SetEntryValidator(GTK_OBJECT(video_port_entry),
  281. GTK_SIGNAL_FUNC(on_changed),
  282. GTK_SIGNAL_FUNC(on_port_leave));
  283. gtk_widget_show(video_port_entry);
  284. gtk_box_pack_start(GTK_BOX(vbox), video_port_entry, FALSE, FALSE, 0);
  285. adjustment = gtk_adjustment_new(
  286. MyConfig->GetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT),
  287. 1024, 65534, 2, 0, 0);
  288. audio_port_entry = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 2, 0);
  289. audio_port_modified = false;
  290. SetEntryValidator(GTK_OBJECT(audio_port_entry),
  291. GTK_SIGNAL_FUNC(on_changed),
  292. GTK_SIGNAL_FUNC(on_port_leave));
  293. gtk_widget_show(audio_port_entry);
  294. gtk_box_pack_start(GTK_BOX(vbox), audio_port_entry, TRUE, TRUE, 0);
  295. ttlIndex = 0; 
  296. for (u_int8_t i = 0; i < sizeof(ttlValues) / sizeof(u_int8_t); i++) {
  297. if (MyConfig->GetIntegerValue(CONFIG_RTP_MCAST_TTL) == ttlValues[i]) {
  298. ttlIndex = i;
  299. break;
  300. }
  301. }
  302. mcast_ttl_menu = CreateOptionMenu (NULL,
  303. ttlNames, 
  304. sizeof(ttlNames) / sizeof(char*),
  305. ttlIndex,
  306. GTK_SIGNAL_FUNC(on_ttl_menu_activate));
  307. gtk_box_pack_start(GTK_BOX(vbox), mcast_ttl_menu, TRUE, TRUE, 0);
  308. sdp_file_entry = gtk_entry_new_with_max_length(128);
  309. gtk_entry_set_text(GTK_ENTRY(sdp_file_entry), 
  310. MyConfig->GetStringValue(CONFIG_SDP_FILE_NAME));
  311. gtk_widget_show(sdp_file_entry);
  312. gtk_box_pack_start(GTK_BOX(vbox), sdp_file_entry, TRUE, TRUE, 0);
  313. vbox = gtk_vbox_new(FALSE, 1);
  314. gtk_widget_show(vbox);
  315. gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
  316. address_generate_button = gtk_button_new_with_label(" Generate ");
  317. gtk_signal_connect(GTK_OBJECT(address_generate_button), 
  318. "clicked",
  319.  GTK_SIGNAL_FUNC(on_address_generate),
  320.  NULL);
  321. gtk_widget_show(address_generate_button);
  322. gtk_box_pack_start(GTK_BOX(vbox), address_generate_button, FALSE, FALSE, 0);
  323. sdp_generate_button = gtk_button_new_with_label(" Generate ");
  324. gtk_signal_connect(GTK_OBJECT(sdp_generate_button), 
  325. "clicked",
  326.  GTK_SIGNAL_FUNC(on_sdp_generate),
  327.  NULL);
  328. gtk_widget_show(sdp_generate_button);
  329. gtk_box_pack_end(GTK_BOX(vbox), sdp_generate_button, FALSE, FALSE, 0);
  330. // do these now so other widget sensitivies will be changed appropriately
  331. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(unicast_button), !isMcast);
  332. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcast_button), isMcast);
  333. // Add standard buttons at bottom
  334. button = AddButtonToDialog(dialog,
  335. " OK ", 
  336. GTK_SIGNAL_FUNC(on_ok_button));
  337. GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
  338. AddButtonToDialog(dialog,
  339. " Cancel ", 
  340. GTK_SIGNAL_FUNC(on_cancel_button));
  341. gtk_widget_show(dialog);
  342. gtk_grab_add(dialog);
  343. }
  344. /* end transmit_dialog.cpp */