1 /***************************************************************************
2 * Copyright (C) 2004, 2005 Max Howell <max.howell@methylblue.com> *
4 * This program 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. *
9 ***************************************************************************/
13 #include <sys/types.h> //this must be _before_ sys/socket on freebsd
14 #include <sys/socket.h>
22 #include "libvisual.h"
26 main( int argc
, char** argv
)
28 if( argc
<= 1 || std::strcmp( argv
[1], "--list" ) == 0 )
30 visual_init( &argc
, &argv
);
33 VisList
*list
= visual_actor_get_list();
35 for( VisListEntry
*entry
= list
->head
->next
; entry
!= list
->tail
; entry
= entry
->next
)
37 VisPluginInfo
*info
= static_cast<VisActor
*>(entry
->data
)->plugin
->ref
->info
;
39 std::cout
<< info
->name
<< '|' << info
->about
<< std::endl
;
43 const char *plugin
= 0;
45 while( (plugin
= visual_actor_get_next_by_name( plugin
)) )
46 std::cout
<< plugin
<< '\n';
51 Vis::plugin
= argv
[2];
55 const int sockfd
= tryConnect( argv
[1] );
57 //register fd/pid combo with Amarok
59 pid_t pid
= ::getpid();
61 *(pid_t
*)&buf
[4] = pid
;
63 ::send( sockfd
, buf
, 4 + sizeof(pid_t
), 0 );
68 Vis::init( argc
, argv
);
72 // 1. we sleep for a bit, listening for messages from Amarok
80 while( nbytes
!= -1 && SDL::event_handler() )
82 //set the time to wait
84 tv
.tv_usec
= render_time
> 16 ? 0 : (16 - render_time
) * 1000; //60Hz
86 //get select to watch the right file descriptor
88 FD_SET( sockfd
, &fds
);
90 ::select( sockfd
+1, &fds
, 0, 0, &tv
);
92 if( FD_ISSET( sockfd
, &fds
) ) {
93 //Amarok sent us some data
96 ::recv( sockfd
, command
, 16, 0 );
98 if( std::strcmp( command
, "fullscreen" ) == 0 )
99 SDL::toggleFullScreen();
103 ::send( sockfd
, "PCM", 4, 0 );
104 nbytes
= ::recv( sockfd
, Vis::pcm_data
, 1024 * sizeof( int16_t ), 0 );
106 render_time
= LibVisual::render();
115 tryConnect( const char *path
)
117 const int fd
= ::socket( AF_UNIX
, SOCK_STREAM
, 0 );
121 struct sockaddr_un local
;
123 std::strcpy( &local
.sun_path
[ 0 ], path
);
124 local
.sun_family
= AF_UNIX
;
126 std::cout
<< "[Amk] Connecting to: " << path
<< '\n';
128 if( connect( fd
, (struct sockaddr
*)&local
, sizeof(local
) ) == -1 )
132 std::cerr
<< "[Amk] Could not connect\n";
146 if( SDL_Init( SDL_INIT_VIDEO
) )
148 std::cerr
<< "Could not initialize SDL: " << SDL_GetError() << std::endl
;
152 std::atexit( SDL::quit
);
159 //visual_bin_destroy( Vis::bin );
162 SDL_FreeSurface( screen
);
170 for( int i
= 0; i
< 256; i
++ )
172 SDL::pal
[i
].r
= Vis::pal
->colors
[i
].r
;
173 SDL::pal
[i
].g
= Vis::pal
->colors
[i
].g
;
174 SDL::pal
[i
].b
= Vis::pal
->colors
[i
].b
;
177 SDL_SetColors( screen
, SDL::pal
, 0, 256 );
181 create( int width
, int height
)
183 SDL_FreeSurface( screen
);
185 if( Vis::pluginIsGL
)
187 const SDL_VideoInfo
*videoinfo
= SDL_GetVideoInfo();
189 if( videoinfo
== NULL
)
191 std::cerr
<< "CRITICAL: Could not get video info\n";
196 videoflags
= SDL_OPENGL
| SDL_GL_DOUBLEBUFFER
| SDL_HWPALETTE
| SDL_RESIZABLE
;
197 videoflags
|= videoinfo
->hw_available
? SDL_HWSURFACE
: SDL_SWSURFACE
;
199 if( videoinfo
->blit_hw
) videoflags
|= SDL_HWACCEL
;
201 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER
, 1);
203 screen
= SDL_SetVideoMode( width
, height
, 16, videoflags
);
205 else screen
= SDL_SetVideoMode( width
, height
, Vis::video
->bpp
* 8, SDL_RESIZABLE
);
207 visual_video_set_buffer( Vis::video
, screen
->pixels
);
208 visual_video_set_pitch( Vis::video
, screen
->pitch
);
215 VisEventQueue
*vevent
;
217 while( SDL_PollEvent( &event
) )
219 vevent
= visual_plugin_get_eventqueue( visual_actor_get_plugin( visual_bin_get_actor( Vis::bin
) ) );
224 visual_event_queue_add_keyboard( vevent
, (VisKey
)event
.key
.keysym
.sym
, event
.key
.keysym
.mod
, VISUAL_KEY_UP
);
228 visual_event_queue_add_keyboard (vevent
, (VisKey
)event
.key
.keysym
.sym
, event
.key
.keysym
.mod
, VISUAL_KEY_DOWN
);
230 switch( event
.key
.keysym
.sym
)
235 SDL::toggleFullScreen();
239 if( SDL::isFullScreen() )
240 SDL::toggleFullScreen();
252 visual_bin_set_morph_by_name( Vis::bin
, (char*)"alphablend" );
253 visual_bin_switch_actor_by_name( Vis::bin
, (char*)Vis::plugin
);
256 SDL_WM_SetCaption( Vis::plugin
, 0 );
265 case SDL_VIDEORESIZE
:
266 Vis::resize( event
.resize
.w
, event
.resize
.h
);
269 case SDL_MOUSEMOTION
:
270 visual_event_queue_add_mousemotion (vevent
, event
.motion
.x
, event
.motion
.y
);
273 case SDL_MOUSEBUTTONDOWN
:
274 if (event
.button
.button
== SDL_BUTTON_RIGHT
)
276 SDL::toggleFullScreen();
279 visual_event_queue_add_mousebutton (vevent
, event
.button
.button
, VISUAL_MOUSE_DOWN
, 0, 0);
282 case SDL_MOUSEBUTTONUP
:
283 visual_event_queue_add_mousebutton (vevent
, event
.button
.button
, VISUAL_MOUSE_UP
, 0, 0);
302 upload_callback( VisInput
*, VisAudio
*audio
, void* )
306 visual_buffer_init( &buf
, pcm_data
, 1024, 0 );
307 visual_audio_samplepool_input( audio
->samplepool
, &buf
, VISUAL_AUDIO_SAMPLE_RATE_44100
,
308 VISUAL_AUDIO_SAMPLE_FORMAT_S16
, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO
);
314 resize( int width
, int height
)
316 visual_video_set_dimension( video
, width
, height
);
318 SDL::create( width
, height
);
320 visual_bin_sync( bin
, false );
324 init( int &argc
, char **&argv
)
328 visual_init( &argc
, &argv
);
330 bin
= visual_bin_new ();
331 depth
= visual_video_depth_enum_from_value( 24 );
333 if( !plugin
) plugin
= visual_actor_get_next_by_name( 0 );
334 if( !plugin
) exit( "Actor plugin not found!" );
336 visual_bin_set_supported_depth( bin
, VISUAL_VIDEO_DEPTH_ALL
);
338 if( NULL
== (video
= visual_video_new()) ) exit( "Cannot create a video surface" );
339 if( visual_video_set_depth( video
, depth
) < 0 ) exit( "Cannot set video depth" );
341 visual_video_set_dimension( video
, 320, 200 );
343 if( visual_bin_set_video( bin
, video
) ) exit( "Cannot set video" );
345 visual_bin_connect_by_names( bin
, (char*)plugin
, 0 );
347 if( visual_bin_get_depth( bin
) == VISUAL_VIDEO_DEPTH_GL
)
349 visual_video_set_depth( video
, VISUAL_VIDEO_DEPTH_GL
);
353 SDL::create( 320, 200 );
355 SDL_WM_SetCaption( plugin
, 0 );
357 /* Called so the flag is set to false, seen we create the initial environment here */
358 visual_bin_depth_changed( bin
);
360 VisInput
*input
= visual_bin_get_input( bin
);
361 if( visual_input_set_callback( input
, upload_callback
, NULL
) < 0 ) exit( "Cannot set input plugin callback" );
363 visual_bin_switch_set_style( bin
, VISUAL_SWITCH_STYLE_MORPH
);
364 visual_bin_switch_set_automatic( bin
, true );
365 visual_bin_switch_set_steps( bin
, 100 );
367 visual_bin_realize( bin
);
368 visual_bin_sync( bin
, false );
370 std::cout
<< "[Amk] Libvisual version " << visual_get_version() << '\n';
371 std::cout
<< "[Amk] bpp: " << video
->bpp
<< std::endl
;
372 std::cout
<< "[Amk] GL: " << (pluginIsGL
? "true\n" : "false\n");
378 /* On depth change */
379 if( visual_bin_depth_changed( bin
) )
383 pluginIsGL
= (visual_bin_get_depth( bin
) == VISUAL_VIDEO_DEPTH_GL
);
385 SDL::create( SDL::screen
->w
, SDL::screen
->h
);
386 visual_bin_sync( bin
, true );
391 long ticks
= -SDL_GetTicks();
395 visual_bin_run( bin
);
397 SDL_GL_SwapBuffers();
403 visual_video_set_buffer( video
, SDL::screen
->pixels
);
404 visual_bin_run( bin
);
408 Vis::pal
= visual_bin_get_palette( bin
);
411 SDL_Flip( SDL::screen
);
414 ticks
+= SDL_GetTicks();
417 } //namespace LibVisual