/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     Internet Radio Automation & Encoding Toolkit
#+
#+     Copyright (C) 2018 - 2025 by Kevin C. O'Kane
#+
#+     Kevin C. O'Kane
#+     kc.okane@gmail.com
#+     https://www.cs.uni.edu/~okane
#+     https://threadsafebooks.com/
#+
#+ 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	Dec 5, 2025

#include "includes.h"
#include "defines.h"
#include "common-externs.h"

#define SLASH '/'

//----------------------------------
//      halt & clear program
//----------------------------------

void    on_haltProgram_clicked (GtkButton *button) {

	char cmd[1024];

	haltProgram_flg = 1;

//        system("killall --signal SIGTERM mpv 2> /dev/null");

//------------------------------------------------
//	button is NULL if called from vlc_start()
//------------------------------------------------

	video_file = 0;

	DisplayCover("default");
	SP->Clock = 0;
	SP->NowPlaying = -1;
	SP->begin=0;
	SP->Pause=0;
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pauseAtEnd), FALSE);
	SP->PauseKill = 0;
	SP->OrgPlay = 1;
	strcpy(SP->CurrentPlay, "");
	SP->t1 = 0;

//--------------------------------
//	restore volume settings
//--------------------------------

	if (AGC) {
		SP->volumeLevel = INIT_VOLUME;
		outVolume(SP->volumeLevel);
		}

	setVlcRate(1.0);
	MaxAudioSample = 0;

	SP->videoPlaying = 0;

	PauseOff(); // turn button to green

	strcpy(SP->next_random, "Next Program Selection");
	gtk_widget_hide(nextPlay); // on screen label showing program mode running

	ClearPlayers();

	DisplayProgramButtons();

	gtk_adjustment_set_value (GTK_ADJUSTMENT(adjustment8), 0);

	gtk_widget_queue_draw (draw1);

	}


void    on_show_video_toggled(GtkWidget *b) {

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_video))) {
		SP->showVideo = 1;
		}
	else {
		SP->showVideo = 0;
		}
	}


void    on_recenter_toggled(GtkWidget *b) {

	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(recenter))) {
		reCenter = 1;
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(recenter1), TRUE);
		return;
		}

	reCenter = 0;
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(recenter1), FALSE);
	}

void    on_recenter1_toggled(GtkWidget *b) {

	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(recenter1))) {
		reCenter = 1;
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(recenter), TRUE);
		return;
		}

	reCenter = 0;
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(recenter), FALSE);
	}


void    on_noMove1_toggled (GtkButton *b) {
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(noMove1)) ) {
		no_move = 1;
		reCenter = 0;
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(recenter), FALSE);
		return;
		}
	no_move = 0;
	}


int     playable(char *text) {
	if (text[0] == 0 ) return 0;
	if (text[strlen(text)-1] == SLASH) return 0;
	else return 1;
	}


void    on_scan_times_clicked(GtkWidget *w) {

	int i;
	char TimeStart[64], TimeEnd[64], length[32];

	for (i = 0; i < SP->scount; i++) {
		if (strlen(ProgramArray[i]) == 0) break;
		SP->begin = i;
		DisplayProgramButtons();
		if ( programTime[i] <= 0)
			GetTime(i, ProgramArray[i], TimeStart);
		while (gtk_events_pending()) gtk_main_iteration();
		}

	SP->begin = 0;
	DisplayProgramButtons();
	}


void    orgPgm() {
	SP->PauseKill = 0;
	SP->begin = 0;
	SP->NowPlaying = -1;
	DisplayProgramButtons();
	}


void    playTime(time_t Now, char *start, char* end, char *length, int lngth) {
	char dmy[64], dmy1[64];

	if (lngth <= 0) {
		strcpy(start,"");
		strcpy(end,"");
		strcpy(length,"");
		return;
		}

	sscanf(ctime(&Now),"%s %s %s %s ",dmy,dmy,dmy,dmy);
	Now = Now + lngth;
	sscanf(ctime(&Now),"%s %s %s %s ",dmy1,dmy1,dmy1,dmy1);
	strcat(dmy,"                     "); // pad time to full tile
	sprintf(start,"%s", dmy);
	sprintf(end,"%s", dmy1);
	sprintf(length,"%4d", lngth);
	return;
	}


void    FileChooser (GtkFileChooserButton *b, int Row, GtkWidget *g_btn, GtkEntry *user_data) {

	chdir(directories[Row]);

	char *filename;
	char *directory;
	char file[2048];

	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(b));
	directory = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(b));


	if (directory != NULL) {
		strcpy(directories[Row], directory);
		lastDir = Row;
		chdir(directory);
		}

	else if (filename != NULL)  {
		char tmp[2048];
		strcpy(tmp, filename);
		strcpy(directories[Row], dirname(tmp));
		lastDir = Row;
		chdir(directory);
		}

	else {
		g_free (filename);
		g_free (directory);
		strcpy(file, "");
		return;
		}

	strcpy(file, filename);


	bigFilename(user_data, file);

	g_free (filename);
	g_free (directory);

	}


int     bigFilename(GtkEntry *user_data, char *file) {

	int i;
	char file1[1024];

	strcpy(file1, file);

	int type = filetype(file);

	if (type > 0 && type < 100) {  // known type and not an image file

		gtk_entry_set_text (user_data, (gchar *) file1);

		i = strlen(file1) - 4;
		}

	else {
		gtk_entry_set_text (user_data, (gchar *) "<bad file name>");
		i = -1;
		}

	gtk_editable_set_position(GTK_EDITABLE(user_data), i);
	return i;
	}


void    on_dxb1_clicked(GtkButton *b) { // ok button

	FILE *f1;
	int i;
	char fileName[512];

	gtk_widget_hide(g_dbox1);

	const gchar *sentry = gtk_entry_get_text( g_dbox1Entry );

	if (strlen(sentry) == 0) {
		Message("Bad File Name");
		return;
		}


	strcpy(fileName,"");
	strcat(fileName,Code_Home); // build filename
	strcat(fileName,"/");
	strcat(fileName,sentry);

	if (SaveFlg) {
		printf("Loading program list from %s\n",fileName);
		LoadProgram(fileName);
		DisplayProgramButtons( );
		return;
		}

	printf("Saving program list to %s\n",fileName);

	f1 = fopen (fileName,"w");
	if (f1 ==NULL ) {
		Message("File Error Saving Program List");
		return;
		}

	for (i=0; i<SP->scount; i++) {
		if (strlen(ProgramArray[i]) == 0 ) continue;
		fprintf(f1, "%s\n", ProgramArray[i]);
		}

	fclose(f1);
	gtk_widget_hide(g_dbox1);
	}


gboolean        on_scroll_scroll_event(GtkScrollbar *b, GdkEventScroll *e) {

//--------------------------------------------------------------
//	see GdkEventScroll data structure for valid elements
//	see: gtk_widget_set_events(xxx,GDK_SCROLL_MASK);
//--------------------------------------------------------------


	if (e->delta_y == 1) { // down


		SP->begin = SP->begin + 12;
		if (SP->begin + PROGRAM_BUTTON_COUNT >= SP->scount) {
			SP->begin = SP->scount - 1;
			}
		if (SP->begin < 0 ) SP->begin = 0;
		SP->NowPlaying = -1;
		DisplayProgramButtons();
		}

	else { // up
		SP->begin = SP->begin - 12;
		if (SP->begin + PROGRAM_BUTTON_COUNT >= SP->scount) {
			SP->begin = SP->scount - PROGRAM_BUTTON_COUNT;
			}
		if (SP->begin < 0 ) SP->begin = 0;
		SP->NowPlaying = -1;
		DisplayProgramButtons();
		}

//---------------------------------------------------------------------------------------
//	gtk_range_set_value (GTK_RANGE(b), SP->begin) is done in DisplayProgramButtons
//	thus triggering a value changed signal
//---------------------------------------------------------------------------------------

	return TRUE;
	}


void    on_scroll_value_changed(GtkRange *r) {

	int k;

	gdouble x = gtk_range_get_value (r);
	k = x; // make integer
	if (k > SP->scount - PROGRAM_BUTTON_COUNT)
		k = SP->scount - PROGRAM_BUTTON_COUNT;
	if (k < 0) k = 0;
	SP->begin = k;
	DisplayProgramButtons();
	}


gboolean        on_search_scroll_scroll_event(GtkScrollbar *b, GdkEventScroll *e) {

//-------------------------------------------------------------
//	see GdkEventScroll data structure for valid elements
//	see: gtk_widget_set_events(g_buttonxx,GDK_SCROLL_MASK);
//-------------------------------------------------------------

	if (e->delta_y == 1) { // down
		SP->Xbegin=SP->Xbegin + 4;
		if (SP->Xbegin + 4 >= SP->scount) {
			SP->Xbegin = SP->scount - 4;
			}
		if (SP->Xbegin < 0 ) SP->Xbegin = 0;
		SP->NowPlaying = -1;
		DisplayProgramButtons();
		}
	else { // up
		SP->Xbegin=SP->Xbegin - 4;
		if (SP->Xbegin + 4 >= SP->scount) {
			SP->Xbegin = SP->scount - 4;
			}
		if (SP->Xbegin < 0 ) SP->Xbegin = 0;
		SP->NowPlaying = -1;
		DisplayProgramButtons();
		}
	gtk_range_set_value (GTK_RANGE(b), SP->Xbegin); // place slider
	return TRUE;
	}


void    entry_insert(GtkEditable  *entry, gchar *edit) {
	unsigned char *file;
	int i=0, j=0;

	gtk_editable_delete_text (entry, 0, -1 );

	i = strlen( (char *) edit);

	file = (unsigned char *) malloc(i + 1);

	if (file == NULL ) {
		printf("Out of memory in entry_insert\n");
		abort();
		}

	strcpy((char *) file, (char *) edit);

	if (strncmp((char *)file, "file://", 7) == 0) strcpy((char *)edit, (char *)&file[7]);
	else strcpy((char *)edit, (char *)file);
	free (file);

	return;
	}

void    entry_changed (GtkEntry *entry, gchar *preedit, gpointer  user_data, int Row) {

	char file[1024],file1[1024];
	int i;

//--------------------------------------------------------------------
//	Note: changes in the entry result in a loopback to this code
//--------------------------------------------------------------------

	strcpy(file, gtk_entry_get_text(entry));

	if (hexcleaner(file)) {
		gtk_entry_set_text(entry, (gchar *) file);
		return;
		}

//------------------
//	basename
//------------------

	if (file[0] == '/' && entry == entry1) strcpy(top1,file);

	i=strlen(file);
	for (int j=0; j<i; j++) if (file[j] == ':') {
			file[j]=0;
			break;
			}

	i=strlen(file);
	for (i = strlen(file); i > 0; i--) if (file[i] == '/') break;

	if (i > 0) strcpy(file1, &file[i+1]);
	else return; // file name had no directory info

	file[i] = 0;

	strcpy(directories[Row], file);

	programTime[Row] = -1; // invalidate

	int ft = filetype(file1);

	if (ft > 0 && ft < 100) {
		gtk_entry_set_text (GTK_ENTRY(entry), (gchar *) file1);
		i = strlen(file1) - 4;
		}

	}

void    on_save3_clicked (GtkButton *btn) {
	SaveFlg = 1;
	gtk_window_set_title(GTK_WINDOW(g_dbox1),"File name to read");
	gtk_widget_show(g_dbox1);  // show dialog
	return ;
	}

void    on_save1_clicked (GtkButton *b) { // left click
	SaveFlg = 0;
	save_flg = 1;
	gtk_window_set_title(GTK_WINDOW(g_dbox1),"File name to save");
	gtk_widget_show(g_dbox1);  // show dialog
	return;
	}

void	on_radio_bars_toggled (GtkWidget *w) {

	which_meters = BAR_METER;
	gtk_widget_hide(vumeter);       // vumeter background not used
	gtk_widget_hide(vumeter1);      // vumeter background not used
//	gtk_fixed_move(GTK_FIXED(Top1), GTK_WIDGET(draw2), 10, ClassicVuVer);
	printf("bars\n");
	}

void	on_radio_vu_toggled (GtkWidget *w) {

	if (! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
		return;

	showArc = 0;
	which_meters = VU_METER;
	gtk_widget_show(vumeter);       // vumeter background not used
	gtk_widget_show(vumeter1);      // vumeter background not used
	gtk_fixed_move(GTK_FIXED(Top1), GTK_WIDGET(draw2), 10, ClassicVuVer);
	printf("vu\n");
	}

void	on_radio_digital_toggled (GtkWidget *w) {

	if (! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
		return;

	showArc = 1;
	which_meters = DIGITAL_METER;
	gtk_widget_hide(vumeter);       // vumeter background not used
	gtk_widget_hide(vumeter1);      // vumeter background not used
	gtk_fixed_move(GTK_FIXED(Top1), GTK_WIDGET(draw2), 10, DigitalVuVer);
	printf("digital\n");
	}

void	on_radio_fans_toggled (GtkWidget *w) {

	if (! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
		return;

	gtk_widget_hide(vumeter);       // vumeter background not used
	gtk_widget_hide(vumeter1);      // vumeter background not used
	which_meters = FAN_METER;

	printf("fans\n");
	gtk_fixed_move(GTK_FIXED(Top1), GTK_WIDGET(draw2), 10, DigitalVuVer);

	}

void    on_addEntry1_clicked(GtkWidget *b) {

	int i;

	if (SP->scount+1 > PROGRAM_MAX) return;

	for (i=SP->scount+1; i>0; i--) {        // shift entries down one
		strcpy(ProgramArray[i], ProgramArray[i-1]);
		if (SP->NowPlaying == i - 1) SP->NowPlaying = i;        // advance current
		programData[i]->play = programData[i-1]->play;
		programPlayed[i] = programPlayed[i-1];
		programTime[i] = programTime[i-1];
		}

	strcpy(ProgramArray[0],top1);   // record file name
	programData[0]->play = 1;
	SP->scount++;
	DisplayProgramButtons();
	}


void     on_slideTime_value_changed(GtkSpinButton *s, GtkScrollType scr) {
	slide_time  = gtk_spin_button_get_value (s);
	if (slide_time < 1) slide_time = 1;
	}


void    on_search_scroll_value_changed(GtkRange *r) {

	int k;

	gdouble x = gtk_range_get_value (r);
	k = x; // make integer
	if (k > SP->scount - 4) k = SP->scount - 4;
	if (k < 0 ) k = 0;
	SP->Xbegin = k;
	DisplayProgramButtons();
	}


gboolean        on_Playerx_button_press_event (GtkButton *btn, GdkEventButton *event,
        gpointer user_data) {

	if (event->button == 1 ) return FALSE;
	for (int i=0; i< PROGRAM_MAX; i++) programData[i]->play = 0;
	DisplayProgramButtons();
	return TRUE;
	}


void    ClearPlayers() {
	if (vlc_playing()) vlc_stop();
	system("killall --signal SIGTERM vlc 2> /dev/null");
	SP->playClip = 0;
	SP->VlcPauseFlg = 0;
	SP->playProgram = 0;
	SP->skipCurrent = 0;
	SP->skip= 0;
	strcpy(SP->next_random, "Next Program Selection");
	for (int i = 0; i < 99; i++) lchan[i] = rchan[i] = 0;
	}


void    on_dxb2_clicked(GtkButton *b) { // cancel button
	gtk_widget_hide(g_dbox1);
	}


int     delDialog() {

	GtkDialogFlags flags = (GtkDialogFlags) (GTK_DIALOG_DESTROY_WITH_PARENT |
	                       GTK_MESSAGE_ERROR | GTK_DIALOG_MODAL |
	                       GTK_DIALOG_USE_HEADER_BAR) ;

	GtkWidget *dialog = gtk_dialog_new_with_buttons  ("Delete entry?",
	                    GTK_WINDOW(window),
	                    flags,
	                    "Yes", 100, "No", 200, NULL);

//-------------------------------------------
//      Expect 200 for NO and 100 for YES
//-------------------------------------------

	gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);

	gint r = gtk_dialog_run (GTK_DIALOG (dialog));

	gtk_widget_destroy (dialog);

	return (int) r;
	}


gboolean        scroll_event2(GdkEventScroll *e, int amount) {

//-------------------------------------------------------------
//	see GdkEventScroll data structure for valid elements
//	see: gtk_widget_set_events(g_buttonxx,GDK_SCROLL_MASK);
//-------------------------------------------------------------

	if (e->direction == 1) { // down
		SP->Xbegin=SP->Xbegin + 1;
		if (SP->Xbegin + amount >= SP->scount) {
			SP->Xbegin = SP->scount - amount;
			}
		if (SP->Xbegin < 0 ) SP->Xbegin = 0;
		DisplayProgramButtons();
		}

	else { // up
		SP->Xbegin=SP->Xbegin - 1;
		if (SP->Xbegin + amount >= SP->scount) {
			SP->Xbegin = SP->scount - amount;
			}
		if (SP->Xbegin < 0 ) SP->Xbegin = 0;
		DisplayProgramButtons();
		}
	return TRUE;
	}


void    PauseOff () {

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pauseAtEnd))) {
		// toggled signal handler will set SP->Pause
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pauseAtEnd), FALSE);
		}
	else {
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pauseAtEnd), TRUE);
		}
	}


int     hexcleaner(char *t) {

	char *_ftmp;
	int m, n = 0, p,f = 0;

	int i = strlen(t);

	_ftmp = (char *)malloc(i + 1);

	if (_ftmp == NULL ) {
		printf("Out of memory in hexcleaner\n");
		abort();
		}

	for(m=0; t[m]; m++) {

		if (t[m] == '\n' ) {
			f = 1;
			continue;
			}
		if (t[m] == '\r' ) {
			f = 1;
			continue;
			}

		if (t[m] == '%') {

			f = 1;
			if (t[m+1] >= 'a' && t[m+1] <= 'z') t[m+1] = t[m+1]-32;
			if (t[m+1] >= '0' && t[m+1] <= '9') p=( t[m+1]-'0' ) * 16;
			else p=(t[m+1]-'A'+10)*16;

			if (t[m+2] >= 'a' && t[m+2] <= 'z') t[m+2] = t[m+2]-32;
			if (t[m+2] >= '0' && t[m+2] <= '9') p = p+(t[m+2]-'0');
			else p = p + (t[m+2] - 'A' + 10);

			_ftmp[n] = p;  /* insert value into output string */
			n++;
			m = m + 2;
			}

		else {
			_ftmp[n++] = t[m];
			}
		}

	_ftmp[n]=0;
	strcpy(t,_ftmp);
	free(_ftmp);
	return f;
	}


void    on_preAmp_value_changed(GtkRange *r) {

	char cmd[64];

	Eq_Vol = gtk_range_get_value (r); //get value from  slider

	SP->volumeLevel = 100.0 + Eq_Vol;

	sprintf(cmd,"%+4.1f%%", Eq_Vol);
	gtk_label_set_text(GTK_LABEL(preampLbl), cmd);

	SetVlcEqualizerPreAmp();
	}


void    on_about_clicked(GtkWidget *b) {

	Message("SGR Player 5.00 (Antrim) is an open source software product licensed under"
	        " the GPL V2 License.\n\nCopyright 2021 Kevin C. O'Kane.\n\nCode available at:\n"
	        "https://www.cs.uni.edu/~okane/pocketradio.html");
	}


void    on_clrPgm_clicked (GtkButton *b) {

	int i;

	GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;

	GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(window),
	                    flags,
	                    GTK_MESSAGE_ERROR,
	                    GTK_BUTTONS_YES_NO,
	                    "%s\nAre You Sure?",
	                    "Erase Program");

//------------------------------------------
//      expect -9 for NO and -8 for YES
//------------------------------------------

	gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);

	gint r = gtk_dialog_run (GTK_DIALOG (dialog));

	gtk_widget_destroy (dialog);

	if ( r == -8) { // YES

		for (i = 0; i < PROGRAM_MAX; i++) {

			strcpy(ProgramArray[i],"");
			programData[i]->play = 0;
			programPlayed[i] = 0;
			programTime[i] = -1;
			}

		SP->scount = 0; // program list is empty
		SP->begin = 0;
		SP->Xbegin = 0;
		DisplayProgramButtons();
		}
	}

//------------------------------------------------
//      Music_Home_Directory Macro
//      Adjust for your situation.
//      This can also be set as a CLI parameter.
//------------------------------------------------

void	css_set1(GtkCssProvider * cssProvider, GtkWidget *g_widget) {

	GtkStyleContext *context;

	context = gtk_widget_get_style_context(g_widget);

	gtk_style_context_add_provider (context,
	                                GTK_STYLE_PROVIDER(cssProvider), 1000);

	}

void    on_Playerx_clicked (GtkButton *b) { // reset play buttons to on

	Playerx_flg = 1;

	for (int i=0; i< PROGRAM_MAX; i++) {
		if (playable(ProgramArray[i])) programData[i]->play = 1;
		}

	DisplayProgramButtons();
	}


gboolean        scroll_event(GdkEventScroll *e) {

//--------------------------------------------------------------
//      see GdkEventScroll data structure for valid elements
//      see: gtk_widget_set_events(g_buttonxx,GDK_SCROLL_MASK);
//--------------------------------------------------------------

	if (e->direction == 1) { // down
		SP->begin=SP->begin + 1;
		if (SP->begin + PROGRAM_BUTTON_COUNT >= SP->scount) {
			SP->begin = SP->scount - PROGRAM_BUTTON_COUNT;
			}
		if (SP->begin < 0 ) SP->begin = 0;
		DisplayProgramButtons();
		}

	else { // up
		SP->begin=SP->begin - 1;
		if (SP->begin + PROGRAM_BUTTON_COUNT >= SP->scount) {
			SP->begin = SP->scount - PROGRAM_BUTTON_COUNT;
			}
		if (SP->begin < 0 ) SP->begin = 0;
		DisplayProgramButtons();
		}
	return TRUE;
	}


void    on_showCurrent_clicked (GtkButton *b) { // shift display to current
	int i;
	showCurrent_flg = 1;
	if (strlen(SP->CurrentPlay) == 0) return; // nothing being played
	for (i = 0; i < SP->scount; i++) {
		if (strcmp(SP->CurrentPlay, ProgramArray[i]) == 0) {
			SP->begin = i;
			DisplayProgramButtons();
			return;
			}
		}
	}


void on_skipThis_clicked (GtkButton *button, GtkEntry *user_data) {

	skipThis_flg = 1;

	SP->skipCurrent = 1;            // indicate action needed

	strcpy(SP->CurrentPlay, "");

	if (AGC) {
		SP->volumeLevel = INIT_VOLUME;
		outVolume(INIT_VOLUME);
		setVlcRate(1.0);
		}
	}


void on_button1_clicked (GtkButton *button, GtkEntry *user_data) {
	SP->Clock = 0;
	PlayClip (button, user_data, -10);
	}


void on_choose1_file_set (GtkFileChooserButton *f) {
	FileChooser(f, 1, g_btn_play2, entry1);
	return;
	}


void    on_skipNext_clicked(GtkButton *button) {
	SP->skip = 1;
	redraw = 1;
	}

void    on_PlayPgm_clicked (GtkWidget *button) {

	PlayPgm_flg = 1;

	SP->playProgram = 0; // no play
	SP->NowPlaying = -1;

	ClearPlayers(); // kill any existing media players

	SP->PauseKill = 0;
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(pauseAtEnd), FALSE);
	SP->Pause = 0;
	SP->playProgram = 1; // play
	return;
	}

void    strip(char* str) {
	int i, x;
	for(i = x = 0; str[i]; ++i)
		if( !isspace(str[i] ) || (i > 0 && !isspace(str[i - 1])))
			str[x++] = str[i];
	str[x] = '\0';
	}

int     lastWord(char * tmp, int off) {
	int i;
	for (i = 0; off + i < PROGRAM_ROW && tmp[i] != 0; i++)
		if (tmp[i] == ' ' ) return 0;
	return 1;
	}

//-----------------------------------------------------------------
//      cursors can be found here:
//      http://developer.gimp.org/api/2.0/gdk/gdk-Cursors.html
//-----------------------------------------------------------------

void    gtkSetCursor(GdkCursorType cursorType) {

	GdkScreen * screen = gdk_screen_get_default();
	GdkWindow * win = gdk_screen_get_root_window(screen);
	GdkCursor * cursor = gdk_cursor_new(cursorType);
	gdk_window_set_cursor(win, cursor);
	while (gtk_events_pending()) gtk_main_iteration();
	}

void    paste1(int *Row) {

	int i,j,playedo, id1=0, id2=0;

	if (SP->scount+1 >= PROGRAM_MAX) {
		Message("Maximum number of program slots exceeded");
		return;
		}

	redraw = 1;

	printf("copy to row %d copyClipRow=%d\n",*Row,copyClipRow);
	if (copyClipRow >= 0 ) {
		}
	else {
		}

	for (i = SP->scount + 1; i > *Row; i--) {        // shift entries up one
		strcpy(ProgramArray[i], ProgramArray[i - 1]);
		programData[i]->play = programData[i - 1]->play;
		programPlayed[i] = programPlayed[i-1];
		programTime[i] = programTime[i-1];
		}

	if (copyClipRow == -10) {
		strcpy(ProgramArray[*Row],top1);
		}
	if (copyClipRow == -20) {
		strcpy(ProgramArray[*Row],top2);
		}
	if (copyClipRow == -30) {
		strcpy(ProgramArray[*Row],top3);
		}

	programData[*Row]->play = 1;
	programTime[*Row] = -1;
	(SP->scount)++;

//------------------------------------------------------
//              set maximum limit of program scroll bars
//------------------------------------------------------

	gtk_range_set_range (GTK_RANGE(scroll), 0, SP->scount);
	gtk_range_set_range (GTK_RANGE(scroll2), 0, SP->scount);
	gtk_range_set_range (GTK_RANGE(search_scroll), 0, SP->scount);

	DisplayProgramButtons();
	}

void    Message(char * msg) {

	if (strlen(msg) == 0) return;

	GdkColor color1;
	color1.red = 0x1111;
	color1.green = 0x1111;
	color1.blue = 0x9999;

	GdkColor color2;
	color2.red = 0xFFFF;
	color2.green = 0xFFFF;
	color2.blue = 0x0000;

	GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT ;

	GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(window),
	                    flags,
	                    GTK_MESSAGE_WARNING,
	                    GTK_BUTTONS_CLOSE,
	                    msg);

	gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &color1);
	gtk_widget_modify_fg(dialog, GTK_STATE_NORMAL, &color2);

	gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);

	gtk_dialog_run (GTK_DIALOG (dialog));
	gtk_widget_destroy (dialog);
	}

gboolean        scroll_event4(GtkEntry *b, GdkEventScroll *e) {

	if (e->direction == 0) { // up
		on_albumForward_clicked(albumForward);
		}

	else { // down
		on_albumBack_clicked(albumBack);
		}
	return TRUE;
	}


void	on_stack1_set_focus_child(GtkContainer *c, GtkWidget *w) {

//-------------------------------------
//	stack visible panel changed
//-------------------------------------

	slide_timer = -1; // force new slide
	return;
	}

void	on_stack1_notify(GtkWidget *w, GParamSpec* child_property, gpointer *user) {

	static int delay;

//----------------------------------------------------------------------
//	printf("stack1 notify %s %s\n",
//		child_property->name,
//			gtk_stack_get_visible_child_name(GTK_STACK(w)));
//----------------------------------------------------------------------

	current_stack = gtk_stack_get_visible_child(GTK_STACK(w));

	if (strcmp(child_property->name, "visible-child") == 0 &&
	        current_stack == movie) {
		gtk_widget_hide(video_draw);
		delay = 0;
		return;
		}

	if (strcmp(child_property->name, "transition-running") == 0 &&
	        current_stack == movie && delay) {
		gtk_widget_show(video_draw);
		delay = 0;
		return;
		}

	if (strcmp(child_property->name, "transition-running") == 0 &&
	        current_stack == movie && !delay) {
		delay = 1;
		return;
		}

	delay = 0;
	gtk_widget_hide(video_draw);

	}

void	on_mini_mode_toggled(GtkWidget *w) {

//-------------------
//	mini mode
//-------------------

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) {
		gtk_widget_hide(stack1);
		gtk_widget_hide(switcher1);
		gtk_window_resize(GTK_WINDOW(window), 400,400);
		}

//-------------------
//	not mini mode
//-------------------

	else {
		gtk_widget_show(stack1);
		gtk_widget_show(switcher1);
		gtk_window_resize(GTK_WINDOW(window), 700,400);
		}

	}


/******************************
gboolean	on_draw1_motion_notify_event(GtkWidget *self, GdkEvent *event)  {

//-----------------------------------------------------------------------------
//	GDK signal rcvd on mouse-over draw1 area.
//	control_panel does not rcv this signal so we use the underlying draw1
//-----------------------------------------------------------------------------

 	return FALSE; // not in use

 	int x, y;

** for reference - the hard way
        GdkEventMotion* e = (GdkEventMotion*)event;
        GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(control_panel));
        x = e->x;
        y = e->y;
	printf("gdk_window=%p window=%p x=%d y=%d\n", gdk_window, e->window, x, y);
***


	gtk_widget_get_pointer (self, &x, &y);
//	printf("pointer at: %d %d\n",x,y);

	if (x < 4  || x > 402  || y < 4  || y > 230 )  {
//		gtk_widget_hide(control_panel);
		gtk_widget_set_opacity (draw1, 1.0);
		return FALSE;
		}

	gtk_widget_set_opacity (draw1, 0.8);
	usleep(500);
	gtk_widget_set_opacity (draw1, 0.4);

	gtk_widget_show(control_panel);
	return FALSE;
	}
****************************************/

// ----------------------------------------------------------------
//	Window has been closed
//	Cleanup dependent windows
// ----------------------------------------------------------------

gboolean	on_window_main_delete_event(GtkWidget *w, GdkEvent *e) {
	return FALSE;
	}

void on_window_main_destroy() {

	/*******************************************************

		audio reset - not currently needed

		char cmd[1024];

	        pa_cvolume vol = {2, 65000, 65000}; // tw channels

		mic_volume = mic_max;

	        vol.values[0] = (mic_volume / 100.0) * 65535;
	        vol.values[1] = (mic_volume / 100.0) * 65535;
		vol.channels = source_channels;

	        if (context_source) { // Mcontext pointer must be non-zero
			printf("*** Restore mic settings %s\n", default_source);
			pa_operation *x  =
				pa_context_set_source_volume_by_name(context_source, default_source,
				&vol, NULL, NULL);

	//-------------------------------------------------------------------------
	//		The above does not work. The following is a workaround
	//		Beware of mic_max - it should be appropos to your system
	//-------------------------------------------------------------------------

			char tmp[2048];
			sprintf(tmp, "pactl set-source-volume %s %d%%", default_source, (int) mic_max);
			printf("*** Reset: %s\n", tmp);
			system(tmp);
			}

		outVolume(INIT_VOLUME); // reset volume

	        if (stream_sink) pa_stream_unref(stream_sink);
	        if (stream_source) pa_stream_unref(stream_source);

	        if(device_name) g_free(device_name);

	        pa_glib_mainloop_free(m_sink);
	        pa_glib_mainloop_free(m_source);
	*****************************************************/

	system("pulseaudio --cleanup-shm");
	system("killall --signal SIGTERM vlc 2> /dev/null");
	system("killall --signal SIGTERM cam-bin 2> /dev/null");

	system("killall --signal SIGTERM sgr-player");

	gtk_main_quit();
	}


void    on_row(GtkButton *b) {
	printf("You selected: %s\n", gtk_button_get_label (b));
	}

void	on_entry1_drag_data_get(GtkEntry *e)	{
	copyClipRow = -10;
	}

//--------------- ENTRY CHANGED signals top two rows

//-----------------------------------------------------------------------------------
//	on_entry1_changed
//-----------------------------------------------------------------------------------

#define ENTRY_TOP_CHANGED(NBR) \
        void on_entry## NBR ##_changed(GtkEntry  *entry, gchar *preedit, gpointer user_data) { \
        int i = gtk_entry_get_text_length (entry); \
        if (i>STR_MAX) { Message("Entry Error"); \
                gtk_editable_delete_text (GTK_EDITABLE(entry), 0, -1 ); \
                return; } \
        entry_changed(entry, preedit, user_data, 0); }

ENTRY_TOP_CHANGED(1)

void	entry_insert1(GtkEntry  *entry, char *edit) {
	char file[1024];
	int i = 0, j = 0;

	strcpy(file, (char *) edit);
	hexcleaner(file);

	if (strncmp(file, "file://", 7) == 0) strcpy(edit, &file[7]);
	else strcpy(edit, file);
	return;
	}

//----------------------------
//	entry changed1
//----------------------------

void	entry_changed1 (GtkEntry *entry, gchar *preedit, gpointer  user_data, int Row) {

//	Handles multiple paste inserts which appear as long strings

	char *file, *file1;
	int i, k, m, flg, flg1 = 0;

	i = gtk_entry_get_text_length (entry);

	file = malloc (i + 9);

	if (file == NULL) {
		printf("Out of memory in entry_changed1\n");
		abort();
		}

	file1 = malloc (i + 9);

	if (file1 == NULL) {
		printf("Out of memory in entry_changed1\n");
		abort();
		}

	strcpy(file, gtk_entry_get_text(entry)); // get file name(s)

again:	// multiple names in one string

	flg1 = 0;
	for(k = 0; file[k] != 0; k++) if (file[k] == '\n') {
			flg1 = 1;
			break;
			}
	file[k] = 0;

	if (hexcleaner(file)) { }

//	don't do filetype() on files that dopn't begin with / as this
//	causes meaningless error messages to be generated.

	if (file[0] == '/' && filetype(file) == DIR) {
		char tmp[4096];
		if (strlen(file) > 4000) return;
		sprintf(tmp,"find \"%s\" -type f > /tmp/player.m3u", file);
		system(tmp);
		printf("Insert directory: %s\n", file);
		strcpy(tmp, "/tmp/player.m3u");
		LoadProgram(tmp);
		return;
		}

// basename

	i = strlen(file);

	flg = 0;

	if (file[0] == '/') flg=1;
	if (strncmp(file, "smb:", 4) == 0) flg=1;

	for (i = strlen(file); i > 0; i--) if (file[i] == '/') break;

//	if (Row >= SP->scount) SP->scount = Row + 1;

	if (i > 0) strcpy(file1, &file[i + 1]);
	else strcpy(file1, file);

	if (flg) {
		char tmp[1024], *p1;
		FILE *f1;

		strcpy(ProgramArray[Row], file);

		programData[Row]->play = 1; // play it?
		programPlayed[Row] = 0; // play count

		file[i]=0;

//		i = filetype(file1);

		for (i = strlen(file1); i > 0 && file1[i] != '.'; i--);

		if (i == UNRECOGNIZED || i > 99) {
			strcpy(file,"Bad File Type");
			}

		else {
			if (i == 7 || i == 8) file1[strlen(file1) - 5] = 0; // filetype ending removal
			else file1[strlen(file1) - 4] = 0;
			gtk_entry_set_text (GTK_ENTRY(entry), (gchar *) file1);
			while (gtk_events_pending ()) gtk_main_iteration ();
			}
		}

	if ( !flg1 ) goto end;

	if (! strlen(file)) goto end;

	strcpy(file1, &file[k + 1]);

	strcpy(file, file1);
	for (m = 0; file[m] != 0; m++) if (file[m] == '\n') break;
	if (file[m] == 0) goto end; // last row
	paste1(&Row);

	flg1=0;

	if (strncmp(file, "file://", 7) == 0) {
		strcpy(file1, &file[7]);
		strcpy(file, file1);
		}

	if (strlen(file)) {
		goto again;
		}

end:
	free (file);
	free (file1);
	}

// ---------------------------------------------------
//	top rows of edit panel clipboard code
// ---------------------------------------------------

void	on_entry1_copy_clipboard(GtkEntry *e) {
	copyClipRow = -10;
	}

void	on_entry1_cut_clipboard(GtkEntry *e) {
	copyClipRow = -10;
	}

void	on_entry1_paste_clipboard(GtkEntry *e) {

	if (copyClipRow>=0) {
		char file[1024],file1[1024];
		int i=0, j=0;
		gtk_editable_delete_text (GTK_EDITABLE(e), 0, -1 );
		strcpy(file, (char *) ProgramArray[copyClipRow]);
		hexcleaner(file);
		if (strncmp(file,"file://",7)==0) {
			strcpy(file1,&file[7]);
			strcpy(file,file1);
			}
		gtk_entry_set_text(e, (gchar *) file);
		return;
		}
	}

void	on_entry1_drag_data_received(GtkEntry *e, GdkDragContext   *context) {
	char file[1024],file1[1024];

	gtk_drag_finish (context, TRUE, FALSE, 0);

	if (copyClipRow>=0) {
		strcpy(top1,ProgramArray[copyClipRow]);
		}
	else return;

	strcpy(file,top1);
	int i=strlen(file);

	for (int j=0; j<i; j++) if (file[j] == ':') {
			file[j]=0;
			break;
			}

	i=strlen(file);
	for (i=strlen(file); i>0; i--) if (file[i]=='/') break;
	file[i]=0;

	strcpy(directories[0],file);
	}

// -------------------------------------------------
//	bottom 12 rows of edit panel cut and paste
// -------------------------------------------------

void	paste(int *Row) {

	int i,j,played,playtime, play, id1=0, id2=0;
	char time[32],file[512];

	if (strlen(cutRow)) {
		paste1(Row);
		strcpy(ProgramArray[*Row], cutRow);
		programData[*Row]->play = cutPlay;
		programPlayed[*Row] = cutPlayed;
		strcpy(cutRow,"");
		DisplayProgramButtons();
		return;
		}

	if (*Row == copyClipRow) {
		Message("Copy to same row");
		return;
		}

	if (copyClipRow < 0 ) {
		paste1(Row);
		return;
		Message("No source row selected");
		return;
		}

	if (SP->scount+1 >= PROGRAM_MAX) {
		Message("Maximum number of program slots exceeded");
		return;
		}

	strcpy(file,ProgramArray[copyClipRow]);
	play = programData[copyClipRow]->play;
	played = programPlayed[copyClipRow];
	playtime = programTime[copyClipRow];

	printf("paste() album move copyClipRow=%d  Row=%d\n",copyClipRow,
	       *Row ) ;

	delRow(copyClipRow);

	for (i=SP->scount+1; i>*Row; i--) {        // shift entries up one
		strcpy(ProgramArray[i], ProgramArray[i-1]);
		programData[i]->play = programData[i-1]->play;
		programPlayed[i] = programPlayed[i-1];
		programTime[i] = programTime[i-1];
		}

	strcpy(ProgramArray[*Row], file);   // insert new entry
	programData[*Row]->play = play;
	programPlayed[*Row] = played;
	programTime[*Row] = playtime;
	(SP->scount)++;
	DisplayProgramButtons();
	copyClipRow = -1;


	}

gboolean on_showCurrent1_button_press_event (GtkButton *btn,
        GdkEventButton *event, gpointer user_data) {

	if (event->button == 1 ) return FALSE;
	static int i = 0;

	if ((i = i ^ 1)) { // show egg

		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(video_panel)))
			gtk_widget_hide(drawV);

		gtk_widget_show(egg_image);
		}

	else { // hide egg

		gtk_widget_hide(egg_image);

		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(video_panel)))
			gtk_widget_show(drawV);

		}

	return TRUE;
	}


//------------------------------------------------------------
//	Tooltip for draw both draw areas (draw1 and draw2)
//------------------------------------------------------------

gboolean on_draw1_query_tooltip(GtkWidget *widget, gint x, gint y,
                                gboolean keyboard, GtkTooltip *tooltip) {

	char cmd[4096];

	strcpy(cmd, "Audio devices in use:\n");

	strcat(cmd, "default source: ");
	strncat(cmd,default_source, 1024);
	strcat(cmd, "\n");

	strcat(cmd, "default sink: ");
	strncat(cmd,default_sink, 1024);

	strcat(cmd, "\n");
	strcat(cmd, "Needles are actual volume levels;\nFloating square markers are RMS volume;\n"
	       "Floating thin markers are recent peaks\n");

	gtk_tooltip_set_text(tooltip, cmd);

	return TRUE;

	}

gboolean plug_removed (GtkSocket *sock) {
	printf("mpv socket disconneted.\n");
	mpv_socket_running = 0;
	gtk_stack_set_visible_child (GTK_STACK(stack1), pg);
	return FALSE; // continue processing (destroy socket)
	}

gboolean plug_added (GtkSocket *sock) {
	printf("mpv socket conneted.\n");
	mpv_socket_running = 1;
	return FALSE; // continue processing (destroy socket)
	}

void    EmbedVideo() {

//	under development


	char cmd[2048];
	unsigned long gtk_socket_get_id (GtkSocket *);
	unsigned x;
	int i;

//	mpv_socket_running = 1;

	gtk_stack_set_visible_child (GTK_STACK(stack1), mpv_player);

	while (gtk_events_pending ()) gtk_main_iteration ();

	system("killall mpv");

	sock1 = gtk_socket_new();

	g_signal_connect(G_OBJECT(sock1), "plug-removed", G_CALLBACK(plug_removed), NULL);
	g_signal_connect(G_OBJECT(sock1), "plug-added", G_CALLBACK(plug_added), NULL);

	gtk_box_pack_start(GTK_BOX(vlcX), sock1, TRUE,  TRUE, 0);

	gtk_widget_show_all(stack1);

	x=gtk_socket_get_id (GTK_SOCKET(sock1));

	printf("mpv please play this: %s\n", SP->playThis);

//	sprintf(cmd, "mpv --wid=%#x --hwdec=vdpau --vo=vdpau --no-osc --taskbar-progress=no "
//	        "--video-osd=no --vd-lavc-fast=yes --sws-scaler=fast-bilinear "
//	        "--input-vo-keyboard=yes --vid=auto --fps=15.0 --background=0.0/0.0/0.5 \"%s\" &",
//	        x, SP->playThis);

	sprintf(cmd, "mpv --wid=%#x --hwdec=vdpau --vo=vdpau  --taskbar-progress=yes "
	        "--video-osd=yes --vd-lavc-fast=yes --sws-scaler=fast-bilinear "
	        "--input-vo-keyboard=yes --vid=auto --fps=15.0 --background=0.0/0.0/0.5 \"%s\" &",
	        x, SP->playThis);

	system(cmd);

	usleep(500);

	}

/*********
gboolean	on_in_event(GtkWidget *w, GtkDirectionType *e) {
	static int video = 0;

	if (video) {
		return FALSE;
		}

	video = 1;
	EmbedVideo();
	return FALSE;
	}
****************/

void	on_finish_pgm_clicked(GtkWidget *b) {
	DisplayCover("default");
	SP->playProgram = 0;
	}


char *	ShortName(char *tmp) {
	int i, j = strlen(tmp);
	for (i = j; i > 0; i--)
		if (tmp[i] == '/') {
			return &tmp[i+1];
			}
	return tmp;
	}



void	on_window_main_check_resize (GtkWidget *w) {

	return;

	}



gboolean	on_window_main_configure(GtkWindow *window, GdkEvent *event) {

//--------------------------------
//	window resize comes here
//--------------------------------

	static int first = 3, last_width = 0, last_height = 0, last_x = 0, last_y = 0;
	int width1, width2, height1, height2;

	if (first) {
		first--;    // first few calls are meaningless
		return FALSE;
		}

//---------------------------
//	get current window
//---------------------------

	gtk_window_get_size (GTK_WINDOW(window), &width1, &height1);

	if (width1 < 1090) width1 = 1090; // min
	if (height1 < 610) height1 = 610; // min

//---------------------------------------------------------
//	if no change in size - possible change in position
//	ereturn
//---------------------------------------------------------

	if (last_width == width1 && last_height == height1) return FALSE;

	last_width = width1;
	last_height = height1;

//------------------------
//	delay slide change
//------------------------

	slide_timer = slide_time;

//---------------------------------
//	destroy current slide image
//---------------------------------

	gtk_image_set_from_pixbuf(GTK_IMAGE(SlidesImage), NULL);

//	if (last_width > 2000 || last_height >1200) { // strnge things can happen
//		printf("Panel width too large\n");
//		gtk_window_resize (GTK_WINDOW(window), 1920, 1080);
//		last_width = 1920;
//		width1 = 1920;
//		last_height = 1080;
//		height1 = 1080;
//		abort();
//		}

//	gtk_fixed_move (GTK_FIXED(fixed1), GTK_WIDGET(Top1), 0.0, 0.0 );

//-----------------------
//      Top1 reposition
//-----------------------

#define HEIGHT_FACTOR 608
#define WIDTH_FACTOR 1090

	gtk_fixed_move(GTK_FIXED(fixed1), GTK_WIDGET(Top1),
	               0, (height1 - HEIGHT_FACTOR)/2);

	gtk_fixed_move(GTK_FIXED(visual), GTK_WIDGET(draw4),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(ed_fixed), GTK_WIDGET(pg_edit),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(pg_fixed), GTK_WIDGET(pg),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(ct_fixed), GTK_WIDGET(controls),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(pg8_fixed), GTK_WIDGET(pg8),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(au_fixed), GTK_WIDGET(audio),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(movie), GTK_WIDGET(video_bg),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);

	gtk_fixed_move(GTK_FIXED(visual), GTK_WIDGET(video_bg1),
	               (width1 - WIDTH_FACTOR) / 2.0, (height1 - HEIGHT_FACTOR) / 2.0);


//----------------------
//	webkit resize
//----------------------

	width2 = width1 - 440;
	height2 = height1 - 30;

	gtk_widget_set_size_request (webkit, width2, height2 - 25);
	gtk_widget_set_size_request (web_panel, width2, height2);

	gtk_widget_show(webkit);
	gtk_widget_show(web_panel);

//-----------------
//	video size
//-----------------

	width2 = width1 - 440;

	gtk_widget_hide(video_draw);

	height2 = height1 - 20;

	gtk_fixed_move (GTK_FIXED(movie), video_draw, (double) 2, (double) 2 );

	gtk_widget_show(video_draw);

	gtk_widget_set_size_request (video_draw, width2, height2);

	while (gtk_events_pending ()) gtk_main_iteration ();

//----------------------------
//	next slide, please
//----------------------------

	slide_timer = slide_time - 1; // force new slide

	gtk_widget_show(fixed1);
	return FALSE;
	}
