2 * page_status.c -- Status Page Handling
3 * Copyright (C) 2002-2003 Charles Yates <charles.yates@pandora.be>
4 * Copyright (C) 2010 Dan Dennedy <dan@dennedy.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include "interface.h"
32 #include "dv1394app.h"
42 pthread_t status_thread
;
46 struct page_t
*parent_page
;
48 *page_status
, page_status_t
;
50 static GtkWidget
*this_page_get_widget( page
);
52 /** Show the status associated to a unit.
55 static char* status_to_text( mvcp_status status
)
57 switch( status
->status
)
59 case unit_offline
: return "offline"; break;
60 case unit_undefined
: return "undefined"; break;
61 case unit_not_loaded
: return "unloaded"; break;
62 case unit_stopped
: return "stopped"; break;
63 case unit_playing
: return "playing"; break;
64 case unit_paused
: return "paused"; break;
65 case unit_disconnected
: return "disconnect"; break;
66 case unit_unknown
: return "unknown"; break;
71 static void format_status_string(char* buf
, int size
, mvcp_status status
, char* sep
)
73 char tc1
[12], tc2
[12], tc3
[12];
76 "[%s]%sIN:%s%sPOS:%s%sOUT:%s%s%s%s",
77 status_to_text( status
), sep
,
78 frames2tc(status
->in
, status
->fps
, tc1
), sep
,
79 frames2tc(status
->position
, status
->fps
, tc2
), sep
,
80 frames2tc(status
->out
, status
->fps
, tc3
), sep
,
86 static int show_status( page_status
this, mvcp_status status
)
88 GtkWidget
*widget
= this_page_get_widget( ( page
)this );
89 char temp
[ 1024 ] = "";
90 char label_name
[ 256 ];
92 format_status_string(temp
, sizeof(temp
), status
, "\n");
93 sprintf( label_name
, "label_unit_%d", status
->unit
);
96 widget
= lookup_widget( widget
, label_name
);
97 gtk_label_set_text( GTK_LABEL( widget
), temp
);
98 if ( status
->unit
== dv1394app_get_selected_unit( this->app
) )
102 snprintf( temp
, sizeof(temp
), "U%d - [%s] %s",
104 status_to_text( status
),
106 widget
= lookup_widget( dv1394app_get_widget( this->app
), "statusbar" );
107 gtk_statusbar_pop( GTK_STATUSBAR( widget
), this->context
);
108 gtk_statusbar_push( GTK_STATUSBAR( widget
), this->context
, temp
);
110 widget
= lookup_widget( dv1394app_get_widget( this->app
), "bbt_label_1a" );
111 snprintf( temp
, sizeof(temp
), "POS: %s",
112 frames2tc(status
->position
, status
->fps
, tc
));
113 gtk_label_set_text( GTK_LABEL( widget
), temp
);
115 widget
= lookup_widget( dv1394app_get_widget( this->app
), "bbt_label_1b" );
116 snprintf( temp
, sizeof(temp
), "REM: %s",
117 frames2tc(status
->out
- status
->position
, status
->fps
, tc
));
118 gtk_label_set_text( GTK_LABEL( widget
), temp
);
120 dv1394app_show_status( this->app
, status
);
125 return status
->unit
>= this->count
;
128 static void show_units( page_status
this, gboolean active
)
134 char temp
[ 1024 ] = "";
135 char button_name
[ 256 ];
137 mvcp_units units
= NULL
;
138 mvcp_unit_entry_t unit
;
141 mvcp_nodes nodes
= NULL
;
142 mvcp_node_entry_t node
;
147 units
= mvcp_units_init( this->status
);
148 unit_count
= mvcp_units_count( units
);
149 nodes
= mvcp_nodes_init( this->status
);
150 node_count
= mvcp_nodes_count( nodes
);
151 this->count
= unit_count
;
156 for ( index
= 0; index
< MAX_UNITS
; index
++ )
158 if ( index
< unit_count
)
160 mvcp_units_get( units
, index
, &unit
);
162 for ( index2
= 0; index2
< node_count
; index2
++ )
164 mvcp_nodes_get( nodes
, index2
, &node
);
165 if ( !strcmp( node
.guid
, unit
.guid
) )
169 if ( index2
< node_count
)
170 sprintf( temp
, "U%d - %s (%s)", unit
.unit
, node
.name
, unit
.guid
);
172 sprintf( temp
, "U%d - %s", unit
.unit
, unit
.guid
);
174 sprintf( button_name
, "radiobutton_%d", index
);
175 widget
= lookup_widget( this_page_get_widget( ( page
)this ), button_name
);
176 gtk_widget_show( widget
);
177 gtk_button_set_label( GTK_BUTTON( widget
), temp
);
178 sprintf( button_name
, "label_unit_%d", index
);
179 widget
= lookup_widget( this_page_get_widget( ( page
)this ), button_name
);
180 gtk_widget_show( widget
);
184 sprintf( button_name
, "radiobutton_%d", index
);
185 widget
= lookup_widget( this_page_get_widget( ( page
)this ), button_name
);
186 gtk_widget_hide( widget
);
187 sprintf( button_name
, "label_unit_%d", index
);
188 widget
= lookup_widget( this_page_get_widget( ( page
)this ), button_name
);
189 gtk_widget_hide( widget
);
195 mvcp_notifier notifier
= mvcp_get_notifier( this->status
);
196 mvcp_status_t status
;
198 for ( index
= 0; index
< MAX_UNITS
; index
++ )
202 status
.status
= unit_disconnected
;
204 mvcp_notifier_get( notifier
, &status
, index
);
205 show_status( this, &status
);
210 mvcp_nodes_close( nodes
);
211 mvcp_units_close( units
);
215 /** Status monitoring thread.
218 static void *status_thread( void *arg
)
221 page_status
this = arg
;
222 mvcp_notifier notifier
= mvcp_get_notifier( this->status
);
223 mvcp_status_t status
;
224 mvcp_status_t
*statuses
;
226 show_units( this, TRUE
);
228 statuses
= malloc(sizeof(mvcp_status_t
) * this->count
);
229 memset(statuses
, 0, sizeof(mvcp_status_t
) * this->count
);
231 while ( !this->terminated
)
235 /* wait for any event from notifier */
236 mvcp_notifier_wait( notifier
, &status
);
238 /* get status for all units */
239 for(i
= 0; i
< this->count
; i
++)
241 mvcp_notifier_get( notifier
, &status
, i
);
243 if ( status
.status
== unit_disconnected
)
244 goto break_unit_disconnected
;
246 if( memcmp(&status
, &statuses
[i
], sizeof(mvcp_status_t
)) || !this->app
->eof
[i
])
249 statuses
[i
] = status
;
251 /* save eof status */
252 if ( !this->app
->eof
[i
] && mvcp_unit_get( this->app
->command
, i
,
253 "eof", buf
, sizeof(buf
) ) != -1)
254 this->app
->eof
[i
] = buf
[0];
256 /* send status update */
257 if ( show_status( this, &status
) )
258 show_units( this, TRUE
);
263 break_unit_disconnected
:
267 show_units( this, FALSE
);
269 if ( !this->terminated
)
271 GtkWidget
*widget
= lookup_widget( dv1394app_get_widget( this->app
), "button_disconnect" );
273 gtk_signal_emit_by_name( GTK_OBJECT( widget
), "clicked" );
280 void on_radiobutton_toggled( GtkToggleButton
*togglebutton
, gpointer user_data
)
282 page_status
this = user_data
;
283 dv1394app app
= this->app
;
285 GtkWidget
*widget
= this_page_get_widget( ( page
)this );
286 for ( index
= 0; index
< MAX_UNITS
; index
++ )
288 char button_name
[ 256 ];
289 sprintf( button_name
, "radiobutton_%d", index
);
290 if ( lookup_widget( widget
, button_name
) == GTK_WIDGET( togglebutton
) )
293 if ( index
< MAX_UNITS
)
295 mvcp_status_t status
;
296 mvcp_notifier notifier
= mvcp_get_notifier( this->status
);
297 dv1394app_on_unit_change( app
, index
);
298 mvcp_notifier_get( notifier
, &status
, index
);
299 gdk_threads_leave( );
300 show_status( this, &status
);
301 gdk_threads_enter( );
305 static GtkWidget
*this_page_get_widget( page super
)
307 page_status
this = ( page_status
)super
;
308 if ( this->widget
== NULL
)
309 this->widget
= this->parent_page
->get_widget(this->parent_page
);
313 static void this_page_get_toolbar_info( page super
, GtkIconSize size
, GtkWidget
**icon
, char **label
)
315 *icon
= gtk_image_new_from_stock( "gtk-home", size
);
316 *label
= _("_Units");
319 static void this_page_on_connect( page super
)
321 page_status
this = ( page_status
)super
;
322 if ( this->terminated
)
324 this->terminated
= 0;
325 this->status
= mvcp_init( dv1394app_get_parser( this->app
) );
326 pthread_create( &this->status_thread
, NULL
, status_thread
, this );
330 static void this_page_on_disconnect( page super
)
332 page_status
this = ( page_status
)super
;
333 if ( !this->terminated
)
336 this->terminated
= 1;
338 pthread_join( this->status_thread
, NULL
);
340 mvcp_close( this->status
);
341 widget
= lookup_widget( dv1394app_get_widget( this->app
), "statusbar" );
342 gtk_statusbar_push( GTK_STATUSBAR( widget
), this->context
, "Disconnected." );
346 static void this_page_close( page super
)
348 page_status
this = ( page_status
)super
;
353 page
page_status_init( dv1394app app
, struct page_t
*parent_page
)
355 page_status
this = calloc( 1, sizeof( page_status_t
) );
359 this->parent_page
= parent_page
;
360 this->parent
.get_widget
= this_page_get_widget
;
361 this->parent
.get_toolbar_info
= this_page_get_toolbar_info
;
362 this->parent
.on_connect
= this_page_on_connect
;
363 this->parent
.on_disconnect
= this_page_on_disconnect
;
364 this->parent
.close
= this_page_close
;
366 this->terminated
= 1;
368 for ( index
= 0; index
< MAX_UNITS
; index
++ )
370 char button_name
[ 256 ];
371 sprintf( button_name
, "radiobutton_%d", index
);
372 widget
= lookup_widget( this_page_get_widget( ( page
)this ), button_name
);
373 gtk_signal_connect( GTK_OBJECT( widget
), "toggled", GTK_SIGNAL_FUNC( on_radiobutton_toggled
), this );
376 widget
= lookup_widget( dv1394app_get_widget( this->app
), "statusbar" );
377 this->context
= gtk_statusbar_get_context_id( GTK_STATUSBAR( widget
), "info" );
378 gtk_statusbar_push( GTK_STATUSBAR( widget
), this->context
, "Disconnected." );