/* gpsk31 - PSK31 for Linux with a GTK+ Interface * Copyright (C) 2000 Luc Langehegermann, LX2GT * Copyright (C) 2005 Joop Stakenborg, PG4I * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, * USA. */ /* * main.c - Main loop and initialisations */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "main_screen.h" #include "misc.h" #include "menu.h" #include "spectrum.h" #include "call_dialog.h" #include "globals.h" #include "phasescope.h" #include "server.h" #include "file.h" #include "main.h" #include "text.h" #include "support.h" #ifndef HAVE_LIBPTHREAD void master_handler(void); #endif struct ini_settings ini_settings; /* Initial Parameters */ extern int scconfig[]; /* [0]==8bit/16bit [1]==mono/stereo */ /* Our Main loop, called with gtk_timeout_add() */ gint main_loop (gpointer data) { static float rxfreqOld, rxfreq; /* last rx freq */ static int oldtx; /* last tx/rx state */ int phdelta; /* last phase scope arc */ int l; char str[2]; GtkTextBuffer *buffer; GtkTextIter iter, end; #ifndef HAVE_LIBPTHREAD // 4 is an empirical value. // If choosen too low, sound card buffer will run empty, and thus sound // will have interruptions (fatal!). A value too high isn't that critical... for(int i=0; i<4; i++) { master_handler(); #endif /* Handle FFT */ int N = getsamplecnt (); float fftval[N]; l = commGetData (COMM_FFTCH, (char *) fftval, sizeof (fftval)); if (l > 0) { spectrum_updateFFT (fftval, N); } #ifndef HAVE_LIBPTHREAD } #endif /* handle echo */ char *time_string = get_time_string(NULL); /* Get the time string, must be freed later */ char buf[256]; l = commGetData (COMM_ECHOCH, buf, sizeof buf); if (l > 0) { for (int i = 0; i < l; i++) { str[0] = buf[i]; str[1] = '\0'; if (str[0] == '\r') break; put_logfile (str); /* Save to the logfile if open */ if (str[0] == 0x7F || str[0] == '\b') { buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main_screen.rxwindow)); gtk_text_buffer_get_end_iter (buffer, &end); gtk_text_buffer_get_end_iter (buffer, &iter); gtk_text_iter_backward_chars (&iter, 1); gtk_text_buffer_delete (buffer, &iter, &end); } else put_rx_window (str, 1); } } /* Handle Receive */ l = commGetData (COMM_RXCH, buf, sizeof buf); if (l > 0) { for (int i = 0; i < l; i++) { str[0] = buf[i]; str[1] = '\0'; if (str[0] == '\r') break; put_logfile (str); /* Save to the logfile if open */ if (str[0] == 0x7F || str[0] == '\b') { buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main_screen.rxwindow)); gtk_text_buffer_get_end_iter (buffer, &end); gtk_text_buffer_get_end_iter (buffer, &iter); gtk_text_iter_backward_chars (&iter, 1); gtk_text_buffer_delete (buffer, &iter, &end); } else put_rx_window (str, 0); } } PSK31info rxinfo; PSK31info txinfo; commGetInfo (COMM_RXCH, &rxinfo, sizeof (rxinfo)); commGetInfo (COMM_TXCH, &txinfo, sizeof (txinfo)); rxfreq = 0.01 * rxinfo.freq; phdelta = rxinfo.phdelta; /* Find out if we are TX or RX, and update the statusbar */ if (rxinfo.ptt == 1 && oldtx == 0) { gtk_statusbar_pop (GTK_STATUSBAR (statusbar.txstate), 1); gtk_statusbar_push (GTK_STATUSBAR (statusbar.txstate), 1, "TX"); oldtx = 1; /* And write the info in the Log file */ put_logfile ("\n\n<<<<<< Transmission started at: "); put_logfile (time_string); put_logfile (" >>>>>>\n\n"); } else if (rxinfo.ptt == 0 && oldtx == 1) { gtk_statusbar_pop (GTK_STATUSBAR (statusbar.txstate), 1); gtk_statusbar_push (GTK_STATUSBAR (statusbar.txstate), 1, "RX"); oldtx = 0; /* And write the info to the Log file */ put_logfile ("\n\n<<<<<< Transmission stopped at: "); put_logfile (time_string); put_logfile (" >>>>>>\n\n"); } if (rxinfo.ptt == 0) { /* Receiving...... */ draw_scope (rxinfo.phdelta, rxinfo.strength, rxinfo.dcd); /* Update RX freq spin button */ if (!GTK_WIDGET_HAS_FOCUS (main_screen.rx_freq) && !GTK_WIDGET_HAS_FOCUS (main_screen.tx_freq)) { if ((rxfreq - rxfreqOld) > .05 || rxfreqOld - rxfreq > .05) { gtk_spin_button_set_value (GTK_SPIN_BUTTON (main_screen.rx_freq), rxfreq); rxfreqOld = rxfreq; } } } g_free (time_string); return (true); } int main (int argc, char *argv[]) { /* create .gpsk31 directory */ char *home = getenv("HOME"); char direct[strlen (home) + 8]; char fn[strlen(home) + 50]; strcpy (direct, home); strcat (direct, "/.gpsk31"); mkdir (direct, 00700); strcpy (fn,direct); strcat (fn, "/"); /* sound card config */ scconfig[0] = 1; scconfig[1] = 1; gtk_init (&argc, &argv); /* init gtk+ */ if (argc > 1 ) { printf("usage: \n\t gpsk31 [gtk-options]\n\n and see gtk-options(7)"); return(-1); } add_pixmap_directory (PIXMAPDIR); read_config (); /* read gpsk.conf and the ini_settings structure */ setup_screen (); /* build the main window */ set_config (); /* set the configuration */ init_call_dialog (); /* init the logbook dialog */ strcat(fn,ini_settings.log_filename); logfile(fn); /* These have always the same values when we start */ commControl (COMM_TXCH, COMM_QPSK, 0); commControl (COMM_RXCH, COMM_QPSK, 0); commControl (COMM_RXCH, COMM_AFC, 1); check_menu ("/Mode/AFC", 1); check_menu ("/Mode/NET", 1); gtk_signal_connect (GTK_OBJECT (main_screen.window), "delete_event", GTK_SIGNAL_FUNC (exit_dialog), NULL); gtk_timeout_add (250, display_time, NULL); /* timeout for clock */ #ifndef HAVE_LIBPTHREAD gtk_idle_add (main_loop, NULL); #else gtk_timeout_add (50, main_loop, NULL); #endif gtk_main (); }