示例#1
0
文件: main.cpp 项目: eddywebs/attract
int main(int argc, char *argv[])
{
	std::string config_path, cmdln_font;
	bool launch_game = false;

	process_args( argc, argv, config_path, cmdln_font );

	//
	// Run the front-end
	//
	std::cout << "Starting " << FE_NAME << " " << FE_VERSION
			<< " (" << get_OS_string() << ")" << std::endl;

	FeSettings feSettings( config_path, cmdln_font );
	feSettings.load();

	std::string def_font_path, def_font_file;
	if ( feSettings.get_font_file( def_font_path, def_font_file ) == false )
	{
		std::cerr << "Error, could not find default font."  << std::endl;
		return 1;
	}

	FeFontContainer def_font;
	def_font.set_font( def_font_path, def_font_file );

	//
	// Set up music/sound playing objects
	//
#ifndef NO_MOVIE
	sf::AudioDevice audio_device;
#endif
	FeSoundSystem soundsys( &feSettings );

	soundsys.update_volumes();
	soundsys.play_ambient();

	FeWindow window( feSettings );
	window.initial_create();

#ifdef SFML_SYSTEM_WINDOWS
	if ( feSettings.get_hide_console() )
		hide_console();
#endif

	FeVM feVM( feSettings, def_font, window, soundsys.get_ambient_sound() );
	FeOverlay feOverlay( window, feSettings, feVM );
	feVM.set_overlay( &feOverlay );

	bool exit_selected=false;

	if ( feSettings.get_language().empty() )
	{
		// If our language isn't set at this point, we want to prompt the user for the language
		// they wish to use
		//
		if ( feOverlay.languages_dialog() < 0 )
			exit_selected = true;

		// Font may change depending on the language selected
		feSettings.get_font_file( def_font_path, def_font_file );
		def_font.set_font( def_font_path, def_font_file );
	}

	soundsys.sound_event( FeInputMap::EventStartup );

	bool redraw=true;
	int guard_joyid=-1, guard_axis=-1;

	// variables used to track movement when a key is held down
	FeInputMap::Command move_state( FeInputMap::LAST_COMMAND );

	sf::Clock move_timer;
	sf::Event move_event;
	int move_last_triggered( 0 );

	// go straight into config mode if there are no lists configured for
	// display
	//
	bool config_mode = ( feSettings.displays_count() < 1 );

	if ( !config_mode )
	{
		// start the intro now
		if ( !feVM.load_intro() )
		{
			// ... or start the layout if there is no intro
			feVM.load_layout( true );

			switch ( feSettings.get_startup_mode() )
			{
			case FeSettings::LaunchLastGame:
				feSettings.select_last_launch();
				launch_game=true;
				break;

			case FeSettings::ShowDisplaysMenu:
				FeVM::cb_signal( "displays_menu" );
				break;

			default:
				break;
			}

		}
	}

	while (window.isOpen() && (!exit_selected))
	{
		if ( config_mode )
		{
			//
			// Enter config mode
			//
			int old_mode = feSettings.get_window_mode();
			if ( feOverlay.config_dialog() )
			{
				// Settings changed, reload
				//
				if ( feSettings.get_font_file( def_font_path, def_font_file ) )
					def_font.set_font( def_font_path, def_font_file );

				feSettings.set_display(
					feSettings.get_current_display_index() );

				soundsys.stop();
				soundsys.update_volumes();
				soundsys.play_ambient();

				// Recreate window if the window mode changed
				if ( feSettings.get_window_mode() != old_mode )
				{
					window.on_exit();
					window.initial_create();
					feVM.init_monitors();
				}

				feVM.load_layout();
			}
			feVM.reset_screen_saver();
			config_mode=false;
			redraw=true;
		}
		else if (( launch_game )
			&& ( !soundsys.is_sound_event_playing( FeInputMap::Select ) ))
		{
			if ( feSettings.get_rom_info( 0, 0, FeRomInfo::Emulator ).compare( "@" ) == 0 )
			{
				// If the rom_info's emulator is set to "@" then this is a shortcut to another
				// display, so instead of running a game we switch to the display specified in the
				// rom_info's Romname field
				//
				std::string name = feSettings.get_rom_info( 0, 0, FeRomInfo::Romname );
				int index = feSettings.get_display_index_from_name( name );

				// if index not found or if we are already in the specified display, then
				// jump to the altromname display instead
				//
				if (( index < 0 ) || ( index == feSettings.get_current_display_index() ))
				{
					name = feSettings.get_rom_info( 0, 0, FeRomInfo::AltRomname );
					if ( !name.empty() )
						index =  feSettings.get_display_index_from_name( name );
				}

				if ( index < 0 )
				{
					std::cerr << "Error resolving shortcut, Display `" << name << "' not found.";
				}
				else
				{
					if ( feSettings.set_display( index ) )
						feVM.load_layout();
					else
						feVM.update_to_new_list( 0, true );
				}
			}
			else
			{
				soundsys.stop();

				soundsys.release_audio( true );
				feVM.pre_run();

				// window.run() returns true if our window has been closed while
				// the other program was running
				if ( !window.run() )
					exit_selected = true;

				feVM.post_run();
				soundsys.release_audio( false );

				soundsys.sound_event( FeInputMap::EventGameReturn );
				soundsys.play_ambient();
			}

			launch_game=false;
			redraw=true;
		}

		FeInputMap::Command c;
		sf::Event ev;
		bool from_ui;
		while ( feVM.poll_command( c, ev, from_ui ) )
		{
			//
			// Special case handling based on event type
			//
			switch ( ev.type )
			{
				case sf::Event::Closed:
					exit_selected = true;
					break;

				case sf::Event::MouseMoved:
					if ( feSettings.test_mouse_reset( ev.mouseMove.x, ev.mouseMove.y ))
					{
						// We reset the mouse if we are capturing it and it has moved
						// outside of its bounding box
						//
						sf::Vector2u s = window.getSize();
						sf::Mouse::setPosition( sf::Vector2i( s.x / 2, s.y / 2 ), window );
					}
					break;

				case sf::Event::KeyPressed:
				case sf::Event::MouseButtonPressed:
				case sf::Event::JoystickButtonPressed:
					//
					// We always want to reset the screen saver on these events,
					// even if they aren't mapped otherwise (mapped events cause
					// a reset too)
					//
					if (( c == FeInputMap::LAST_COMMAND )
							&& ( feVM.reset_screen_saver() ))
						redraw = true;
					break;

				case sf::Event::GainedFocus:
				case sf::Event::Resized:
					redraw = true;
					break;


				case sf::Event::JoystickMoved:
					if ( c != FeInputMap::LAST_COMMAND )
					{
						// Only allow one mapped "Joystick Moved" input through at a time
						//
						if ( guard_joyid != -1 )
							continue;

						guard_joyid = ev.joystickMove.joystickId;
						guard_axis = ev.joystickMove.axis;
					}
					break;

				case sf::Event::Count:
				default:
					break;
			}

			// Test if we need to keep the joystick axis guard up
			//
			if (( guard_joyid >= 0 )
				&& ( std::abs( sf::Joystick::getAxisPosition(
					guard_joyid, (sf::Joystick::Axis)guard_axis )
						< feSettings.get_joy_thresh() )))
			{
				guard_joyid = -1;
				guard_axis = -1;
			}

			if ( c == FeInputMap::LAST_COMMAND )
				continue;

			//
			// Special case: handle the reload signal now
			//
			if ( c == FeInputMap::Reload )
			{
				feVM.load_layout();
				continue;
			}

			//
			// If we are responding to user input (as opposed to a signal raised from a
			// script) then manage keyrepeats now.
			//
			if ( from_ui )
			{
				if ( move_state != FeInputMap::LAST_COMMAND )
					continue;

				move_state=FeInputMap::LAST_COMMAND;

				if ( ( is_ui_command( c ) && ( c != FeInputMap::Back ) )
					|| is_repeatable_command( c ) )
				{
					// setup variables to test for when the navigation keys are held down
					move_state = c;
					move_timer.restart();
					move_event = ev;
				}
			}

			//
			// Map Up/Down/Left/Right/Back to their default action now
			//
			if ( is_ui_command( c ) )
			{
				//
				// Give the script the option to handle the (pre-map) action.
				//
				if ( feVM.script_handle_event( c ) )
				{
					redraw=true;
					continue;
				}

				c = feSettings.get_default_command( c );
				if ( c == FeInputMap::LAST_COMMAND )
				{
					redraw=true;
					continue;
				}
			}

			//
			// Give the script the option to handle the command.
			//
			if ( feVM.script_handle_event( c ) )
			{
				redraw=true;
				continue;
			}

			//
			// Check if we need to get out of intro mode
			//
			if ( feSettings.get_present_state() == FeSettings::Intro_Showing )
			{
				move_state = FeInputMap::LAST_COMMAND;
				move_last_triggered = 0;

				feVM.load_layout( true );

				switch ( feSettings.get_startup_mode() )
				{
				case FeSettings::LaunchLastGame:
					feSettings.select_last_launch();
					launch_game=true;
					break;

				case FeSettings::ShowDisplaysMenu:
					FeVM::cb_signal( "displays_menu" );
					break;

				default:
					break;
				}

				redraw=true;
				continue;
			}

			//
			// Default command handling
			//
			soundsys.sound_event( c );
			if ( feVM.handle_event( c ) )
				redraw = true;
			else
			{
				// handle the things that fePresent doesn't do
				switch ( c )
				{
				case FeInputMap::ExitMenu:
					{
						int retval = feOverlay.confirm_dialog(
							"Exit Attract-Mode?",
							"",
							FeInputMap::ExitMenu );

						//
						// retval is 0 if the user confirmed exit.
						// it is <0 if we are being forced to close
						//
						if ( retval < 1 )
						{
							exit_selected = true;
							if ( retval == 0 )
								feSettings.exit_command();
						}
						else
							redraw=true;
					}
					break;

				case FeInputMap::ExitNoMenu:
					exit_selected = true;
					break;

				case FeInputMap::ReplayLastGame:
					if ( feSettings.select_last_launch() )
						feVM.load_layout();
					else
						feVM.update_to_new_list();

					launch_game=true;
					redraw=true;
					break;

				case FeInputMap::Select:
					launch_game=true;
					break;

				case FeInputMap::ToggleMute:
					feSettings.set_mute( !feSettings.get_mute() );
					soundsys.update_volumes();
					feVM.toggle_mute();
					break;

				case FeInputMap::ScreenShot:
					{
						std::string filename;
						get_available_filename( feSettings.get_config_dir(),
										"screen", ".png", filename );

						sf::Image sshot_img = window.capture();
						sshot_img.saveToFile( filename );
					}
					break;

				case FeInputMap::Configure:
					config_mode = true;
					break;

				case FeInputMap::DisplaysMenu:
					{
						std::vector<std::string> disp_names;
						std::vector<int> disp_indices;
						int current_idx;

						feSettings.get_display_menu( disp_names, disp_indices, current_idx );
						std::string title;
						feSettings.get_resource( "Displays", title );

						int exit_opt=-999;
						if ( feSettings.get_info_bool( FeSettings::DisplaysMenuExit ) )
						{
							//
							// Add an exit option at the end of the lists menu
							//
							std::string exit_str;
							feSettings.get_resource( "Exit Attract-Mode", exit_str );
							disp_names.push_back( exit_str );
							exit_opt = disp_names.size() - 1;
						}

						if ( !disp_names.empty() )
						{
							int sel_idx = feOverlay.common_list_dialog(
								title,
								disp_names,
								current_idx,
								-1,
								FeInputMap::DisplaysMenu );

							if ( sel_idx == exit_opt )
							{
								exit_selected = true;
								feSettings.exit_command();
							}
							else if ( sel_idx >= 0 )
							{
								if ( feSettings.set_display( disp_indices[sel_idx] ) )
									feVM.load_layout();
								else
									feVM.update_to_new_list( 0, true );
							}
							redraw=true;
						}
					}
					break;

				case FeInputMap::FiltersMenu:
					{
						std::vector<std::string> names_list;
						feSettings.get_current_display_filter_names( names_list );

						std::string title;
						feSettings.get_resource( "Filters", title );

						int filter_index = feOverlay.common_list_dialog(
										title,
										names_list,
										feSettings.get_current_filter_index(),
										-1,
										FeInputMap::FiltersMenu );

						if ( filter_index >= 0 )
						{
							feSettings.set_current_selection( filter_index, -1 );
							feVM.update_to_new_list();
						}

						redraw=true;
					}
					break;

				case FeInputMap::ToggleFavourite:
					{
						bool new_state = !feSettings.get_current_fav();

						if ( feSettings.get_info_bool( FeSettings::ConfirmFavourites ) )
						{
							std::string msg = ( new_state )
								? "Add '$1' to Favourites?"
								: "Remove '$1' from Favourites?";

							// returns 0 if user confirmed toggle
							if ( feOverlay.confirm_dialog(
									msg,
									feSettings.get_rom_info( 0, 0, FeRomInfo::Title ) ) == 0 )
							{
								if ( feSettings.set_current_fav( new_state ) )
									feVM.update_to_new_list( 0, true ); // our current display might have changed, so update
							}
						}
						else
						{
							if ( feSettings.set_current_fav( new_state ) )
								feVM.update_to_new_list( 0, true ); // our current display might have changed, so update
						}
						redraw = true;
					}
					break;

				case FeInputMap::ToggleTags:
					if ( feOverlay.tags_dialog() < 0 )
						exit_selected = true;

					redraw = true;
					break;

				default:
					break;
				}
			}
		}

		//
		// Determine if we have to do anything because a key is being held down
		//
		if ( move_state != FeInputMap::LAST_COMMAND )
		{
			bool cont=false;

			switch ( move_event.type )
			{
			case sf::Event::KeyPressed:
				if ( sf::Keyboard::isKeyPressed( move_event.key.code ) )
					cont=true;
				break;

			case sf::Event::MouseButtonPressed:
				if ( sf::Mouse::isButtonPressed( move_event.mouseButton.button ) )
					cont=true;
				break;

			case sf::Event::JoystickButtonPressed:
				if ( sf::Joystick::isButtonPressed(
						move_event.joystickButton.joystickId,
						move_event.joystickButton.button ) )
					cont=true;
				break;

			case sf::Event::JoystickMoved:
				{
					sf::Joystick::update();

					float pos = sf::Joystick::getAxisPosition(
							move_event.joystickMove.joystickId,
							move_event.joystickMove.axis );
					if ( std::abs( pos ) > feSettings.get_joy_thresh() )
						cont=true;
				}
				break;

			default:
				break;
			}

			if ( cont )
			{
				const int TRIG_CHANGE_MS = 400;
				int t = move_timer.getElapsedTime().asMilliseconds();
				if (( t > TRIG_CHANGE_MS ) && ( t - move_last_triggered > feSettings.selection_speed() ))
				{
					FeInputMap::Command ms = move_state;
					if ( is_ui_command( ms ) )
					{
						//
						// Give the script the option to handle the (pre-map) action.
						//
						if ( feVM.script_handle_event( ms ) )
						{
							redraw=true;
							ms = FeInputMap::LAST_COMMAND;
						}
						else
						{
							ms = feSettings.get_default_command( ms );
							if ( !is_repeatable_command( ms ) )
								ms = FeInputMap::LAST_COMMAND;
						}
					}

					if ( ms != FeInputMap::LAST_COMMAND )
					{
						move_last_triggered = t;
						int step = 1;

						if ( feSettings.get_info_bool( FeSettings::AccelerateSelection ) )
						{
							// As the button is held down, the advancement accelerates
							int shift = ( t / TRIG_CHANGE_MS ) - 3;
							if ( shift < 0 )
								shift = 0;
							else if ( shift > 7 ) // don't go above a maximum advance of 2^7 (128)
								shift = 7;

							step = 1 << ( shift );
						}

						switch ( ms )
						{
						case FeInputMap::PrevGame: step = -step; break;
						case FeInputMap::NextGame: break; // do nothing
						case FeInputMap::PrevPage: step *= -feVM.get_page_size(); break;
						case FeInputMap::NextPage: step *= feVM.get_page_size(); break;
						case FeInputMap::PrevFavourite:
							{
								int temp = feSettings.get_prev_fav_offset();
								step = ( temp < 0 ) ? temp : 0;
							}
							break;
						case FeInputMap::NextFavourite:
							{
								int temp = feSettings.get_next_fav_offset();
								step = ( temp > 0 ) ? temp : 0;
							}
							break;
						case FeInputMap::PrevLetter:
							{
								int temp = feSettings.get_next_letter_offset( -1 );
								step = ( temp < 0 ) ? temp : 0;
							}
							break;
						case FeInputMap::NextLetter:
							{
								int temp = feSettings.get_next_letter_offset( 1 );
								step = ( temp > 0 ) ? temp : 0;
							}
							break;
						default: break;
						}

						//
						// Limit the size of our step so that there is no wrapping around at the end of the list
						//
						int curr_sel = feSettings.get_rom_index( feSettings.get_current_filter_index(), 0 );
						if ( ( curr_sel + step ) < 0 )
							step = -curr_sel;
						else
						{
							int list_size = feSettings.get_filter_size( feSettings.get_current_filter_index() );
							if ( ( curr_sel + step ) >= list_size )
								step = list_size - curr_sel - 1;
						}

						if ( step != 0 )
						{
							if ( feVM.script_handle_event( ms ) == false )
								feVM.change_selection( step, false );

							redraw=true;
						}
					}
				}
			}
			else
			{
				//
				// If we are ending a "repeatable" input (prev/next game etc) or a UI input
				// that maps to a repeatable input (i.e. "Up"->"prev game") then trigger the
				// "End Navigation" stuff now
				//
				FeInputMap::Command ms = move_state;
				if ( is_ui_command( ms ) )
					ms = feSettings.get_default_command( ms );

				if ( is_repeatable_command( ms ) )
					feVM.on_end_navigation();

				move_state = FeInputMap::LAST_COMMAND;
				move_last_triggered = 0;

				redraw=true;
			}
		}

		if ( feVM.on_tick() )
			redraw=true;

		if ( feVM.video_tick() )
			redraw=true;

		if ( feVM.saver_activation_check() )
			soundsys.sound_event( FeInputMap::ScreenSaver );

		if ( redraw )
		{
			// begin drawing
			window.clear();
			window.draw( feVM );
			window.display();
			redraw=false;
		}
		else
			sf::sleep( sf::milliseconds( 30 ) );

		soundsys.tick();
	}

	window.on_exit();
	feVM.on_stop_frontend();

	if ( window.isOpen() )
		window.close();

	FeRomListSorter::clear_title_rex();

	soundsys.stop();
	feSettings.save_state();

	return 0;
}
示例#2
0
LRESULT CALLBACK settings_proc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	static HWND grippy=0;
	static int font_changed=FALSE;
	static int justify_changed=FALSE;
	switch(msg){
	case WM_INITDIALOG:
		{
			extern int keep_closed;
			int val;
			get_ini_value(INI_SETTINGS,"KEEP_CLOSED",&keep_closed);
			if(!keep_closed)
				CheckDlgButton(hwnd,IDC_KEEP_CONNECTED,BST_CHECKED);
			val=0;
			get_ini_value(INI_SETTINGS,"SINGLE_INSTANCE",&val);
			if(val)
				CheckDlgButton(hwnd,IDC_SINGLE_INSTANCE,BST_CHECKED);
			val=0;
			get_ini_value(INI_SETTINGS,"DEBUG",&val);
			if(val)
				CheckDlgButton(hwnd,IDC_DEBUG,BST_CHECKED);

			get_ini_value(INI_SETTINGS,"TRIM_TRAILING",&trim_trailing);
			if(trim_trailing)
				CheckDlgButton(hwnd,IDC_TRIM_TRAILING,BST_CHECKED);

			get_ini_value(INI_SETTINGS,"LEFT_JUSTIFY",&left_justify);
			if(left_justify)
				CheckDlgButton(hwnd,IDC_LEFT_JUSTIFY,BST_CHECKED);

			get_ini_value(INI_SETTINGS,"SAVE_MDI_WIN_SIZE",&save_mdi_win_size);
			if(save_mdi_win_size)
				CheckDlgButton(hwnd,IDC_SAVE_MDI_WIN_SIZE,BST_CHECKED);

			add_fonts(hwnd,IDC_SQL_FONT);
			add_fonts(hwnd,IDC_LISTVIEW_FONT);
			add_fonts(hwnd,IDC_TREEVIEW_FONT);
			select_current_font(hwnd,IDC_SQL_FONT);
			select_current_font(hwnd,IDC_LISTVIEW_FONT);
			select_current_font(hwnd,IDC_TREEVIEW_FONT);
			font_changed=FALSE;
			justify_changed=FALSE;
		}
		grippy=create_grippy(hwnd);
		break;
	case WM_SIZE:
		grippy_move(hwnd,grippy);
		break;
	case WM_COMMAND:
		switch(LOWORD(wparam)){
		case IDC_DEBUG:
			printf("debug %08X %08X\n",wparam,lparam);
			if(IsDlgButtonChecked(hwnd,IDC_DEBUG)==BST_CHECKED)
				open_console();
			else
				hide_console();
			break;
		case IDC_FILE_ASSOCIATIONS:
			DialogBoxParam(ghinstance,IDD_FILE_ASSOCIATIONS,hwnd,file_assoc_proc,0);
			break;
		case IDC_OPEN_INI:
			open_ini(hwnd,FALSE);
			break;
		case IDC_SQL_FONT:
			if(HIWORD(wparam)==CBN_SELENDOK){
				int i,max=get_max_table_windows();
				int font;
				char str[80]={0};
				GetDlgItemText(hwnd,IDC_SQL_FONT,str,sizeof(str));
				font=fontname_to_int(str);
				for(i=0;i<max;i++){
					HWND hedit=0;
					if(get_win_hwnds(i,NULL,&hedit,NULL)){
						SendMessage(hedit,WM_SETFONT,GetStockObject(font),0);
						InvalidateRect(hedit,NULL,TRUE);
					}
				}
				font_changed=TRUE;
			}
			break;
		case IDC_LISTVIEW_FONT:
			if(HIWORD(wparam)==CBN_SELENDOK){
				int i,max=get_max_table_windows();
				int font;
				char str[80]={0};
				GetDlgItemText(hwnd,IDC_LISTVIEW_FONT,str,sizeof(str));
				font=fontname_to_int(str);
				for(i=0;i<max;i++){
					HWND hlistview;
					if(get_win_hwnds(i,NULL,NULL,&hlistview)){
						SendMessage(hlistview,WM_SETFONT,GetStockObject(font),0);
						InvalidateRect(hlistview,NULL,TRUE);
					}
				}
				font_changed=TRUE;
			}
			break;
		case IDC_TREEVIEW_FONT:
			if(HIWORD(wparam)==CBN_SELENDOK){
				extern HWND ghtreeview;
				int font;
				char str[80]={0};
				GetDlgItemText(hwnd,IDC_TREEVIEW_FONT,str,sizeof(str));
				font=fontname_to_int(str);
				if(ghtreeview!=0){
					SendMessage(ghtreeview,WM_SETFONT,GetStockObject(font),0);
					InvalidateRect(ghtreeview,NULL,TRUE);
				}
				font_changed=TRUE;
			}
			break;
		case IDC_LEFT_JUSTIFY:
			if(HIWORD(wparam)==BN_CLICKED){
				extern int left_justify;
				int i,max=get_max_table_windows();
				if(IsDlgButtonChecked(hwnd,IDC_LEFT_JUSTIFY)==BST_CHECKED)
					left_justify=1;
				else
					left_justify=0;
				for(i=0;i<max;i++){
					HWND hlistview;
					if(get_win_hwnds(i,NULL,NULL,&hlistview))
						InvalidateRect(hlistview,NULL,TRUE);
				}
				justify_changed=TRUE;
			}
			break;
		case IDOK:
			{
			extern int keep_closed;
			char key[80],str[80];
			int i,val,ctrls[3]={IDC_SQL_FONT,IDC_LISTVIEW_FONT,IDC_TREEVIEW_FONT};
			if(IsDlgButtonChecked(hwnd,IDC_KEEP_CONNECTED)==BST_CHECKED)
				keep_closed=FALSE;
			else
				keep_closed=TRUE;
			
			write_ini_value(INI_SETTINGS,"KEEP_CLOSED",keep_closed);

			val=0;
			if(IsDlgButtonChecked(hwnd,IDC_SINGLE_INSTANCE)==BST_CHECKED)
				val=1;
			write_ini_value(INI_SETTINGS,"SINGLE_INSTANCE",val);
			set_single_instance(val);

			val=0;
			if(IsDlgButtonChecked(hwnd,IDC_DEBUG)==BST_CHECKED)
				val=1;
			write_ini_value(INI_SETTINGS,"DEBUG",val);

			
			if(IsDlgButtonChecked(hwnd,IDC_TRIM_TRAILING)==BST_CHECKED)
				trim_trailing=1;
			else
				trim_trailing=0;
			write_ini_value(INI_SETTINGS,"TRIM_TRAILING",trim_trailing);

			if(IsDlgButtonChecked(hwnd,IDC_LEFT_JUSTIFY)==BST_CHECKED)
				left_justify=1;
			else
				left_justify=0;
			write_ini_value(INI_SETTINGS,"LEFT_JUSTIFY",left_justify);

			if(IsDlgButtonChecked(hwnd,IDC_SAVE_MDI_WIN_SIZE)==BST_CHECKED)
				save_mdi_win_size=1;
			else
				save_mdi_win_size=0;
			write_ini_value(INI_SETTINGS,"SAVE_MDI_SIZE",save_mdi_win_size);

			for(i=0;i<sizeof(ctrls)/sizeof(int);i++){
				key[0]=0;
				get_control_name(ctrls[i],key,sizeof(key));
				str[0]=0;
				GetDlgItemText(hwnd,ctrls[i],str,sizeof(str));
				write_ini_str(INI_SETTINGS,key,str);
			}
			}
		case IDCANCEL:
			if(font_changed){
				int i,ctrls[3]={IDC_SQL_FONT,IDC_LISTVIEW_FONT,IDC_TREEVIEW_FONT};
				for(i=0;i<sizeof(ctrls)/sizeof(int);i++){
					char key[80],str[80];
					key[0]=0;
					get_control_name(ctrls[i],key,sizeof(key));
					str[0]=0;
					GetDlgItemText(hwnd,ctrls[i],str,sizeof(str));
					get_ini_str(INI_SETTINGS,key,str,sizeof(str));
					if(str[0]!=0){
						int max=get_max_table_windows();
						int font=fontname_to_int(str);
						if(ctrls[i]==IDC_SQL_FONT){
							int j;
							for(j=0;j<max;j++){
								HWND hedit=0;
								if(get_win_hwnds(j,NULL,&hedit,NULL)){
									SendMessage(hedit,WM_SETFONT,GetStockObject(font),0);
									InvalidateRect(hedit,NULL,TRUE);
								}
							}
						}
						else if(ctrls[i]==IDC_LISTVIEW_FONT){
							int j;
							for(j=0;j<max;j++){
								HWND hlistview;
								if(get_win_hwnds(j,NULL,NULL,&hlistview)){
									SendMessage(hlistview,WM_SETFONT,GetStockObject(font),0);
									InvalidateRect(hlistview,NULL,TRUE);
								}
							}
						}
						else if(ctrls[i]==IDC_TREEVIEW_FONT){
							extern HWND ghtreeview;
							SendMessage(ghtreeview,WM_SETFONT,GetStockObject(font),0);
						}
					}
				}
			}
			if(justify_changed){
				int i,max=get_max_table_windows();
				get_ini_value(INI_SETTINGS,"LEFT_JUSTIFY",&left_justify);
				for(i=0;i<max;i++){
					HWND hlistview;
					if(get_win_hwnds(i,NULL,NULL,&hlistview))
						InvalidateRect(hlistview,NULL,TRUE);
				}
			}
			EndDialog(hwnd,0);
			break;
		}
		break;
	}
	return 0;
}