4
* This file contains the main control UI for xvidcap
5
* \todo rename the global variables pthread* to xvc_pthread*
8
/* Copyright (C) 2003-07 Karl H. Beckers, Frankfurt
9
* EMail: khb@jarre-de-the.net
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#ifndef DOXYGEN_SHOULD_SKIP_THIS
32
#define DEBUGFILE "gnome_ui.c"
33
#endif // DOXYGEN_SHOULD_SKIP_THIS
35
#include <sys/time.h> // for timeval struct and related
44
#include <X11/cursorfont.h>
45
#include <X11/Xmu/WinUtil.h>
48
#include <X11/extensions/Xfixes.h>
49
#include <X11/extensions/Xdamage.h>
50
#include <X11/Xproto.h>
55
#include <glade/glade.h>
59
#include "led_meter.h"
66
#include "gnome_warning.h"
67
#include "gnome_options.h"
69
#include "gnome_frame.h"
70
#include "xvidcap-intl.h"
71
#include "eggtrayicon.h"
76
#ifndef DOXYGEN_SHOULD_SKIP_THIS
77
extern GtkWidget *xvc_pref_main_window;
78
extern GtkWidget *xvc_warn_main_window;
79
#endif // DOXYGEN_SHOULD_SKIP_THIS
81
/** \brief make the main control panel globally available */
82
GtkWidget *xvc_ctrl_main_window = NULL;
85
* \brief make the main control panel's menu globally available
87
* @note this is needed because the warning dialog may need to change the
88
* status of capture type select buttons. If you change from e. g.
89
* single-frame capture to multi-frame capture, xvidcap checks your
90
* preferences for the new capture type and finding errors allows you
91
* to cancel back out of the change ... and needs to reset the menu.
93
GtkWidget *xvc_ctrl_m1 = NULL;
96
* \brief the value here is picked up by the LED frame drop monitor widget.
97
* Set to 0 to clear the widget.
101
// those are for recording video in thread
102
/** \brief mutex for the recording, state changes and pausing/unpausing */
103
pthread_mutex_t recording_mutex = PTHREAD_MUTEX_INITIALIZER;
105
/** \brief condition for pausing/unpausing a recording effectively */
106
pthread_cond_t recording_condition_unpaused;
108
/** \brief the recording thread */
109
static pthread_t recording_thread;
111
/** \brief attributes of the recording thread */
112
static pthread_attr_t recording_thread_attr;
115
/** \brief mutex for the Xdamage support. It governs write access to the
116
* damaged region storage */
117
pthread_mutex_t damage_regions_mutex = PTHREAD_MUTEX_INITIALIZER;
118
#endif // USE_XDAMAGE
120
/** \brief is the recording thread running?
122
* \todo find out if there's a way to tell that from the tread directly
124
static Boolean recording_thread_running = FALSE;
126
/** \brief make the results dialog globally available to callbacks here */
127
static GtkWidget *xvc_result_dialog = NULL;
129
/** \brief remember the previous led_time set */
130
static int last_led_time = 0;
132
/** \brief remember the previously set picture number to allow for a quick
133
* check on the next call if we need to do anything */
134
static int last_pic_no = 0;
136
/** \brief store a timer that may be registered when setting a max recording
138
static guint stop_timer_id = 0;
140
/** calculate recording time */
141
static long start_time = 0, pause_time = 0, time_captured = 0;
143
/** \brief used to faciltate passing the filename selection from a file
144
* selector dialog back off the results dialog back to the results
145
* dialog and eventually the main dialog */
146
static char *target_file_name = NULL;
149
* \brief the errors found on submitting a set of preferences
151
* Used to pass this between the various components involved in deciding
152
* what to do when OK is clicked
153
* \todo the whole display of preferences and warning dialogs should be
154
* simplified through _run_dialog()
156
static XVC_ErrorListItem *errors_after_cli = NULL;
159
* \brief remember the number of attempts to submit a set of preferences
161
* Hitting OK on a warning may make automatic changes to the preferences.
162
* But it may not resolve all conflicts in one go and pop up the warning
163
* dialog again, again offering automatic resultion actions. This should be
164
* a rare case, however
166
static int OK_attempts = 0;
168
/** \brief eggtrayicon for minimizing xvidcap to the system tray */
169
static GtkWidget *tray_icon = NULL;
171
/** \brief frame drop monitor for inclusion in the system tray */
172
static GtkWidget *tray_frame_mon = NULL;
174
/** \brief popup menu for the system tray icon */
175
static GtkWidget *tray_icon_menu = NULL;
178
* HELPER FUNCTIONS ...
183
* \brief create the LED frame drop meter widget
185
* This function needs to conform to the custom widget creation functions
186
* as libglade uses them
187
* @param widget_name the name of the widget as set in glade
188
* @param string1 not used
189
* @param string2 not used
190
* @param int1 not used
191
* @param int2 not used
192
* @return the created LED frame drop meter widget
195
glade_create_led_meter (gchar * widget_name, gchar * string1,
196
gchar * string2, gint int1, gint int2)
198
#define DEBUGFUNCTION "glade_create_led_meter()"
199
GtkWidget *frame_monitor = led_meter_new ();
201
g_assert (frame_monitor);
203
gtk_widget_set_name (GTK_WIDGET (frame_monitor), widget_name);
204
gtk_widget_show (GTK_WIDGET (frame_monitor));
206
return frame_monitor;
211
* this isn't used atm
213
gint keySnooper (GtkWidget *grab_widget, GdkEventKey *event, gpointer func_data) {
214
printf("keyval: %i - mods: %i\n", event->keyval, event->state);
218
* \brief change value of frame/filename display
220
* @param pic_no update the display according to this frame number
223
GtkChangeLabel (int pic_no)
225
#define DEBUGFUNCTION "GtkChangeLabel()"
226
static char file[PATH_MAX + 1], tmp_buf[PATH_MAX + 1];
227
PangoLayout *layout = NULL;
228
gint width = 0, height = 0;
229
int filename_length = 0;
230
GladeXML *xml = NULL;
232
Job *jobp = xvc_job_ptr ();
233
XVC_AppData *app = xvc_appdata_ptr ();
235
// generate the string to display in the filename button
236
if (app->current_mode > 0) {
237
sprintf (tmp_buf, jobp->file, jobp->movie_no);
238
sprintf (file, "%s[%04d]", tmp_buf, pic_no);
240
sprintf (file, jobp->file, pic_no);
242
// cut the string to a sensible maximum length
243
filename_length = strlen (file);
244
if (filename_length > 60) {
245
char tmp_file[PATH_MAX + 1];
246
char *tmp_file2, *ptr;
249
strncpy (tmp_file, file, 20);
251
n = filename_length - 20;
252
ptr = (char *) &file + n;
253
tmp_file2 = strncat (tmp_file, "...", 4);
254
tmp_file2 = strncat (tmp_file, ptr, 45);
255
strncpy (file, tmp_file2, 45);
257
// get the filename button widget
258
xml = glade_get_widget_tree (xvc_ctrl_main_window);
260
w = glade_xml_get_widget (xml, "xvc_ctrl_filename_button");
264
gtk_button_set_label (GTK_BUTTON (w), file);
266
// adjust the size of the filname button
267
layout = gtk_widget_create_pango_layout (w, file);
269
pango_layout_get_pixel_size (layout, &width, &height);
270
g_object_unref (layout);
272
gtk_widget_set_size_request (GTK_WIDGET (w), (width + 30), -1);
277
* \brief implements the actions required when successfully submitting the
278
* warning dialog, mainly resetting the control UI to the current
279
* state of the preferences.
284
#define DEBUGFUNCTION "warning_submit()"
286
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
288
XVC_AppData *app = xvc_appdata_ptr ();
290
xvc_job_set_from_app_data (app);
292
// set controls active/inactive/sensitive/insensitive according to
294
if (!(app->flags & FLG_NOGUI)) {
295
xvc_reset_ctrl_main_window_according_to_current_prefs ();
298
if (xvc_errorlist_delete (errors_after_cli)) {
300
"%s %s: Unrecoverable error while freeing error list, please contact the xvidcap project.\n",
301
DEBUGFILE, DEBUGFUNCTION);
304
// reset attempts so warnings will be shown again next time ...
308
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
315
* \brief this toggles the type of capture (sf vs. mf) currently active
317
* This is global because it can be necessary to call this from the warning
321
xvc_toggle_cap_type ()
323
#define DEBUGFUNCTION "xvc_toggle_cap_type()"
324
int count_non_info_messages, rc;
325
XVC_AppData *app = xvc_appdata_ptr ();
327
count_non_info_messages = 0;
329
errors_after_cli = xvc_appdata_validate (app, 1, &rc);
333
"%s %s: Unrecoverable error while validating options, please contact the xvidcap project.\n",
334
DEBUGFILE, DEBUGFUNCTION);
338
if (errors_after_cli != NULL) {
339
XVC_ErrorListItem *err;
341
err = errors_after_cli;
342
for (; err != NULL; err = err->next) {
343
if (err->err->type != XVC_ERR_INFO)
344
count_non_info_messages++;
346
if (count_non_info_messages > 0
347
|| (app->flags & FLG_RUN_VERBOSE && OK_attempts == 0)) {
348
xvc_warn_main_window =
349
xvc_create_warning_with_errors (errors_after_cli, 1);
361
* \brief this undoes an attempt to toggle the type of capture (sf vs. mf)
364
* This is global because it can be necessary to call this from the warning
368
xvc_undo_toggle_cap_type ()
370
#define DEBUGFUNCTION "xvc_undo_toggle_cap_type()"
371
GladeXML *xml = NULL;
372
GtkWidget *mitem = NULL;
373
XVC_AppData *app = xvc_appdata_ptr ();
375
xml = glade_get_widget_tree (xvc_ctrl_m1);
381
printf ("%s %s: pre current_mode %i\n", DEBUGFILE, DEBUGFUNCTION,
385
app->current_mode = (app->current_mode == 0) ? 1 : 0;
388
printf ("%s %s: post current_mode %i\n", DEBUGFILE, DEBUGFUNCTION,
392
if (app->current_mode == 0) {
393
mitem = glade_xml_get_widget (xml, "xvc_ctrl_m1_mitem_sf_capture");
395
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem), TRUE);
397
mitem = glade_xml_get_widget (xml, "xvc_ctrl_m1_mitem_mf_capture");
399
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem), TRUE);
408
* \brief event filter to register with gdk to retrieve X11 events
410
* @param xevent pointer to the wrapped X11 event
411
* @param event pointer to the GdkEvent
412
* @param user_data pointer to other data
413
* @return flag to gdk whether to pass the event on or drop it
416
xvc_xdamage_event_filter (GdkXEvent * xevent, GdkEvent * event, void *user_data)
418
XVC_AppData *app = xvc_appdata_ptr ();
419
XEvent *xev = (XEvent *) xevent;
420
XDamageNotifyEvent *e = (XDamageNotifyEvent *) (xevent);
421
static XserverRegion region = None, clip_region = None;
422
Job *job = xvc_job_ptr ();
424
if (!recording_thread_running || job == NULL ||
425
(job->flags & FLG_USE_XDAMAGE) == 0) {
426
if (region != None) {
427
XFixesDestroyRegion (app->dpy, region);
430
if (clip_region != None) {
431
XFixesDestroyRegion (app->dpy, clip_region);
434
return GDK_FILTER_CONTINUE;
438
region = XFixesCreateRegion (app->dpy, 0, 0);
439
if (clip_region == None)
440
clip_region = XFixesCreateRegion (app->dpy, 0, 0);
442
if (xev->type == MapNotify) {
443
// XSelectInput (app->dpy, xev->xcreatewindow.window, StructureNotifyMask);
444
// if (!attribs.override_redirect /* && attribs.depth==pdata->specs.depth */) {
445
XDamageCreate (app->dpy, xev->xcreatewindow.window,
446
XDamageReportRawRectangles);
448
} else if (xev->type == app->dmg_event_base) {
450
XVC_MAX (e->area.x - 10, 0),
451
XVC_MAX (e->area.y - 10, 0),
455
XRectangle clip_rect = {
461
XFixesSetRegion (app->dpy, region, &rect, 1);
462
XFixesSetRegion (app->dpy, clip_region, &clip_rect, 1);
464
// Offset the region with the windows' position
465
XFixesTranslateRegion (app->dpy, region, e->geometry.x, e->geometry.y);
466
XFixesIntersectRegion (app->dpy, clip_region, region, clip_region);
468
pthread_mutex_lock (&damage_regions_mutex);
469
XFixesUnionRegion (app->dpy, job->dmg_region, job->dmg_region,
471
XDamageSubtract (app->dpy, e->damage, region, None);
472
pthread_mutex_unlock (&damage_regions_mutex);
475
return GDK_FILTER_CONTINUE;
477
#endif // USE_XDAMAGE
480
* \brief this is what the thread spawned on record actually does. It is
481
* normally stopped by setting the state machine to VC_STOP
486
#define DEBUGFUNCTION "do_record_thread()"
487
Job *job = xvc_job_ptr ();
491
printf ("%s %s: Entering with state = %i and tid = %i\n", DEBUGFILE,
492
DEBUGFUNCTION, job->state, recording_thread);
495
recording_thread_running = TRUE;
497
if (!(job->flags & FLG_NOGUI)) {
498
xvc_idle_add (xvc_change_filename_display, (void *) NULL);
499
xvc_idle_add (xvc_frame_monitor, (void *) NULL);
502
while ((job->state & VC_READY) == 0) {
504
printf ("%s %s: going for next frame with state %i\n", DEBUGFILE,
505
DEBUGFUNCTION, job->state);
507
if ((job->state & VC_PAUSE) && !(job->state & VC_STEP)) {
508
// make the led monitor stop for pausing
511
pthread_mutex_lock (&recording_mutex);
512
pthread_cond_wait (&recording_condition_unpaused, &recording_mutex);
513
pthread_mutex_unlock (&recording_mutex);
515
printf ("%s %s: unpaused\n", DEBUGFILE, DEBUGFUNCTION);
518
pause = job->capture ();
521
usleep (pause * 1000);
523
printf ("%s %s: woke up\n", DEBUGFILE, DEBUGFUNCTION);
528
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
531
recording_thread_running = FALSE;
537
* \brief implements those actions required for stopping a capture session
538
* that are not GUI related
541
stop_recording_nongui_stuff ()
543
#define DEBUGFUNCTION "stop_recording_nongui_stuff()"
545
struct timeval curr_time;
547
XVC_AppData *app = xvc_appdata_ptr ();
550
printf ("%s %s: Entering with thread running %i\n",
551
DEBUGFILE, DEBUGFUNCTION, recording_thread_running);
555
stop_time = pause_time;
557
gettimeofday (&curr_time, NULL);
558
stop_time = curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000;
559
time_captured += (stop_time - start_time);
563
g_source_remove (stop_timer_id);
566
if (app->flags & FLG_AUTO_CONTINUE) {
567
state |= VC_CONTINUE;
569
xvc_job_set_state (state);
571
if (recording_thread_running) {
572
pthread_join (recording_thread, NULL);
574
printf ("%s %s: joined thread\n", DEBUGFILE, DEBUGFUNCTION);
578
if (app->flags & FLG_USE_XDAMAGE)
579
gdk_window_remove_filter (NULL,
580
(GdkFilterFunc) xvc_xdamage_event_filter,
582
#endif // USE_XDAMAGE
585
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
592
* \brief displays the xvidcap user manual.
597
system ((char *) "yelp ghelp:xvidcap?xvidcap-results &");
601
* \brief implements the GUI related actions involved when stopping a
605
stop_recording_gui_stuff ()
607
#define DEBUGFUNCTION "stop_recording_gui_stuff()"
608
GladeXML *xml = NULL;
610
XVC_CapTypeOptions *target = NULL;
611
Job *jobp = xvc_job_ptr ();
612
XVC_AppData *app = xvc_appdata_ptr ();
615
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
619
if (app->current_mode > 0)
620
target = &(app->multi_frame);
623
target = &(app->single_frame);
625
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
629
w = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
631
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
633
w = glade_xml_get_widget (xml, "xvc_ctrl_select_toggle");
635
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
637
w = glade_xml_get_widget (xml, "xvc_ctrl_record_toggle");
639
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
640
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (w)))
641
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
643
w = glade_xml_get_widget (xml, "xvc_ctrl_filename_button");
645
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
647
w = glade_xml_get_widget (xml, "xvc_ctrl_edit_button");
649
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
651
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
653
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
655
if (app->current_mode > 0) {
657
if (xvc_is_filename_mutable (jobp->file) == TRUE) {
658
if (jobp->movie_no > 0) {
659
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
661
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
664
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
666
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
669
if (xvc_is_filename_mutable (jobp->file) == TRUE) {
670
if (jobp->pic_no >= target->step) {
671
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
673
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
676
if (target->frames == 0
677
|| jobp->pic_no < (target->frames - target->step)) {
678
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
680
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
685
w = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
687
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (w)))
688
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
689
w = glade_xml_get_widget (xml, "xvc_ctrl_stop_toggle");
691
if (!gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (w)))
692
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), TRUE);
694
GtkChangeLabel (jobp->pic_no);
696
if (app->flags & FLG_TO_TRAY) {
697
gtk_widget_destroy (GTK_WIDGET (tray_frame_mon));
698
tray_frame_mon = NULL;
699
gtk_widget_destroy (GTK_WIDGET (tray_icon));
701
gtk_widget_destroy (GTK_WIDGET (tray_icon_menu));
702
tray_icon_menu = NULL;
703
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (xvc_ctrl_main_window),
705
gtk_window_deiconify (GTK_WINDOW (xvc_ctrl_main_window));
708
if ((strlen (target->file) < 1 ||
709
(app->flags & FLG_ALWAYS_SHOW_RESULTS) > 0) &&
710
(app->flags & FLG_AUTO_CONTINUE) == 0) {
715
GladeXML *xml = NULL;
718
// load the interface
719
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_result_dialog", NULL);
721
// connect the signals in the interface
722
glade_xml_signal_autoconnect (xml);
724
xvc_result_dialog = glade_xml_get_widget (xml, "xvc_result_dialog");
725
g_assert (xvc_result_dialog);
728
w = glade_xml_get_widget (xml, "xvc_result_dialog_width_label");
730
snprintf (buf, 99, "%i", app->area->width);
731
gtk_label_set_text (GTK_LABEL (w), buf);
734
w = glade_xml_get_widget (xml, "xvc_result_dialog_height_label");
736
snprintf (buf, 99, "%i", app->area->height);
737
gtk_label_set_text (GTK_LABEL (w), buf);
740
w = glade_xml_get_widget (xml, "xvc_result_dialog_video_format_label");
742
gtk_label_set_text (GTK_LABEL (w),
743
_(xvc_formats[jobp->target].longname));
746
w = glade_xml_get_widget (xml, "xvc_result_dialog_video_codec_label");
748
gtk_label_set_text (GTK_LABEL (w), xvc_codecs[jobp->targetCodec].name);
751
w = glade_xml_get_widget (xml, "xvc_result_dialog_audio_codec_label");
753
gtk_label_set_text (GTK_LABEL (w),
754
((jobp->flags & FLG_REC_SOUND) ?
755
xvc_audio_codecs[jobp->au_targetCodec].name :
759
w = glade_xml_get_widget (xml, "xvc_result_dialog_fps_label");
761
snprintf (buf, 99, "%.2f",
762
((float) target->fps.num / (float) target->fps.den));
763
gtk_label_set_text (GTK_LABEL (w), buf);
766
w = glade_xml_get_widget (xml, "xvc_result_dialog_actual_fps_label");
769
char *str_template = NULL;
771
((float) jobp->pic_no / (float) target->step) + 1;
773
((float) total_frames) / ((float) time_captured / 1000);
776
((float) target->fps.num / (float) target->fps.den))
777
actual_fps = (float) target->fps.num / (float) target->fps.den;
779
actual_fps / ((float) target->fps.num /
780
(float) target->fps.den);
782
if (fps_ratio > (((float) LM_NUM_DAS - LM_LOW_THRESHOLD) / 10)) {
783
str_template = "%.2f";
784
} else if (fps_ratio >
785
(((float) LM_NUM_DAS - LM_MEDIUM_THRESHOLD) / 10)) {
786
str_template = "<span background=\"#EEEE00\">%.2f</span>";
788
str_template = "<span background=\"#EE0000\">%.2f</span>";
791
snprintf (buf, 99, str_template, actual_fps);
792
gtk_label_set_markup (GTK_LABEL (w), buf);
796
w = glade_xml_get_widget (xml,
797
"xvc_result_dialog_fps_ratio_progressbar");
799
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (w), fps_ratio);
800
snprintf (buf, 99, "%.2f %%", fps_ratio * 100);
801
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (w), buf);
804
w = glade_xml_get_widget (xml, "xvc_result_dialog_total_frames_label");
806
snprintf (buf, 99, "%i", (jobp->pic_no / target->step) + 1);
807
gtk_label_set_text (GTK_LABEL (w), buf);
810
w = glade_xml_get_widget (xml, "xvc_result_dialog_video_length_label");
812
snprintf (buf, 99, "%.2f seconds", ((float) time_captured / 1000));
813
gtk_label_set_text (GTK_LABEL (w), buf);
815
if (strlen (target->file) > 0) {
816
w = glade_xml_get_widget (xml,
817
"xvc_result_dialog_select_filename_button");
819
gtk_widget_hide (GTK_WIDGET (w));
821
w = glade_xml_get_widget (xml, "xvc_result_dialog_filename_label");
823
gtk_widget_hide (GTK_WIDGET (w));
825
w = glade_xml_get_widget (xml, "xvc_result_dialog_no_button");
827
gtk_widget_hide (GTK_WIDGET (w));
829
w = glade_xml_get_widget (xml, "xvc_result_dialog_save_button");
831
gtk_widget_hide (GTK_WIDGET (w));
833
w = glade_xml_get_widget (xml,
834
"xvc_result_dialog_show_next_time_checkbutton");
836
gtk_widget_show (GTK_WIDGET (w));
838
w = glade_xml_get_widget (xml, "xvc_result_dialog_close_button");
840
gtk_widget_show (GTK_WIDGET (w));
844
result = gtk_dialog_run (GTK_DIALOG (xvc_result_dialog));
847
case GTK_RESPONSE_OK:
848
if (target_file_name != NULL) {
849
char cmd_buf[PATH_MAX * 2 + 5];
852
snprintf (cmd_buf, (PATH_MAX * 2 + 5), "mv %s %s",
853
target->file, target_file_name);
854
errnum = system ((char *) cmd_buf);
856
GtkWidget *err_dialog =
857
gtk_message_dialog_new (GTK_WINDOW
858
(xvc_ctrl_main_window),
859
GTK_DIALOG_DESTROY_WITH_PARENT,
862
"Error moving file from '%s' to '%s'\n%s",
865
g_strerror (errnum));
867
gtk_dialog_run (GTK_DIALOG (err_dialog));
868
gtk_widget_destroy (err_dialog);
871
case GTK_RESPONSE_CANCEL:
872
case GTK_RESPONSE_CLOSE:
873
w = glade_xml_get_widget (xml,
874
"xvc_result_dialog_show_next_time_checkbutton");
876
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)))
877
app->flags &= ~FLG_ALWAYS_SHOW_RESULTS;
879
case GTK_RESPONSE_HELP:
882
case GTK_RESPONSE_ACCEPT:
883
if (!app->current_mode) {
884
xvc_command_execute (target->play_cmd, 1, 0,
885
target->file, target->start_no,
886
jobp->pic_no, app->area->width,
887
app->area->height, target->fps);
889
xvc_command_execute (target->play_cmd, 2,
890
jobp->movie_no, target->file,
891
target->start_no, jobp->pic_no,
893
app->area->height, target->fps);
899
} while (result == GTK_RESPONSE_HELP || result == GTK_RESPONSE_ACCEPT);
901
gtk_widget_destroy (xvc_result_dialog);
902
xvc_result_dialog = NULL;
904
// FIXME: realize move in a way that gives me real error codes
907
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
914
* \brief this function is hooked up as the action to execute when a
915
* capture session with max_time set times out.
917
* \todo might be able to trigger xvc_capture_stop_signal directly
920
timer_stop_recording ()
922
#define DEBUGFUNCTION "timer_stop_recording()"
923
xvc_capture_stop_signal (FALSE);
929
on_tray_icon_button_press_event (GtkWidget * widget,
930
GdkEvent * event, gpointer user_data)
932
GdkEventButton *bevent = NULL;
936
bevent = (GdkEventButton *) event;
938
if (bevent->button == (guint) 3) {
939
g_assert (tray_icon_menu);
941
gtk_menu_popup (GTK_MENU (tray_icon_menu), NULL, NULL,
942
NULL, widget, bevent->button, bevent->time);
943
// Tell calling code that we have handled this event; the buck
951
* \brief implements the GUI related actions involved in starting a
955
start_recording_gui_stuff ()
957
#define DEBUGFUNCTION "start_recording_gui_stuff()"
958
GladeXML *xml = NULL;
960
Job *jobp = xvc_job_ptr ();
961
XVC_CapTypeOptions *target = NULL;
962
XVC_AppData *app = xvc_appdata_ptr ();
965
if (app->current_mode > 0)
966
target = &(app->multi_frame);
969
target = &(app->single_frame);
971
if (app->flags & FLG_TO_TRAY) {
972
GtkWidget *ebox = NULL, *hbox = NULL, *pause_cb;
974
// GtkWidget *image = NULL;
975
// GdkBitmap *bm = NULL;
977
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (xvc_ctrl_main_window),
980
tray_icon = GTK_WIDGET (egg_tray_icon_new ("xvc_tray_icon"));
981
g_assert (tray_icon);
982
ebox = gtk_event_box_new ();
984
hbox = gtk_hbox_new (FALSE, 2);
986
tray_frame_mon = NULL;
987
tray_frame_mon = glade_create_led_meter ("tray_frame_mon", NULL,
989
g_assert (tray_frame_mon);
990
gtk_container_add (GTK_CONTAINER (hbox), tray_frame_mon);
992
// image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_RECORD,
993
// GTK_ICON_SIZE_SMALL_TOOLBAR);
995
// gtk_container_add (GTK_CONTAINER (hbox), image);
996
gtk_container_add (GTK_CONTAINER (ebox), hbox);
997
gtk_container_add (GTK_CONTAINER (tray_icon), ebox);
998
gtk_widget_show_all (tray_icon);
1000
g_signal_connect (G_OBJECT (ebox), "button_press_event",
1001
G_CALLBACK (on_tray_icon_button_press_event), NULL);
1003
// load the interface
1004
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_ti_menu", NULL);
1007
// connect the signals in the interface
1008
glade_xml_signal_autoconnect (xml);
1009
// store the toplevel widget for further reference
1010
tray_icon_menu = glade_xml_get_widget (xml, "xvc_ti_menu");
1011
if (jobp->state & VC_PAUSE) {
1012
pause_cb = glade_xml_get_widget (xml, "xvc_ti_pause");
1013
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (pause_cb),
1017
gtk_window_iconify (GTK_WINDOW (xvc_ctrl_main_window));
1019
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
1023
w = glade_xml_get_widget (xml, "xvc_ctrl_record_toggle");
1025
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1027
w = glade_xml_get_widget (xml, "xvc_ctrl_stop_toggle");
1029
if ((jobp->state & VC_PAUSE) == 0) {
1030
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1032
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
1034
w = glade_xml_get_widget (xml, "xvc_ctrl_select_toggle");
1036
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1038
w = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
1040
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1042
w = glade_xml_get_widget (xml, "xvc_ctrl_filename_button");
1044
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1046
w = glade_xml_get_widget (xml, "xvc_ctrl_edit_button");
1048
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1050
if (jobp->state & VC_PAUSE) {
1051
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
1053
if (app->current_mode == 0) {
1054
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1056
if (target->frames == 0
1057
|| jobp->pic_no <= (target->frames - target->step)) {
1058
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
1060
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1062
if (jobp->pic_no >= target->step) {
1063
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
1065
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1068
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1069
if (!xvc_is_filename_mutable (target->file)) {
1070
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
1072
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1074
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
1076
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1080
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
1082
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1084
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
1086
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1088
#undef DEBUGFUNCTION
1092
* \brief implements those actions involved in starting a capture session
1093
* that are not GUI related
1096
start_recording_nongui_stuff ()
1098
#define DEBUGFUNCTION "start_recording_nongui_stuff()"
1099
if (!recording_thread_running) {
1100
struct timeval curr_time;
1101
Job *job = xvc_job_ptr ();
1102
XVC_CapTypeOptions *target = NULL;
1103
XVC_AppData *app = xvc_appdata_ptr ();
1106
if (app->current_mode > 0)
1107
target = &(app->multi_frame);
1109
#endif // USE_FFMPEG
1110
target = &(app->single_frame);
1112
// the following also unsets VC_READY
1113
xvc_job_keep_and_merge_state (VC_PAUSE, (VC_REC | VC_START));
1115
if (app->current_mode > 0) {
1116
job->pic_no = target->start_no;
1119
if ((job->state & VC_PAUSE) == 0) {
1120
// if (job->max_time != 0 && (job->state & VC_PAUSE) == 0) {
1121
gettimeofday (&curr_time, NULL);
1123
start_time = curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000;
1124
if (target->time != 0) {
1125
// install a timer which stops recording
1126
// we need milli secs ..
1128
g_timeout_add ((guint32) (target->time * 1000),
1129
(GtkFunction) timer_stop_recording, job);
1133
if (job->flags & FLG_USE_XDAMAGE) {
1134
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (app->dpy);
1135
Window *children, root_return, parent_return, root;
1136
XWindowAttributes root_attrs;
1137
unsigned int nchildren, i;
1139
root = DefaultRootWindow (app->dpy);
1140
XGetWindowAttributes (app->dpy, root, &root_attrs);
1141
XSelectInput (app->dpy, root, StructureNotifyMask);
1142
XDamageCreate (app->dpy, DefaultRootWindow (app->dpy),
1143
XDamageReportRawRectangles);
1144
XQueryTree (app->dpy,
1145
DefaultRootWindow (app->dpy),
1146
&root_return, &parent_return, &children, &nchildren);
1148
for (i = 0; i < nchildren; i++) {
1149
XWindowAttributes attribs;
1152
gdk_error_trap_push ();
1153
ret = XGetWindowAttributes (app->dpy, children[i], &attribs);
1154
gdk_error_trap_pop ();
1157
//XSelectInput (app->dpy, children[i], StructureNotifyMask);
1158
// if (!attribs.override_redirect /* && attribs.depth==root_attr.depth */ ) {
1159
XDamageCreate (app->dpy, children[i],
1160
XDamageReportRawRectangles);
1164
XSync (app->dpy, False);
1167
gdk_window_add_filter (NULL,
1168
(GdkFilterFunc) xvc_xdamage_event_filter,
1172
gdk_x11_register_standard_event_type (gdpy,
1173
app->dmg_event_base,
1174
XDamageNumberEvents);
1176
#endif // USE_XDAMAGE
1177
// initialize recording thread
1178
pthread_mutex_init (&recording_mutex, NULL);
1179
pthread_cond_init (&recording_condition_unpaused, NULL);
1181
pthread_attr_init (&recording_thread_attr);
1182
pthread_attr_setdetachstate (&recording_thread_attr,
1183
PTHREAD_CREATE_JOINABLE);
1184
pthread_create (&recording_thread, &recording_thread_attr,
1185
(void *) do_record_thread, (void *) job);
1188
#undef DEBUGFUNCTION
1192
* \brief this positions the main control's menu (which is actually a
1193
* popup menu a.k.a. context menu) in the same way it would if it
1194
* were a normal menu
1196
* @param menu pointer to the menu widget
1197
* @param x pointer to an int where the calculated x-position will be returned
1198
* @param y pointer to an int where the calculated y-position will be returned
1199
* @param push_in not actively used
1200
* @param user_data not actively used
1203
position_popup_menu (GtkMenu * menu, gint * x, gint * y,
1204
gboolean * push_in, gpointer user_data)
1206
#define DEBUGFUNCTION "position_popup_menu()"
1207
int pheight = 0, px = 0, py = 0, tx = 0, ty = 0;
1208
GtkWidget *w = NULL;
1210
w = GTK_WIDGET (user_data);
1212
g_return_if_fail (w != NULL);
1214
pheight = w->allocation.height;
1215
px = w->allocation.x;
1216
py = w->allocation.y;
1220
w = gtk_widget_get_toplevel (GTK_WIDGET (w));
1222
g_return_if_fail (w != NULL);
1224
gdk_window_get_origin (GDK_WINDOW (w->window), &px, &py);
1230
#undef DEBUGFUNCTION
1234
* \brief resets the main control window according to the preferences
1238
xvc_reset_ctrl_main_window_according_to_current_prefs ()
1240
#define DEBUGFUNCTION "xvc_reset_ctrl_main_window_according_to_current_prefs()"
1241
GladeXML *mwxml = NULL, *menuxml = NULL;
1242
GtkWidget *w = NULL;
1243
GtkTooltips *tooltips;
1244
Job *jobp = xvc_job_ptr ();
1245
XVC_CapTypeOptions *target = NULL;
1246
XVC_AppData *app = xvc_appdata_ptr ();
1249
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1253
if (app->current_mode > 0)
1254
target = &(app->multi_frame);
1256
#endif // USE_FFMPEG
1257
target = &(app->single_frame);
1259
mwxml = glade_get_widget_tree (xvc_ctrl_main_window);
1261
menuxml = glade_get_widget_tree (xvc_ctrl_m1);
1264
// various GUI initialization things
1267
// first: the autocontinue menu item
1269
// make autocontinue menuitem invisible if no ffmpeg
1272
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_autocontinue");
1273
g_return_if_fail (w != NULL);
1274
gtk_widget_hide (GTK_WIDGET (w));
1277
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_separator1");
1278
g_return_if_fail (w != NULL);
1279
gtk_widget_hide (GTK_WIDGET (w));
1282
// the rest in case we have ffmpeg
1283
if (app->current_mode > 0) {
1284
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_autocontinue");
1287
if ((app->flags & FLG_AUTO_CONTINUE) != 0) {
1288
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1289
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);
1291
if (xvc_is_filename_mutable (jobp->file)) {
1292
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1293
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), FALSE);
1295
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1296
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), FALSE);
1300
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_autocontinue");
1303
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1304
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), FALSE);
1306
#endif // USE_FFMPEG
1309
// the filename button
1311
GtkChangeLabel (jobp->pic_no);
1313
// previous and next buttons have different meanings for on-the-fly
1314
// encoding and individual frame capture ...
1315
// this sets the tooltips accordingly
1316
if (app->current_mode == 0) {
1317
tooltips = gtk_tooltips_new ();
1318
g_assert (tooltips);
1321
w = glade_xml_get_widget (mwxml, "xvc_ctrl_back_button");
1323
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips,
1324
_("Move cursor back one frame"),
1325
_("Move cursor back one frame"));
1326
if (jobp->pic_no >= target->step)
1327
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1329
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
1331
w = glade_xml_get_widget (mwxml, "xvc_ctrl_forward_button");
1333
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips,
1334
_("Move cursor to next frame"),
1335
_("Move cursor to next frame"));
1336
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
1338
w = glade_xml_get_widget (mwxml, "xvc_ctrl_filename_button");
1340
gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), GTK_WIDGET (w),
1342
("Left Click: Reset frame counter and filename\nRight Click: Popup Menu"),
1344
("Left Click: Reset frame counter and filename\nRight Click: Popup Menu"));
1346
w = glade_xml_get_widget (mwxml, "xvc_ctrl_edit_button");
1348
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips,
1349
_("Edit current individual frame"),
1350
_("Edit current individual frame"));
1352
w = glade_xml_get_widget (mwxml, "xvc_ctrl_step_button");
1354
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips,
1355
_("Capture single frame"),
1356
_("Capture single frame"));
1358
GtkWidget *next = NULL, *previous = NULL, *filename = NULL, *w = NULL;
1360
next = glade_xml_get_widget (mwxml, "xvc_ctrl_forward_button");
1362
previous = glade_xml_get_widget (mwxml, "xvc_ctrl_back_button");
1363
g_assert (previous);
1364
filename = glade_xml_get_widget (mwxml, "xvc_ctrl_filename_button");
1365
g_assert (filename);
1366
tooltips = gtk_tooltips_new ();
1367
g_assert (tooltips);
1369
if (xvc_is_filename_mutable (jobp->file)) {
1370
gtk_widget_set_sensitive (GTK_WIDGET (next), TRUE);
1371
if (jobp->movie_no > 0)
1372
gtk_widget_set_sensitive (GTK_WIDGET (previous), TRUE);
1374
gtk_widget_set_sensitive (GTK_WIDGET (previous), FALSE);
1376
gtk_widget_set_sensitive (GTK_WIDGET (next), FALSE);
1377
gtk_widget_set_sensitive (GTK_WIDGET (previous), FALSE);
1379
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (previous), tooltips,
1380
_("Move cursor to previous movie"),
1381
_("Move cursor to previous movie"));
1382
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (next), tooltips,
1383
_("Move cursor to next movie"),
1384
_("Move cursor to next movie"));
1385
gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips),
1386
GTK_WIDGET (filename),
1388
("Left Click: Reset movie counter to zero\nRight Click: Popup Menu"),
1390
("Left Click: Reset movie counter to zero\nRight Click: Popup Menu"));
1392
w = glade_xml_get_widget (mwxml, "xvc_ctrl_edit_button");
1394
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips,
1395
_("Edit current movie"),
1396
_("Edit current movie"));
1398
w = glade_xml_get_widget (mwxml, "xvc_ctrl_step_button");
1400
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (w), tooltips, NULL, NULL);
1404
// capture type radio buttons
1406
// make capture type radio buttons invisible if no ffmpeg
1409
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_sf_capture");
1410
g_return_if_fail (w != NULL);
1411
gtk_widget_hide (GTK_WIDGET (w));
1414
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_mf_capture");
1415
g_return_if_fail (w != NULL);
1416
gtk_widget_hide (GTK_WIDGET (w));
1418
if (app->current_mode == 0) {
1420
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_sf_capture");
1421
g_return_if_fail (w != NULL);
1422
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);
1426
w = glade_xml_get_widget (menuxml, "xvc_ctrl_m1_mitem_mf_capture");
1427
g_return_if_fail (w != NULL);
1428
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), TRUE);
1430
#endif // USE_FFMPEG
1432
#undef DEBUGFUNCTION
1436
* XVIDCAP GUI API<br>
1437
* ( IF THAT WORD IS ALLOWED HERE ;) )<br>
1439
* <tr><td>xvc_init_pre</td><td>do gui preintialization like setting fallback options, initializing thread libraries and the like</td></tr>
1440
* <tr><td>xvc_ui_create</td><td>create the gui</td></tr>
1441
* <tr><td>xvc_frame_create</td><td>create the frame for selecting the area to capture</td></tr>
1442
* <tr><td>xvc_check_start_options</td><td>check the preferences on program start</td></tr>
1443
* <tr><td>xvc_ui_init</td><td>gui initialization</td></tr>
1444
* <tr><td>xvc_ui_run</td><td>start the ui's main loop</td></tr>
1445
* <tr><td>xvc_idle_add</td><td>queue an idle action</td></tr>
1446
* <tr><td>xvc_change_filename_display</td><td>update the display of the current frame/file</td></tr>
1447
* <tr><td>xvc_capture_stop_signal</td><td>tell the ui you want it to stop recording</td></tr>
1448
* <tr><td>xvc_capture_stop</td><td>implements the functions for actually stopping</td></tr>
1449
* <tr><td>xvc_capture_start</td><td>implements the functions for starting a recording</td></tr>
1450
* <tr><td>xvc_frame_change</td><td>change the area to capture</td></tr>
1451
* <tr><td>xvc_frame_monitor</td><td>update a widget monitoring frame rate</td></tr>
1456
* \brief does gui preintialization, mainly initializing thread libraries
1457
* and calling gtk_init with the command line arguments
1459
* @param argc number of command line arguments
1460
* @param argv pointer to the command line arguments
1461
* @return Could be FALSE for failure, but de facto always TRUE
1464
xvc_init_pre (int argc, char **argv)
1466
#define DEBUGFUNCTION "xvc_init_pre()"
1467
g_thread_init (NULL);
1468
gdk_threads_init ();
1470
gtk_init (&argc, &argv);
1472
#undef DEBUGFUNCTION
1476
* \brief creates the main control and menu from the glade definition,
1477
* connects the signals and stores the widget pointers for further
1480
* @return Could be FALSE for failure, but de facto always TRUE
1485
#define DEBUGFUNCTION "xvc_ui_create()"
1486
GladeXML *xml = NULL;
1487
XVC_AppData *app = xvc_appdata_ptr ();
1490
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1493
// only show the ui if not in nogui
1494
if ((app->flags & FLG_NOGUI) == 0) {
1496
// load the interface
1497
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_ctrl_main_window", NULL);
1501
// connect the signals in the interface
1502
glade_xml_signal_autoconnect (xml);
1503
// store the toplevel widget for further reference
1504
xvc_ctrl_main_window =
1505
glade_xml_get_widget (xml, "xvc_ctrl_main_window");
1507
#if GTK_CHECK_VERSION(2, 5, 0)
1510
GtkWidget *w = NULL;
1513
* replace the following stock ids
1515
gtk-media-stop gtk-stop
1516
gtk-media-pause gtk-go-up (funky, but it works)
1517
gtk-media-record gtk-convert
1518
gtk-media-next gtk-goto-last
1519
gtk-media-rewind gtk-go-back
1520
gtk-media-forward gtk-go-forward
1521
gtk-edit gtk-paste (2nd choice would be gtk-open)
1524
w = glade_xml_get_widget (xml, "xvc_ctrl_stop_toggle");
1526
gtk_button_set_image (GTK_BUTTON (w),
1527
gtk_image_new_from_stock ("gtk-stop",
1528
GTK_ICON_SIZE_BUTTON));
1530
w = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
1532
gtk_button_set_image (GTK_BUTTON (w),
1533
gtk_image_new_from_stock ("gtk-go-up",
1534
GTK_ICON_SIZE_BUTTON));
1536
w = glade_xml_get_widget (xml, "xvc_ctrl_record_toggle");
1538
gtk_button_set_image (GTK_BUTTON (w),
1539
gtk_image_new_from_stock ("gtk-convert",
1540
GTK_ICON_SIZE_BUTTON));
1542
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
1544
gtk_button_set_image (GTK_BUTTON (w),
1545
gtk_image_new_from_stock ("gtk-goto-last",
1546
GTK_ICON_SIZE_BUTTON));
1548
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
1550
gtk_button_set_image (GTK_BUTTON (w),
1551
gtk_image_new_from_stock ("gtk-go-back",
1552
GTK_ICON_SIZE_BUTTON));
1554
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
1556
gtk_button_set_image (GTK_BUTTON (w),
1557
gtk_image_new_from_stock
1558
("gtk-go-forward", GTK_ICON_SIZE_BUTTON));
1560
w = glade_xml_get_widget (xml, "xvc_ctrl_edit_button");
1562
gtk_button_set_image (GTK_BUTTON (w),
1563
gtk_image_new_from_stock ("gtk-paste",
1564
GTK_ICON_SIZE_BUTTON));
1567
#endif // GTK_CHECK_VERSION
1571
// load the interface
1572
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_ctrl_m1", NULL);
1576
// connect the signals in the interface
1577
glade_xml_signal_autoconnect (xml);
1578
xvc_ctrl_m1 = glade_xml_get_widget (xml, "xvc_ctrl_m1");
1581
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1585
#undef DEBUGFUNCTION
1589
* \brief creates the frame around the area to capture by calling the
1590
* actual implementation in xvc_create_gtk_frame
1592
* @see xvc_create_gtk_frame
1593
* @param win a Window (ID) to allow passing a window id for selecting
1594
* the area to capture (i.e. capture that window ... but not if you
1595
* move the window afterwards)
1596
* @return Could be FALSE for failure, but de facto always TRUE
1599
xvc_frame_create (Window win)
1601
#define DEBUGFUNCTION "xvc_frame_create()"
1602
XVC_AppData *app = xvc_appdata_ptr ();
1604
if ((app->flags & FLG_NOGUI) == 0) { /* there's one good reason for not
1605
* having a main window */
1606
g_assert (xvc_ctrl_main_window);
1610
Window root = DefaultRootWindow (app->dpy);
1612
// display and window attributes seem to be set correctly only if
1613
// retrieved after the UI was mapped
1614
gtk_init_add ((GtkFunction) xvc_appdata_set_window_attributes,
1617
if (app->area->width == 0)
1618
app->area->width = 10;
1619
if (app->area->height == 0)
1620
app->area->height = 10;
1622
xvc_create_gtk_frame (xvc_ctrl_main_window, app->area->width,
1623
app->area->height, app->area->x, app->area->y);
1625
Display *display = app->dpy;
1628
Window root = DefaultRootWindow (display);
1630
// display and window attributes seem to be set correctly only if
1631
// retrieved after the UI was mapped
1632
gtk_init_add ((GtkFunction) xvc_appdata_set_window_attributes,
1634
XTranslateCoordinates (display, win, root, 0, 0, &x, &y, &temp);
1638
app->area->width = app->win_attr.width;
1639
app->area->height = app->win_attr.height;
1641
xvc_create_gtk_frame (xvc_ctrl_main_window, app->area->width,
1642
app->area->height, app->area->x, app->area->y);
1645
#undef DEBUGFUNCTION
1649
* \brief checks the current preferences and should be used to check
1650
* preferences right before running the UI
1652
* This does not return anything but must react on errors found on its own.
1653
* It is global mainly for allowing it to be called from the warning dialog
1654
* in case the startup check produced an error with a default action, you
1655
* clicked OK and then the validation needs to run again.
1658
xvc_check_start_options ()
1660
#define DEBUGFUNCTION "xvc_check_start_options()"
1661
int count_non_info_messages = 0;
1663
XVC_AppData *app = xvc_appdata_ptr ();
1666
printf ("%s %s: Entering with errors_after_cli = %p\n", DEBUGFILE,
1667
DEBUGFUNCTION, errors_after_cli);
1670
if (OK_attempts > 0 && errors_after_cli != NULL) {
1671
errors_after_cli = xvc_appdata_validate (app, 1, &rc);
1674
printf ("%s %s: new errors_after_cli = %p\n", DEBUGFILE,
1675
DEBUGFUNCTION, errors_after_cli);
1680
"%s %s: Unrecoverable error while validating options, please contact the xvidcap project.\n",
1681
DEBUGFILE, DEBUGFUNCTION);
1686
if ((app->flags & FLG_NOGUI) == 0) { // we're running with gui
1687
if (errors_after_cli != NULL) {
1688
XVC_ErrorListItem *err;
1690
err = errors_after_cli;
1691
count_non_info_messages = 0;
1693
for (; err != NULL; err = err->next) {
1694
if (err->err->type != XVC_ERR_INFO)
1695
count_non_info_messages++;
1697
if (count_non_info_messages > 0
1698
|| (app->flags & FLG_RUN_VERBOSE && OK_attempts == 0)) {
1699
xvc_warn_main_window =
1700
xvc_create_warning_with_errors (errors_after_cli, 2);
1708
} else { // or without
1709
while (errors_after_cli != NULL && OK_attempts < 6) {
1710
XVC_ErrorListItem *err;
1712
err = errors_after_cli;
1713
count_non_info_messages = rc = 0;
1715
for (; err != NULL; err = err->next) {
1716
if (err->err->type != XVC_ERR_INFO)
1717
count_non_info_messages++;
1719
if (count_non_info_messages > 0
1720
|| (app->flags & FLG_RUN_VERBOSE && OK_attempts == 0)) {
1721
err = errors_after_cli;
1722
for (; err != NULL; err = err->next) {
1723
if (err->err->type != XVC_ERR_INFO ||
1724
app->flags & FLG_RUN_VERBOSE) {
1725
xvc_error_write_msg (err->err->code,
1728
FLG_RUN_VERBOSE) ? 1 : 0));
1729
(*err->err->action) (err);
1736
errors_after_cli = xvc_appdata_validate (app, 1, &rc);
1739
"%s %s: Unrecoverable error while validating options, please contact the xvidcap project.\n",
1740
DEBUGFILE, DEBUGFUNCTION);
1745
if (errors_after_cli != NULL && count_non_info_messages > 0) {
1747
"%s %s: You have specified some conflicting settings which could not be resolved automatically.\n",
1748
DEBUGFILE, DEBUGFUNCTION);
1755
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1758
#undef DEBUGFUNCTION
1762
* \brief initializes the UI by mainly ensuring xvc_check_start_options is
1763
* called with the errors found in main
1765
* @see xvc_check_start_options
1766
* @param errors the errors in the preferences found in the main function
1767
* @return Could be FALSE for failure, but de facto always TRUE
1770
xvc_ui_init (XVC_ErrorListItem * errors)
1772
#define DEBUGFUNCTION "xvc_ui_init()"
1773
XVC_AppData *app = xvc_appdata_ptr ();
1776
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1779
// display warning dialog if required
1780
errors_after_cli = errors;
1781
// the gui warning dialog needs a realized window, therefore we
1782
// schedule it do be displayed (potentially) when the main loop starts
1783
// this does not seem to work with nogui
1784
if (!(app->flags & FLG_NOGUI)) {
1785
gtk_init_add ((GtkFunction) xvc_check_start_options, NULL);
1787
xvc_check_start_options ();
1788
gtk_init_add ((GtkFunction) xvc_capture_start, NULL);
1792
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1796
#undef DEBUGFUNCTION
1800
* \brief runs the UI by executing the main loop
1802
* @return Could be any integer for failure, but de facto always 0
1807
#define DEBUGFUNCTION "xvc_ui_run()";
1812
#undef DEBUGFUNCTION
1816
* \brief adds an action to the event queue to be executed when there's time
1818
* The functions added here are executed whenever there's time until they
1821
* @param func a pointer to a function to queue
1822
* @param data a pointer to an argument to that function
1825
xvc_idle_add (void *func, void *data)
1827
g_idle_add (func, data);
1831
* \brief updates the display of the current frame/filename according to
1832
* the current state of job.
1834
* This is meant to be used through xvc_idle_add during recording
1835
* @return TRUE for as long as the recording thread is running or FALSE
1839
xvc_change_filename_display ()
1841
#define DEBUGFUNCTION "xvc_change_filename_display()"
1843
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1845
Job *job = xvc_job_ptr ();
1846
Boolean ret = recording_thread_running;
1850
GtkChangeLabel (job->pic_no);
1851
} else if (job->pic_no != last_pic_no) {
1852
last_pic_no = job->pic_no;
1853
GtkChangeLabel (last_pic_no);
1856
printf ("%s %s: Leaving! ...continuing? %i\n", DEBUGFILE, DEBUGFUNCTION,
1861
#undef DEBUGFUNCTION
1865
* \brief tell the recording thread to stop
1867
* The actual stopping is done through the capture's state machine. This
1868
* just sets the state to VC_STOP and sends the recording thread an ALARM
1869
* signal to terminate a potential usleep. It may then wait for the thread
1871
* @param wait should this function actually wait for the thread to finish?
1874
xvc_capture_stop_signal (Boolean wait)
1876
#define DEBUGFUNCTION "xvc_capture_stop_signal()"
1880
printf ("%s %s: Entering, should we wait? %i\n",
1881
DEBUGFILE, DEBUGFUNCTION, wait);
1884
xvc_job_set_state (VC_STOP);
1886
if (recording_thread_running) {
1888
printf ("%s %s: stop pressed while recording\n",
1889
DEBUGFILE, DEBUGFUNCTION);
1891
// stop waiting for next frame to capture
1892
status = pthread_kill (recording_thread, SIGALRM);
1894
printf ("%s %s: thread %i kill with rc %i\n",
1895
DEBUGFILE, DEBUGFUNCTION, (int) recording_thread, status);
1900
while (recording_thread_running) {
1905
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1907
#undef DEBUGFUNCTION
1911
* \brief implements the actual actions required when stopping a recording
1912
* session, both GUI related an not.
1917
#define DEBUGFUNCTION "xvc_capture_stop()"
1918
Job *job = xvc_job_ptr ();
1921
printf ("%s %s: stopping\n", DEBUGFILE, DEBUGFUNCTION);
1923
stop_recording_nongui_stuff (job);
1925
printf ("%s %s: done stopping non-gui stuff\n", DEBUGFILE, DEBUGFUNCTION);
1927
if (!(job->flags & FLG_NOGUI)) {
1928
gdk_threads_enter ();
1929
stop_recording_gui_stuff (job);
1931
gdk_threads_leave ();
1937
#undef DEBUGFUNCTION
1941
* \brief starts a recording session
1944
xvc_capture_start ()
1946
#define DEBUGFUNCTION "xvc_capture_start()"
1947
Job *job = xvc_job_ptr ();
1949
start_recording_nongui_stuff (job);
1950
if (!(job->flags & FLG_NOGUI))
1951
start_recording_gui_stuff (job);
1953
#undef DEBUGFUNCTION
1957
* \brief changes the frame around the area to capture by calling the
1958
* implementing function xvc_change_gtk_frame
1960
* @see xvc_change_gtk_frame
1961
* \todo sice nobody outside this file is calling it, it needs to be neither
1962
* global nor in the "API" functions. Prolly don't need this wrapper at
1966
xvc_frame_change (int x, int y, int width, int height,
1967
Boolean reposition_control, Boolean show_dimensions)
1969
#define DEBUGFUNCTION "xvc_frame_change()"
1970
xvc_change_gtk_frame (x, y, width, height, reposition_control,
1972
#undef DEBUGFUNCTION
1977
* \brief updates the widget monitoring the current frame rate based on
1978
* the current value of xvc_led_time and last_led_time
1980
* This is meant to be used through xvc_idle_add during recording
1981
* @return TRUE for as long as the recording thread is running or FALSE
1984
* @see last_led_time
1988
xvc_frame_monitor ()
1990
#define DEBUGFUNCTION "xvc_frame_monitor()"
1992
Job *job = xvc_job_ptr ();
1993
XVC_AppData *app = xvc_appdata_ptr ();
1994
int percent = 0, diff = 0;
1995
GladeXML *xml = NULL;
1996
GtkWidget *w = NULL;
1997
int ret = recording_thread_running;
2000
printf ("%s %s: Entering with time = %i\n", DEBUGFILE, DEBUGFUNCTION,
2005
if (xvc_led_time != 0 && last_led_time == xvc_led_time)
2008
if (app->flags & FLG_TO_TRAY && tray_frame_mon) {
2010
g_return_val_if_fail (w != NULL, FALSE);
2012
xml = glade_get_widget_tree (xvc_ctrl_main_window);
2013
g_return_val_if_fail (xml != NULL, FALSE);
2014
w = glade_xml_get_widget (xml, "xvc_ctrl_led_meter");
2015
g_return_val_if_fail (w != NULL, FALSE);
2019
xvc_led_time = last_led_time = 0;
2022
if (xvc_led_time == 0) {
2024
} else if (xvc_led_time <= job->time_per_frame)
2026
else if (xvc_led_time >= (job->time_per_frame * 2))
2029
diff = xvc_led_time - job->time_per_frame;
2030
percent = diff * 70 / job->time_per_frame;
2034
led_meter_set_percent (LED_METER (w), percent);
2037
LED_METER (w)->old_max_da = 0;
2040
printf ("%s %s: Leaving with percent = %i ... continuing? %i\n",
2041
DEBUGFILE, DEBUGFUNCTION, percent, ret);
2045
#undef DEBUGFUNCTION
2049
* callbacks here ....
2052
#ifndef DOXYGEN_SHOULD_SKIP_THIS
2054
on_xvc_ctrl_main_window_delete_event (GtkWidget * widget,
2055
GdkEvent * event, gpointer user_data)
2057
#define DEBUGFUNCTION "on_xvc_ctrl_main_window_delete_event()"
2058
Job *jobp = xvc_job_ptr ();
2060
if (jobp && (jobp->state & VC_STOP) == 0) {
2061
xvc_capture_stop_signal (TRUE);
2064
xvc_destroy_gtk_frame ();
2065
gtk_main_quit (); /** \todo why does this seem to be
2066
necessary with libglade where it was not previously */
2068
#undef DEBUGFUNCTION
2072
on_xvc_ctrl_main_window_destroy_event (GtkWidget * widget,
2073
GdkEvent * event, gpointer user_data)
2075
#define DEBUGFUNCTION "on_xvc_ctrl_main_window_destroy_event()"
2078
#undef DEBUGFUNCTION
2082
on_xvc_ctrl_m1_mitem_preferences_activate (GtkMenuItem * menuitem,
2085
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_preferences_activate()"
2086
XVC_AppData *app = xvc_appdata_ptr ();
2089
printf ("%s %s: Entering with app %p\n", DEBUGFILE, DEBUGFUNCTION, app);
2092
xvc_create_pref_dialog (app);
2095
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
2097
#undef DEBUGFUNCTION
2101
on_xvc_ctrl_m1_mitem_save_preferences_activate (GtkMenuItem *
2102
menuitem, gpointer user_data)
2104
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_save_preferences_activate()"
2105
Job *jobp = xvc_job_ptr ();
2107
xvc_write_options_file (jobp);
2108
#undef DEBUGFUNCTION
2112
on_xvc_ctrl_m1_mitem_sf_capture_activate (GtkMenuItem * menuitem,
2116
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_sf_capture_activate()"
2117
XVC_AppData *app = xvc_appdata_ptr ();
2119
if (app->current_mode == 1
2120
&& gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)) !=
2122
app->current_mode = (app->current_mode == 0) ? 1 : 0;
2123
xvc_toggle_cap_type ();
2125
#undef DEBUGFUNCTION
2126
#endif // USE_FFMPEG
2130
on_xvc_ctrl_m1_mitem_mf_capture_activate (GtkMenuItem * menuitem,
2134
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_mf_capture_activate()"
2135
XVC_AppData *app = xvc_appdata_ptr ();
2137
if (app->current_mode == 0
2138
&& gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)) !=
2140
app->current_mode = (app->current_mode == 0) ? 1 : 0;
2141
xvc_toggle_cap_type ();
2143
#undef DEBUGFUNCTION
2144
#endif // USE_FFMPEG
2148
on_xvc_ctrl_m1_mitem_autocontinue_activate (GtkMenuItem * menuitem,
2151
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_autocontinue_activate()"
2152
Job *jobp = xvc_job_ptr ();
2153
XVC_AppData *app = xvc_appdata_ptr ();
2155
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem))) {
2156
if ((!xvc_is_filename_mutable (jobp->file))
2157
|| app->current_mode == 0) {
2159
("Output not a video file or no counter in filename\nDisabling autocontinue!\n");
2160
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM
2163
jobp->flags |= FLG_AUTO_CONTINUE;
2164
app->flags |= FLG_AUTO_CONTINUE;
2167
jobp->flags &= ~FLG_AUTO_CONTINUE;
2168
app->flags &= ~FLG_AUTO_CONTINUE;
2170
#undef DEBUGFUNCTION
2174
on_xvc_ctrl_m1_mitem_make_activate (GtkMenuItem * menuitem, gpointer user_data)
2176
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_make_activate()"
2177
Job *jobp = xvc_job_ptr ();
2178
XVC_CapTypeOptions *target = NULL;
2179
XVC_AppData *app = xvc_appdata_ptr ();
2182
if (app->current_mode > 0)
2183
target = &(app->multi_frame);
2185
#endif // USE_FFMPEG
2186
target = &(app->single_frame);
2188
if (!app->current_mode) {
2189
xvc_command_execute (target->video_cmd, 0, 0,
2190
jobp->file, target->start_no, jobp->pic_no,
2191
app->area->width, app->area->height, target->fps);
2193
xvc_command_execute (target->video_cmd, 2,
2194
jobp->movie_no, jobp->file, target->start_no,
2195
jobp->pic_no, app->area->width,
2196
app->area->height, target->fps);
2198
#undef DEBUGFUNCTION
2202
on_xvc_ctrl_m1_mitem_help_activate (GtkMenuItem * menuitem, gpointer user_data)
2204
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_help_activate()"
2205
system ("yelp ghelp:xvidcap &");
2206
#undef DEBUGFUNCTION
2210
on_xvc_ctrl_m1_mitem_quit_activate (GtkMenuItem * menuitem, gpointer user_data)
2212
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_quit_activate()"
2213
gboolean ignore = TRUE;
2215
g_signal_emit_by_name ((GtkObject *) xvc_ctrl_main_window,
2216
"destroy_event", 0, &ignore);
2217
#undef DEBUGFUNCTION
2221
on_xvc_result_dialog_key_press_event (GtkWidget * widget, GdkEvent * event)
2223
#define DEBUGFUNCTION "on_xvc_result_dialog_key_press_event()"
2224
GdkEventKey *kevent = NULL;
2228
kevent = (GdkEventKey *) event;
2231
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
2234
if (kevent->keyval == 65470) {
2238
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
2241
// Tell calling code that we have not handled this event; pass it on.
2243
#undef DEBUGFUNCTION
2247
on_xvc_result_dialog_select_filename_button_clicked (GtkButton * button,
2250
#define DEBUGFUNCTION "on_xvc_result_select_filename_button_clicked()"
2253
GladeXML *xml = NULL;
2254
GtkWidget *w = NULL, *dialog = NULL;
2257
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
2260
// load the interface
2261
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_save_filechooserdialog", NULL);
2263
// connect the signals in the interface
2264
glade_xml_signal_autoconnect (xml);
2266
dialog = glade_xml_get_widget (xml, "xvc_save_filechooserdialog");
2268
gtk_window_set_title (GTK_WINDOW (dialog), "Save Video As:");
2270
result = gtk_dialog_run (GTK_DIALOG (dialog));
2272
if (result == GTK_RESPONSE_OK) {
2274
gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
2276
if (xvc_result_dialog != NULL) {
2278
xml = glade_get_widget_tree (GTK_WIDGET (xvc_result_dialog));
2282
w = glade_xml_get_widget (xml, "xvc_result_dialog_filename_label");
2285
gtk_label_set_text (GTK_LABEL (w), target_file_name);
2288
w = glade_xml_get_widget (xml, "xvc_result_dialog_save_button");
2290
printf ("setting save button sensitive\n");
2291
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2295
gtk_widget_destroy (dialog);
2298
printf ("%s %s: Leaving with filename %s\n", DEBUGFILE, DEBUGFUNCTION,
2301
#undef DEBUGFUNCTION
2305
on_xvc_ctrl_stop_toggle_toggled (GtkToggleToolButton * button,
2308
#define DEBUGFUNCTION "on_xvc_ctrl_stop_toggle_toggled()"
2311
printf ("%s %s: stopp button toggled (%i)\n", DEBUGFILE, DEBUGFUNCTION,
2312
gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON
2316
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button))) {
2317
if (recording_thread_running)
2318
xvc_capture_stop_signal (FALSE);
2320
GladeXML *xml = NULL;
2321
GtkWidget *w = NULL;
2323
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2325
w = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
2327
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (w)))
2328
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON
2334
#undef DEBUGFUNCTION
2338
on_xvc_ctrl_record_toggle_toggled (GtkToggleToolButton * button,
2341
#define DEBUGFUNCTION "on_xvc_ctrl_record_toggle_toggled()"
2343
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button))) {
2344
xvc_capture_start ();
2348
#undef DEBUGFUNCTION
2352
on_xvc_ctrl_pause_toggle_toggled (GtkToggleToolButton * button,
2355
#define DEBUGFUNCTION "on_xvc_ctrl_pause_toggle_toggled()"
2356
struct timeval curr_time;
2357
GladeXML *xml = NULL;
2358
GtkWidget *w = NULL;
2359
Job *jobp = xvc_job_ptr ();
2360
XVC_CapTypeOptions *target = NULL;
2361
XVC_AppData *app = xvc_appdata_ptr ();
2364
if (app->current_mode > 0)
2365
target = &(app->multi_frame);
2367
#endif // USE_FFMPEG
2368
target = &(app->single_frame);
2370
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2374
printf ("%s %s: is paused? (%d)\n", DEBUGFILE, DEBUGFUNCTION,
2375
gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON
2379
if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button))) {
2380
gettimeofday (&curr_time, NULL);
2381
pause_time = curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000;
2382
if ((jobp->state & VC_REC) != 0) {
2383
time_captured += (pause_time - start_time);
2387
// stop timer handling only if max_time is configured
2388
if (target->time != 0) {
2390
g_source_remove (stop_timer_id);
2392
xvc_job_merge_and_remove_state (VC_PAUSE, VC_STOP);
2395
w = glade_xml_get_widget (xml, "xvc_ctrl_stop_toggle");
2397
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (w), FALSE);
2399
if (app->current_mode == 0 && jobp->state & VC_REC) {
2400
if (target->frames == 0
2401
|| jobp->pic_no <= (target->frames - target->step)) {
2402
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
2404
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2406
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
2408
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2411
if (jobp->pic_no >= target->step) {
2412
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2414
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2417
w = glade_xml_get_widget (xml, "xvc_ctrl_edit_button");
2419
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2422
xvc_job_remove_state (VC_PAUSE | VC_STEP);
2423
// step is always only active if a running recording session is
2425
// so releasing pause can always deactivate it
2427
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
2429
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2430
// the following only when recording is going on (not when just
2433
if (jobp->state & VC_REC) {
2434
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
2436
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2438
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2440
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2442
w = glade_xml_get_widget (xml, "xvc_ctrl_edit_button");
2444
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2446
xvc_job_merge_state (VC_STOP);
2450
gettimeofday (&curr_time, NULL);
2451
start_time = curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000;
2452
// restart timer handling only if max_time is configured
2453
if (target->time != 0) {
2454
// install a timer which stops recording
2455
// we need milli secs ..
2456
stop_timer_id = g_timeout_add ((guint32)
2457
(target->time * 1000 -
2458
time_captured), (GtkFunction)
2459
timer_stop_recording, jobp);
2463
#undef DEBUGFUNCTION
2467
on_xvc_ctrl_step_button_clicked (GtkButton * button, gpointer user_data)
2469
#define DEBUGFUNCTION "on_xvc_ctrl_step_button_clicked()"
2470
GladeXML *xml = NULL;
2471
GtkWidget *w = NULL;
2472
Job *jobp = xvc_job_ptr ();
2473
int pic_no = jobp->pic_no;
2474
XVC_CapTypeOptions *target = NULL;
2475
XVC_AppData *app = xvc_appdata_ptr ();
2478
if (app->current_mode > 0)
2479
target = &(app->multi_frame);
2481
#endif // USE_FFMPEG
2482
target = &(app->single_frame);
2484
if (app->current_mode == 0) {
2485
if (!(jobp->state & (VC_PAUSE | VC_REC)))
2488
xvc_job_merge_state (VC_STEP);
2490
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2494
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2496
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2499
if (target->frames > 0 && pic_no >= (target->frames - target->step)) {
2500
if (pic_no > (target->frames - target->step)) {
2501
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
2503
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2506
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
2508
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2511
#undef DEBUGFUNCTION
2515
on_xvc_ctrl_filename_button_clicked (GtkButton * button, gpointer user_data)
2517
#define DEBUGFUNCTION "on_xvc_ctrl_filename_button_clicked()"
2518
GladeXML *xml = NULL;
2519
GtkWidget *w = NULL;
2520
Job *jobp = xvc_job_ptr ();
2521
XVC_CapTypeOptions *target = NULL;
2522
XVC_AppData *app = xvc_appdata_ptr ();
2525
if (app->current_mode > 0)
2526
target = &(app->multi_frame);
2528
#endif // USE_FFMPEG
2529
target = &(app->single_frame);
2531
if (app->current_mode == 0) {
2532
if (jobp->pic_no != target->start_no
2533
&& ((jobp->state & VC_STOP) > 0 || (jobp->state & VC_PAUSE) > 0)) {
2534
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2537
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2539
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2541
jobp->pic_no = target->start_no;
2542
GtkChangeLabel (jobp->pic_no);
2545
if (jobp->movie_no != 0 && (jobp->state & VC_STOP) > 0) {
2547
jobp->pic_no = target->start_no;
2548
GtkChangeLabel (jobp->pic_no);
2551
#undef DEBUGFUNCTION
2555
on_xvc_ctrl_back_button_clicked (GtkButton * button, gpointer user_data)
2557
#define DEBUGFUNCTION "on_xvc_ctrl_back_button_clicked()"
2558
GladeXML *xml = NULL;
2559
GtkWidget *w = NULL;
2560
Job *jobp = xvc_job_ptr ();
2561
XVC_CapTypeOptions *target = NULL;
2562
XVC_AppData *app = xvc_appdata_ptr ();
2565
if (app->current_mode > 0)
2566
target = &(app->multi_frame);
2568
#endif // USE_FFMPEG
2569
target = &(app->single_frame);
2571
if (app->current_mode == 0) {
2572
if (jobp->pic_no >= target->step) {
2573
jobp->pic_no -= target->step;
2574
GtkChangeLabel (jobp->pic_no);
2577
"%s %s: back button active although picture number < step. this should never happen\n",
2578
DEBUGFILE, DEBUGFUNCTION);
2580
if (jobp->pic_no < target->step)
2581
gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
2583
if (target->frames == 0
2584
|| jobp->pic_no == (target->frames - target->step)) {
2585
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2588
if (jobp->state & VC_PAUSE) {
2589
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
2591
if (app->current_mode == 0)
2592
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2595
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
2597
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2600
if (jobp->movie_no > 0) {
2601
jobp->movie_no -= 1;
2602
GtkChangeLabel (jobp->pic_no);
2605
"%s %s: back button active although movie number == 0. this should never happen\n",
2606
DEBUGFILE, DEBUGFUNCTION);
2608
if (jobp->movie_no == 0)
2609
gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
2611
#undef DEBUGFUNCTION
2615
on_xvc_ctrl_forward_button_clicked (GtkButton * button, gpointer user_data)
2617
#define DEBUGFUNCTION "on_xvc_ctrl_forward_button_clicked()"
2618
GladeXML *xml = NULL;
2619
GtkWidget *w = NULL;
2620
Job *jobp = xvc_job_ptr ();
2621
XVC_CapTypeOptions *target = NULL;
2622
XVC_AppData *app = xvc_appdata_ptr ();
2625
if (app->current_mode > 0)
2626
target = &(app->multi_frame);
2628
#endif // USE_FFMPEG
2629
target = &(app->single_frame);
2631
if (app->current_mode == 0) {
2632
jobp->pic_no += target->step;
2633
GtkChangeLabel (jobp->pic_no);
2635
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2638
if (jobp->pic_no == target->step) {
2639
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2642
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2644
if (target->frames > 0
2645
&& jobp->pic_no > (target->frames - target->step)) {
2646
if (jobp->pic_no >= (target->frames - target->step)) {
2647
w = glade_xml_get_widget (xml, "xvc_ctrl_step_button");
2649
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2652
w = glade_xml_get_widget (xml, "xvc_ctrl_forward_button");
2654
gtk_widget_set_sensitive (GTK_WIDGET (w), FALSE);
2658
jobp->movie_no += 1;
2659
GtkChangeLabel (jobp->pic_no);
2660
if (jobp->movie_no == 1) {
2661
xml = glade_get_widget_tree (GTK_WIDGET (xvc_ctrl_main_window));
2664
w = glade_xml_get_widget (xml, "xvc_ctrl_back_button");
2667
gtk_widget_set_sensitive (GTK_WIDGET (w), TRUE);
2670
#undef DEBUGFUNCTION
2674
on_xvc_ctrl_lock_toggle_toggled (GtkToggleToolButton *
2675
togglebutton, gpointer user_data)
2677
#define DEBUGFUNCTION "on_xvc_ctrl_lock_toggle_toggled()"
2678
GtkTooltips *tooltips;
2679
XRectangle *frame_rectangle = NULL;
2680
int x, y, pheight, pwidth;
2682
tooltips = gtk_tooltips_new ();
2684
if (gtk_toggle_tool_button_get_active (togglebutton)) {
2685
xvc_set_frame_locked (1); /* button pressed = move frame with
2687
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (togglebutton), tooltips,
2688
_("Detach selection frame"),
2689
_("Detach selection frame"));
2691
gtk_window_set_gravity (GTK_WINDOW (xvc_ctrl_main_window),
2692
GDK_GRAVITY_NORTH_WEST);
2693
gtk_window_get_position (GTK_WINDOW (xvc_ctrl_main_window), &x, &y);
2694
gtk_window_get_size (GTK_WINDOW (xvc_ctrl_main_window), &pwidth,
2696
gtk_window_set_gravity (GTK_WINDOW (xvc_ctrl_main_window),
2697
GDK_GRAVITY_STATIC);
2698
gtk_window_get_position (GTK_WINDOW (xvc_ctrl_main_window), &x, &y);
2699
gtk_window_get_size (GTK_WINDOW (xvc_ctrl_main_window), &pwidth,
2703
y += pheight + FRAME_OFFSET + FRAME_WIDTH;
2706
frame_rectangle = xvc_get_capture_area ();
2707
xvc_change_gtk_frame (x, y, frame_rectangle->width,
2708
frame_rectangle->height, FALSE, TRUE);
2710
xvc_set_frame_locked (0);
2711
gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (togglebutton), tooltips,
2712
_("Attach selection frame"),
2713
_("Attach selection frame"));
2715
#undef DEBUGFUNCTION
2719
on_xvc_ctrl_select_toggle_toggled (GtkToggleToolButton *
2720
togglebutton, gpointer user_data)
2722
#define DEBUGFUNCTION "on_xvc_ctrl_select_toggle_toggled()"
2723
Job *jobp = xvc_job_ptr ();
2724
XVC_AppData *app = xvc_appdata_ptr ();
2726
if (gtk_toggle_tool_button_get_active (togglebutton)) {
2727
Display *display = xvc_frame_get_capture_display ();
2729
Window root = None, target_win = None, temp = None;
2732
int x_down, y_down, x_up, y_up, x, y;
2736
XVC_CapTypeOptions *target = NULL;
2739
if (app->current_mode > 0)
2740
target = &(app->multi_frame);
2742
#endif // USE_FFMPEG
2743
target = &(app->single_frame);
2747
root = DefaultRootWindow (display);
2748
cursor = XCreateFontCursor (display, XC_crosshair);
2750
gcv.background = XBlackPixel (display, XDefaultScreen (display));
2751
gcv.foreground = XWhitePixel (display, XDefaultScreen (display));
2752
gcv.function = GXinvert;
2753
gcv.plane_mask = gcv.background ^ gcv.foreground;
2754
gcv.subwindow_mode = IncludeInferiors;
2755
gc = XCreateGC (display, root,
2756
GCBackground | GCForeground | GCFunction |
2757
GCPlaneMask | GCSubwindowMode, &gcv);
2761
if (XGrabPointer (display, root, False,
2762
PointerMotionMask | ButtonPressMask |
2763
ButtonReleaseMask, GrabModeSync,
2764
GrabModeAsync, root, cursor, CurrentTime)
2766
fprintf (stderr, "%s %s: Can't grab mouse!\n", DEBUGFILE,
2770
x_down = y_down = x_up = y_up = width = height = 0;
2772
while (buttons < 2) {
2773
// allow pointer events
2774
XAllowEvents (display, SyncPointer, CurrentTime);
2775
// search in the queue for button events
2776
XWindowEvent (display, root,
2777
PointerMotionMask | ButtonPressMask |
2778
ButtonReleaseMask, &event);
2779
switch (event.type) {
2781
x_down = event.xbutton.x;
2782
y_down = event.xbutton.y;
2783
target_win = event.xbutton.subwindow; // window selected
2785
if (target_win == None) {
2791
x_up = event.xbutton.x;
2792
y_up = event.xbutton.y;
2798
// button is pressed
2799
if (x_down > event.xbutton.x) {
2800
width = x_down - event.xbutton.x + 1;
2801
x = event.xbutton.x;
2803
width = event.xbutton.x - x_down + 1;
2806
if (y_down > event.xbutton.y) {
2807
height = y_down - event.xbutton.y + 1;
2808
y = event.xbutton.y;
2810
height = event.xbutton.y - y_down + 1;
2813
xvc_change_gtk_frame (x, y, width, height, FALSE, TRUE);
2814
// the previous call changes the frame edges, which are
2815
// gtk windows. we need to call the gtk main loop for
2816
// them to be drawn properly within this callback
2817
while (gtk_events_pending ())
2818
gtk_main_iteration ();
2823
// if (width > 0) // remove old frame
2824
// xvc_change_gtk_frame (x, y, width, height, FALSE, TRUE);
2826
XUngrabPointer (display, CurrentTime); // Done with pointer
2828
XFreeCursor (display, cursor);
2829
XFreeGC (display, gc);
2831
if ((x_down != x_up) && (y_down != y_up)) {
2832
// an individual frame was selected
2833
if (x_up < x_down) {
2834
width = x_down - x_up + 2;
2837
width = x_up - x_down + 2;
2840
if (y_up < y_down) {
2841
height = y_down - y_up + 2;
2844
height = y_up - y_down + 2;
2847
xvc_appdata_set_window_attributes (target_win);
2848
app->area->width = width;
2849
app->area->height = height;
2851
if (target_win != root) {
2852
// get the real window
2853
target_win = XmuClientWindow (display, target_win);
2855
xvc_appdata_set_window_attributes (target_win);
2856
XTranslateCoordinates (display, target_win, root, 0, 0, &x, &y,
2858
app->area->width = app->win_attr.width;
2859
app->area->height = app->win_attr.height;
2865
xvc_change_gtk_frame (x, y, app->area->width,
2866
app->area->height, xvc_is_frame_locked (), FALSE);
2868
// update colors and colormap
2869
xvc_job_set_colors ();
2871
if (app->flags & FLG_RUN_VERBOSE) {
2872
fprintf (stderr, "%s %s: color_table first entry: 0x%.8X\n",
2873
DEBUGFILE, DEBUGFUNCTION,
2874
*(u_int32_t *) jobp->color_table);
2876
xvc_job_set_save_function (jobp->target);
2879
printf ("%s%s: new visual: %d\n", DEBUGFILE, DEBUGFUNCTION,
2880
app->win_attr.visual->class);
2884
gtk_toggle_tool_button_set_active (togglebutton, FALSE);
2886
#undef DEBUGFUNCTION
2890
on_xvc_ctrl_m1_mitem_animate_activate (GtkButton * button, gpointer user_data)
2892
#define DEBUGFUNCTION "on_xvc_ctrl_m1_mitem_animate_activate()"
2893
Job *jobp = xvc_job_ptr ();
2894
XVC_CapTypeOptions *target = NULL;
2895
XVC_AppData *app = xvc_appdata_ptr ();
2898
if (app->current_mode > 0)
2899
target = &(app->multi_frame);
2901
#endif // USE_FFMPEG
2902
target = &(app->single_frame);
2904
if (!app->current_mode) {
2905
xvc_command_execute (target->play_cmd, 1, 0,
2906
jobp->file, target->start_no, jobp->pic_no,
2907
app->area->width, app->area->height, target->fps);
2909
xvc_command_execute (target->play_cmd, 2,
2910
jobp->movie_no, jobp->file, target->start_no,
2911
jobp->pic_no, app->area->width,
2912
app->area->height, target->fps);
2914
#undef DEBUGFUNCTION
2918
on_xvc_ctrl_edit_button_clicked (GtkToolButton * button, gpointer user_data)
2920
#define DEBUGFUNCTION "on_xvc_ctrl_edit_button_clicked()"
2921
Job *jobp = xvc_job_ptr ();
2922
XVC_CapTypeOptions *target = NULL;
2923
XVC_AppData *app = xvc_appdata_ptr ();
2926
if (app->current_mode > 0)
2927
target = &(app->multi_frame);
2929
#endif // USE_FFMPEG
2930
target = &(app->single_frame);
2932
if (!app->current_mode) {
2933
xvc_command_execute (target->edit_cmd, 2,
2934
jobp->pic_no, jobp->file, target->start_no,
2935
jobp->pic_no, app->area->width,
2936
app->area->height, target->fps);
2938
xvc_command_execute (target->edit_cmd, 2,
2939
jobp->movie_no, jobp->file, target->start_no,
2940
jobp->pic_no, app->area->width,
2941
app->area->height, target->fps);
2943
#undef DEBUGFUNCTION
2947
on_xvc_ctrl_filename_button_button_press_event (GtkWidget * widget,
2950
#define DEBUGFUNCTION "on_xvc_ctrl_filename_button_press_event()"
2951
gboolean is_sensitive = FALSE;
2952
GdkEventButton *bevent = NULL;
2956
bevent = (GdkEventButton *) event;
2958
// FIXME: changing from menu sensitive or not to button sensitive or
2959
// not ... make sure that that's what I set elsewhere, too.
2960
g_object_get ((gpointer) widget, (gchar *) "sensitive", &is_sensitive,
2962
if (bevent->button == (guint) 3 && is_sensitive == TRUE) {
2964
g_assert (xvc_ctrl_m1);
2966
gtk_menu_popup (GTK_MENU (xvc_ctrl_m1), NULL, NULL,
2967
position_popup_menu, widget, bevent->button,
2969
// Tell calling code that we have handled this event; the buck
2973
// Tell calling code that we have not handled this event; pass it on.
2975
#undef DEBUGFUNCTION
2978
// this handles the shortcut keybindings for the menu
2980
on_xvc_ctrl_main_window_key_press_event (GtkWidget * widget, GdkEvent * event)
2982
#define DEBUGFUNCTION "on_xvc_ctrl_main_window_key_press_event()"
2983
gboolean is_sensitive = FALSE;
2984
GtkWidget *button = NULL, *mitem = NULL;
2985
GdkEventKey *kevent = NULL;
2986
GladeXML *xml = NULL;
2990
kevent = (GdkEventKey *) event;
2993
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
2996
xml = glade_get_widget_tree (xvc_ctrl_main_window);
2998
button = glade_xml_get_widget (xml, "xvc_ctrl_filename_button");
3001
g_object_get ((gpointer) button, (gchar *) "sensitive", &is_sensitive,
3004
if (kevent->keyval == 112 && kevent->state == 4) {
3005
xml = glade_get_widget_tree (xvc_ctrl_m1);
3007
mitem = glade_xml_get_widget (xml, "xvc_ctrl_m1_mitem_preferences");
3009
gtk_menu_item_activate (GTK_MENU_ITEM (mitem));
3011
} else if (kevent->keyval == 113 && kevent->state == 4) {
3012
xml = glade_get_widget_tree (xvc_ctrl_m1);
3014
mitem = glade_xml_get_widget (xml, "xvc_ctrl_m1_mitem_quit");
3016
gtk_menu_item_activate (GTK_MENU_ITEM (mitem));
3018
} else if (kevent->keyval == 65470
3019
|| (kevent->state == 4 && kevent->keyval == 104)) {
3020
xml = glade_get_widget_tree (xvc_ctrl_m1);
3022
mitem = glade_xml_get_widget (xml, "xvc_ctrl_m1_mitem_help");
3024
gtk_menu_item_activate (GTK_MENU_ITEM (mitem));
3028
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
3031
// Tell calling code that we have not handled this event; pass it on.
3033
#undef DEBUGFUNCTION
3037
on_xvc_about_main_window_close (GtkAboutDialog * window, gpointer user_data)
3039
gtk_widget_destroy (GTK_WIDGET (window));
3043
on_xvc_ctrl_m1_mitem_about_activate (GtkMenuItem * menuitem, gpointer user_data)
3045
GladeXML *xml = NULL;
3047
// load the interface
3048
xml = glade_xml_new (XVC_GLADE_FILE, "xvc_about_main_window", NULL);
3050
// connect the signals in the interface
3051
glade_xml_signal_autoconnect (xml);
3055
on_xvc_ti_stop_selected (GtkMenuItem * menuitem, gpointer user_data)
3057
GtkWidget *button = NULL;
3058
GladeXML *xml = NULL;
3060
xml = glade_get_widget_tree (xvc_ctrl_main_window);
3062
button = glade_xml_get_widget (xml, "xvc_ctrl_stop_toggle");
3065
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (button), TRUE);
3069
on_xvc_ti_pause_selected (GtkMenuItem * menuitem, gpointer user_data)
3071
GtkWidget *button = NULL;
3072
GladeXML *xml = NULL;
3074
xml = glade_get_widget_tree (xvc_ctrl_main_window);
3076
button = glade_xml_get_widget (xml, "xvc_ctrl_pause_toggle");
3079
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (button),
3080
gtk_check_menu_item_get_active
3081
(GTK_CHECK_MENU_ITEM (menuitem)));
3084
#endif // DOXYGEN_SHOULD_SKIP_THIS