// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // init_gui // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void init_gui(void) { // Bring globals into scope extern GladeXML * gui; extern GtkWidget * window; // Set up global GUI Handles gui = glade_xml_new ("../res/gui/gui.glade", NULL, NULL); window = glade_xml_get_widget (gui, "window"); // Set up splash screen GtkWidget *splash = glade_xml_get_widget(gui,"splash"); gtk_widget_show(GTK_WIDGET(splash)); // update splash status splash_status("Initializing User Interface..."); // Add timeout functions g_timeout_add(1000, check_amp_timeout, NULL); g_timeout_add(1000,close_splash_timeout, (gpointer)splash); // Initialize connect_event_handlers(); init_data(); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // init_data // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void init_data(void) { // Bring globals into scope extern GladeXML * gui; // Locals int BUFFER_SIZE = 7; // update splash screen status splash_status("Initializing Data..."); // Local variables char bs_buffer[BUFFER_SIZE]; char cc_buffer[BUFFER_SIZE]; char cp_buffer[BUFFER_SIZE]; char dp_buffer[BUFFER_SIZE]; char fs_buffer[BUFFER_SIZE]; // Load data into text buffers g_snprintf(fs_buffer,BUFFER_SIZE,"%d",DEFAULT_FS); g_snprintf(bs_buffer,BUFFER_SIZE,"%d",DEFAULT_BLOCKSIZE); g_snprintf(cc_buffer,BUFFER_SIZE,"%d",NUMBER_OF_CHANNELS); g_snprintf(cp_buffer,BUFFER_SIZE,"%d",DEFAULT_CP); g_snprintf(dp_buffer,BUFFER_SIZE,"%d",DEFAULT_DP); // Set amp indicator gtk_image_set_from_file(GTK_IMAGE(glade_xml_get_widget(gui, "amp_indicator")), "../res/gui/img/noamp.jpg"); // Update GUI text boxes gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "Fs_view")),fs_buffer); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "Bs_view")),bs_buffer); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "number_of_channels_view")),cc_buffer); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "sequence_filename")),"sequences.txt"); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "control_port_view")),cp_buffer); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(gui, "data_port_view")),dp_buffer); gtk_editable_set_editable(GTK_EDITABLE(glade_xml_get_widget(gui, "control_port_view")),FALSE); gtk_editable_set_editable(GTK_EDITABLE(glade_xml_get_widget(gui, "data_port_view")),FALSE); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // connect_event_handlers // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void connect_event_handlers(void) { extern GladeXML * gui; GtkWidget * widget; splash_status("Initializing Interface Events..."); // Windows --------------------------------------- // Main window widget = glade_xml_get_widget (gui, "window"); g_signal_connect (widget, "delete-event",G_CALLBACK (delete_event), NULL); g_signal_connect (widget, "destroy",G_CALLBACK (destroy), NULL); // System parameters window widget = glade_xml_get_widget(gui, "system_parameters"); g_signal_connect (widget, "delete_event",G_CALLBACK (hide_widget), NULL); // Calibration Progress window widget = glade_xml_get_widget(gui, "cal_progress"); g_signal_connect (widget, "delete_event", G_CALLBACK (hide_widget), NULL); // Sequence loading window widget = glade_xml_get_widget(gui, "seq_progress"); g_signal_connect (widget, "delete_event", G_CALLBACK (hide_widget), NULL); // Buttons --------------------------------------- // Edit parameters button widget = glade_xml_get_widget (gui, "edit_parameters_button"); g_signal_connect (widget, "clicked",G_CALLBACK (edit_system_parameters), NULL); // Update parameters button widget = glade_xml_get_widget (gui, "update_parameters_button"); g_signal_connect (widget, "clicked",G_CALLBACK (update_system_parameters), NULL); // Close logger button widget = glade_xml_get_widget (gui, "close_log_button"); g_signal_connect (widget, "clicked",G_CALLBACK (close_log), NULL); // Run test button widget = glade_xml_get_widget (gui, "run_test_button"); g_signal_connect (widget, "clicked",G_CALLBACK (run_test_button_callback), NULL); // Connect FGFS button widget = glade_xml_get_widget(gui, "connect_fgfs_button"); g_signal_connect (widget, "clicked", G_CALLBACK(connect_fgfs_button_callback), NULL); // Detect button widget = glade_xml_get_widget(gui, "detect_button"); g_signal_connect (widget, "clicked", G_CALLBACK(detect_button_callback), NULL); // Load Sequences button widget = glade_xml_get_widget(gui, "load_sequences_button"); g_signal_connect (widget, "clicked", G_CALLBACK(load_sequences_button_callback), NULL); // Calibrate button widget = glade_xml_get_widget(gui, "calibrate_button"); g_signal_connect (widget, "clicked", G_CALLBACK(calibrate_button_callback), NULL); // Load templates button widget = glade_xml_get_widget(gui, "load_templates_button"); g_signal_connect (widget, "clicked", G_CALLBACK(load_templates_button_callback), NULL); // create_whitening_filter_button widget = glade_xml_get_widget(gui, "create_whitening_filter_button"); g_signal_connect (widget, "clicked", G_CALLBACK(create_whitening_filter_button_callback), NULL); // load whitening filter button widget = glade_xml_get_widget(gui, "load_whitening_filter_button"); g_signal_connect (widget, "clicked", G_CALLBACK(load_whitening_filter_button_callback), NULL); // Drawing Areas --------------------------------- widget = glade_xml_get_widget (gui, "inst_pitch"); g_signal_connect (widget, "expose_event", G_CALLBACK(inst_pitch_expose), NULL); widget = glade_xml_get_widget (gui, "inst_roll"); g_signal_connect (widget, "expose_event", G_CALLBACK(inst_roll_expose), NULL); }
gint init(void* arg) { gint x; gint y; DISCOVERED* d; char *res; char wisdom_directory[1024]; char wisdom_file[1024]; fprintf(stderr,"init\n"); audio_get_cards(0); audio_get_cards(1); cursor_arrow=gdk_cursor_new(GDK_ARROW); cursor_watch=gdk_cursor_new(GDK_WATCH); GdkWindow *gdk_splash_window = gtk_widget_get_window(splash_window); gdk_window_set_cursor(gdk_splash_window,cursor_watch); init_radio(); // check if wisdom file exists res=getcwd(wisdom_directory, sizeof(wisdom_directory)); strcpy(&wisdom_directory[strlen(wisdom_directory)],"/"); strcpy(wisdom_file,wisdom_directory); strcpy(&wisdom_file[strlen(wisdom_file)],"wdspWisdom"); splash_status("Checking FFTW Wisdom file ..."); if(access(wisdom_file,F_OK)<0) { int rc=sem_init(&wisdom_sem, 0, 0); rc=pthread_create(&wisdom_thread_id, NULL, wisdom_thread, (void *)wisdom_directory); while(sem_trywait(&wisdom_sem)<0) { splash_status(wisdom_get_status()); while (gtk_events_pending ()) gtk_main_iteration (); usleep(100000); // 100ms } } while(!start) { gdk_window_set_cursor(gdk_splash_window,cursor_watch); selected_device=0; devices=0; splash_status("Old Protocol ... Discovering Devices"); old_discovery(); splash_status("New Protocol ... Discovering Devices"); new_discovery(); #ifdef LIMESDR splash_status("LimeSDR ... Discovering Devices"); lime_discovery(); #endif splash_status("Discovery"); if(devices==0) { gdk_window_set_cursor(gdk_splash_window,cursor_arrow); fprintf(stderr,"No devices found!\n"); GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT; discovery_dialog = gtk_message_dialog_new (GTK_WINDOW(splash_window), flags, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, "No devices found! Retry Discovery?"); gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 18")); gint result=gtk_dialog_run (GTK_DIALOG (discovery_dialog)); gtk_widget_destroy(discovery_dialog); if(result==GTK_RESPONSE_CANCEL) { _exit(0); } } else { fprintf(stderr,"%s: found %d devices.\n", (char *)arg, devices); gdk_window_set_cursor(gdk_splash_window,cursor_arrow); GtkDialogFlags flags=GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT; discovery_dialog = gtk_dialog_new_with_buttons ("Discovered", GTK_WINDOW(splash_window), flags, #ifdef GPIO "Configure GPIO", GTK_RESPONSE_YES, #endif "Discover", GTK_RESPONSE_REJECT, "Exit", GTK_RESPONSE_CLOSE, NULL); gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 18")); GtkWidget *content; content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog)); GtkWidget *grid=gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_row_spacing (GTK_GRID(grid),10); int i; char version[16]; char text[128]; for(i=0;i<devices;i++) { d=&discovered[i]; fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name); if(d->protocol==ORIGINAL_PROTOCOL) { sprintf(version,"%d.%d", d->software_version/10, d->software_version%10); } else { sprintf(version,"%d.%d.%d", d->software_version/100, (d->software_version%100)/10, d->software_version%10); } switch(d->protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", d->name, d->protocol==ORIGINAL_PROTOCOL?"old":"new", version, inet_ntoa(d->info.network.address.sin_addr), d->info.network.mac_address[0], d->info.network.mac_address[1], d->info.network.mac_address[2], d->info.network.mac_address[3], d->info.network.mac_address[4], d->info.network.mac_address[5], d->info.network.interface_name); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: /* sprintf(text,"%s (%s %s)\n", d->name, "lime", version); */ sprintf(text,"%s\n", d->name); break; #endif } GtkWidget *label=gtk_label_new(text); gtk_widget_override_font(label, pango_font_description_from_string("FreeMono 12")); gtk_widget_show(label); gtk_grid_attach(GTK_GRID(grid),label,0,i,3,1); GtkWidget *start_button=gtk_button_new_with_label("Start"); gtk_widget_override_font(start_button, pango_font_description_from_string("FreeMono 18")); gtk_widget_show(start_button); gtk_grid_attach(GTK_GRID(grid),start_button,3,i,1,1); g_signal_connect(start_button,"pressed",G_CALLBACK(start_cb),(gpointer)d); // if not available then cannot start it if(d->status!=STATE_AVAILABLE) { gtk_button_set_label(GTK_BUTTON(start_button),"In Use"); gtk_widget_set_sensitive(start_button, FALSE); } // if not on the same subnet then cannot start it if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) { gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!"); gtk_widget_set_sensitive(start_button, FALSE); } } gtk_container_add (GTK_CONTAINER (content), grid); gtk_widget_show_all(discovery_dialog); gint result=gtk_dialog_run(GTK_DIALOG(discovery_dialog)); if(result==GTK_RESPONSE_CLOSE) { _exit(0); } if(!start) { gtk_widget_destroy(discovery_dialog); } #ifdef GPIO if(result==GTK_RESPONSE_YES) { configure_gpio(splash_window); } #endif } } gdk_window_set_cursor(gdk_splash_window,cursor_watch); splash_status("Initializing wdsp ..."); fprintf(stderr,"selected radio=%p device=%d\n",radio,radio->device); protocol=radio->protocol; device=radio->device; switch(radio->protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props", radio->info.network.mac_address[0], radio->info.network.mac_address[1], radio->info.network.mac_address[2], radio->info.network.mac_address[3], radio->info.network.mac_address[4], radio->info.network.mac_address[5]); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: sprintf(property_path,"limesdr.props"); break; #endif } radioRestoreState(); fprintf(stderr,"malloc samples\n"); if(radio->protocol==NEW_PROTOCOL) { samples=malloc(display_width*sizeof(float)*2*4); // 192 -> 48 } else { samples=malloc(display_width*sizeof(float)*2); } //splash_status("Initializing wdsp ..."); fprintf(stderr,"wdsp_init\n"); wdsp_init(0,display_width,radio->protocol); switch(radio->protocol) { case ORIGINAL_PROTOCOL: splash_status("Initializing old protocol ..."); fprintf(stderr,"old_protocol_init\n"); old_protocol_init(0,display_width); break; case NEW_PROTOCOL: splash_status("Initializing new protocol ..."); fprintf(stderr,"new_protocol_init\n"); new_protocol_init(0,display_width); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: splash_status("Initializing lime protocol ..."); lime_protocol_init(0,display_width); break; #endif } fprintf(stderr,"gpio_init\n"); splash_status("Initializing GPIO ..."); #ifdef GPIO if(gpio_init()<0) { } #endif window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "pihpsdr"); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); g_signal_connect (window, "delete-event", G_CALLBACK (main_delete), NULL); fixed=gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed); y=0; fprintf(stderr,"vfo_height=%d\n",VFO_HEIGHT); vfo = vfo_init(VFO_WIDTH,VFO_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),vfo,0,0); rit_control = rit_init(RIT_WIDTH,MENU_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),rit_control,VFO_WIDTH,y); fprintf(stderr,"menu_height=%d\n",MENU_HEIGHT); //menu = menu_init(MENU_WIDTH,MENU_HEIGHT,window); menu = new_menu_init(MENU_WIDTH-RIT_WIDTH,MENU_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),menu,VFO_WIDTH+((MENU_WIDTH/3)*2),y); fprintf(stderr,"meter_height=%d\n",METER_HEIGHT); meter = meter_init(METER_WIDTH,METER_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH+MENU_WIDTH,y); y+=VFO_HEIGHT; if(display_panadapter) { int height=PANADAPTER_HEIGHT; if(!display_waterfall) { height+=WATERFALL_HEIGHT; if(!display_sliders) { height+=SLIDERS_HEIGHT; } if(!display_toolbar) { height+=TOOLBAR_HEIGHT; } } else { if(!display_sliders) { height+=SLIDERS_HEIGHT/2; } } fprintf(stderr,"panadapter_height=%d\n",height); panadapter = panadapter_init(display_width,height); gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,VFO_HEIGHT); y+=height; } if(display_waterfall) { int height=WATERFALL_HEIGHT; if(!display_panadapter) { height+=PANADAPTER_HEIGHT; } if(!display_sliders) { if(display_panadapter) { height+=SLIDERS_HEIGHT/2; } else { height+=SLIDERS_HEIGHT; } } if(!display_toolbar) { height+=TOOLBAR_HEIGHT; } fprintf(stderr,"waterfall_height=%d\n",height); waterfall = waterfall_init(display_width,height); gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y); y+=height; } #ifdef PSK int psk_height=PSK_WATERFALL_HEIGHT; if(!display_sliders) { psk_height+=SLIDERS_HEIGHT/2; } if(!display_toolbar) { psk_height+=TOOLBAR_HEIGHT/2; } psk_waterfall = psk_waterfall_init(display_width,psk_height); gtk_fixed_put(GTK_FIXED(fixed),psk_waterfall,0,VFO_HEIGHT); psk = init_psk(); gtk_fixed_put(GTK_FIXED(fixed),psk,0,VFO_HEIGHT+psk_height); #endif if(display_sliders) { fprintf(stderr,"sliders_height=%d\n",SLIDERS_HEIGHT); sliders = sliders_init(display_width,SLIDERS_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y); y+=SLIDERS_HEIGHT; } if(display_toolbar) { fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT); toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window); gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); y+=TOOLBAR_HEIGHT; } splash_close(); gtk_widget_show_all (window); if(full_screen) { gtk_window_fullscreen(GTK_WINDOW(window)); } GdkWindow *gdk_window = gtk_widget_get_window(window); gdk_window_set_cursor(gdk_window,cursor_arrow); // start the receiver SetChannelState(CHANNEL_RX0,1,1); //update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL); update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/updates_per_second, update, NULL, NULL); // save every 30 seconds save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL); if(protocol!=NEW_PROTOCOL) { setFrequency(getFrequency()); } #ifdef PSK if(mode==modePSK) { show_psk(); } else { show_waterfall(); } #endif g_idle_add(vfo_update,(gpointer)NULL); return 0; }
static void* wisdom_thread(void *arg) { splash_status("Creating FFTW Wisdom file ..."); WDSPwisdom ((char *)arg); sem_post(&wisdom_sem); }