1 /*
2 * Copyright (c) 2010-2011, Texas Instruments Incorporated
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * * Neither the name of Texas Instruments Incorporated nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Contact information for paper mail:
32 * Texas Instruments
33 * Post Office Box 655303
34 * Dallas, Texas 75265
35 * Contact information:
36 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm
37 * ?DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
38 * ============================================================================
39 *
40 */
42 /**
43 * @file gui.c
44 *
45 * @brief Defines the functions exported by the GUI.
46 * Also, defines the static functions and the callback funtions
47 */
49 #include <gtk/gtk.h>
51 #include <gui.h>
52 #include <common.h>
53 #include <gst-controller.h>
55 /******************************************************************************
56 * Static variables declaration
57 ******************************************************************************/
58 static GUIWindow *window[] = {NULL, NULL};
59 static Pipeline *pipes[] = {NULL, NULL};
60 static GtkWidget *logWindow[] = {NULL, NULL};
61 static GtkWidget *helpWindow = NULL;
64 /******************************************************************************
65 * Static functions declaration
66 ******************************************************************************/
67 static void setControlMode(GUIWindow *thisWindow,gint modeFlag,gint activeFlag);
68 static void setControlActive(GUIWindow *window, gboolean activeFlag);
69 static void setup();
70 static void setDecodeSwitch(gint decodeSwitch);
71 static GtkWidget *createLogWindow();
72 static GtkWidget *createHelpWindow();
73 static void logGUI(GtkWidget *logWindow, gchar *format, ...);
74 static void setWindowSizeLocation();
75 static GUIWindow *createWindow();
77 static gboolean cbOpenClicked(GtkWidget *widget, gpointer data);
78 static gboolean cbPlayClicked(GtkWidget *widget, gpointer data);
79 static gboolean cbPauseClicked(GtkWidget *widget, gpointer data);
80 static gboolean cbStopClicked(GtkWidget *widget, gpointer data);
81 static gboolean cbWindowClosed(GtkWidget *widget, gpointer data);
82 static gboolean cbTimerInterval(gpointer data);
83 static gboolean cbSeekValueChanged(GtkWidget *widget, gpointer data);
86 /******************************************************************************
87 * Callback functions definiation
88 ******************************************************************************/
90 /*Timer Interval Callback Function*/
91 static gboolean cbTimerInterval(gpointer data)
92 {
93 gint64 position = 0;
94 gint64 duration = 0;
95 gdouble seekScaleValue = 0.0;
96 gchar *timeLabelText = TIME_LABEL_ORIGIN;
97 GUIWindow *thisWindow = (GUIWindow *)data;
98 gboolean ret = TRUE;
100 if(DECODE_MODE_SINGLE == decodeMode){
101 ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
102 &seekScaleValue,
103 &timeLabelText);
105 g_signal_handler_block(window[DECODER_INDEX_SINGLE]->seekScale,
106 window[DECODER_INDEX_SINGLE]->seekSignal);
107 gtk_range_set_value(window[DECODER_INDEX_SINGLE]->seekScale,
108 seekScaleValue);
109 gtk_label_set_text(window[DECODER_INDEX_SINGLE]->timeLabel,
110 timeLabelText);
111 g_signal_handler_unblock(window[DECODER_INDEX_SINGLE]->seekScale,
112 window[DECODER_INDEX_SINGLE]->seekSignal);
114 g_signal_handler_block(window[DECODER_INDEX_DOUBLE]->seekScale,
115 window[DECODER_INDEX_DOUBLE]->seekSignal);
116 gtk_range_set_value(window[DECODER_INDEX_DOUBLE]->seekScale,
117 seekScaleValue);
118 gtk_label_set_text(window[DECODER_INDEX_DOUBLE]->timeLabel,
119 timeLabelText);
120 g_signal_handler_unblock(window[DECODER_INDEX_DOUBLE]->seekScale,
121 window[DECODER_INDEX_DOUBLE]->seekSignal);
122 }else{
123 if(window[DECODER_INDEX_SINGLE] == thisWindow){
124 ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_SINGLE],
125 &seekScaleValue,
126 &timeLabelText);
128 g_signal_handler_block(window[DECODER_INDEX_SINGLE]->seekScale,
129 window[DECODER_INDEX_SINGLE]->seekSignal);
130 gtk_range_set_value(window[DECODER_INDEX_SINGLE]->seekScale,
131 seekScaleValue);
132 gtk_label_set_text(window[DECODER_INDEX_SINGLE]->timeLabel,
133 timeLabelText);
134 g_signal_handler_unblock(window[DECODER_INDEX_SINGLE]->seekScale,
135 window[DECODER_INDEX_SINGLE]->seekSignal);
136 }else{
137 ret = DualDecode_getMediaPosition(pipes[DECODER_INDEX_DOUBLE],
138 &seekScaleValue,
139 &timeLabelText);
141 g_signal_handler_block(window[DECODER_INDEX_DOUBLE]->seekScale,
142 window[DECODER_INDEX_DOUBLE]->seekSignal);
143 gtk_range_set_value(window[DECODER_INDEX_DOUBLE]->seekScale,
144 seekScaleValue);
145 gtk_label_set_text(window[DECODER_INDEX_DOUBLE]->timeLabel,
146 timeLabelText);
147 g_signal_handler_unblock(window[DECODER_INDEX_DOUBLE]->seekScale,
148 window[DECODER_INDEX_DOUBLE]->seekSignal);
149 }
150 }
151 if(ret){
152 g_free(timeLabelText);
153 }
154 }
156 /*Seek Scale Changed Value Callback Function*/
157 static gboolean cbSeekValueChanged(GtkWidget *widget, gpointer data)
158 {
159 }
161 /*Open Button Clicked Callback Function*/
162 static gboolean cbOpenClicked(GtkWidget *widget, gpointer data)
163 {
164 GUIWindow *thisWindow = (GUIWindow *)data;
165 GtkWidget *fileChooser = gtk_file_chooser_dialog_new(
166 "Open",
167 GTK_WINDOW(thisWindow->window),
168 GTK_FILE_CHOOSER_ACTION_OPEN,
169 GTK_STOCK_OPEN,
170 GTK_RESPONSE_OK,
171 GTK_STOCK_CANCEL,
172 GTK_RESPONSE_CANCEL,
173 NULL);
174 gtk_window_set_modal(GTK_WINDOW(fileChooser),TRUE);
175 gtk_window_set_destroy_with_parent(GTK_WINDOW(fileChooser),TRUE);
176 gtk_widget_set_sensitive(thisWindow->window,FALSE);
178 if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(fileChooser))){
179 g_printerr("%s\n",
180 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser)));
181 /*TODO : set global filename here*/
183 if(DECODE_MODE_SINGLE == decodeMode){
184 setControlMode(window[DECODER_INDEX_SINGLE],
185 CONTROL_MODE_PLAYING,
186 window[DECODER_INDEX_SINGLE]->activeFlag);
187 setControlMode(window[DECODER_INDEX_DOUBLE],
188 CONTROL_MODE_PLAYING,
189 window[DECODER_INDEX_DOUBLE]->activeFlag);
190 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
191 filename[DECODER_INDEX_SINGLE],
192 SEEK_START,
193 window[DECODER_INDEX_SINGLE]->drawArea,
194 window[DECODER_INDEX_DOUBLE]->drawArea);
195 }else{
196 if(window[DECODER_INDEX_SINGLE] == thisWindow){
197 setControlMode(window[DECODER_INDEX_SINGLE],
198 CONTROL_MODE_PLAYING,
199 window[DECODER_INDEX_SINGLE]->activeFlag);
200 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
201 filename[DECODER_INDEX_SINGLE],
202 SEEK_START,
203 window[DECODER_INDEX_SINGLE]->drawArea,
204 NULL);
205 }else{
206 setControlMode(window[DECODER_INDEX_DOUBLE],
207 CONTROL_MODE_PLAYING,
208 window[DECODER_INDEX_DOUBLE]->activeFlag);
209 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
210 filename[DECODER_INDEX_DOUBLE],
211 SEEK_START,
212 window[DECODER_INDEX_DOUBLE]->drawArea,
213 NULL);
214 }
215 }
216 }
217 if(GTK_IS_WIDGET(fileChooser))
218 gtk_widget_destroy(fileChooser);
220 if(GTK_IS_WIDGET(thisWindow->window))
221 gtk_widget_set_sensitive(thisWindow->window,TRUE);
222 }
224 /*Play Button Clicked Callback Function*/
225 static gboolean cbPlayClicked(GtkWidget *widget, gpointer data)
226 {
227 GUIWindow *thisWindow = (GUIWindow *)data;
229 if(DECODE_MODE_SINGLE == decodeMode){
230 setControlMode(window[DECODER_INDEX_SINGLE],
231 CONTROL_MODE_PLAYING,
232 window[DECODER_INDEX_SINGLE]->activeFlag);
233 setControlMode(window[DECODER_INDEX_DOUBLE],
234 CONTROL_MODE_PLAYING,
235 window[DECODER_INDEX_DOUBLE]->activeFlag);
236 if(GST_STATE_PAUSED ==
237 DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
238 DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
239 }else{
240 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
241 filename[DECODER_INDEX_SINGLE],
242 SEEK_START,
243 window[DECODER_INDEX_SINGLE]->drawArea,
244 window[DECODER_INDEX_DOUBLE]->drawArea);
245 }
246 }else{
247 if(window[DECODER_INDEX_SINGLE] == thisWindow){
248 setControlMode(window[DECODER_INDEX_SINGLE],
249 CONTROL_MODE_PLAYING,
250 window[DECODER_INDEX_SINGLE]->activeFlag);
251 if(GST_STATE_PAUSED ==
252 DualDecode_getMediaState(pipes[DECODER_INDEX_SINGLE])){
253 DualDecode_resumeMedia(pipes[DECODER_INDEX_SINGLE]);
254 }else{
255 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
256 filename[DECODER_INDEX_SINGLE],
257 SEEK_START,
258 window[DECODER_INDEX_SINGLE]->drawArea,
259 NULL);
260 }
261 }else{
262 setControlMode(window[DECODER_INDEX_DOUBLE],
263 CONTROL_MODE_PLAYING,
264 window[DECODER_INDEX_DOUBLE]->activeFlag);
265 if(GST_STATE_PAUSED ==
266 DualDecode_getMediaState(pipes[DECODER_INDEX_DOUBLE])){
267 DualDecode_resumeMedia(pipes[DECODER_INDEX_DOUBLE]);
268 }else{
269 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
270 filename[DECODER_INDEX_DOUBLE],
271 SEEK_START,
272 window[DECODER_INDEX_DOUBLE]->drawArea,
273 NULL);
274 }
275 }
276 }
277 }
279 /*Pause Button Clicked Callback Function*/
280 static gboolean cbPauseClicked(GtkWidget *widget, gpointer data)
281 {
282 GUIWindow *thisWindow = (GUIWindow *)data;
284 if(DECODE_MODE_SINGLE == decodeMode){
285 setControlMode(window[DECODER_INDEX_SINGLE],
286 CONTROL_MODE_PAUSED,
287 window[DECODER_INDEX_SINGLE]->activeFlag);
288 setControlMode(window[DECODER_INDEX_DOUBLE],
289 CONTROL_MODE_PAUSED,
290 window[DECODER_INDEX_DOUBLE]->activeFlag);
291 DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
292 }else{
293 if(window[DECODER_INDEX_SINGLE] == thisWindow){
294 setControlMode(window[DECODER_INDEX_SINGLE],
295 CONTROL_MODE_PAUSED,
296 window[DECODER_INDEX_SINGLE]->activeFlag);
297 DualDecode_pauseMedia(pipes[DECODER_INDEX_SINGLE]);
298 }else{
299 setControlMode(window[DECODER_INDEX_DOUBLE],
300 CONTROL_MODE_PAUSED,
301 window[DECODER_INDEX_DOUBLE]->activeFlag);
302 DualDecode_pauseMedia(pipes[DECODER_INDEX_DOUBLE]);
303 }
304 }
305 }
307 /*Stop Button Clicked Callback Function*/
308 static gboolean cbStopClicked(GtkWidget *widget, gpointer data)
309 {
310 GUIWindow *thisWindow = (GUIWindow *)data;
312 if(DECODE_MODE_SINGLE == decodeMode){
313 setControlMode(window[DECODER_INDEX_SINGLE],
314 CONTROL_MODE_STOPPED,
315 window[DECODER_INDEX_SINGLE]->activeFlag);
316 setControlMode(window[DECODER_INDEX_DOUBLE],
317 CONTROL_MODE_STOPPED,
318 window[DECODER_INDEX_DOUBLE]->activeFlag);
319 DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
320 }else{
321 if(window[DECODER_INDEX_SINGLE] == thisWindow){
322 setControlMode(window[DECODER_INDEX_SINGLE],
323 CONTROL_MODE_STOPPED,
324 window[DECODER_INDEX_SINGLE]->activeFlag);
325 DualDecode_stopMedia(pipes[DECODER_INDEX_SINGLE]);
326 }else{
327 setControlMode(window[DECODER_INDEX_DOUBLE],
328 CONTROL_MODE_STOPPED,
329 window[DECODER_INDEX_DOUBLE]->activeFlag);
330 DualDecode_stopMedia(pipes[DECODER_INDEX_DOUBLE]);
331 }
332 }
333 }
335 /*Window Close Callback Function*/
336 static gboolean cbWindowClosed(GtkWidget *widget, gpointer data){
337 DualDecode_exitApplication();
338 }
340 /******************************************************************************
341 * static utility functions definition
342 ******************************************************************************/
343 static void setControlActive(GUIWindow *window, gboolean activeFlag)
344 {
345 gtk_widget_set_sensitive(window->playButton,activeFlag);
346 gtk_widget_set_sensitive(window->pauseButton,activeFlag);
347 gtk_widget_set_sensitive(window->stopButton,activeFlag);
348 gtk_widget_set_sensitive(window->rewindButton,activeFlag);
349 gtk_widget_set_sensitive(window->forwardButton,activeFlag);
350 gtk_widget_set_sensitive(window->openButton,activeFlag);
351 gtk_widget_set_sensitive(window->seekScale,activeFlag);
352 }
354 static void setControlMode(GUIWindow *thisWindow,
355 gint modeFlag,
356 gint activeFlag)
357 {
358 setControlActive(thisWindow, activeFlag);
359 if(activeFlag){
360 switch(modeFlag){
361 case CONTROL_MODE_NO_FILE:
362 gtk_widget_set_sensitive(thisWindow->playButton,FALSE);
363 gtk_widget_set_sensitive(thisWindow->pauseButton,FALSE);
365 gtk_widget_set_sensitive(thisWindow->stopButton,FALSE);
366 gtk_widget_set_sensitive(thisWindow->rewindButton,FALSE);
367 gtk_widget_set_sensitive(thisWindow->forwardButton,FALSE);
368 gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
370 break;
371 case CONTROL_MODE_PLAYING:
372 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
373 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
375 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
376 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
377 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
378 gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
380 break;
381 case CONTROL_MODE_STOPPED:
382 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
383 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
385 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
386 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
387 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
388 gtk_widget_set_sensitive(thisWindow->seekScale,FALSE);
390 break;
391 case CONTROL_MODE_PAUSED:
392 gtk_widget_set_sensitive(thisWindow->playButton,TRUE);
393 gtk_widget_set_sensitive(thisWindow->pauseButton,TRUE);
395 gtk_widget_set_sensitive(thisWindow->stopButton,TRUE);
396 gtk_widget_set_sensitive(thisWindow->rewindButton,TRUE);
397 gtk_widget_set_sensitive(thisWindow->forwardButton,TRUE);
398 gtk_widget_set_sensitive(thisWindow->seekScale,TRUE);
400 break;
401 }
402 }
403 switch(modeFlag){
404 case CONTROL_MODE_NO_FILE:
405 gtk_widget_show(thisWindow->playButton);
406 gtk_widget_hide(thisWindow->pauseButton);
408 gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
409 LABEL_TEXT_NO_FILE);
410 gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
411 TIME_LABEL_ORIGIN);
412 if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
413 g_source_remove(thisWindow->timerSignal);
414 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
415 }
416 break;
417 case CONTROL_MODE_PLAYING:
418 gtk_widget_show(thisWindow->pauseButton);
419 gtk_widget_hide(thisWindow->playButton);
421 gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
422 LABEL_TEXT_PLAYING);
423 gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
424 TIME_LABEL_ORIGIN);
426 if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
427 g_source_remove(thisWindow->timerSignal);
428 thisWindow->timerSignal = g_timeout_add(TIMER_INTERVAL,
429 cbTimerInterval,
430 thisWindow);
431 }
432 break;
433 case CONTROL_MODE_STOPPED:
434 gtk_widget_show(thisWindow->playButton);
435 gtk_widget_hide(thisWindow->pauseButton);
437 gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
438 LABEL_TEXT_STOPPED);
439 gtk_label_set_text(GTK_LABEL(thisWindow->timeLabel),
440 TIME_LABEL_ORIGIN);
442 if(thisWindow->timerSignal != TIMER_SIGNAL_NONE){
443 g_source_remove(thisWindow->timerSignal);
444 thisWindow->timerSignal = TIMER_SIGNAL_NONE;
445 }
446 break;
447 case CONTROL_MODE_PAUSED:
448 gtk_widget_show(thisWindow->playButton);
449 gtk_widget_hide(thisWindow->pauseButton);
451 gtk_label_set_text(GTK_LABEL(thisWindow->statusLabel),
452 LABEL_TEXT_PAUSED);
453 break;
455 }
456 thisWindow->modeFlag = modeFlag;
457 thisWindow->activeFlag = activeFlag;
458 }
460 static void setDecodeSwitch(gint decodeSwitch)
461 {
462 switch(decodeSwitch){
463 case DECODE_MODE_SINGLE:
464 gtk_button_set_label(
465 GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
466 SWITCH_TEXT_SINGLE);
467 gtk_button_set_label(
468 GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
469 SWITCH_TEXT_SINGLE);
470 break;
471 case DECODE_MODE_DUAL:
472 gtk_button_set_label(
473 GTK_BUTTON(window[DECODER_INDEX_SINGLE]->switchButton),
474 SWITCH_TEXT_DUAL);
475 gtk_button_set_label(
476 GTK_BUTTON(window[DECODER_INDEX_DOUBLE]->switchButton),
477 SWITCH_TEXT_DUAL);
478 }
479 }
481 static void setup()
482 {
483 gtk_widget_show_all(window[DECODER_INDEX_SINGLE]->window);
484 gtk_widget_show_all(window[DECODER_INDEX_DOUBLE]->window);
486 switch(decodeMode){
487 case DECODE_MODE_NONE:
488 setControlMode(window[DECODER_INDEX_SINGLE],
489 CONTROL_MODE_NO_FILE,
490 CONTROL_MODE_ACTIVE);
491 setControlMode(window[DECODER_INDEX_DOUBLE],
492 CONTROL_MODE_NO_FILE,
493 CONTROL_MODE_ACTIVE);
494 decodeMode = DECODE_MODE_DUAL;
495 setDecodeSwitch(DECODE_MODE_SINGLE);
496 break;
497 case DECODE_MODE_SINGLE:
498 setControlMode(window[DECODER_INDEX_SINGLE],
499 CONTROL_MODE_PLAYING,
500 CONTROL_MODE_ACTIVE);
501 setControlMode(window[DECODER_INDEX_DOUBLE],
502 CONTROL_MODE_PLAYING,
503 CONTROL_MODE_INACTIVE);
504 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
505 filename[DECODER_INDEX_SINGLE],
506 SEEK_START,
507 window[DECODER_INDEX_SINGLE]->drawArea,
508 window[DECODER_INDEX_DOUBLE]->drawArea);
509 setDecodeSwitch(DECODE_MODE_DUAL);
510 break;
511 case DECODE_MODE_DUAL:
512 setControlMode(window[DECODER_INDEX_SINGLE],
513 CONTROL_MODE_PLAYING,
514 CONTROL_MODE_ACTIVE);
515 DualDecode_playMedia(pipes[DECODER_INDEX_SINGLE],
516 filename[DECODER_INDEX_SINGLE],
517 SEEK_START,
518 window[DECODER_INDEX_SINGLE]->drawArea,
519 NULL);
520 setControlMode(window[DECODER_INDEX_DOUBLE],
521 CONTROL_MODE_PLAYING,
522 CONTROL_MODE_ACTIVE);
523 DualDecode_playMedia(pipes[DECODER_INDEX_DOUBLE],
524 filename[DECODER_INDEX_DOUBLE],
525 SEEK_START,
526 window[DECODER_INDEX_DOUBLE]->drawArea,
527 NULL);
528 setDecodeSwitch(DECODE_MODE_SINGLE);
529 break;
530 }
531 }
533 static GUIWindow *createWindow()
534 {
535 GUIWindow *ret = NULL;
536 ret = g_malloc0(sizeof(GUIWindow));
537 if(NULL == ret){
538 return ret;
539 }
540 DualDecode_builderCreate();
542 ret->window = DualDecode_getWidget("decodeWindowSingle");
543 if(NULL == ret->window){
544 goto memCleanup;
545 }
546 ret->windowCloseSignal = g_signal_connect(G_OBJECT(ret->window),
547 "delete-event",
548 G_CALLBACK(cbWindowClosed),
549 NULL);
551 GtkWidget *toolbar = DualDecode_getWidget("toolbarSingle");
552 if(NULL == toolbar){
553 goto memCleanup;
554 }
555 ret->drawArea = DualDecode_getWidget("videoViewerSingle");
556 if(NULL == ret->drawArea){
557 goto memCleanup;
558 }
560 ret->openButton = GTK_WIDGET(
561 gtk_tool_button_new_from_stock(GTK_STOCK_OPEN));
562 if(NULL == ret->openButton){
563 goto memCleanup;
564 }
565 ret->rewindButton = GTK_WIDGET(
566 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND));
567 if(NULL == ret->rewindButton){
568 goto memCleanup;
569 }
570 ret->playButton = GTK_WIDGET(
571 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY));
572 if(NULL == ret->playButton){
573 goto memCleanup;
574 }
575 ret->pauseButton = GTK_WIDGET(
576 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE));
577 if(NULL == ret->pauseButton){
578 goto memCleanup;
579 }
580 ret->stopButton = GTK_WIDGET(
581 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP));
582 if(NULL == ret->stopButton){
583 goto memCleanup;
584 }
585 ret->forwardButton = GTK_WIDGET(
586 gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_FORWARD));
587 if(NULL == ret->forwardButton){
588 goto memCleanup;
589 }
590 ret->helpButton = GTK_WIDGET(
591 gtk_tool_button_new_from_stock(GTK_STOCK_HELP));
592 if(NULL == ret->helpButton){
593 goto memCleanup;
594 }
596 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
597 GTK_TOOL_ITEM(ret->openButton),
598 -1);
599 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
600 gtk_separator_tool_item_new(),
601 -1);
602 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
603 GTK_TOOL_ITEM(ret->rewindButton),
604 -1);
605 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
606 GTK_TOOL_ITEM(ret->playButton),
607 -1);
608 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
609 GTK_TOOL_ITEM(ret->pauseButton),
610 -1);
611 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
612 GTK_TOOL_ITEM(ret->stopButton),
613 -1);
614 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
615 GTK_TOOL_ITEM(ret->forwardButton),
616 -1);
617 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
618 gtk_separator_tool_item_new(),
619 -1);
620 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
621 GTK_TOOL_ITEM(ret->helpButton),
622 -1);
624 ret->openSignal = g_signal_connect(G_OBJECT(ret->openButton),
625 "clicked",
626 G_CALLBACK(cbOpenClicked),
627 ret);
628 ret->stopSignal = g_signal_connect(G_OBJECT(ret->stopButton),
629 "clicked",
630 G_CALLBACK(cbStopClicked),
631 ret);
632 ret->pauseSignal = g_signal_connect(G_OBJECT(ret->pauseButton),
633 "clicked",
634 G_CALLBACK(cbPauseClicked),
635 ret);
636 ret->playSignal = g_signal_connect(G_OBJECT(ret->playButton),
637 "clicked",
638 G_CALLBACK(cbPlayClicked),
639 ret);
641 ret->switchButton = DualDecode_getWidget("switchButtonSingle");
642 if(NULL == ret->switchButton){
643 goto memCleanup;
644 }
646 /*TODO: connect switch signal here*/
648 ret->seekScale = DualDecode_getWidget("seekScaleSingle");
649 if(NULL == ret->seekScale){
650 goto memCleanup;
651 }
653 /*TODO: connect scale signal here*/
655 ret->statusLabel = DualDecode_getWidget("statusLabelSingle");
656 if(NULL == ret->statusLabel){
657 goto memCleanup;
658 }
660 ret->timeLabel = DualDecode_getWidget("timeLabelSingle");
661 if(NULL == ret->timeLabel){
662 goto memCleanup;
663 }
665 goto last;
667 cleanup:
668 gtk_widget_destroy(ret->window);
669 memCleanup:
670 g_free(ret);
671 last:
672 DualDecode_builderClose();
673 return ret;
674 }
676 static GtkWidget *createLogWindow()
677 {
678 /*TODO: create help window*/
679 return gtk_window_new(GTK_WINDOW_TOPLEVEL);
680 }
682 static GtkWidget *createHelpWindow()
683 {
684 /*TODO: create help window*/
685 return gtk_window_new(GTK_WINDOW_TOPLEVEL);
686 }
688 static void logGUI(GtkWidget *logWindow, gchar *format, ...)
689 {
690 /*TODO: dummy now*/
691 }
692 static void setWindowSizeLocation()
693 {
694 GdkScreen *screen = NULL;
695 gint screenWidth = -1;
696 gint screenHeight = -1;
697 gint windowWidth = -1;
698 gint windowHeight = -1;
700 screen = gdk_screen_get_default();
701 screenWidth = gdk_screen_get_width(screen);
702 screenHeight = gdk_screen_get_height(screen);
703 windowWidth = screenWidth/SCREEN_WIDTH_FACTOR;
704 windowHeight = screenHeight/SCREEN_HEIGHT_FACTOR;
706 gtk_widget_set_size_request(window[DECODER_INDEX_SINGLE]->window,
707 windowWidth,windowHeight);
708 gtk_widget_set_size_request(window[DECODER_INDEX_DOUBLE]->window,
709 windowWidth,windowHeight);
710 gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_SINGLE]->window),
711 (screenWidth-2*windowWidth)/2,
712 0);
713 gtk_window_move(GTK_WINDOW(window[DECODER_INDEX_DOUBLE]->window),
714 (screenWidth-2*windowWidth)/2+windowWidth,
715 0);
716 }
718 /******************************************************************************
719 * Exported Function Definition
720 ******************************************************************************/
722 /******************************************************************************
723 * See gui.h
724 ******************************************************************************/
725 void DualDecode_startApplication()
726 {
727 window[DECODER_INDEX_SINGLE] = createWindow();
728 g_assert(window[DECODER_INDEX_SINGLE] != NULL);
730 window[DECODER_INDEX_DOUBLE] = createWindow();
731 g_assert(window[DECODER_INDEX_DOUBLE] != NULL);
733 setWindowSizeLocation();
735 helpWindow = createHelpWindow();
736 g_assert(helpWindow != NULL);
738 logWindow[DECODER_INDEX_SINGLE] = createLogWindow();
739 g_assert(logWindow[DECODER_INDEX_SINGLE] != NULL);
741 logWindow[DECODER_INDEX_DOUBLE] = createLogWindow();
742 g_assert(logWindow[DECODER_INDEX_DOUBLE] != NULL);
744 pipes[DECODER_INDEX_SINGLE] = DualDecode_createPipeline();
745 /* DualDecode_setLogFunction(pipes[DECODER_INDEX_SINGLE],
746 logGUI,
747 logWindow[DECODER_INDEX_SINGLE]);
748 */
749 pipes[DECODER_INDEX_DOUBLE] = DualDecode_createPipeline();
750 /* DualDecode_setLogFunction(pipes[DECODER_INDEX_DOUBLE],
751 logGUI,
752 logWindow[DECODER_INDEX_DOUBLE]);
753 */
754 setup();
756 gtk_main();
757 }
759 /******************************************************************************
760 * See gui.h
761 ******************************************************************************/
762 void DualDecode_exitApplication()
763 {
764 gtk_widget_destroy(window[DECODER_INDEX_SINGLE]->window);
765 gtk_widget_destroy(window[DECODER_INDEX_DOUBLE]->window);
766 g_free(window[DECODER_INDEX_SINGLE]);
767 g_free(window[DECODER_INDEX_DOUBLE]);
768 gtk_widget_destroy(logWindow[DECODER_INDEX_SINGLE]);
769 gtk_widget_destroy(logWindow[DECODER_INDEX_DOUBLE]);
770 gtk_widget_destroy(helpWindow);
772 /*TODO: destroy pipes here*/
774 gtk_main_quit();
775 }
777 /******************************************************************************
778 * See gui.h
779 ******************************************************************************/
780 gboolean DualDecode_initGUI(gint *argc, char **argv[])
781 {
782 return gtk_init_check(argc,argv);
783 }