1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 /* playbar window */
20 
21 #include <math.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27 
28 #include "gui/app/app.h"
29 #include "gui/app/gui.h"
30 #include "gui/interface.h"
31 #include "gui/skin/font.h"
32 #include "gui/skin/skin.h"
33 #include "gui/util/mem.h"
34 #include "gui/util/misc.h"
35 #include "gui/wm/ws.h"
36 
37 #include "help_mp.h"
38 #include "mp_msg.h"
39 #include "mp_core.h"
40 #include "libvo/x11_common.h"
41 #include "libvo/fastmemcpy.h"
42 
43 #include "stream/stream.h"
44 #include "mixer.h"
45 #include "sub/sub.h"
46 
47 #include "libmpdemux/demuxer.h"
48 #include "libmpdemux/stheader.h"
49 #include "codec-cfg.h"
50 #include "libavutil/avstring.h"
51 
52 #include "ui.h"
53 #include "actions.h"
54 #include "gui/dialog/dialog.h"
55 #include "render.h"
56 
57 unsigned int GetTimerMS( void );
58 unsigned int GetTimer( void );
59 
60 unsigned char * playbarDrawBuffer = NULL;
61 int             playbarVisible = False;
62 int             playbarLength = 0;
63 int             uiPlaybarFade = 0;
64 
uiPlaybarDraw(void)65 static void uiPlaybarDraw( void )
66 {
67  int x;
68 
69  if ( !guiApp.videoWindow.isFullScreen ) return;
70  if ( !playbarVisible || !guiApp.playbarIsPresent ) return;
71 
72 // guiApp.playbar.x=( guiApp.videoWindow.Width - guiApp.playbar.width ) / 2;
73  switch( guiApp.playbar.x )
74   {
75    case -1: x=( guiApp.videoWindow.Width - guiApp.playbar.width ) / 2; break;
76    case -2: x=( guiApp.videoWindow.Width - guiApp.playbar.width ); break;
77    default: x=guiApp.playbar.x;
78   }
79 
80  switch ( uiPlaybarFade )
81   {
82    case 1: // fade in
83         playbarLength--;
84         if ( guiApp.videoWindow.Height - guiApp.playbar.height >= playbarLength )
85          {
86           playbarLength=guiApp.videoWindow.Height - guiApp.playbar.height;
87           uiPlaybarFade=0;
88           wsMouseVisibility(&guiApp.videoWindow, wsShowMouseCursor);
89          }
90         wsWindowMove( &guiApp.playbarWindow,True,x,playbarLength );
91         break;
92    case 2: // fade out
93         playbarLength+=10;
94         if ( playbarLength > guiApp.videoWindow.Height )
95          {
96           playbarLength=guiApp.videoWindow.Height;
97           uiPlaybarFade=0;
98           playbarVisible=False;
99           wsMouseVisibility(&guiApp.videoWindow, wsHideMouseCursor);
100           wsWindowVisibility( &guiApp.playbarWindow,wsHideWindow );
101           return;
102          }
103         wsWindowMove( &guiApp.playbarWindow,True,x,playbarLength );
104         break;
105   }
106 
107 /* render */
108  if ( guiApp.playbarWindow.State == wsWindowExpose )
109   {
110    btnModify( evSetMoviePosition,guiInfo.Position );
111    btnModify( evSetVolume,guiInfo.Volume );
112    btnModify( evSetBalance,guiInfo.Balance );
113 
114    wsMouseVisibility(&guiApp.videoWindow, wsShowMouseCursor);
115 
116    fast_memcpy( playbarDrawBuffer,guiApp.playbar.Bitmap.Image,guiApp.playbar.Bitmap.ImageSize );
117    RenderAll( &guiApp.playbarWindow,guiApp.playbarItems,guiApp.IndexOfPlaybarItems,playbarDrawBuffer );
118    wsImageRender( &guiApp.playbarWindow,playbarDrawBuffer );
119   }
120  wsImageDraw( &guiApp.playbarWindow );
121 }
122 
uiPlaybarMouse(int Button,int X,int Y,int RX,int RY)123 static void uiPlaybarMouse( int Button, int X, int Y, int RX, int RY )
124 {
125  static int     itemtype = 0;
126         int     i;
127         guiItem * item = NULL;
128  static double  prev_point;
129         double  point;
130         float   value = 0.0f;
131 
132  static int     SelectedItem = -1;
133         int     currentselected = -1;
134  static int     endstop;
135 
136  for ( i=0;i <= guiApp.IndexOfPlaybarItems;i++ )
137    if ( ( guiApp.playbarItems[i].pressed != btnDisabled )&&
138       ( isInside( X,Y,guiApp.playbarItems[i].x,guiApp.playbarItems[i].y,guiApp.playbarItems[i].x+guiApp.playbarItems[i].width,guiApp.playbarItems[i].y+guiApp.playbarItems[i].height ) ) )
139     { currentselected=i; break; }
140 
141  switch ( Button )
142   {
143    case wsPMMouseButton:
144         gtkShow( ivHidePopUpMenu,NULL );
145         uiMenuShow( RX,RY );
146         break;
147    case wsRMMouseButton:
148         uiMenuHide( RX,RY,0 );
149         break;
150    case wsRRMouseButton:
151         gtkShow( ivShowPopUpMenu, (void *) wPlaybar );
152         break;
153 /* --- */
154    case wsPLMouseButton:
155         gtkShow( ivHidePopUpMenu,NULL );
156         SelectedItem=currentselected;
157         if ( SelectedItem == -1 ) break; // yeees, i'm move the fucking window
158         item=&guiApp.playbarItems[SelectedItem];
159         itemtype=item->type;
160         item->pressed=btnPressed;
161 
162         switch( item->type )
163          {
164           // NOTE TO MYSELF: commented, because the expression can never be true
165           /*case itButton:
166                if ( ( SelectedItem > -1 ) &&
167                  ( ( ( item->message == evPlaySwitchToPause && item->message == evPauseSwitchToPlay ) ) ||
168                  ( ( item->message == evPauseSwitchToPlay && item->message == evPlaySwitchToPause ) ) ) )
169                  { item->pressed=btnDisabled; }
170                break;*/
171           case itRPotmeter:
172                prev_point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
173                if ( prev_point < 0.0 ) prev_point+=2*M_PI;
174                if ( prev_point <= item->arclength ) endstop=False;
175                else endstop=STOPPED_AT_0 + STOPPED_AT_100;   // block movement
176                break;
177          }
178 
179         break;
180    case wsRLMouseButton:
181         if ( SelectedItem != -1 )   // NOTE TO MYSELF: only if hasButton
182          {
183           item=&guiApp.playbarItems[SelectedItem];
184           item->pressed=btnReleased;
185          }
186         if ( currentselected == - 1 || SelectedItem == -1 ) { itemtype=0; break; }
187         SelectedItem=-1;
188         value=0;
189 
190         switch( itemtype )
191          {
192           case itHPotmeter:
193                value=100.0 * ( X - item->x ) / item->width;
194                break;
195           case itVPotmeter:
196                value=100.0 - 100.0 * ( Y - item->y ) / item->height;
197                break;
198           case itRPotmeter:
199                if ( endstop ) { itemtype=0; return; }
200                point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
201                if ( point < 0.0 ) point+=2*M_PI;
202                value=100.0 * point / item->arclength;
203                break;
204          }
205         uiEvent( item->message,value );
206 
207         itemtype=0;
208         break;
209 /* --- */
210    case wsP5MouseButton: value=-2.5f; goto rollerhandled;
211    case wsP4MouseButton: value= 2.5f;
212 rollerhandled:
213         if (currentselected != - 1)
214          {
215           item=&guiApp.playbarItems[currentselected];
216           if ( ( item->type == itHPotmeter )||( item->type == itVPotmeter )||( item->type == itRPotmeter ) )
217            {
218             item->value=constrain(item->value + value);
219             uiEvent( item->message,item->value );
220            }
221          }
222         break;
223 /* --- */
224    case wsMoveMouse:
225         item=&guiApp.playbarItems[SelectedItem];
226         switch ( itemtype )
227          {
228           case itPRMButton:
229                if (guiApp.menuIsPresent) guiApp.menuWindow.MouseHandler( 0,RX,RY,0,0 );
230                break;
231           case itRPotmeter:
232                point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
233                if ( point < 0.0 ) point+=2*M_PI;
234                if ( item->arclength < 2 * M_PI )
235                /* a potmeter with separated 0% and 100% positions */
236                 {
237                  value=item->value;
238                  if ( point - prev_point > M_PI )
239                  /* turned beyond the 0% position */
240                   {
241                    if ( !endstop )
242                     {
243                      endstop=STOPPED_AT_0;
244                      value=0.0f;
245                     }
246                   }
247                  else if ( prev_point - point > M_PI )
248                  /* turned back from beyond the 0% position */
249                   {
250                    if ( endstop == STOPPED_AT_0 ) endstop=False;
251                   }
252                  else if ( prev_point <= item->arclength && point > item->arclength )
253                  /* turned beyond the 100% position */
254                   {
255                    if ( !endstop )
256                     {
257                      endstop=STOPPED_AT_100;
258                      value=100.0f;
259                     }
260                   }
261                  else if ( prev_point > item->arclength && point <= item->arclength )
262                  /* turned back from beyond the 100% position */
263                   {
264                    if ( endstop == STOPPED_AT_100 ) endstop=False;
265                   }
266                 }
267                if ( !endstop ) value=100.0 * point / item->arclength;
268                prev_point=point;
269                goto potihandled;
270           case itVPotmeter:
271                value=100.0 - 100.0 * ( Y - item->y ) / item->height;
272                goto potihandled;
273           case itHPotmeter:
274                value=100.0 * ( X - item->x ) / item->width;
275 potihandled:
276                item->value=constrain(value);
277                uiEvent( item->message,item->value );
278                break;
279          }
280         break;
281   }
282 }
283 
uiPlaybarInit(void)284 void uiPlaybarInit( void )
285 {
286  if ( !guiApp.playbarIsPresent ) return;
287 
288  if ( ( playbarDrawBuffer = malloc( guiApp.playbar.Bitmap.ImageSize ) ) == NULL )
289   {
290    char msg[80] = "[playbar] ";
291 
292    av_strlcat( msg, _(MSGTR_GUI_MSG_MemoryErrorWindow), sizeof(msg) );
293    gmp_msg( MSGT_GPLAYER, MSGL_FATAL, msg );
294    mplayer( MPLAYER_EXIT_GUI, EXIT_ERROR, 0 );
295   }
296 
297  guiApp.playbarWindow.Parent=guiApp.videoWindow.WindowID;
298  wsWindowCreate( &guiApp.playbarWindow,
299    guiApp.playbar.x,guiApp.playbar.y,guiApp.playbar.width,guiApp.playbar.height,
300    wsHideFrame|wsHideWindow,wsShowMouseCursor|wsHandleMouseButton|wsHandleMouseMove,MPlayer" - PlayBar" );
301 
302  mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[playbar] playbarWindow ID: 0x%x\n",(int)guiApp.playbarWindow.WindowID );
303 
304  wsWindowShape( &guiApp.playbarWindow,guiApp.playbar.Mask.Image );
305 
306  guiApp.playbarWindow.DrawHandler=uiPlaybarDraw;
307  guiApp.playbarWindow.MouseHandler=uiPlaybarMouse;
308  guiApp.playbarWindow.KeyHandler=guiApp.mainWindow.KeyHandler;
309 
310  playbarLength=guiApp.videoWindow.Height;
311 }
312 
uiPlaybarDone(void)313 void uiPlaybarDone( void )
314 {
315   nfree(playbarDrawBuffer);
316   wsWindowDestroy(&guiApp.playbarWindow);
317   wsEvents();
318 }
319 
uiPlaybarShow(int y)320 void uiPlaybarShow( int y )
321 {
322  if ( !guiApp.playbarIsPresent || !gtkEnablePlayBar ) return;
323  if ( !guiApp.videoWindow.isFullScreen ) return;
324 
325  if ( y > guiApp.videoWindow.Height - guiApp.playbar.height )
326   {
327    if ( !uiPlaybarFade ) wsWindowVisibility( &guiApp.playbarWindow,wsShowWindow );
328    uiPlaybarFade=1; playbarVisible=True; wsWindowRedraw( &guiApp.playbarWindow );
329   }
330   else if ( !uiPlaybarFade ) uiPlaybarFade=2;
331 }
332