/* * setup_menu.c: Setup Menu * * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * * $Id: setup_menu.c,v 1.1 2006-06-03 10:01:17 phintuka Exp $ * */ #include #include #include #include "setup_menu.h" #include "device.h" #include "menuitems.h" #include "config.h" namespace XinelibOutputSetupMenu { //#define INTEGER_CONFIG_VIDEO_CONTROLS //#define LINEAR_VIDEO_CONTROLS //--- Setup Menu ------------------------------------------------------------- const char *ModeLineChars = " 0123456789+-hvsync."; const char *DriverNameChars = " abcdefghijklmnopqrstuvwxyz0123456789-.,#~:;"; const char *OptionsChars = "=.,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const char *controls[] = { "Off", "[|---------------]","[|---------------]", "[-|--------------]","[-|--------------]", "[--|-------------]","[--|-------------]", "[---|------------]","[---|------------]", "[----|-----------]","[----|-----------]", "[-----|----------]","[-----|----------]", "[------|---------]","[------|---------]", "[-------|--------]","[-------|--------]", "[--------|-------]","[--------|-------]", "[---------|------]","[---------|------]", "[----------|-----]","[----------|-----]", "[-----------|----]","[-----------|----]", "[------------|---]","[------------|---]", "[-------------|--]","[-------------|--]", "[--------------|-]","[--------------|-]", "[---------------|]","[---------------|]", NULL }; #ifdef LINEAR_VIDEO_CONTROLS # define CONTROL_TO_INDEX(val) ((val)>=0 ? ((val)>>11)+1 : 0) # define INDEX_TO_CONTROL(ind) ((ind)==0 ? -1 : ((ind)-1)<<11) #else const int ind2ctrl_tbl[33] = { -1, 0, 0x0001, 0x0002, 0x0003, 0x0004, 0x0007, 0x000a, 0x000f, 0x0014, 0x001f, 42, 0x003f, 80, 0x007f, 170, 0x00ff, 336, 0x01ff, 682, 0x03ff, 1630, 0x07ff, 2730, 0x0fff, 5726, 0x1fff, 10858, 0x3fff, 22110, 0x7fff, 43224, 0xffff }; static int CONTROL_TO_INDEX(int val) { for(int i=0; i<33;i++) if(val<=ind2ctrl_tbl[i]) return i; return 32; } static int INDEX_TO_CONTROL(int ind) { if(ind<0) ind=0; if(ind>32) ind=32; return ind2ctrl_tbl[ind]; } #endif static cOsdItem *NewTitle(const char *s) { char str[128]; cOsdItem *tmp; sprintf(str,"----- %s -----", tr(s)); tmp = new cOsdItem(str); tmp->SetSelectable(false); return tmp; } //--- cMenuSetupAudio -------------------------------------------------------- class cMenuSetupAudio : public cMenuSetupPage { private: config_t newconfig; int audio_driver; int visualization; cOsdItem *audio_driver_item; cOsdItem *audio_ctrl_delay; cOsdItem *audio_ctrl_compression; cOsdItem *audio_ctrl_upmix; cOsdItem *audio_ctrl_surround; cOsdItem *audio_ctrl_headphone; cMenuEditItem *audio_port_item; protected: virtual void Store(void); void Set(void); public: cMenuSetupAudio(void); ~cMenuSetupAudio(void); virtual eOSState ProcessKey(eKeys Key); }; cMenuSetupAudio::cMenuSetupAudio(void) { memcpy(&newconfig, &xc, sizeof(config_t)); audio_driver = strstra(xc.audio_driver, xc.s_audioDrivers, 0); visualization = strstra(xc.audio_visualization, xc.s_audioVisualizations, 0); Set(); } cMenuSetupAudio::~cMenuSetupAudio(void) { cXinelibDevice::Instance().ConfigurePostprocessing( xc.deinterlace_method, xc.audio_delay, xc.audio_compression, xc.audio_equalizer, xc.audio_surround); #ifdef ENABLE_TEST_POSTPLUGINS cXinelibDevice::Instance().ConfigurePostprocessing( "upmix", xc.audio_upmix ? true : false, NULL); cXinelibDevice::Instance().ConfigurePostprocessing( "headphone", xc.headphone ? true : false, NULL); #endif } void cMenuSetupAudio::Set(void) { SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N)); int current = Current(); Clear(); Add(NewTitle("Audio")); Add(audio_driver_item = new cMenuEditStraI18nItem(tr("Driver"), &audio_driver, AUDIO_DRIVER_count, xc.s_audioDriverNames)); if(audio_driver != AUDIO_DRIVER_AUTO && audio_driver != AUDIO_DRIVER_NONE) Add(audio_port_item = new cMenuEditStrItem(tr("Port"), newconfig.audio_port, 31, DriverNameChars)); else audio_port_item = NULL; Add(audio_ctrl_delay = new cMenuEditTypedIntItem(tr("Delay"), tr("ms"), &newconfig.audio_delay, -3000, 3000, tr("Off"))); Add(audio_ctrl_compression = new cMenuEditTypedIntItem(tr("Audio Compression"), "%", &newconfig.audio_compression, 100, 500, tr("Off"))); Add(audio_ctrl_upmix = new cMenuEditBoolItem(tr("Upmix stereo to 5.1"), &newconfig.audio_upmix)); Add(audio_ctrl_surround = new cMenuEditBoolItem(tr("Downmix AC3 to surround"), &newconfig.audio_upmix)); #ifdef ENABLE_TEST_POSTPLUGINS Add(audio_ctrl_headphone = new cMenuEditBoolItem(tr("Mix to headphones"), &newconfig.headphone)); #else audio_ctrl_headphone = NULL; #endif Add(new cMenuEditStraI18nItem(tr("Visualization"), &visualization, AUDIO_VIS_count, xc.s_audioVisualizationNames)); if(current<1) current=1; /* first item is not selectable */ SetCurrent(Get(current)); Display(); } eOSState cMenuSetupAudio::ProcessKey(eKeys Key) { cOsdItem *item = Get(Current()); int val = audio_driver; eOSState state = cMenuSetupPage::ProcessKey(Key); if(Key!=kLeft && Key!=kRight) return state; if(item == audio_driver_item) { if(val != audio_driver) { if(audio_driver == AUDIO_DRIVER_ALSA) { strcpy(newconfig.audio_port, "default"); Set(); } else if(audio_driver == AUDIO_DRIVER_OSS) { strcpy(newconfig.audio_port, "/dev/dsp0"); Set(); } else { strcpy(newconfig.audio_port, ""); Set(); } } else if((audio_driver != AUDIO_DRIVER_AUTO && audio_driver != AUDIO_DRIVER_NONE) && !audio_port_item) Set(); else if((audio_driver == AUDIO_DRIVER_AUTO || audio_driver == AUDIO_DRIVER_NONE) && audio_port_item) Set(); } else if(item == audio_ctrl_delay || item == audio_ctrl_compression || item == audio_ctrl_surround) { cXinelibDevice::Instance().ConfigurePostprocessing( xc.deinterlace_method, newconfig.audio_delay, newconfig.audio_compression, newconfig.audio_equalizer, newconfig.audio_surround); } else if(item == audio_ctrl_upmix) { cXinelibDevice::Instance().ConfigurePostprocessing( "upmix", newconfig.audio_upmix ? true : false, NULL); } #ifdef ENABLE_TEST_POSTPLUGINS else if(item == audio_ctrl_headphone) { cXinelibDevice::Instance().ConfigurePostprocessing( "headphone", newconfig.headphone ? true : false, NULL); } #endif return state; } void cMenuSetupAudio::Store(void) { memcpy(&xc, &newconfig, sizeof(config_t)); strcpy(xc.audio_driver, xc.s_audioDrivers[audio_driver]); strcpy(xc.audio_visualization, xc.s_audioVisualizations[visualization]); SetupStore("Audio.Driver", xc.audio_driver); SetupStore("Audio.Port", xc.audio_port); SetupStore("Audio.Delay", xc.audio_delay); SetupStore("Audio.Compression", xc.audio_compression); SetupStore("Audio.Surround", xc.audio_surround); SetupStore("Audio.Upmix", xc.audio_upmix); SetupStore("Audio.Headphone", xc.headphone); SetupStore("Audio.Visualization",xc.audio_visualization); } //--- cMenuSetupAudioEq ------------------------------------------------------ class cMenuSetupAudioEq : public cMenuSetupPage { private: config_t newconfig; protected: virtual void Store(void); void Set(void); public: cMenuSetupAudioEq(void); ~cMenuSetupAudioEq(void); virtual eOSState ProcessKey(eKeys Key); }; cMenuSetupAudioEq::cMenuSetupAudioEq(void) { memcpy(&newconfig, &xc, sizeof(config_t)); Set(); } cMenuSetupAudioEq::~cMenuSetupAudioEq(void) { cXinelibDevice::Instance().ConfigurePostprocessing( xc.deinterlace_method, xc.audio_delay, xc.audio_compression, xc.audio_equalizer, xc.audio_surround); } void cMenuSetupAudioEq::Set(void) { SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N)); int current = Current(); Clear(); Add(NewTitle("Audio Equalizer")); for(int i=0; i cmdline) Add(ctrl_autocrop = new cMenuEditBoolItem(tr("Crop letterbox to 16:9"), &newconfig.autocrop)); #endif Add(NewTitle("Local Frontend")); Add(ctrl_local_fe = new cMenuEditStraI18nItem(tr("Local Display Frontend"), &local_frontend, FRONTEND_count, xc.s_frontendNames)); if(local_frontend == FRONTEND_X11) { Add(ctrl_driver = new cMenuEditStraI18nItem(tr("Driver"), &video_driver, X11_DRIVER_count, xc.s_videoDriverNamesX11)); strcpy(newconfig.video_port, "127.0.0.1:0.0"); Add(new cMenuEditStrItem(tr("Display address"), newconfig.video_port, 31, DriverNameChars)); Add(new cMenuEditBoolItem(tr("Use keyboard"), &newconfig.use_x_keyboard)); } else if(local_frontend == FRONTEND_FB) { Add(ctrl_driver = new cMenuEditStraI18nItem(tr("Driver"), &video_driver, FB_DRIVER_count, xc.s_videoDriverNamesFB)); strcpy(newconfig.video_port, "/dev/fb/0"); Add(new cMenuEditStrItem(tr("Framebuffer device"), newconfig.video_port, 31, DriverNameChars)); } #if 0 if(local_frontend == FRONTEND_FB || !newconfig.fullscreen) { Add(new cMenuEditStrItem( "Modeline", newconfig.modeline, 31, ModeLineChars)); Add(new cMenuEditBoolItem("Videomode switching", &xc.modeswitch)); } #endif if(local_frontend == FRONTEND_X11) { Add(ctrl_fullscreen = new cMenuEditBoolItem(tr("Fullscreen mode"), &newconfig.fullscreen)); if(!newconfig.fullscreen) { Add(ctrl_window_width = new cMenuEditTypedIntItem( tr(" Window width"), tr("px"), &newconfig.width, 1, 2048)); Add(ctrl_window_height = new cMenuEditTypedIntItem( tr(" Window height"), tr("px"), &newconfig.height, 1, 2048)); } } if(local_frontend != FRONTEND_NONE) { Add(ctrl_aspect = new cMenuEditStraI18nItem(tr("Window aspect"), &newconfig.display_aspect, ASPECT_count, xc.s_aspects)); Add(ctrl_scale = new cMenuEditBoolItem(tr("Scale to window size"), &newconfig.scale_video)); Add(ctrl_deinterlace = new cMenuEditStraI18nItem(tr("Deinterlacing"), &deinterlace, DEINTERLACE_count, xc.s_deinterlaceMethodNames)); if(deinterlace == DEINTERLACE_TVTIME) Add(ctrl_deinterlace_opts = new cMenuEditStrItem(tr(" Options:"), newconfig.deinterlace_opts, 64, OptionsChars)); #ifdef HAVE_XV_FIELD_ORDER if(!deinterlace) Add(ctrl_interlace_order = new cMenuEditStraI18nItem(tr("Interlaced Field Order"), &newconfig.field_order, FIELD_ORDER_count, xc.s_fieldOrder)); #endif } if(current<1) current=1; /* first item is not selectable */ SetCurrent(Get(current)); Display(); } eOSState cMenuSetupLocal::ProcessKey(eKeys Key) { int prev_frontend = local_frontend; cOsdItem *item = Get(Current()); eOSState state = cMenuSetupPage::ProcessKey(Key); if((Key!=kLeft && Key!=kRight) || !item) return state; if(item == ctrl_aspect || item == ctrl_scale || item == ctrl_interlace_order) cXinelibDevice::Instance().ConfigureWindow( xc.fullscreen, xc.width, xc.height, xc.modeswitch, xc.modeline, newconfig.display_aspect, newconfig.scale_video, newconfig.field_order); else if(item == ctrl_local_fe && local_frontend != prev_frontend) Set(); else if(item == ctrl_fullscreen) { if(!newconfig.fullscreen && !ctrl_window_width) { Set(); } else if(newconfig.fullscreen && ctrl_window_width) { Set(); } #ifdef ENABLE_TEST_POSTPLUGINS } else if(item == ctrl_autocrop) { cXinelibDevice::Instance().ConfigurePostprocessing( "autocrop", xc.autocrop ? true : false, NULL); #endif } else if(item == ctrl_deinterlace) { if(deinterlace == DEINTERLACE_TVTIME && !ctrl_deinterlace_opts) { Set(); } else if(deinterlace != DEINTERLACE_TVTIME && ctrl_deinterlace_opts) { Set(); } } #ifdef HAVE_XV_FIELD_ORDER else if(item == ctrl_deinterlace) { if(!deinterlace && !ctrl_interlace_order) { Set(); } else if(deinterlace && ctrl_interlace_order) { Set(); } } #endif return state; } void cMenuSetupLocal::Store(void) { memcpy(&xc, &newconfig, sizeof(config_t)); strcpy(xc.local_frontend, xc.s_frontends[local_frontend]); if(local_frontend == FRONTEND_X11) strcpy(xc.video_driver, xc.s_videoDriversX11[video_driver]); if(local_frontend == FRONTEND_FB) strcpy(xc.video_driver, xc.s_videoDriversFB[video_driver]); strcpy(xc.deinterlace_method, xc.s_deinterlaceMethods[deinterlace]); SetupStore("Frontend", xc.local_frontend); SetupStore("Modeline", xc.modeline); SetupStore("VideoModeSwitching", xc.modeswitch); SetupStore("Fullscreen", xc.fullscreen); SetupStore("DisplayAspect", xc.s_aspects[xc.display_aspect]); SetupStore("X11.WindowWidth", xc.width); SetupStore("X11.WindowHeight", xc.height); SetupStore("X11.UseKeyboard", xc.use_x_keyboard); SetupStore("Video.Driver", xc.video_driver); SetupStore("Video.Port", xc.video_port); SetupStore("Video.Scale", xc.scale_video); SetupStore("Video.Deinterlace", xc.deinterlace_method); SetupStore("Video.DeinterlaceOptions", xc.deinterlace_opts); SetupStore("Video.FieldOrder", xc.field_order); SetupStore("Video.AutoCrop", xc.autocrop); } //--- cMenuSetupRemote ------------------------------------------------------- class cMenuSetupRemote : public cMenuSetupPage { private: config_t newconfig; cOsdItem *ctrl_remote_mode; cOsdItem *ctrl_usertp; cOsdItem *ctrl_rtp_addr; protected: virtual void Store(void); void Set(void); public: cMenuSetupRemote(void); virtual eOSState ProcessKey(eKeys Key); }; cMenuSetupRemote::cMenuSetupRemote(void) { memcpy(&newconfig, &xc, sizeof(config_t)); Set(); } void cMenuSetupRemote::Set(void) { SetPlugin(cPluginManager::GetPlugin(PLUGIN_NAME_I18N)); Clear(); Add(NewTitle("Remote Clients")); Add(ctrl_remote_mode = new cMenuEditBoolItem(tr("Allow remote clients"), &newconfig.remote_mode)); ctrl_usertp = NULL; ctrl_rtp_addr = NULL; if(newconfig.remote_mode) { Add(new cMenuEditIntItem( tr(" Listen port (TCP and broadcast)"), &newconfig.listen_port, 0, 0xffff)); Add(new cMenuEditBoolItem(tr(" Remote keyboard"), &newconfig.use_remote_keyboard)); Add(new cMenuEditBoolItem(tr(" TCP transport"), &newconfig.remote_usetcp)); Add(new cMenuEditBoolItem(tr(" UDP transport"), &newconfig.remote_useudp)); Add(ctrl_usertp = new cMenuEditBoolItem(tr(" RTP (multicast) transport"), &newconfig.remote_usertp)); if(newconfig.remote_usertp) { Add(ctrl_rtp_addr = new cMenuEditStrItem( tr(" Multicast address"), &newconfig.remote_rtp_addr[0], 16, "0123456789.")); Add(new cMenuEditIntItem( tr(" Multicast port"), &newconfig.remote_rtp_port, 1000, 0xffff)); Add(new cMenuEditIntItem( tr(" Multicast TTL"), &newconfig.remote_rtp_ttl, 1, 10)); Add(new cMenuEditBoolItem(tr(" Transmit always on"), &newconfig.remote_rtp_always_on)); } Add(new cMenuEditBoolItem(tr(" PIPE transport"), &newconfig.remote_usepipe)); Add(new cMenuEditBoolItem(tr(" Server announce broadcasts"), &newconfig.remote_usebcast)); } Display(); } eOSState cMenuSetupRemote::ProcessKey(eKeys Key) { cOsdItem *item = Get(Current()); eOSState state = cMenuSetupPage::ProcessKey(Key); if(Key!=kLeft && Key!=kRight) return state; if(item == ctrl_remote_mode) { if(newconfig.remote_mode && !ctrl_usertp) { Set(); } else if(!newconfig.remote_mode && ctrl_usertp) { Set(); } } if(item == ctrl_usertp) { if(newconfig.remote_usertp && !ctrl_rtp_addr) { Set(); } else if(!newconfig.remote_usertp && ctrl_rtp_addr) { Set(); } } return state; } void cMenuSetupRemote::Store(void) { memcpy(&xc, &newconfig, sizeof(config_t)); SetupStore("RemoteMode", xc.remote_mode); SetupStore("Remote.ListenPort", xc.listen_port); SetupStore("Remote.Keyboard", xc.use_remote_keyboard); SetupStore("Remote.UseTcp", xc.remote_usetcp); SetupStore("Remote.UseUdp", xc.remote_useudp); SetupStore("Remote.UseRtp", xc.remote_usertp); SetupStore("Remote.UsePipe",xc.remote_usepipe); SetupStore("Remote.UseBroadcast", xc.remote_usebcast); SetupStore("Remote.Rtp.Address", xc.remote_rtp_addr); SetupStore("Remote.Rtp.Port", xc.remote_rtp_port); SetupStore("Remote.Rtp.TTL", xc.remote_rtp_ttl); SetupStore("Remote.Rtp.AlwaysOn", xc.remote_rtp_always_on); cXinelibDevice::Instance().Listen(xc.remote_mode, xc.listen_port); } } // namespace //--- cMenuSetupXinelib ------------------------------------------------------ cMenuSetupXinelib::cMenuSetupXinelib(void) { XinelibOutputSetupMenu::controls[0] = tr("Off"); Set(); } void cMenuSetupXinelib::Set(void) { Clear(); SetHasHotkeys(); Add(new cOsdItem(hk(tr("Audio")), osUser1)); Add(new cOsdItem(hk(tr("Audio Equalizer")),osUser2)); Add(new cOsdItem(hk(tr("Video")), osUser3)); Add(new cOsdItem(hk(tr("OSD")), osUser4)); Add(new cOsdItem(hk(tr("Decoder")), osUser5)); Add(new cOsdItem(hk(tr("Local Frontend")), osUser6)); Add(new cOsdItem(hk(tr("Remote Clients")), osUser7)); Display(); } eOSState cMenuSetupXinelib::ProcessKey(eKeys Key) { eOSState state = cMenuSetupPage::ProcessKey(Key); switch (state) { case osUser1: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupAudio); case osUser2: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupAudioEq); case osUser3: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupVideo); case osUser4: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupOSD); case osUser5: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupDecoder); case osUser6: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupLocal); case osUser7: return AddSubMenu(new XinelibOutputSetupMenu::cMenuSetupRemote); default: ; } return state; }