Mercurial > mplayer.hg
view gui/interface.c @ 35148:89660feadcce
Add necessary checks to the vd_hmblck input.
The code assumes the input image contains whole macroblocks (16x16).
Since same thing applies to the downsampled chroma channels,
the final requirement is the image to be multiple of 32.
Also, add explicit pixel format check at init.
author | iive |
---|---|
date | Thu, 11 Oct 2012 22:06:42 +0000 |
parents | 203d0d5cac1f |
children | ade40c1d69b8 |
line wrap: on
line source
/* * This file is part of MPlayer. * * MPlayer 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. * * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "interface.h" #include "app.h" #include "skin/skin.h" #include "ui/gmplayer.h" #include "ui/widgets.h" #include "util/list.h" #include "util/mem.h" #include "util/string.h" #include "wm/ws.h" #include "wm/wsxdnd.h" #include "access_mpcontext.h" #include "config.h" #include "help_mp.h" #include "input/input.h" #include "libaf/equalizer.h" #include "libavutil/common.h" #include "libmpcodecs/dec_audio.h" #include "libmpcodecs/dec_video.h" #include "libmpcodecs/vd.h" #include "libmpcodecs/vf.h" #include "libvo/video_out.h" #include "libvo/x11_common.h" #include "mixer.h" #include "mp_msg.h" #include "mpcommon.h" #include "mplayer.h" #include "path.h" #include "sub/font_load.h" #include "sub/sub.h" #ifdef CONFIG_DVDREAD #include "stream/stream_dvd.h" #endif guiInterface_t guiInfo = { .StreamType = STREAMTYPE_DUMMY, .Balance = 50.0f }; static int initialized; /* MPlayer -> GUI */ void guiInit(void) { int i; plItem *playlist; mp_msg(MSGT_GPLAYER, MSGL_V, "GUI init.\n"); if (!cdrom_device) cdrom_device = strdup(DEFAULT_CDROM_DEVICE); if (!dvd_device) dvd_device = strdup(DEFAULT_DVD_DEVICE); if (!gtkDXR3Device) gtkDXR3Device = strdup("/dev/em8300-0"); if (stream_cache_size > 0) { gtkCacheOn = 1; gtkCacheSize = stream_cache_size; } else if (stream_cache_size == 0) gtkCacheOn = 0; if (autosync && (autosync != gtkAutoSync)) { gtkAutoSyncOn = 1; gtkAutoSync = autosync; } gtkASS.enabled = ass_enabled; gtkASS.use_margins = ass_use_margins; gtkASS.top_margin = ass_top_margin; gtkASS.bottom_margin = ass_bottom_margin; gtkInit(); /* initialize X */ wsXInit(mDisplay); /* load skin */ skinDirInHome = get_path("skins"); skinMPlayerDir = MPLAYER_DATADIR "/skins"; mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] skin directory #1: %s\n", skinDirInHome); mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] skin directory #2: %s\n", skinMPlayerDir); if (!skinName) skinName = strdup("default"); i = skinRead(skinName); if (i == -1 && strcmp(skinName, "default") != 0) { mp_msg(MSGT_GPLAYER, MSGL_WARN, MSGTR_SKIN_SKINCFG_SelectedSkinNotFound, skinName); skinName = strdup("default"); i = skinRead(skinName); } switch (i) { case -1: gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_SKIN_SKINCFG_SkinNotFound, skinName); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); case -2: gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_SKIN_SKINCFG_SkinCfgError, skinName); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } /* initialize windows */ mainDrawBuffer = malloc(guiApp.main.Bitmap.ImageSize); if (!mainDrawBuffer) { gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_NEMDB); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } if (gui_save_pos) { if (gui_main_pos_x != -3) guiApp.main.x = gui_main_pos_x; if (gui_main_pos_y != -3) guiApp.main.y = gui_main_pos_y; if (gui_video_pos_x != -3) guiApp.video.x = gui_video_pos_x; if (gui_video_pos_y != -3) guiApp.video.y = gui_video_pos_y; } if (WinID > 0) { guiApp.videoWindow.Parent = WinID; guiApp.video.x = 0; guiApp.video.y = 0; } if (guiWinID >= 0) guiApp.mainWindow.Parent = guiWinID; wsCreateWindow(&guiApp.videoWindow, guiApp.video.x, guiApp.video.y, guiApp.video.width, guiApp.video.height, wsNoBorder, wsShowMouseCursor | wsHandleMouseButton | wsHandleMouseMove, wsShowFrame | wsHideWindow, "MPlayer - Video"); wsDestroyImage(&guiApp.videoWindow); wsCreateImage(&guiApp.videoWindow, guiApp.video.Bitmap.Width, guiApp.video.Bitmap.Height); wsXDNDMakeAwareness(&guiApp.videoWindow); WinID = guiApp.videoWindow.WindowID; uiMenuInit(); uiPlaybarInit(); // i=wsHideFrame|wsMaxSize|wsHideWindow; // if ( guiApp.mainDecoration ) i=wsShowFrame|wsMaxSize|wsHideWindow; i = wsShowFrame | wsMaxSize | wsHideWindow; wsCreateWindow(&guiApp.mainWindow, guiApp.main.x, guiApp.main.y, guiApp.main.width, guiApp.main.height, wsNoBorder, wsShowMouseCursor | wsHandleMouseButton | wsHandleMouseMove, i, "MPlayer"); wsSetShape(&guiApp.mainWindow, guiApp.main.Mask.Image); wsXDNDMakeAwareness(&guiApp.mainWindow); mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] screen depth: %d\n", wsDepthOnScreen); mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] mainWindow ID: 0x%x\n", (int)guiApp.mainWindow.WindowID); mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] videoWindow ID: 0x%x\n", (int)guiApp.videoWindow.WindowID); guiApp.mainWindow.ReDraw = (void *)uiMainDraw; guiApp.mainWindow.MouseHandler = uiMainMouseHandle; guiApp.mainWindow.KeyHandler = uiMainKeyHandle; guiApp.mainWindow.DandDHandler = uiDandDHandler; guiApp.videoWindow.ReDraw = (void *)uiVideoDraw; guiApp.videoWindow.MouseHandler = uiVideoMouseHandle; guiApp.videoWindow.KeyHandler = uiMainKeyHandle; guiApp.videoWindow.DandDHandler = uiDandDHandler; wsSetBackgroundRGB(&guiApp.videoWindow, guiApp.video.R, guiApp.video.G, guiApp.video.B); wsClearWindow(guiApp.videoWindow); if (guiApp.video.Bitmap.Image) wsConvert(&guiApp.videoWindow, guiApp.video.Bitmap.Image); btnModify(evSetVolume, guiInfo.Volume); btnModify(evSetBalance, guiInfo.Balance); btnModify(evSetMoviePosition, guiInfo.Position); wsSetIcon(wsDisplay, guiApp.mainWindow.WindowID, &guiIcon); wsSetIcon(wsDisplay, guiApp.videoWindow.WindowID, &guiIcon); if (!guiApp.mainDecoration) wsWindowDecoration(&guiApp.mainWindow, 0); wsVisibleWindow(&guiApp.mainWindow, wsShowWindow); if (gtkShowVideoWindow) { wsVisibleWindow(&guiApp.videoWindow, wsShowWindow); { XEvent xev; do XNextEvent(wsDisplay, &xev); while (xev.type != MapNotify || xev.xmap.event != guiApp.videoWindow.WindowID); guiApp.videoWindow.Mapped = wsMapped; guiInfo.VideoWindow = True; } if (gtkLoadFullscreen) uiFullScreen(); } else wsSetBackgroundRGB(&guiApp.videoWindow, 0, 0, 0); if (gtkLoadFullscreen) btnSet(evFullScreen, btnPressed); guiInfo.Playing = GUI_STOP; uiVideoRender = 1; playlist = listMgr(PLAYLIST_ITEM_GET_CURR, 0); if (playlist && !filename) { uiSetFileName(playlist->path, playlist->name, STREAMTYPE_FILE); filename = NULL; // don't start playing } if (subdata) setdup(&guiInfo.SubtitleFilename, subdata->filename); mplayerLoadFont(); initialized = 1; } void guiDone(void) { if (initialized) { uiMainRender = 0; if (gui_save_pos) { gui_main_pos_x = guiApp.mainWindow.X; gui_main_pos_y = guiApp.mainWindow.Y; gui_video_pos_x = guiApp.video.x; gui_video_pos_y = guiApp.video.y; } ass_enabled = gtkASS.enabled; ass_use_margins = gtkASS.use_margins; ass_top_margin = gtkASS.top_margin; ass_bottom_margin = gtkASS.bottom_margin; cfg_write(); wsXDone(); } appFreeStruct(); listMgr(PLAYLIST_DELETE, 0); listMgr(URLLIST_DELETE, 0); free(guiIcon.collection); if (gui_conf) { m_config_free(gui_conf); gui_conf = NULL; } mp_msg(MSGT_GPLAYER, MSGL_V, "GUI done.\n"); } static void add_vf(char *str) { void *p; if (vf_settings) { int i = 0; while (vf_settings[i].name) { if (!gstrcmp(vf_settings[i++].name, str)) { i = -1; break; } } if (i != -1) { p = realloc(vf_settings, (i + 2) * sizeof(m_obj_settings_t)); if (!p) return; vf_settings = p; vf_settings[i].name = strdup(str); vf_settings[i].attribs = NULL; vf_settings[i + 1].name = NULL; } } else { vf_settings = malloc(2 * sizeof(m_obj_settings_t)); vf_settings[0].name = strdup(str); vf_settings[0].attribs = NULL; vf_settings[1].name = NULL; } mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_AddingVideoFilter, str); } int gui(int what, void *data) { mixer_t *mixer = NULL; stream_t *stream; #ifdef CONFIG_DVDREAD dvd_priv_t *dvd; #endif plItem *next; int msg, state; if (guiInfo.mpcontext) mixer = mpctx_get_mixer(guiInfo.mpcontext); switch (what) { case GUI_SET_CONTEXT: guiInfo.mpcontext = data; break; case GUI_SET_STATE: switch ((int)data) { case GUI_STOP: case GUI_PLAY: // if ( !gtkShowVideoWindow ) wsVisibleWindow( &guiApp.videoWindow,wsHideWindow ); case GUI_PAUSE: guiInfo.Playing = (int)data; break; } uiState(); break; case GUI_HANDLE_EVENTS: if (!guiInfo.Playing || !guiInfo.VideoWindow) wsHandleEvents(); wsAutohideCursor(); gtkEventHandling(); break; case GUI_RUN_COMMAND: mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] GUI_RUN_COMMAND: %d\n", (int)data); switch ((int)data) { case MP_CMD_VO_FULLSCREEN: uiEventHandling(evFullScreen, 0); break; case MP_CMD_PLAY_TREE_STEP: uiEventHandling(evNext, 0); break; case -MP_CMD_PLAY_TREE_STEP: uiEventHandling(evPrev, 0); break; case MP_CMD_STOP: uiEventHandling(evStop, 0); break; case MP_CMD_QUIT: uiEventHandling(evExit, 0); break; } break; case GUI_RUN_MESSAGE: mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] GUI_RUN_MESSAGE: %s\n", (const char *)data); msg = appFindMessage((const char *)data); if ((msg == evMenu) || appFindItem(msg)) uiEventHandling(msg, 0); break; case GUI_PREPARE: wsVisibleMouse(&guiApp.videoWindow, wsHideMouseCursor); if (guiInfo.NewPlay == GUI_FILE_NEW) { dvd_title = 0; audio_id = -1; video_id = -1; dvdsub_id = -1; vobsub_id = -1; stream_cache_size = -1; autosync = 0; force_fps = 0; } switch (guiInfo.StreamType) { case STREAMTYPE_FILE: case STREAMTYPE_STREAM: break; case STREAMTYPE_CDDA: { char tmp[512]; sprintf(tmp, "cdda://%d", guiInfo.Track); uiSetFileName(NULL, tmp, SAME_STREAMTYPE); } break; case STREAMTYPE_VCD: { char tmp[512]; sprintf(tmp, "vcd://%d", guiInfo.Track); uiSetFileName(NULL, tmp, SAME_STREAMTYPE); } break; case STREAMTYPE_DVD: { char tmp[512]; sprintf(tmp, "dvd://%d", guiInfo.Track); uiSetFileName(NULL, tmp, SAME_STREAMTYPE); } dvd_chapter = guiInfo.Chapter; dvd_angle = guiInfo.Angle; break; } /* video opts */ if (!video_driver_list) { int i = 0; while (video_out_drivers[i++]) { if (video_out_drivers[i - 1]->control(VOCTRL_GUISUPPORT, NULL) == VO_TRUE) { listSet(&video_driver_list, (char *)video_out_drivers[i - 1]->info->short_name); break; } } } if (!video_driver_list && !video_driver_list[0]) { gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_IDFGCVD); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } { int i = 0; guiInfo.VideoWindow = True; while (video_out_drivers[i++]) { if (video_out_drivers[i - 1]->control(VOCTRL_GUISUPPORT, NULL) == VO_TRUE) { if ((video_driver_list && !gstrcmp(video_driver_list[0], (char *)video_out_drivers[i - 1]->info->short_name)) && (video_out_drivers[i - 1]->control(VOCTRL_GUI_NOWINDOW, NULL) == VO_TRUE)) { guiInfo.VideoWindow = False; break; } } } } if (video_driver_list && !gstrcmp(video_driver_list[0], "dxr3")) if (guiInfo.StreamType != STREAMTYPE_DVD && guiInfo.StreamType != STREAMTYPE_VCD) if (gtkVfLAVC) add_vf("lavc"); if (gtkVfPP) add_vf("pp"); /* audio opts */ // if ( ao_plugin_cfg.plugin_list ) { free( ao_plugin_cfg.plugin_list ); ao_plugin_cfg.plugin_list=NULL; } if (gtkAONorm) listRepl(&af_cfg.list, "volnorm", "volnorm"); if (gtkEnableAudioEqualizer) listRepl(&af_cfg.list, "equalizer", "equalizer"); if (gtkAOExtraStereo) { char *name; name = malloc(12 + 20 + 1); snprintf(name, 12 + 20, "extrastereo=%f", gtkAOExtraStereoMul); name[12 + 20] = 0; listRepl(&af_cfg.list, "extrastereo", name); free(name); } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "oss", 3)) { mixer_device = gtkAOOSSMixer; mixer_channel = gtkAOOSSMixerChannel; if (gtkAOOSSDevice) { char *tmp; tmp = calloc(1, strlen(gtkAOOSSDevice) + 7); sprintf(tmp, "oss:%s", gtkAOOSSDevice); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "alsa", 4)) { mixer_device = gtkAOALSAMixer; mixer_channel = gtkAOALSAMixerChannel; if (gtkAOALSADevice) { char *tmp; tmp = calloc(1, strlen(gtkAOALSADevice) + 14); sprintf(tmp, "alsa:device=%s", gtkAOALSADevice); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "sdl", 3)) { if (gtkAOSDLDriver) { char *tmp; tmp = calloc(1, strlen(gtkAOSDLDriver) + 10); sprintf(tmp, "sdl:%s", gtkAOSDLDriver); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "esd", 3)) { if (gtkAOESDDevice) { char *tmp; tmp = calloc(1, strlen(gtkAOESDDevice) + 10); sprintf(tmp, "esd:%s", gtkAOESDDevice); listSet(&audio_driver_list, tmp); free(tmp); } } /* subtitle */ // subdata->filename=gstrdup( guiInfo.SubtitleFilename ); stream_dump_type = 0; if (gtkSubDumpMPSub) stream_dump_type = 4; if (gtkSubDumpSrt) stream_dump_type = 6; gtkSubDumpMPSub = gtkSubDumpSrt = 0; mplayerLoadFont(); /* misc */ if (gtkCacheOn) stream_cache_size = gtkCacheSize; if (gtkAutoSyncOn) autosync = gtkAutoSync; if (guiInfo.AudioFilename) audio_stream = gstrdup(guiInfo.AudioFilename); else if (guiInfo.NewPlay == GUI_FILE_NEW) nfree(audio_stream); // audio_stream = NULL; guiInfo.NewPlay = 0; ass_enabled = gtkASS.enabled; ass_use_margins = gtkASS.use_margins; ass_top_margin = gtkASS.top_margin; ass_bottom_margin = gtkASS.bottom_margin; break; case GUI_SET_STREAM: if (guiInfo.StreamType == STREAMTYPE_PLAYLIST) guiInfo.mpcontext->file_format = DEMUXER_TYPE_PLAYLIST; stream = data; guiInfo.StreamType = stream->type; switch (guiInfo.StreamType) { case STREAMTYPE_FILE: case STREAMTYPE_STREAM: break; case STREAMTYPE_CDDA: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); break; case STREAMTYPE_VCD: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); break; case STREAMTYPE_DVD: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); guiInfo.Chapters = 0; stream_control(stream, STREAM_CTRL_GET_NUM_CHAPTERS, &guiInfo.Chapters); guiInfo.Angles = 0; stream_control(stream, STREAM_CTRL_GET_NUM_ANGLES, &guiInfo.Angles); #ifdef CONFIG_DVDREAD dvd = stream->priv; guiInfo.AudioStreams = dvd->nr_of_channels; memcpy(guiInfo.AudioStream, dvd->audio_streams, sizeof(dvd->audio_streams)); guiInfo.Subtitles = dvd->nr_of_subtitles; memcpy(guiInfo.Subtitle, dvd->subtitles, sizeof(dvd->subtitles)); #endif guiInfo.Track = dvd_title + 1; guiInfo.Chapter = dvd_chapter + 1; guiInfo.Angle = dvd_angle + 1; break; } break; case GUI_SET_AFILTER: guiInfo.afilter = data; break; case GUI_SET_VIDEO: /* video */ guiInfo.sh_video = data; state = (guiInfo.StreamType == STREAMTYPE_STREAM ? btnDisabled : btnReleased); btnSet(evForward10sec, state); btnSet(evBackward10sec, state); btnSet(evForward1min, state); btnSet(evBackward1min, state); btnSet(evForward10min, state); btnSet(evBackward10min, state); btnSet(evSetMoviePosition, state); if (video_driver_list && !gstrcmp(video_driver_list[0], "dxr3") && (((demuxer_t *)mpctx_get_demuxer(guiInfo.mpcontext))->file_format != DEMUXER_TYPE_MPEG_PS) && !gtkVfLAVC) { gtkMessageBox(GTK_MB_FATAL, MSGTR_NEEDLAVC); return False; } break; case GUI_SET_AUDIO: guiInfo.AudioChannels = data ? ((sh_audio_t *)data)->channels : 0; if (data && !guiInfo.sh_video) guiInfo.VideoWindow = False; gui(GUI_SET_MIXER, 0); if (gtkEnableAudioEqualizer) { equalizer_t eq; unsigned int i, j; for (i = 0; i < FF_ARRAY_ELEMS(gtkEquChannels); i++) { for (j = 0; j < FF_ARRAY_ELEMS(*gtkEquChannels); j++) { eq.channel = i; eq.band = j; eq.gain = gtkEquChannels[i][j]; mplayer(MPLAYER_SET_EQUALIZER, 0, &eq); } } } // These must be done here (in the last call from MPlayer before // playback starts) and not in GUI_SETUP_VIDEO_WINDOW, because... // ...without video there will be no call to GUI_SETUP_VIDEO_WINDOW if (!guiInfo.VideoWindow) { wsVisibleWindow(&guiApp.videoWindow, wsHideWindow); btnSet(evFullScreen, (gtkLoadFullscreen ? btnPressed : btnReleased)); } // ...option variable fullscreen determines whether MPlayer will handle // the window given by WinID as fullscreen window (and will do aspect // scaling then) or not - quite rubbish fullscreen = gtkLoadFullscreen; break; case GUI_SET_MIXER: if (mixer) { float l, r; static float last_balance = -1; mixer_getvolume(mixer, &l, &r); guiInfo.Volume = FFMAX(l, r); btnModify(evSetVolume, guiInfo.Volume); if (guiInfo.Balance != last_balance) { if (guiInfo.Volume) guiInfo.Balance = ((r - l) / guiInfo.Volume + 1.0) * 50.0; else guiInfo.Balance = 50.0f; last_balance = guiInfo.Balance; btnModify(evSetBalance, guiInfo.Balance); } } break; case GUI_REDRAW: uiEventHandling(ivRedraw, 0); break; case GUI_SETUP_VIDEO_WINDOW: guiInfo.VideoWidth = vo_dwidth; guiInfo.VideoHeight = vo_dheight; if (!guiApp.videoWindow.isFullScreen || !guiApp.videoWindow.Mapped) { if (!guiApp.videoWindow.isFullScreen) wsResizeWindow(&guiApp.videoWindow, guiInfo.VideoWidth, guiInfo.VideoHeight); wsMoveWindow(&guiApp.videoWindow, False, guiApp.video.x, guiApp.video.y); if (!guiApp.videoWindow.Mapped) wsVisibleWindow(&guiApp.videoWindow, wsShowWindow); } if (gtkLoadFullscreen ^ guiApp.videoWindow.isFullScreen) uiEventHandling(evFullScreen, 0); if (guiWinID >= 0) wsMoveWindow(&guiApp.mainWindow, True, 0, guiInfo.VideoHeight); break; case GUI_HANDLE_X_EVENT: wsEvents(wsDisplay, data); gtkEventHandling(); break; case GUI_END_FILE: uiEventHandling(ivRedraw, 1); guiInfo.sh_video = NULL; if (!uiGotoTheNext && guiInfo.Playing) { uiGotoTheNext = 1; break; } if (guiInfo.StreamType == STREAMTYPE_CDDA) { uiNext(); if (guiInfo.Playing) break; } next = listMgr(PLAYLIST_ITEM_GET_NEXT, 0); if (guiInfo.Playing && next) { uiSetFileName(next->path, next->name, STREAMTYPE_FILE); guiInfo.NewPlay = GUI_FILE_NEW; guiInfo.Track++; } else { if (guiInfo.NewPlay == GUI_FILE_NEW) break; filename = NULL; guiInfo.ElapsedTime = 0; guiInfo.Position = 0; guiInfo.AudioChannels = 0; guiInfo.Track = 1; guiInfo.Chapter = 1; guiInfo.Angle = 1; if (gtkShowVideoWindow) { guiInfo.VideoWindow = True; guiInfo.VideoWidth = guiApp.video.width; guiInfo.VideoHeight = guiApp.video.height; if (!guiApp.videoWindow.isFullScreen) { wsResizeWindow(&guiApp.videoWindow, guiInfo.VideoWidth, guiInfo.VideoHeight); wsMoveWindow(&guiApp.videoWindow, False, guiApp.video.x, guiApp.video.y); } if (!guiApp.videoWindow.Mapped) wsVisibleWindow(&guiApp.videoWindow, wsShowWindow); if (gtkLoadFullscreen ^ guiApp.videoWindow.isFullScreen) uiEventHandling(evFullScreen, 0); } else { wsVisibleWindow(&guiApp.videoWindow, wsHideWindow); guiInfo.VideoWindow = False; btnSet(evFullScreen, (gtkLoadFullscreen ? btnPressed : btnReleased)); } gui(GUI_SET_STATE, (void *)GUI_STOP); wsHandleEvents(); uiVideoRender = 1; wsSetBackgroundRGB(&guiApp.videoWindow, guiApp.video.R, guiApp.video.G, guiApp.video.B); wsClearWindow(guiApp.videoWindow); wsPostRedisplay(&guiApp.videoWindow); wsVisibleMouse(&guiApp.videoWindow, wsShowMouseCursor); } break; } return True; } // This function adds/inserts one file into the gui playlist. static int import_file_into_gui(char *temp, int insert) { char *filename, *pathname; plItem *item; filename = strdup(mp_basename(temp)); pathname = strdup(temp); if (strlen(pathname) - strlen(filename) > 0) pathname[strlen(pathname) - strlen(filename) - 1] = 0; // we have some path, so remove / at end else pathname[strlen(pathname) - strlen(filename)] = 0; mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] playtree, add: %s/%s\n", pathname, filename); item = calloc(1, sizeof(plItem)); if (!item) return 0; item->name = filename; item->path = pathname; if (insert) listMgr(PLAYLIST_ITEM_INSERT, item); // inserts the item after current, and makes current=item else listMgr(PLAYLIST_ITEM_APPEND, item); return 1; } // This function imports the initial playtree (based on cmd-line files) // into the gui playlist by either: // - overwriting gui pl (enqueue=0) // - appending it to gui pl (enqueue=1) int guiPlaylistInitialize(play_tree_t *my_playtree, m_config_t *config, int enqueue) { play_tree_iter_t *my_pt_iter = NULL; int result = 0; if (!enqueue) listMgr(PLAYLIST_DELETE, 0); // delete playlist before "appending" if ((my_pt_iter = pt_iter_create(&my_playtree, config))) { while ((filename = pt_iter_get_next_file(my_pt_iter)) != NULL) /* add it to end of list */ if (import_file_into_gui(filename, 0)) result = 1; } uiCurr(); // update filename uiGotoTheNext = 1; if (enqueue) filename = NULL; // don't start playing return result; } // This function imports and inserts an playtree, that is created "on the fly", // for example by parsing some MOV-Reference-File; or by loading an playlist // with "File Open". (The latter, actually, isn't allowed in MPlayer and thus // not working which is why this function won't get called for that reason.) // The file which contained the playlist is thereby replaced with it's contents. int guiPlaylistAdd(play_tree_t *my_playtree, m_config_t *config) { play_tree_iter_t *my_pt_iter = NULL; int result = 0; plItem *save; save = (plItem *)listMgr(PLAYLIST_ITEM_GET_CURR, 0); // save current item if ((my_pt_iter = pt_iter_create(&my_playtree, config))) { while ((filename = pt_iter_get_next_file(my_pt_iter)) != NULL) /* insert it into the list and set plCurrent=new item */ if (import_file_into_gui(filename, 1)) result = 1; pt_iter_destroy(&my_pt_iter); } if (save) listMgr(PLAYLIST_ITEM_SET_CURR, save); else listMgr(PLAYLIST_ITEM_SET_CURR, listMgr(PLAYLIST_GET, 0)); // go to head, if plList was empty before if (save && result) listMgr(PLAYLIST_ITEM_DEL_CURR, 0); uiCurr(); // update filename return result; } /* GUI -> MPlayer */ void mplayer(int what, float value, void *data) { equalizer_t *eq = (equalizer_t *)data; switch (what) { /* subtitle */ case MPLAYER_SET_FONT_FACTOR: font_factor = value; mplayerLoadFont(); break; case MPLAYER_SET_FONT_OUTLINE: subtitle_font_thickness = (8.0f / 100.0f) * value; mplayerLoadFont(); break; case MPLAYER_SET_FONT_BLUR: subtitle_font_radius = (8.0f / 100.0f) * value; mplayerLoadFont(); break; case MPLAYER_SET_FONT_TEXTSCALE: text_font_scale_factor = value; mplayerLoadFont(); break; case MPLAYER_SET_FONT_OSDSCALE: osd_font_scale_factor = value; mplayerLoadFont(); break; case MPLAYER_SET_FONT_ENCODING: nfree(subtitle_font_encoding); subtitle_font_encoding = gstrdup((char *)data); mplayerLoadFont(); break; case MPLAYER_SET_FONT_AUTOSCALE: subtitle_autoscale = (int)value; mplayerLoadFont(); break; case MPLAYER_SET_SUB_ENCODING: nfree(sub_cp); sub_cp = gstrdup((char *)data); break; case MPLAYER_SET_EXTRA_STEREO: gtkAOExtraStereoMul = value; if (guiInfo.afilter) af_control_any_rev(guiInfo.afilter, AF_CONTROL_ES_MUL | AF_CONTROL_SET, >kAOExtraStereoMul); break; case MPLAYER_SET_PANSCAN: { mp_cmd_t *mp_cmd; mp_cmd = calloc(1, sizeof(*mp_cmd)); mp_cmd->id = MP_CMD_PANSCAN; mp_cmd->name = strdup("panscan"); mp_cmd->args[0].v.f = value; mp_cmd->args[1].v.i = 1; mp_input_queue_cmd(mp_cmd); } break; case MPLAYER_SET_AUTO_QUALITY: auto_quality = (int)value; break; /* set equalizers */ case MPLAYER_SET_CONTRAST: if (guiInfo.sh_video) set_video_colors(guiInfo.sh_video, "contrast", (int)value); break; case MPLAYER_SET_BRIGHTNESS: if (guiInfo.sh_video) set_video_colors(guiInfo.sh_video, "brightness", (int)value); break; case MPLAYER_SET_HUE: if (guiInfo.sh_video) set_video_colors(guiInfo.sh_video, "hue", (int)value); break; case MPLAYER_SET_SATURATION: if (guiInfo.sh_video) set_video_colors(guiInfo.sh_video, "saturation", (int)value); break; case MPLAYER_SET_EQUALIZER: { af_control_ext_t tmp; if (eq) { gtkEquChannels[eq->channel][eq->band] = eq->gain; tmp.ch = eq->channel; tmp.arg = gtkEquChannels[eq->channel]; if (guiInfo.afilter) af_control_any_rev(guiInfo.afilter, AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET, &tmp); } else { unsigned int i; memset(gtkEquChannels, 0, sizeof(gtkEquChannels)); if (guiInfo.afilter) { for (i = 0; i < FF_ARRAY_ELEMS(gtkEquChannels); i++) { tmp.ch = i; tmp.arg = gtkEquChannels[i]; af_control_any_rev(guiInfo.afilter, AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET, &tmp); } } } break; } case MPLAYER_EXIT_GUI: exit_player_with_rc((enum exit_reason)value, (enum exit_reason)value >= EXIT_ERROR); break; } } void mplayerLoadFont(void) { #ifdef CONFIG_FREETYPE load_font_ft(vo_image_width, vo_image_height, &vo_font, font_name, osd_font_scale_factor); #else if (vo_font) { int i; free(vo_font->name); free(vo_font->fpath); for (i = 0; i < 16; i++) { if (vo_font->pic_a[i]) { free(vo_font->pic_a[i]->bmp); free(vo_font->pic_a[i]->pal); } } for (i = 0; i < 16; i++) { if (vo_font->pic_b[i]) { free(vo_font->pic_b[i]->bmp); free(vo_font->pic_b[i]->pal); } } free(vo_font); vo_font = NULL; } if (font_name) { vo_font = read_font_desc(font_name, font_factor, 0); if (!vo_font) gmp_msg(MSGT_GPLAYER, MSGL_ERR, MSGTR_CantLoadFont, font_name); } else { font_name = gstrdup(get_path("font/font.desc")); vo_font = read_font_desc(font_name, font_factor, 0); if (!vo_font) { nfree(font_name); font_name = gstrdup(MPLAYER_DATADIR "/font/font.desc"); vo_font = read_font_desc(font_name, font_factor, 0); } } #endif } void mplayerLoadSubtitle(const char *name) { if (guiInfo.Playing == 0) return; if (subdata) { mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_DeletingSubtitles); sub_free(subdata); subdata = NULL; vo_sub = NULL; if (vo_osd_list) { int len; mp_osd_obj_t *osd; osd = vo_osd_list; while (osd) { if (osd->type == OSDTYPE_SUBTITLE) break; osd = osd->next; } if (osd && (osd->flags & OSDFLAG_VISIBLE)) { len = osd->stride * (osd->bbox.y2 - osd->bbox.y1); memset(osd->bitmap_buffer, 0, len); memset(osd->alpha_buffer, 0, len); } } } if (name) { mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_LoadingSubtitles, name); subdata = sub_read_file(name, (guiInfo.sh_video ? guiInfo.sh_video->fps : 0)); if (!subdata) gmp_msg(MSGT_GPLAYER, MSGL_ERR, MSGTR_CantLoadSub, name); sub_name = (malloc(2 * sizeof(char *))); // when mplayer will be restarted sub_name[0] = strdup(name); // sub_name[0] will be read sub_name[1] = NULL; } update_set_of_subtitles(); } // NOTE TO MYSELF: This function is nonsense. // MPlayer should pass messages to the GUI // which must decide then which message has // to be shown (MSGL_FATAL, for example). // But with this function it is at least // possible to show GUI's very critical or // abort messages. void gmp_msg(int mod, int lev, const char *format, ...) { char msg[512]; va_list va; va_start(va, format); vsnprintf(msg, sizeof(msg), format, va); va_end(va); mp_msg(mod, lev, msg); if (mp_msg_test(mod, lev)) gtkMessageBox(GTK_MB_FATAL, msg); }