~ubuntu-branches/ubuntu/maverick/zapping/maverick

« back to all changes in this revision

Viewing changes to src/zapping.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-03-08 23:19:08 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050308231908-oip7rfv6lcmo8c0e
Tags: 0.9.2-2ubuntu1
Rebuilt for Python transition (2.3 -> 2.4)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Zapping (TV viewer for the Gnome Desktop)
 
3
 *
 
4
 * Copyright (C) 2004 Michael H. Schimek
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 */
 
20
 
 
21
/* $Id: zapping.c,v 1.11 2005/01/19 04:16:24 mschimek Exp $ */
 
22
 
 
23
#include "site_def.h"
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#  include "config.h"
 
27
#endif
 
28
 
 
29
#include "audio.h"
 
30
#include "interface.h"
 
31
#include "v4linterface.h"
 
32
#include "plugins.h"
 
33
#include "properties-handler.h"
 
34
#include "subtitle.h"
 
35
#include "zconf.h"
 
36
#include "zmisc.h"
 
37
#include "zgconf.h"
 
38
#include "zvideo.h"
 
39
#include "zapping.h"
 
40
#include "zvbi.h"
 
41
#include "remote.h"
 
42
 
 
43
static GObjectClass *           parent_class;
 
44
 
 
45
static void
 
46
quit_action                     (GtkAction *            action _unused_,
 
47
                                 Zapping *              z)
 
48
{
 
49
  on_python_command1 (GTK_WIDGET (z), "zapping.quit()");
 
50
}
 
51
 
 
52
static void
 
53
preferences_action              (GtkAction *            action _unused_,
 
54
                                 Zapping *              z)
 
55
 
 
56
{
 
57
  on_python_command1 (GTK_WIDGET (z), "zapping.properties()");
 
58
}
 
59
 
 
60
static void
 
61
plugins_action                  (GtkAction *            action _unused_,
 
62
                                 Zapping *              z)
 
63
{
 
64
  on_python_command1 (GTK_WIDGET (z), "zapping.plugin_properties()");
 
65
}
 
66
 
 
67
static void
 
68
channel_editor_action           (GtkAction *            action _unused_,
 
69
                                 Zapping *              z)
 
70
{
 
71
  on_python_command1 (GTK_WIDGET (z), "zapping.channel_editor()");
 
72
}
 
73
 
 
74
static void
 
75
window_action                   (GtkAction *            action _unused_,
 
76
                                 Zapping *              z)
 
77
{
 
78
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('window')");
 
79
}
 
80
 
 
81
static void
 
82
fullscreen_action               (GtkAction *            action _unused_,
 
83
                                 Zapping *              z)
 
84
{
 
85
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('fullscreen')");
 
86
}
 
87
 
 
88
static void
 
89
background_action               (GtkAction *            action _unused_,
 
90
                                 Zapping *              z)
 
91
{
 
92
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('background')");
 
93
}
 
94
 
 
95
#if 0 /* Ok that's nice, but how can we SET current?
 
96
         gtk_toggle_action active? */
 
97
 
 
98
static void
 
99
display_mode_action             (GtkRadioAction *       action,
 
100
                                 GtkRadioAction *       current _unused_,
 
101
                                 Zapping *              z)
 
102
{
 
103
  gint value;
 
104
 
 
105
  value = gtk_radio_action_get_current_value (action);
 
106
 
 
107
  switch ((display_mode) value)
 
108
    {
 
109
    case DISPLAY_MODE_WINDOW:
 
110
      on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('window')");
 
111
      break;
 
112
 
 
113
    case DISPLAY_MODE_FULLSCREEN:
 
114
      on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('fullscreen')");
 
115
      break;
 
116
 
 
117
    case DISPLAY_MODE_BACKGROUND:
 
118
      on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('background')");
 
119
      break;
 
120
 
 
121
    default:
 
122
      break;
 
123
    }
 
124
}
 
125
 
 
126
#endif
 
127
 
 
128
static void
 
129
overlay_action                  (GtkAction *            action _unused_,
 
130
                                 Zapping *              z)
 
131
{
 
132
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('preview')");
 
133
}
 
134
 
 
135
static void
 
136
capture_action                  (GtkAction *            action _unused_,
 
137
                                 Zapping *              z)
 
138
{
 
139
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('capture')");
 
140
}
 
141
 
 
142
static void
 
143
teletext_action                 (GtkAction *            action _unused_,
 
144
                                 Zapping *              z)
 
145
{
 
146
  on_python_command1 (GTK_WIDGET (z), "zapping.switch_mode('teletext')");
 
147
}
 
148
 
 
149
static void
 
150
restore_video_action            (GtkAction *            action _unused_,
 
151
                                 Zapping *              z)
 
152
{
 
153
  on_python_command1 (GTK_WIDGET (z), "zapping.toggle_mode()");
 
154
}
 
155
 
 
156
static void
 
157
new_teletext_action             (GtkAction *            action _unused_,
 
158
                                 Zapping *              z)
 
159
{
 
160
  on_python_command1 (GTK_WIDGET (z), "zapping.ttx_open_new()");
 
161
}
 
162
 
 
163
static void
 
164
mute_action                     (GtkToggleAction *      toggle_action,
 
165
                                 Zapping *              z _unused_)
 
166
{
 
167
  gboolean mute;
 
168
 
 
169
  mute = gtk_toggle_action_get_active (toggle_action);
 
170
  set_mute (mute, TRUE, TRUE);
 
171
}
 
172
 
 
173
static void
 
174
subtitles_action                (GtkToggleAction *      toggle_action,
 
175
                                 Zapping *              z _unused_)
 
176
{
 
177
  python_command_printf (NULL, "zapping.closed_caption(%u)",
 
178
                         gtk_toggle_action_get_active (toggle_action));
 
179
}
 
180
 
 
181
static void
 
182
zconf_hook_subtitles            (const gchar *          key _unused_,
 
183
                                 gpointer               new_value_ptr,
 
184
                                 gpointer               user_data)
 
185
{
 
186
  gboolean active = * (gboolean *) new_value_ptr;
 
187
  GtkToggleAction *toggle_action = user_data;
 
188
 
 
189
  if (active != gtk_toggle_action_get_active (toggle_action))
 
190
    gtk_toggle_action_set_active (toggle_action, active);
 
191
}
 
192
 
 
193
static void
 
194
view_menu                       (Zapping *              z,
 
195
                                 gboolean               view)
 
196
{
 
197
  BonoboDockItem *dock_item;
 
198
 
 
199
  if (view && z->decorated)
 
200
    {
 
201
      /* Adding a hidden menu is impossible, we have to add when the
 
202
         menu becomes first visible. */
 
203
      if (!z->menubar_added)
 
204
        {
 
205
          z->menubar_added = TRUE;
 
206
          gnome_app_set_menus (&z->app, z->menubar);
 
207
        }
 
208
 
 
209
      dock_item = gnome_app_get_dock_item_by_name
 
210
        (&z->app, GNOME_APP_MENUBAR_NAME);
 
211
 
 
212
      gtk_widget_show (GTK_WIDGET (dock_item));
 
213
    }
 
214
  else if (z->menubar_added)
 
215
    {
 
216
      dock_item = gnome_app_get_dock_item_by_name
 
217
        (&z->app, GNOME_APP_MENUBAR_NAME);
 
218
 
 
219
      gtk_widget_hide (GTK_WIDGET (dock_item));
 
220
    }
 
221
 
 
222
  gtk_widget_queue_resize (GTK_WIDGET (z));
 
223
}
 
224
 
 
225
static void
 
226
view_toolbar                    (Zapping *              z,
 
227
                                 gboolean               view)
 
228
{
 
229
  BonoboDockItem *dock_item;
 
230
 
 
231
  if (view && z->decorated)
 
232
    {
 
233
      /* Same as above. */
 
234
      if (!z->toolbar_added)
 
235
        {
 
236
          z->toolbar_added = TRUE;
 
237
          gnome_app_set_toolbar (&z->app, z->toolbar);
 
238
        }
 
239
 
 
240
      dock_item = gnome_app_get_dock_item_by_name
 
241
        (&z->app, GNOME_APP_TOOLBAR_NAME);
 
242
 
 
243
      gtk_widget_show (GTK_WIDGET (dock_item));
 
244
    }
 
245
  else if (z->toolbar_added)
 
246
    {
 
247
      dock_item = gnome_app_get_dock_item_by_name
 
248
        (&z->app, GNOME_APP_TOOLBAR_NAME);
 
249
 
 
250
      gtk_widget_hide (GTK_WIDGET (dock_item));
 
251
    }
 
252
 
 
253
  gtk_widget_queue_resize (GTK_WIDGET (z));
 
254
}
 
255
 
 
256
void
 
257
zapping_view_appbar             (Zapping *              z,
 
258
                                 gboolean               view)
 
259
{
 
260
  if (view && z->decorated)
 
261
    {
 
262
      /* Same as above. */
 
263
      if (!z->appbar_added)
 
264
        {
 
265
          z->appbar_added = TRUE;
 
266
          gnome_app_set_statusbar (&z->app, GTK_WIDGET (z->appbar));
 
267
        }
 
268
      else
 
269
        {
 
270
          gtk_widget_show (GTK_WIDGET (z->appbar));
 
271
        }
 
272
    }
 
273
  else if (z->appbar_added)
 
274
    {
 
275
      gtk_widget_hide (GTK_WIDGET (z->appbar));
 
276
    }
 
277
 
 
278
  gtk_widget_queue_resize (GTK_WIDGET (z));
 
279
}
 
280
 
 
281
static void
 
282
view_menu_action                (GtkToggleAction *      toggle_action,
 
283
                                 Zapping *              z)
 
284
{
 
285
  view_menu (z, gtk_toggle_action_get_active (toggle_action));
 
286
}
 
287
 
 
288
static void
 
289
view_toolbar_action             (GtkToggleAction *      toggle_action,
 
290
                                 Zapping *              z)
 
291
{
 
292
  view_toolbar (z, gtk_toggle_action_get_active (toggle_action));
 
293
}
 
294
 
 
295
static PyObject *
 
296
py_hide_controls                (PyObject *             self _unused_,
 
297
                                 PyObject *             args)
 
298
{
 
299
  int hide;
 
300
  GtkToggleAction *toggle_action;
 
301
 
 
302
  if (!zapping)
 
303
    py_return_false;
 
304
 
 
305
  hide = 2; /* toggle */
 
306
 
 
307
  if (!ParseTuple (args, "|i", &hide))
 
308
    g_error ("zapping.hide_controls(|i)");
 
309
 
 
310
  toggle_action = GTK_TOGGLE_ACTION
 
311
    (gtk_action_group_get_action (zapping->generic_action_group, "ViewMenu"));
 
312
 
 
313
  if (hide > 1)
 
314
    hide = !!gtk_toggle_action_get_active (toggle_action);
 
315
 
 
316
  gtk_toggle_action_set_active (toggle_action, !hide);
 
317
 
 
318
  toggle_action = GTK_TOGGLE_ACTION
 
319
    (gtk_action_group_get_action (zapping->generic_action_group,
 
320
                                  "ViewToolbar"));
 
321
 
 
322
  gtk_toggle_action_set_active (toggle_action, !hide);
 
323
 
 
324
  py_return_none;
 
325
}
 
326
 
 
327
static void
 
328
keep_window_on_top_action       (GtkToggleAction *      toggle_action,
 
329
                                 Zapping *              z)
 
330
{
 
331
  gboolean keep;
 
332
 
 
333
  keep = gtk_toggle_action_get_active (toggle_action);
 
334
  x11_window_on_top (GTK_WINDOW (z), keep);
 
335
}
 
336
 
 
337
static PyObject *
 
338
py_keep_on_top                  (PyObject *             self _unused_,
 
339
                                 PyObject *             args)
 
340
{
 
341
  int keep;
 
342
 
 
343
  if (!zapping)
 
344
    py_return_false;
 
345
 
 
346
  keep = 2; /* toggle */
 
347
 
 
348
  if (!ParseTuple (args, "|i", &keep))
 
349
    g_error ("zapping.keep_on_top(|i)");
 
350
 
 
351
  if (have_wm_hints)
 
352
    {
 
353
      GtkToggleAction *action;
 
354
 
 
355
      action = GTK_TOGGLE_ACTION (gtk_action_group_get_action
 
356
                                  (zapping->generic_action_group,
 
357
                                   "KeepWindowOnTop"));
 
358
      if (keep > 1)
 
359
        keep = !gtk_toggle_action_get_active (action);
 
360
 
 
361
      gtk_toggle_action_set_active (action, keep);
 
362
    }
 
363
 
 
364
  py_return_none;
 
365
}
 
366
 
 
367
static void
 
368
help_contents_action            (GtkAction *            action _unused_,
 
369
                                 Zapping *              z _unused_)
 
370
{
 
371
  z_help_display (NULL, "zapping", NULL);
 
372
}
 
373
 
 
374
static void
 
375
about_action                    (GtkAction *            action _unused_,
 
376
                                 Zapping *              z)
 
377
{
 
378
  on_python_command1 (GTK_WIDGET (z), "zapping.about()");
 
379
}
 
380
 
 
381
static void
 
382
channel_up_action               (GtkAction *            action _unused_,
 
383
                                 Zapping *              z)
 
384
{
 
385
  on_python_command1 (GTK_WIDGET (z), "zapping.channel_up()");
 
386
}
 
387
 
 
388
static void
 
389
channel_down_action             (GtkAction *            action _unused_,
 
390
                                 Zapping *              z)
 
391
{
 
392
  on_python_command1 (GTK_WIDGET (z), "zapping.channel_down()");
 
393
}
 
394
 
 
395
static void
 
396
controls_action                 (GtkAction *            action _unused_,
 
397
                                 Zapping *              z)
 
398
{
 
399
  on_python_command1 (GTK_WIDGET (z), "zapping.control_box()");
 
400
}
 
401
 
 
402
static GtkActionEntry
 
403
generic_actions [] = {
 
404
  { "FileSubmenu", NULL, N_("_File"), NULL, NULL, NULL },
 
405
  { "Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (quit_action) },
 
406
  { "EditSubmenu", NULL, N_("_Edit"), NULL, NULL, NULL },
 
407
  { "Preferences", GTK_STOCK_PREFERENCES, NULL, NULL,
 
408
    NULL, G_CALLBACK (preferences_action) },
 
409
  { "Plugins", NULL, N_("P_lugins"), NULL,
 
410
    NULL, G_CALLBACK (plugins_action) },
 
411
  { "ChannelEditor", NULL /* 2.6 GTK_STOCK_EDIT */, N_("_Channels"), NULL,
 
412
    NULL, G_CALLBACK (channel_editor_action) },
 
413
  { "ViewSubmenu", NULL, N_("_View"), NULL, NULL, NULL },
 
414
  { "Window", GTK_STOCK_EXECUTE, N_("_Window"), "<Control>w",
 
415
    NULL, G_CALLBACK (window_action) },
 
416
  { "Fullscreen", GTK_STOCK_EXECUTE, N_("_Fullscreen"), "<Control>f",
 
417
    NULL, G_CALLBACK (fullscreen_action) },
 
418
  { "Background", GTK_STOCK_EXECUTE, N_("_Background"), "<Control>b",
 
419
    NULL, G_CALLBACK (background_action) },
 
420
  { "Overlay", GTK_STOCK_EXECUTE, N_("_Overlay mode"), "<Control>o",
 
421
    NULL, G_CALLBACK (overlay_action) },
 
422
  { "Capture", GTK_STOCK_EXECUTE, N_("_Capture mode"), "<Control>c",
 
423
    NULL, G_CALLBACK (capture_action) },
 
424
  { "ChannelsSubmenu", NULL, N_("_Channels"), NULL, NULL, NULL },
 
425
  { "HelpSubmenu", NULL, N_("_Help"), NULL, NULL, NULL },
 
426
  { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1",
 
427
    NULL, G_CALLBACK (help_contents_action) },
 
428
  { "About", GNOME_STOCK_ABOUT, N_("_About"), NULL,
 
429
    NULL, G_CALLBACK (about_action) },
 
430
  { "PopupSubmenu", NULL, "Dummy", NULL, NULL, NULL },
 
431
  { "Appearance", NULL, N_("Appearance"), NULL, NULL, NULL },
 
432
  { "ChannelUp", GTK_STOCK_GO_UP, N_("Ch. Up"), NULL,
 
433
    N_("Switch to higher channel"), G_CALLBACK (channel_up_action) },
 
434
  { "ChannelDown", GTK_STOCK_GO_DOWN, N_("Ch. Down"), NULL,
 
435
    N_("Switch to lower channel"), G_CALLBACK (channel_down_action) },
 
436
  { "Controls", GTK_STOCK_EXECUTE, N_("Controls"), NULL,
 
437
    N_("Change picture controls"), G_CALLBACK (controls_action) },
 
438
};
 
439
 
 
440
static GtkToggleActionEntry
 
441
generic_toggle_actions [] = {
 
442
  { "Mute", "zapping-mute", N_("_Mute"), "<Control>a",
 
443
    N_("Switch audio on or off"), G_CALLBACK (mute_action), FALSE },
 
444
  { "ViewMenu", NULL, N_("Menu"), NULL,
 
445
    NULL, G_CALLBACK (view_menu_action), TRUE },
 
446
  { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
 
447
    NULL, G_CALLBACK (view_toolbar_action), TRUE },
 
448
  { "KeepWindowOnTop", NULL, N_("Keep window on top"), NULL,
 
449
    NULL, G_CALLBACK (keep_window_on_top_action), FALSE },
 
450
};
 
451
 
 
452
#if 0 /* TODO */
 
453
static GtkRadioActionEntry
 
454
display_mode_radio_actions [] = {
 
455
  { "Window", NULL, N_("_Window"), "<Control>w",
 
456
    NULL, (gint) DISPLAY_MODE_WINDOW },
 
457
  { "Fullscreen", NULL, N_("_Fullscreen"), "<Control>f",
 
458
    NULL, (gint) DISPLAY_MODE_FULLSCREEN },
 
459
  { "Background", NULL, N_("_Background"), "<Control>b",
 
460
    NULL, (gint) DISPLAY_MODE_BACKGROUND },
 
461
};
 
462
#endif
 
463
 
 
464
static GtkActionEntry
 
465
vbi_actions [] = {
 
466
  { "TeletextSubmenu", NULL, N_("_Teletext"), NULL, NULL, NULL },
 
467
  { "SubtitlesSubmenu", NULL, N_("_Subtitles"), NULL, NULL, NULL },
 
468
  { "BookmarksSubmenu", NULL, N_("_Bookmarks"), NULL, NULL, NULL },
 
469
  { "Teletext", "zapping-teletext", N_("_Teletext"), "<Control>t",
 
470
    N_("Activate Teletext mode"), G_CALLBACK (teletext_action) },
 
471
  { "RestoreVideo", "zapping-video", N_("_Video"), "<Control>v",
 
472
    N_("Return to video mode"), G_CALLBACK (restore_video_action) },
 
473
  { "NewTeletext", NULL, N_("_New Teletext View"), "<Control>n",
 
474
    NULL, G_CALLBACK (new_teletext_action) },
 
475
};
 
476
 
 
477
static GtkToggleActionEntry
 
478
vbi_toggle_actions [] = {
 
479
  { "Subtitles", "zapping-subtitle", N_("_Subtitles"), "<Control>u",
 
480
    N_("Switch subtitles on or off"), G_CALLBACK (subtitles_action), FALSE },
 
481
};
 
482
 
 
483
static const char *
 
484
ui_description =
 
485
"<ui>"
 
486
" <menubar name='MainMenu'>"
 
487
"  <menu action='FileSubmenu'>"
 
488
"   <menuitem action='Quit'/>"
 
489
"  </menu>"
 
490
"  <menu action='EditSubmenu'>"
 
491
"   <menuitem action='Preferences'/>"
 
492
"   <menuitem action='Plugins'/>"
 
493
"   <menuitem action='ChannelEditor'/>"
 
494
"  </menu>"
 
495
"  <menu action='ViewSubmenu'>"
 
496
"   <menuitem action='Window'/>"
 
497
"   <menuitem action='Fullscreen'/>"
 
498
"   <menuitem action='Background'/>"
 
499
"   <separator/>"
 
500
"   <menuitem action='Overlay'/>"
 
501
"   <menuitem action='Capture'/>"
 
502
"   <separator/>"
 
503
"   <menuitem action='Teletext'/>"
 
504
"   <menuitem action='RestoreVideo'/>"
 
505
"   <menuitem action='NewTeletext'/>"
 
506
"   <separator/>"
 
507
"   <menuitem action='Mute'/>"
 
508
"   <menuitem action='Subtitles'/>"
 
509
"   <separator/>"
 
510
"   <menuitem action='ViewMenu'/>"
 
511
"   <menuitem action='ViewToolbar'/>"
 
512
"   <menuitem action='KeepWindowOnTop'/>"
 
513
"  </menu>"
 
514
"  <menu action='ChannelsSubmenu'>"
 
515
"  </menu>"
 
516
"  <menu action='HelpSubmenu'>"
 
517
"   <menuitem action='HelpContents'/>"
 
518
"   <separator/>"
 
519
"   <menuitem action='About'/>"
 
520
"  </menu>"
 
521
" </menubar>"
 
522
" <toolbar name='Toolbar'>"
 
523
"  <toolitem action='ChannelUp'/>"
 
524
"  <toolitem action='ChannelDown'/>"
 
525
"  <separator/>"
 
526
"  <toolitem action='Controls'/>"
 
527
"  <toolitem action='Mute'/>"
 
528
"  <toolitem action='Teletext'/>"
 
529
"  <toolitem action='RestoreVideo'/>"
 
530
"  <toolitem action='Subtitles'/>"
 
531
" </toolbar>"  
 
532
"</ui>";
 
533
 
 
534
static const char *
 
535
popup_menu_description =
 
536
"<ui>"
 
537
" <menubar name='Popup'>"
 
538
"  <menu action='PopupSubmenu'>"
 
539
"   <menuitem action='Window'/>"
 
540
"   <menuitem action='Fullscreen'/>"
 
541
"   <menuitem action='Background'/>"
 
542
"   <separator/>"
 
543
"   <menuitem action='Overlay'/>"
 
544
"   <menuitem action='Capture'/>"
 
545
"   <separator/>"
 
546
"   <menuitem action='Teletext'/>"
 
547
"   <menu action='TeletextSubmenu'>"
 
548
"   </menu>"
 
549
"   <menu action='SubtitlesSubmenu'>"
 
550
"   </menu>"
 
551
"   <menu action='BookmarksSubmenu'>"
 
552
"   </menu>"
 
553
"   <separator/>"
 
554
"   <menu action='Appearance'>"
 
555
"    <menuitem action='ViewMenu'/>"
 
556
"    <menuitem action='ViewToolbar'/>"
 
557
"    <menuitem action='KeepWindowOnTop'/>"
 
558
"   </menu>"
 
559
"   <separator/>"
 
560
"  </menu>"  
 
561
" </menubar>"
 
562
"</ui>";
 
563
 
 
564
void
 
565
zapping_create_popup            (Zapping *              z,
 
566
                                 GdkEventButton *       event)
 
567
{
 
568
  GError *error = NULL;
 
569
  GtkUIManager *ui_manager;
 
570
  GtkWidget *widget;
 
571
  GtkWidget *popup_menu;
 
572
  GtkWidget *menu;
 
573
  gboolean success;
 
574
 
 
575
  ui_manager = gtk_ui_manager_new ();
 
576
  gtk_ui_manager_insert_action_group (ui_manager,
 
577
                                      z->generic_action_group, APPEND);
 
578
  gtk_ui_manager_insert_action_group (ui_manager,
 
579
                                      z->vbi_action_group, APPEND);
 
580
 
 
581
  success = gtk_ui_manager_add_ui_from_string (ui_manager,
 
582
                                               popup_menu_description,
 
583
                                               NUL_TERMINATED,
 
584
                                               &error);
 
585
  if (!success || error)
 
586
    {
 
587
      if (error)
 
588
        {
 
589
          g_message ("Cannot build popup menu:\n%s", error->message);
 
590
          g_error_free (error);
 
591
          error = NULL;
 
592
        }
 
593
 
 
594
      exit (EXIT_FAILURE);
 
595
    }
 
596
 
 
597
  widget = gtk_ui_manager_get_widget (ui_manager, "/Popup/PopupSubmenu");
 
598
  popup_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
 
599
 
 
600
  widget = gtk_separator_menu_item_new ();
 
601
  gtk_widget_show (widget);
 
602
  gtk_menu_shell_prepend (GTK_MENU_SHELL (popup_menu), widget);
 
603
 
 
604
  add_channel_entries (GTK_MENU_SHELL (popup_menu), 0, 10, z->info);
 
605
 
 
606
#ifdef HAVE_LIBZVBI
 
607
  if (zvbi_get_object ())
 
608
    {
 
609
      if (CAPTURE_MODE_TELETEXT == tv_get_capture_mode (z->info))
 
610
        {
 
611
          widget = gtk_ui_manager_get_widget
 
612
            (ui_manager, "/Popup/PopupSubmenu/TeletextSubmenu");
 
613
 
 
614
          if (widget)
 
615
            {
 
616
              menu = NULL;
 
617
              if (_ttxview_popup_menu_new)
 
618
                menu = _ttxview_popup_menu_new (GTK_WIDGET (zapping), event);  
 
619
              if (menu)
 
620
                gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
 
621
              else
 
622
                gtk_widget_hide (widget);
 
623
            }
 
624
 
 
625
          widget = gtk_ui_manager_get_widget
 
626
            (ui_manager, "/Popup/PopupSubmenu/BookmarksSubmenu");
 
627
          if (widget)
 
628
            {
 
629
              if (_ttxview_bookmarks_menu_new)
 
630
                {
 
631
                  menu = _ttxview_bookmarks_menu_new (GTK_WIDGET (z));
 
632
                  gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
 
633
                }
 
634
              else
 
635
                {
 
636
                  gtk_widget_hide (widget);
 
637
                }
 
638
            }
 
639
        }
 
640
      else
 
641
        {
 
642
          widget = gtk_ui_manager_get_widget
 
643
            (ui_manager, "/Popup/PopupSubmenu/TeletextSubmenu");
 
644
          if (widget)
 
645
            gtk_widget_hide (widget);
 
646
 
 
647
          widget = gtk_ui_manager_get_widget
 
648
            (ui_manager, "/Popup/PopupSubmenu/BookmarksSubmenu");
 
649
          if (widget)
 
650
            gtk_widget_hide (widget);
 
651
        }
 
652
 
 
653
      widget = gtk_ui_manager_get_widget
 
654
        (ui_manager, "/Popup/PopupSubmenu/SubtitlesSubmenu");
 
655
      if (widget)
 
656
        {
 
657
          if ((menu = subtitle_menu_new ()))
 
658
            gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
 
659
          else
 
660
            gtk_widget_hide (widget);
 
661
        }
 
662
 
 
663
      widget = gtk_ui_manager_get_widget
 
664
        (ui_manager, "/Popup/PopupSubmenu/BookmarksSubmenu");
 
665
      if (widget)
 
666
        {
 
667
          gint index;
 
668
 
 
669
          index = g_list_index (GTK_MENU_SHELL (popup_menu)->children, widget);
 
670
          if (index >= 0)
 
671
            {
 
672
              if (_ttxview_hotlist_menu_insert)
 
673
                _ttxview_hotlist_menu_insert (GTK_MENU_SHELL (popup_menu),
 
674
                                              /* separator */ FALSE,
 
675
                                              index + 1);
 
676
            }
 
677
        }
 
678
    }
 
679
  else
 
680
#endif
 
681
    {
 
682
      /* separator */
 
683
      /* teletext */
 
684
      /* subtitles */
 
685
      /* bookmarks */
 
686
    }
 
687
 
 
688
  widget = gtk_ui_manager_get_widget (ui_manager,
 
689
                                      "/Popup/PopupSubmenu/Appearance");
 
690
  menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
 
691
 
 
692
  picture_sizes_append_menu (GTK_MENU_SHELL (menu));
 
693
 
 
694
  {
 
695
    GList *glist;
 
696
 
 
697
    /* Let plugins add their GUI to this context menu */
 
698
    for (glist = plugin_list; glist; glist = glist->next)
 
699
      plugin_process_popup_menu (GTK_WIDGET (z), event,
 
700
                                 GTK_MENU (popup_menu),
 
701
                                 (struct plugin_info *) glist->data);
 
702
  }
 
703
 
 
704
  gtk_menu_popup (GTK_MENU (popup_menu),
 
705
                  /* parent_menu_shell */ NULL,
 
706
                  /* parent_menu_item */ NULL,
 
707
                  /* menu position func */ NULL,
 
708
                  /* menu position data */ NULL,
 
709
                  event->button,
 
710
                  event->time);
 
711
}
 
712
 
 
713
void
 
714
zapping_rebuild_channel_menu    (Zapping *              z)
 
715
{
 
716
  if (z->info && z->channels_menu)
 
717
    {
 
718
      GtkMenuShell *menu;
 
719
      GtkWidget *menu_item;
 
720
      GtkWidget *widget;
 
721
 
 
722
      widget = gtk_menu_new ();
 
723
      gtk_widget_show (widget);
 
724
      menu = GTK_MENU_SHELL (widget);
 
725
 
 
726
      menu_item = gtk_tearoff_menu_item_new();
 
727
      gtk_widget_show (menu_item);
 
728
      gtk_menu_shell_append (menu, menu_item);
 
729
 
 
730
      gtk_menu_item_remove_submenu (z->channels_menu);
 
731
      gtk_menu_item_set_submenu (z->channels_menu, widget);
 
732
 
 
733
      add_channel_entries (menu, 1, 16, z->info);
 
734
    }
 
735
}
 
736
 
 
737
static gboolean
 
738
scroll_event                    (GtkWidget *            widget,
 
739
                                 GdkEventScroll *       event)
 
740
{
 
741
  switch (event->direction)
 
742
    {
 
743
    case GDK_SCROLL_UP:
 
744
    case GDK_SCROLL_LEFT:
 
745
      python_command (widget, "zapping.channel_up()");
 
746
      return TRUE; /* handled */
 
747
 
 
748
    case GDK_SCROLL_DOWN:
 
749
    case GDK_SCROLL_RIGHT:
 
750
      python_command (widget, "zapping.channel_down()");
 
751
      return TRUE; /* handled */
 
752
 
 
753
    default:
 
754
      break;
 
755
    }
 
756
 
 
757
  return FALSE; /* pass on */
 
758
}
 
759
    
 
760
static gboolean
 
761
on_button_press_event           (GtkWidget *            widget,
 
762
                                 GdkEventButton *       event,
 
763
                                 gpointer               user_data)
 
764
{
 
765
  Zapping *z = ZAPPING (user_data);
 
766
 
 
767
  switch (event->button)
 
768
    {
 
769
    case 2: /* Middle button */
 
770
      python_command (widget, "zapping.switch_mode('fullscreen')");
 
771
      return TRUE; /* handled */
 
772
 
 
773
    case 3: /* Right button */
 
774
      zapping_create_popup (z, event);
 
775
      return TRUE; /* handled */
 
776
 
 
777
    default:
 
778
      break;
 
779
    }
 
780
 
 
781
  return FALSE; /* pass on */
 
782
}
 
783
 
 
784
static gboolean
 
785
delete_event                    (GtkWidget *            widget,
 
786
                                 GdkEventAny *          event _unused_)
 
787
{
 
788
  python_command (widget, "zapping.quit()");
 
789
  return TRUE; /* handled */
 
790
}
 
791
 
 
792
static void
 
793
map                             (GtkWidget *            widget)
 
794
{
 
795
  Zapping *z = ZAPPING (widget);
 
796
  GtkAction *action;
 
797
 
 
798
  GTK_WIDGET_CLASS (parent_class)->map (widget);
 
799
 
 
800
  action = gtk_action_group_get_action (z->generic_action_group,
 
801
                                        "KeepWindowOnTop");
 
802
  if (have_wm_hints)
 
803
    {
 
804
      GtkToggleAction *toggle_action;
 
805
 
 
806
      toggle_action = GTK_TOGGLE_ACTION (action);
 
807
      z_toggle_action_connect_gconf_key (toggle_action,
 
808
                                         "/apps/zapping/window/keep_on_top");
 
809
      /* Window is mapped now, set the initial state. */
 
810
      keep_window_on_top_action (toggle_action, z);
 
811
    }
 
812
  else
 
813
    {
 
814
      z_action_set_sensitive (action, FALSE);
 
815
    }
 
816
}
 
817
 
 
818
static void
 
819
instance_finalize               (GObject *              object)
 
820
{
 
821
  extern void shutdown_zapping(void); /* main.c */
 
822
  /* Zapping *z = ZAPPING (object); */
 
823
 
 
824
  /* preliminary */
 
825
  shutdown_zapping ();
 
826
 
 
827
  parent_class->finalize (object);
 
828
}
 
829
 
 
830
static void
 
831
instance_init                   (GTypeInstance *        instance,
 
832
                                 gpointer               g_class _unused_)
 
833
{
 
834
  Zapping *z = (Zapping *) instance;
 
835
  GError *error = NULL;
 
836
  GtkAction *action;
 
837
  GtkToggleAction *toggle_action;
 
838
  GtkWidget *box;
 
839
  GtkWidget *widget;
 
840
  gboolean success;
 
841
 
 
842
  z->generic_action_group = gtk_action_group_new ("ZappingGenericActions");
 
843
#ifdef ENABLE_NLS
 
844
  gtk_action_group_set_translation_domain (z->generic_action_group,
 
845
                                           GETTEXT_PACKAGE);
 
846
#endif                                     
 
847
  gtk_action_group_add_actions (z->generic_action_group,
 
848
                                generic_actions,
 
849
                                G_N_ELEMENTS (generic_actions),
 
850
                                /* user_data */ z);
 
851
  gtk_action_group_add_toggle_actions
 
852
    (z->generic_action_group,
 
853
     generic_toggle_actions, G_N_ELEMENTS (generic_toggle_actions),
 
854
     /* user_data */ z);
 
855
#if 0 /* TODO */
 
856
  gtk_action_group_add_radio_actions
 
857
    (z->generic_action_group,
 
858
     display_mode_radio_actions, G_N_ELEMENTS (display_mode_radio_actions),
 
859
     (gint) DISPLAY_MODE_WINDOW,
 
860
     G_CALLBACK (display_mode_action), /* user_data */ z);
 
861
#endif
 
862
 
 
863
  /* We add the submenu ourselves. Make sure the menu item is
 
864
     visible despite initially without menu. */
 
865
  z_show_empty_submenu (z->generic_action_group, "ChannelsSubmenu");
 
866
 
 
867
  z->vbi_action_group = gtk_action_group_new ("ZappingVBIActions");
 
868
#ifdef ENABLE_NLS
 
869
  gtk_action_group_set_translation_domain (z->vbi_action_group,
 
870
                                           GETTEXT_PACKAGE);
 
871
#endif                                     
 
872
  gtk_action_group_add_actions (z->vbi_action_group,
 
873
                                vbi_actions, G_N_ELEMENTS (vbi_actions),
 
874
                                /* user_data */ z);
 
875
  gtk_action_group_add_toggle_actions (z->vbi_action_group,
 
876
                                       vbi_toggle_actions,
 
877
                                       G_N_ELEMENTS (vbi_toggle_actions),
 
878
                                       /* user_data */ z);
 
879
 
 
880
  /* Mutual exclusive with "Teletext". */
 
881
  action = gtk_action_group_get_action (z->vbi_action_group, "RestoreVideo");
 
882
  z_action_set_visible (action, FALSE);
 
883
 
 
884
#ifdef HAVE_LIBZVBI
 
885
  action = gtk_action_group_get_action (z->vbi_action_group, "Subtitles");
 
886
  zconf_add_hook ("/zapping/internal/callbacks/closed_caption",
 
887
                  (ZConfHook) zconf_hook_subtitles,
 
888
                  GTK_TOGGLE_ACTION (action));
 
889
#endif
 
890
 
 
891
  /* We add the submenu ourselves. Make sure the menu item is
 
892
     visible despite initially without menu. */
 
893
  z_show_empty_submenu (z->vbi_action_group, "TeletextSubmenu");
 
894
  z_show_empty_submenu (z->vbi_action_group, "SubtitlesSubmenu");
 
895
  z_show_empty_submenu (z->vbi_action_group, "BookmarksSubmenu");
 
896
 
 
897
  gnome_app_construct (&z->app, "Zapping", "Zapping");
 
898
 
 
899
  z->ui_manager = gtk_ui_manager_new ();
 
900
  gtk_ui_manager_insert_action_group (z->ui_manager,
 
901
                                      z->generic_action_group, APPEND);
 
902
  gtk_ui_manager_insert_action_group (z->ui_manager,
 
903
                                      z->vbi_action_group, APPEND);
 
904
 
 
905
  success = gtk_ui_manager_add_ui_from_string (z->ui_manager,
 
906
                                               ui_description,
 
907
                                               NUL_TERMINATED,
 
908
                                               &error);
 
909
  if (!success || error)
 
910
    {
 
911
      if (error)
 
912
        {
 
913
          g_message ("Cannot build main menu:\n%s", error->message);
 
914
          g_error_free (error);
 
915
          error = NULL;
 
916
        }
 
917
 
 
918
      exit (EXIT_FAILURE);
 
919
    }
 
920
 
 
921
  gtk_window_add_accel_group (GTK_WINDOW (z),
 
922
                              gtk_ui_manager_get_accel_group (z->ui_manager));
 
923
 
 
924
  z->decorated = TRUE;
 
925
 
 
926
  {
 
927
    widget = gtk_ui_manager_get_widget (z->ui_manager, "/MainMenu");
 
928
    z->menubar = GTK_MENU_BAR (widget);
 
929
    widget = gtk_ui_manager_get_widget (z->ui_manager,
 
930
                                        "/MainMenu/ChannelsSubmenu");
 
931
    z->channels_menu = GTK_MENU_ITEM (widget);
 
932
    zapping_rebuild_channel_menu (z);
 
933
 
 
934
    toggle_action = GTK_TOGGLE_ACTION (gtk_action_group_get_action
 
935
                                       (z->generic_action_group,
 
936
                                        "ViewMenu"));
 
937
    z_toggle_action_connect_gconf_key (toggle_action,
 
938
                                       "/apps/zapping/window/view_menu");
 
939
    /* Adds the menu if necessary. */
 
940
    view_menu_action (toggle_action, z);
 
941
  }
 
942
 
 
943
  {
 
944
    widget = gtk_ui_manager_get_widget (z->ui_manager, "/Toolbar");
 
945
    z->toolbar = GTK_TOOLBAR (widget);
 
946
 
 
947
    toggle_action = GTK_TOGGLE_ACTION (gtk_action_group_get_action
 
948
                                       (z->generic_action_group,
 
949
                                        "ViewToolbar"));
 
950
    z_toggle_action_connect_gconf_key (toggle_action,
 
951
                                       "/apps/zapping/window/view_toolbar");
 
952
    /* Adds the toolbar if necessary. */
 
953
    view_toolbar_action (toggle_action, z);
 
954
  }
 
955
 
 
956
  {
 
957
    widget = gnome_appbar_new (/* progress */ FALSE,
 
958
                               /* status */ TRUE,
 
959
                               /* interactive */ GNOME_PREFERENCES_NEVER);
 
960
    z->appbar = GNOME_APPBAR (widget);
 
961
 
 
962
    /* Cannot hide the appbar at this point, so we add (and show) when
 
963
       the Teletext plugin needs it. */
 
964
  }
 
965
 
 
966
  box = gtk_hbox_new (FALSE, 0);
 
967
  z->contents = GTK_BOX (box);
 
968
  gtk_widget_show (box);
 
969
  gnome_app_set_contents (&z->app, box);
 
970
 
 
971
  widget = z_video_new ();
 
972
  z->video = Z_VIDEO (widget);
 
973
  gtk_widget_show (widget);
 
974
  gtk_container_add (GTK_CONTAINER (box), widget);
 
975
 
 
976
  {
 
977
    GdkColor black = { 0, 0, 0, 0 };
 
978
    gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &black);
 
979
  }
 
980
 
 
981
  z_video_set_min_size (z->video, 64, 64 * 3 / 4);
 
982
 
 
983
  /* XXX free, 4:3, 16:9 */
 
984
  if (zconf_get_boolean (NULL, "/zapping/options/main/fixed_increments"))
 
985
    z_video_set_size_inc (z->video, 64, 64 * 3 / 4);
 
986
 
 
987
  /* NOTE video only, not the entire window. */
 
988
  g_signal_connect (G_OBJECT (widget), "button-press-event",
 
989
                    G_CALLBACK (on_button_press_event), z);
 
990
 
 
991
  gtk_widget_add_events (widget,
 
992
                         GDK_BUTTON_PRESS_MASK |
 
993
                         GDK_BUTTON_RELEASE_MASK |
 
994
                         GDK_SCROLL_MASK |
 
995
                         GDK_EXPOSURE_MASK |
 
996
                         GDK_POINTER_MOTION_MASK |
 
997
                         GDK_VISIBILITY_NOTIFY_MASK |
 
998
                         GDK_KEY_PRESS_MASK);
 
999
}
 
1000
 
 
1001
GtkWidget *
 
1002
zapping_new                     (void)
 
1003
{
 
1004
  return GTK_WIDGET (g_object_new (TYPE_ZAPPING, NULL));
 
1005
}
 
1006
 
 
1007
static void
 
1008
class_init                      (gpointer               g_class,
 
1009
                                 gpointer               class_data _unused_)
 
1010
{
 
1011
  GObjectClass *object_class;
 
1012
  GtkWidgetClass *widget_class;
 
1013
 
 
1014
  object_class = G_OBJECT_CLASS (g_class);
 
1015
  widget_class = GTK_WIDGET_CLASS (g_class);
 
1016
  parent_class = g_type_class_peek_parent (g_class);
 
1017
 
 
1018
  object_class->finalize = instance_finalize;
 
1019
 
 
1020
  widget_class->map = map;
 
1021
  widget_class->delete_event = delete_event;
 
1022
  widget_class->scroll_event = scroll_event;
 
1023
 
 
1024
  cmd_register ("hide_controls", py_hide_controls, METH_VARARGS,
 
1025
                N_("Show menu and toolbar"), "zapping.hide_controls()");
 
1026
  cmd_register ("keep_on_top", py_keep_on_top, METH_VARARGS,
 
1027
                N_("Keep window on top"), "zapping.keep_on_top()");
 
1028
}
 
1029
 
 
1030
GType
 
1031
zapping_get_type                (void)
 
1032
{
 
1033
  static GType type = 0;
 
1034
  
 
1035
  if (!type)
 
1036
    {
 
1037
      GTypeInfo info;
 
1038
 
 
1039
      CLEAR (info);
 
1040
 
 
1041
      info.class_size = sizeof (ZappingClass);
 
1042
      info.class_init = class_init;
 
1043
      info.instance_size = sizeof (Zapping);
 
1044
      info.instance_init = instance_init;
 
1045
 
 
1046
      type = g_type_register_static (GNOME_TYPE_APP,
 
1047
                                     "Zapping",
 
1048
                                     &info, (GTypeFlags) 0);
 
1049
    }
 
1050
 
 
1051
  return type;
 
1052
}