Update of /cvsroot/xine/gnome-xine/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10397/src Modified Files: globals.h key_events.c main.c mediamarks.c menu.c menu.h noskin_window.c player.c ui.c vis.c vis.h Log Message: Stop using GtkItemFactory (and, incidentally, GtkMenuShell and Gtk*MenuItem) in favour of GtkUIManager and Gtk*Action. Adapt various Javascript implementation functions etc. to work with the new implementation (they need to activate GtkAction objects); for a few radio groups, add a few hidden actions for "other" values. Test this code - I've probably missed something subtle in the changeover :-) Index: globals.h =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/globals.h,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- globals.h 6 May 2005 18:22:15 -0000 1.26 +++ globals.h 11 May 2005 20:13:17 -0000 1.27 @@ -47,16 +47,14 @@ extern GtkWidget *menubar, *popup_menu; extern GSList *infobars; extern pthread_mutex_t engine_lock; -extern GtkMenuShell *media_menu[2], - *vis_menu[2]; -extern GtkCheckMenuItem *fullscreen_menu_item[2], - *auto_resize_menu_item[2], - *auto_rescale_menu_item[2], - *deinterlace_menu_item[2], - *pp_video_menu_item[2], - *pp_audio_menu_item[2], - *toolbar_item[3][2]; -extern GSList *aspect_menu_items[2]; + +typedef struct { + GtkToggleAction *fullscreen, *auto_resize, *auto_rescale, + *deinterlace, *vo_postproc, *ao_postproc, *toolbar; + GSList *aspect, *vis, *toolbar_pos, *video_size, *subtitles; +} action_items_t; +extern action_items_t action_items; + extern int verbosity; extern xine_t *xine; extern xine_stream_t *stream; Index: key_events.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/key_events.c,v retrieving revision 1.63 retrieving revision 1.64 diff -u -r1.63 -r1.64 --- key_events.c 10 May 2005 17:33:14 -0000 1.63 +++ key_events.c 11 May 2005 20:13:17 -0000 1.64 @@ -174,7 +174,7 @@ return TRUE; case GDK_Pointer_Button2: if (gtk_video_is_fullscreen (GTK_VIDEO(gtv))) - ui_toolbar_toggle (); + gtk_action_activate (GTK_ACTION(action_items.toolbar)); return TRUE; } Index: main.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/main.c,v retrieving revision 1.122 retrieving revision 1.123 diff -u -r1.122 -r1.123 --- main.c 6 May 2005 18:23:19 -0000 1.122 +++ main.c 11 May 2005 20:13:18 -0000 1.123 @@ -214,7 +214,7 @@ if (xine_config_lookup_entry (xine, "gui.post_plugins.audio_visualisation", &entry)) - vis_set (v, entry.enum_values[entry.num_value], &audio_port); + vis_set (entry.enum_values[entry.num_value]); return FALSE; } @@ -420,6 +420,7 @@ gxine_lirc_init (); snapshot_init (); ui_init (); + vis_init (); post_init (); stream_info_init (); wizards_init (); Index: mediamarks.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/mediamarks.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- mediamarks.c 6 May 2005 18:24:19 -0000 1.44 +++ mediamarks.c 11 May 2005 20:13:18 -0000 1.45 @@ -46,103 +46,139 @@ static GtkTreeIter cat_iter; static gboolean is_visible, cat_edited; -static void menu_cb (GtkWidget* widget, gpointer data) { +static GtkActionGroup *media_group = NULL; +static guint media_merge; - play_item_t *item_orig = (play_item_t *) data; +static void menu_cb (GtkAction* action, gpointer data) +{ + if (data) + playlist_play (playlist_add (play_item_copy (data), -1)); +} - if (item_orig) { - play_item_t *item; - int pos; +static int gen_actions_sub (GtkUIManager *ui, GtkActionGroup *actions, + GtkTreeIter *iter, int count) +{ + do { + GValue v; + char *id; - item = play_item_copy (item_orig); + memset (&v, 0, sizeof (GValue)); + gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), iter, 0, &v); + id = g_value_peek_pointer (&v); - pos = playlist_add (item, -1); - playlist_play (pos); - } -} + if (id) { + char *name = g_strdup_printf ("_mediamark_%d", count++); + GtkAction *action = gtk_action_new (name, id, NULL, NULL); + play_item_t *item; -static void gen_items (GtkMenuShell *submenu, GtkTreeIter *iter) { + gtk_action_group_add_action (actions, action); + free (name); - int pos; + g_value_unset (&v); + memset (&v, 0, sizeof (GValue)); + gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), iter, 2, &v); + item = g_value_peek_pointer (&v); + + if (item) + g_signal_connect (G_OBJECT(action), "activate", + G_CALLBACK(menu_cb), (gpointer) item); + else + { + GtkTreeIter children; + if (gtk_tree_model_iter_children (GTK_TREE_MODEL(mm_store), + &children, iter)) + count = gen_actions_sub (ui, actions, &children, count); + } + } - pos = 4; + g_value_unset (&v); + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(mm_store), iter)); + + return count; +} +static GtkActionGroup *gen_actions (GtkUIManager *ui, GtkTreeIter *iter) +{ + GtkActionGroup *actions = gtk_action_group_new ("mediamarks"); + gen_actions_sub (ui, actions, iter, 0); + return actions; +} + +static int gen_items (GtkUIManager *ui, const char *path, GtkTreeIter *iter, + guint merge, int count) +{ do { + GValue v; + char *id; - GValue v; - play_item_t *play_item; - GtkWidget *item; - char *id; - memset (&v, 0, sizeof (GValue)); - gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), - iter, 0, &v); + gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), iter, 0, &v); id = g_value_peek_pointer (&v); if (id) { - item = gtk_menu_item_new_with_label (id); - g_value_unset (&v); + char *name = g_strdup_printf ("_mediamark_%d", count++); + play_item_t *item; + g_value_unset (&v); memset (&v, 0, sizeof (GValue)); - gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), - iter, 2, &v); - play_item = g_value_peek_pointer (&v); + gtk_tree_model_get_value (GTK_TREE_MODEL (mm_store), iter, 2, &v); + item = g_value_peek_pointer (&v); - if (play_item) { - - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (menu_cb), (gpointer) play_item); - - } else { - - GtkWidget *submenu; - GtkTreeIter children; - - submenu = gtk_menu_new (); - - if (gtk_tree_model_iter_children (GTK_TREE_MODEL(mm_store), &children, iter)) - gen_items (GTK_MENU_SHELL(submenu), &children); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - + if (item) + gtk_ui_manager_add_ui (ui, merge, path, name, name, + GTK_UI_MANAGER_MENUITEM, FALSE); + else + { + GtkTreeIter children; + gtk_ui_manager_add_ui (ui, merge, path, name, name, + GTK_UI_MANAGER_MENU, FALSE); + if (gtk_tree_model_iter_children (GTK_TREE_MODEL(mm_store), + &children, iter)) + { + char *newpath = g_strdup_printf ("%s/%s", path, name); + count = gen_items (ui, newpath, &children, merge, count); + free (newpath); + } } - - gtk_menu_shell_insert (submenu, item, pos); - gtk_widget_show(item); - - pos++; } g_value_unset (&v); - } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(mm_store), iter)); + + return count; } -static void update_menu (GtkMenuShell *submenu) { +extern GtkUIManager *ui; - GList *olditems; - GtkWidget *item; +static void update_menu (void) +{ GtkTreeIter iter; - if (!submenu) - return; - - /* - * remove old items (if any) - */ - - olditems = gtk_container_children (GTK_CONTAINER(submenu)); - while ( (item = (GtkWidget *) g_list_nth_data (olditems, 4)) ) { - gtk_container_remove (GTK_CONTAINER (submenu), item); - olditems = gtk_container_children (GTK_CONTAINER (submenu)); + /* remove old items (if any) */ + if (media_group) + { + gtk_ui_manager_remove_ui (ui, media_merge); + gtk_ui_manager_remove_action_group (ui, media_group); + media_group = NULL; } - /* - * add current items - */ + /* add current items */ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (mm_store), &iter)) - gen_items (submenu, &iter); + { + int i; + const char *tree; + media_merge = gtk_ui_manager_new_merge_id (ui); + media_group = gen_actions (ui, &iter); + gtk_ui_manager_insert_action_group (ui, media_group, 0); + for (i = 0; (tree = menu_get_tree_name (i)) != NULL; ++i) + { + char *key = g_strdup_printf ("/ui/%s/MediaMenu/MediaItems", tree); + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (mm_store), &iter); + gen_items (ui, key, &iter, media_merge, 0); + free (key); + } + } } /* @@ -438,8 +474,7 @@ static void tree_changed_cb (GtkTreeModel *treemodel, GtkTreePath *arg1, gpointer user_data) { - update_menu (media_menu[0]); - update_menu (media_menu[1]); + update_menu (); } static int load_mediamarks (gchar *fname) @@ -457,8 +492,7 @@ } else load_new_file (node); - update_menu (media_menu[0]); - update_menu (media_menu[1]); + update_menu (); g_signal_handlers_unblock_by_func (G_OBJECT(mm_store), tree_changed_cb, NULL); free (mmfile); @@ -715,8 +749,7 @@ g_signal_connect (G_OBJECT (mm_store), "rows-reordered", G_CALLBACK (tree_changed_cb), NULL); - update_menu (media_menu[0]); - update_menu (media_menu[1]); + update_menu (); /* * create (for now invisible) mm_manage dialog Index: menu.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/menu.c,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- menu.c 29 Apr 2005 19:50:05 -0000 1.46 +++ menu.c 11 May 2005 20:13:18 -0000 1.47 @@ -29,25 +29,28 @@ #include "menu.h" #include "playlist.h" #include "engine.h" +#include "ui.h" #include "utils.h" #include "gtkvideo.h" #include "vis.h" -/* global pointers to menus: */ +/* + * global variables + */ GtkWidget *popup_menu = NULL, *menubar = NULL; -GtkMenuShell *media_menu[2] = { NULL, NULL }, - *vis_menu[2] = { NULL, NULL }; -GtkCheckMenuItem *fullscreen_menu_item[2] = { NULL, NULL }, - *deinterlace_menu_item[2] = { NULL, NULL }, - *pp_video_menu_item[2] = { NULL, NULL }, - *pp_audio_menu_item[2] = { NULL, NULL }, - *auto_resize_menu_item[2] = { NULL, NULL }, - *auto_rescale_menu_item[2] = { NULL, NULL }, - *toolbar_item[3][2] = { { NULL, NULL }, { NULL, NULL }, - { NULL, NULL } }; -GSList *aspect_menu_items[2] = { NULL, NULL }; +GtkUIManager *ui = NULL; +action_items_t action_items = { NULL }; + +/* + * local bits + */ + +#define get_action(name) gtk_action_group_get_action (action, (name)) +#define get_toggle(name) GTK_TOGGLE_ACTION(get_action ((name))) +#define get_radio(name) GTK_RADIO_ACTION(get_action ((name))) +#define get_radio_group(name) gtk_radio_action_get_group (get_radio ((name))) /* * context menu @@ -73,8 +76,16 @@ } #endif -static void autoplay_cb (GtkWidget* widget, gpointer data) { +static const char type[][8] = { "menubar", "popup" }; + +const char *menu_get_tree_name (int tree) +{ + return (tree >= 0 && tree < G_N_ELEMENTS(type)) ? type[tree] : NULL; +} + +static void autoplay_cb (GtkAction *action, gpointer data) +{ char **mrls, *mrl; int n, i, pos; @@ -103,11 +114,15 @@ playlist_play (pos); } -static void add_autoplay_entries (GtkMenuShell *submenu, int index) { +#define AUTOPLAY_NAME "_autoplay_" +#define VIS_NAME "_vis_" - GtkWidget *item = NULL; - int i; +static size_t add_autoplay_actions (GtkUIManager *ui) +{ const char *const *autoplay_ids = xine_get_autoplay_input_plugin_ids (xine); + GtkActionGroup *actions; + char name[20]; + size_t i; static const struct { char id[8]; @@ -121,186 +136,90 @@ if (!autoplay_ids) { logprintf ("menu: warning: didn't get any autoplay entries\n"); - return; + return 0; } - i=0; - while (autoplay_ids[i]) { + actions = gtk_action_group_new ("autoplay"); + + for (i = 0; autoplay_ids[i]; ++i) + { int j = sizeof (stock) / sizeof (stock[0]); while (j--) if (!strcmp (autoplay_ids[i], stock[j].id)) - { - item = gtk_image_menu_item_new_with_label (autoplay_ids[i]); - gtk_image_menu_item_set_image - (GTK_IMAGE_MENU_ITEM(item), - gtk_image_new_from_stock (stock[j].stock, GTK_ICON_SIZE_MENU)); break; - } - if (j < 0) - item = gtk_menu_item_new_with_label (autoplay_ids[i]); - - g_signal_connect (GTK_OBJECT(item), "activate", - G_CALLBACK (autoplay_cb), - (gpointer) strdup (autoplay_ids[i])); - - gtk_menu_shell_insert (submenu, item, ++index); - gtk_widget_show(item); - - i++; + snprintf (name, sizeof (name), AUTOPLAY_NAME"%d", i); + GtkAction *action = gtk_action_new (name, autoplay_ids[i], NULL, + j < 0 ? NULL : stock[j].stock); + g_signal_connect (G_OBJECT(action), "activate", + G_CALLBACK(autoplay_cb), + (gpointer) strdup (autoplay_ids[i])); + gtk_action_group_add_action (actions, action); } -} -static void vis_none_cb (gpointer callback_data, guint callback_action, - GtkWidget *widget) -{ - vis_set (GTK_VIDEO(gtv), "none", &audio_port); -} + gtk_ui_manager_insert_action_group (ui, actions, 0); -static void vis_cb (GtkWidget* widget, gpointer data) -{ - vis_set (GTK_VIDEO(gtv), data, &audio_port); + return i; } -static void add_vis_entries (GtkMenuShell *submenu, GtkRadioMenuItem *none_item) +static size_t add_vis_actions (GtkUIManager *ui, GtkAction *group_action) { const char *const *pol = xine_list_post_plugins_typed (xine, XINE_POST_TYPE_AUDIO_VISUALIZATION); - if (pol) - { - xine_cfg_entry_t entry; - gboolean ticked = FALSE; - int i; - GSList *group = - gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (none_item)); - const char *vis = xine_config_lookup_entry - (xine, "gui.post_plugins.audio_visualisation", &entry) - ? entry.enum_values[entry.num_value] : NULL; + GtkActionGroup *actions; + GSList *radiogroup; + char name[20]; + xine_cfg_entry_t entry; + const char *vis; + size_t i; + GtkRadioAction *tick; + + if (!pol) + return 0; + + actions = gtk_action_group_new ("vis"); + vis = xine_config_lookup_entry + (xine, "gui.post_plugins.audio_visualisation", &entry) + ? entry.enum_values[entry.num_value] : NULL; + tick = GTK_RADIO_ACTION(group_action); + radiogroup = gtk_radio_action_get_group (tick); - for (i = 0; pol[i]; ++i) - { - GtkWidget *item = gtk_radio_menu_item_new_with_label (group, pol[i]); -// group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM(item)); - g_object_set_data (G_OBJECT (item), "vis", (gpointer) strdup (pol[i])); - g_signal_connect (GTK_OBJECT(item), "activate", - G_CALLBACK (vis_cb), (gpointer) strdup (pol[i])); - gtk_menu_shell_insert (submenu, item, i + 1); - gtk_widget_show(item); - if (vis && !strcasecmp (vis, pol[i])) - GTK_CHECK_MENU_ITEM(item)->active = ticked = TRUE; - } - GTK_CHECK_MENU_ITEM(none_item)->active = !ticked; + for (i = 0; pol[i]; ++i) + { + snprintf (name, sizeof (name), VIS_NAME"%d", i); + GtkRadioAction *action = gtk_radio_action_new + (name, pol[i], NULL, NULL, i + 1); + g_signal_connect (G_OBJECT(action), "activate", + G_CALLBACK(vis_cb), (gpointer) strdup (pol[i])); + gtk_radio_action_set_group (action, radiogroup); + radiogroup = gtk_radio_action_get_group (action); + gtk_action_group_add_action (actions, GTK_ACTION(action)); + if (vis && !strcasecmp (vis, pol[i])) + tick = action; } -} - -enum { - /* File */ - JS_CB_OPEN, - JS_CB_OPEN_MRL, - JS_CB_PLAYLIST, - JS_CB_PREFERENCES, - JS_CB_KEYBINDINGS, - JS_CB_SNAPSHOT, - JS_CB_EXIT, - /* View */ - JS_CB_FULLSCREEN, - JS_CB_TOOLBAR, - JS_CB_ZOOM_IN, - JS_CB_ZOOM_OUT, - JS_CB_ZOOM_100, - JS_CB_VIDEO_SETTINGS, - JS_CB_POSTPROC_DEINTERLACE, - JS_CB_POSTPROC_VIDEO, - JS_CB_AUDIO_SETTINGS, - JS_CB_EQUALISER, - JS_CB_POSTPROC_AUDIO, - /* Media */ - JS_CB_MEDIAMARKS_ADD, - JS_CB_MEDIAMARKS_MANAGE, - JS_CB_MEDIAMARKS_IMPORT, - /* Help */ - JS_CB_ABOUT, - JS_CB_LOG, - JS_CB_STREAM_INFO, - JS_CB_WIZARDS, -}; - -static void js_cb (gpointer data, guint action, GtkWidget *widget) -{ - static const char *const cmds[] = { - /* File */ - [JS_CB_OPEN] = "open_show ();", - [JS_CB_OPEN_MRL] = "open_mrl_show ();", - [JS_CB_PLAYLIST] = "playlist_show ();", - [JS_CB_PREFERENCES] = "preferences_show ();", - [JS_CB_KEYBINDINGS] = "keybindings_show ();", - [JS_CB_SNAPSHOT] = "snapshot ();", - [JS_CB_EXIT] = "exit ();", - /* View */ - [JS_CB_FULLSCREEN] = "vo_fullscreen.toggle ();", - [JS_CB_TOOLBAR] = "toolbar_show ();", - [JS_CB_ZOOM_IN] = "vo_zoom.v += 5;", - [JS_CB_ZOOM_OUT] = "vo_zoom.v -= 5;", - [JS_CB_ZOOM_100] = "vo_zoom.v = 100;", - [JS_CB_VIDEO_SETTINGS] = "settings_show (0);", - [JS_CB_POSTPROC_DEINTERLACE] = "deinterlace_show ();", - [JS_CB_POSTPROC_VIDEO] = "postproc_video_show ();", - [JS_CB_AUDIO_SETTINGS] = "settings_show (1);", - [JS_CB_EQUALISER] = "settings_show (2);", - [JS_CB_POSTPROC_AUDIO] = "postproc_audio_show ();", - /* Media */ - [JS_CB_MEDIAMARKS_ADD] = "mm_add_show ();", - [JS_CB_MEDIAMARKS_MANAGE] = "mm_manage_show ();", - [JS_CB_MEDIAMARKS_IMPORT] = "import_mediamarks ();", - /* Help */ - [JS_CB_ABOUT] = "about_show ();", - [JS_CB_LOG] = "log_show ();", - [JS_CB_STREAM_INFO] = "stream_info_show ();", - [JS_CB_WIZARDS] = "run_wizards ();", - }; - engine_exec (cmds[action], NULL, NULL); -} + gtk_action_activate (GTK_ACTION(tick)); -enum { - JS_TOGGLE_CB_DEINTERLACE, - JS_TOGGLE_CB_AUTO_RESIZE, - JS_TOGGLE_CB_AUTO_RESCALE, - JS_TOGGLE_CB_POSTPROC_VIDEO, - JS_TOGGLE_CB_POSTPROC_AUDIO, -}; - -static void js_toggle_cb (gpointer data, guint action, GtkWidget *widget) -{ - static const char *const cmds[] = { - [JS_TOGGLE_CB_DEINTERLACE] = "vo_deinterlace", - [JS_TOGGLE_CB_AUTO_RESIZE] = "vo_auto_resize", - [JS_TOGGLE_CB_AUTO_RESCALE] = "vo_auto_rescale", - [JS_TOGGLE_CB_POSTPROC_VIDEO] = "vo_postproc", - [JS_TOGGLE_CB_POSTPROC_AUDIO] = "ao_postproc", - }; - v_engine_exec ("%s.v = %s;", NULL, NULL, cmds[action], - gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)) - ? "true" : "false"); -} + gtk_ui_manager_insert_action_group (ui, actions, 0); -static void tbar_position_cb(gpointer data, guint action, GtkWidget *widget) -{ - v_engine_exec ("set_toolbar_position (%d);", NULL, NULL, action); + return i; } -static void factor_cb(gpointer data, guint action, GtkWidget *widget) +void menu_add_items (GtkUIManager *ui, const char *const prefix, + const char *const label, guint merge, size_t count) { - v_engine_exec ("set_video_size (%d);", NULL, NULL, action); -} - -static void aspect_cb(gpointer data, guint action, GtkWidget *widget) -{ - v_engine_exec ("vo_aspect = %d;", NULL, NULL, action); -} - -static void sub_cb (gpointer data, guint action, GtkWidget *widget) -{ - if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) - v_engine_exec ("vo_subtitle.v = %d;", NULL, NULL, action); + char name[32]; + int i; + for (i = 0; i < 2; ++i) + { + char *path = g_strdup_printf ("/ui/%s/%s", type[i], prefix); + size_t j = count; + while (j--) + { + snprintf (name, sizeof (name), "%s%d", label, j); + gtk_ui_manager_add_ui (ui, merge, path, name, name, + GTK_UI_MANAGER_MENUITEM, TRUE); + } + free (path); + } } static void popdown_idle_cb (GtkWidget *widget) @@ -319,190 +238,363 @@ return TRUE; } -#define STOCK(x) "<StockItem>", GTK_STOCK_##x -#define STOCKQ(x) "<StockItem>", "gxine-" #x -#define ASPECT(x) aspect_cb, XINE_VO_ASPECT_##x -#define JS(x) js_cb, JS_CB_##x -#define JSTOGGLE(x) js_toggle_cb, JS_TOGGLE_CB_##x -static GtkItemFactoryEntry menu_items[] = { - { N_("/_File"), NULL, NULL, 0, "<Branch>" }, - { N_("/File/_Open..."), "<control>O", JS(OPEN), STOCK(OPEN) }, - { N_("/File/Open _MRL..."), "<control>M", JS(OPEN_MRL), STOCK(OPEN) }, - { N_("/File/Play_list..."), NULL, JS(PLAYLIST), STOCKQ(media-playlist) }, - { "/File/sep0", NULL, NULL, 0, "<Separator>" }, - { N_("/File/_Preferences..."), NULL, JS(PREFERENCES), STOCK(PREFERENCES) }, - { N_("/File/_Keybindings..."), NULL, JS(KEYBINDINGS), STOCK(PREFERENCES) }, - { "/File/sep1", NULL, NULL, 0, "<Separator>" }, - { "/File/sep2", NULL, NULL, 0, "<Separator>" }, - { N_("/File/_Snapshot..."), "<control>S", JS(SNAPSHOT), NULL }, - { "/File/sep3", NULL, NULL, 0, "<Separator>" }, - { N_("/File/_Quit"), "<control>Q", JS(EXIT), STOCK(QUIT) }, - { N_("/_View"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/_Fullscreen mode"), "<control>F", JS(FULLSCREEN), "<CheckItem>" }, - { N_("/View/Fullscreen _toolbar"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/Fullscreen toolbar/_Visible"), NULL, JS(TOOLBAR), "<CheckItem>" }, - { N_("/View/Fullscreen toolbar/At _top"), NULL, tbar_position_cb, 1, "<RadioItem>" }, - { N_("/View/Fullscreen toolbar/At _bottom"), NULL, tbar_position_cb, 0, "/View/Fullscreen toolbar/At top" }, - { "/View/sep3", NULL, NULL, 0, "<Separator>" }, - { N_("/View/_Window"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/Window/_50%"), NULL, factor_cb, 50, NULL }, - { N_("/View/Window/_100%"), NULL, factor_cb, 100, STOCK(ZOOM_100) }, - { N_("/View/Window/_200%"), NULL, factor_cb, 200, NULL }, - { N_("/View/Window/Auto _resize"), NULL, JSTOGGLE(AUTO_RESIZE), "<CheckItem>" }, - { N_("/View/Window/_Magnify low-res video"), NULL, JSTOGGLE(AUTO_RESCALE), "<CheckItem>" }, - { N_("/View/Zoom _in"), NULL, JS(ZOOM_IN), STOCK(ZOOM_IN) }, - { N_("/View/Zoom _out"), NULL, JS(ZOOM_OUT), STOCK(ZOOM_OUT) }, - { N_("/View/_Zoom 100%"), NULL, JS(ZOOM_100), STOCK(ZOOM_100) }, - { "/View/sep5", NULL, NULL, 0, "<Separator>" }, - { N_("/View/_Aspect ratio"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/Aspect ratio/_Auto"), NULL, ASPECT(AUTO), "<RadioItem>" }, - { N_("/View/Aspect ratio/_Square"), NULL, ASPECT(SQUARE), "/View/Aspect ratio/Auto"}, - { N_("/View/Aspect ratio/_4:3"), NULL, ASPECT(4_3), "/View/Aspect ratio/Auto"}, - { N_("/View/Aspect ratio/_16:9"), NULL, ASPECT(ANAMORPHIC), "/View/Aspect ratio/Auto"}, - { N_("/View/Aspect ratio/_2:1"), NULL, ASPECT(DVB), "/View/Aspect ratio/Auto"}, - { "/View/sep6", NULL, NULL, 0, "<Separator>" }, - { N_("/View/_Visualisations"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/Visualisations/_None"), NULL, vis_none_cb, 0, "<RadioItem>"}, - { "/View/sep7", NULL, NULL, 0, "<Separator>" }, - { N_("/View/_Subtitles"), NULL, NULL, 0, "<Branch>" }, - { N_("/View/Subtitles/_Auto"), NULL, sub_cb, -1, "<RadioItem>"}, - { N_("/View/Subtitles/_None"), NULL, sub_cb, -2, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _0"), NULL, sub_cb, 0, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _1"), NULL, sub_cb, 1, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _2"), NULL, sub_cb, 2, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _3"), NULL, sub_cb, 3, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _4"), NULL, sub_cb, 4, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _5"), NULL, sub_cb, 5, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _6"), NULL, sub_cb, 6, "/View/Subtitles/Auto"}, - { N_("/View/Subtitles/Channel _7"), NULL, sub_cb, 7, "/View/Subtitles/Auto"}, - { N_("/V_ideo"), NULL, NULL, 0, "<Branch>" }, - { N_("/Video/_Settings..."), NULL, JS(VIDEO_SETTINGS), STOCK(PROPERTIES) }, - { N_("/Video/_Deinterlace"), "<control>I", JSTOGGLE(DEINTERLACE), "<CheckItem>" }, - { N_("/Video/_Post-processing"), NULL, JSTOGGLE(POSTPROC_VIDEO), "<CheckItem>" }, - { N_("/Video/_Configure"), NULL, NULL, 0, "<Branch>" }, - { N_("/Video/Configure/_Deinterlace..."), NULL, JS(POSTPROC_DEINTERLACE), STOCK(PREFERENCES) }, - { N_("/Video/Configure/_Post-processing..."), NULL, JS(POSTPROC_VIDEO), STOCK(PREFERENCES) }, - { N_("/_Audio"), NULL, NULL, 0, "<Branch>" }, - { N_("/Audio/_Settings..."), NULL, JS(AUDIO_SETTINGS), STOCK(PROPERTIES) }, - { N_("/Audio/_Equaliser..."), NULL, JS(EQUALISER), STOCK(PROPERTIES) }, - { N_("/Audio/_Post-processing"), NULL, JSTOGGLE(POSTPROC_AUDIO), "<CheckItem>" }, - { N_("/Audio/_Configure"), NULL, NULL, 0, "<Branch>" }, - { N_("/Audio/Configure/_Post-processing..."), NULL, JS(POSTPROC_AUDIO), STOCK(PREFERENCES) }, - { N_("/_Media"), NULL, NULL, 0, "<Branch>" }, - { N_("/Media/_Add media mark..."), "<control>D", JS(MEDIAMARKS_ADD), STOCK(NEW) }, - { N_("/Media/_Manage media marks..."), "<control>B", JS(MEDIAMARKS_MANAGE), NULL }, - { N_("/Media/_Import media marks..."), NULL, JS(MEDIAMARKS_IMPORT), STOCK(OPEN) }, - { "/Media/sep8", NULL, NULL, 0, "<Separator>" }, - { N_("/_Help"), NULL, NULL, 0, "<LastBranch>" }, - { N_("/Help/_About..."), NULL, JS(ABOUT), STOCK(ABOUT) }, - { N_("/Help/Engine _Log..."), "<control>L", JS(LOG), NULL }, - { N_("/Help/Stream _Info..."), NULL, JS(STREAM_INFO), NULL }, - { "/Help/sep6", NULL, NULL, 0, "<Separator>" }, - { N_("/Help/_Re-run setup wizards..."), NULL, JS(WIZARDS), NULL }, +/* Standard callback (invokes Javascript) */ +#define JS_CB(func, command) \ + static void js_##func##_cb (GtkAction *action, gpointer data) \ + { \ + engine_exec ((command), NULL, NULL); \ + } + +/* Radio action callback (no Javascript) + * Requires a function body, to which is passed int v = radio action value + */ +#define JS_CB_R(func) \ + static always_inline void js_##func##_cb_int (int); \ + static void js_##func##_cb (GtkRadioAction *action, gpointer data) \ + { js_##func##_cb_int (gtk_radio_action_get_current_value (action)); } \ + static always_inline void js_##func##_cb_int (int v) + /* function body goes here */ + +/* Toggle action callback (no Javascript) + * Requires a function body, to which is passed gboolean v = toggle state + */ +#define JS_CB_T(func) \ + static always_inline void js_##func##_cb_int (gboolean); \ + static void js_##func##_cb (GtkToggleAction *action, gpointer data) \ + { js_##func##_cb_int (gtk_toggle_action_get_active (action)); } \ + static always_inline void js_##func##_cb_int (gboolean v) + /* function body goes here */ + +/* File */ +JS_CB (Open, "open_show ();") +JS_CB (MRL, "open_mrl_show ();") +JS_CB (Playlist, "playlist_show ();") +JS_CB (Prefs, "preferences_show ();") +JS_CB (Keys, "keybindings_show ();") +JS_CB (Snapshot, "snapshot ();") +JS_CB (Quit, "exit ();") + +/* View */ +JS_CB_T (Fullscreen) +{ + gtk_video_set_fullscreen (GTK_VIDEO(gtv), v); + if (v) + window_toolbar_restore (); + else + window_toolbar_reset (); +} +JS_CB_T (FSToolbarVisible) { window_toolbar_show (v); } +JS_CB_R (FSToolbarPos) { window_toolbar_position (v); } +JS_CB_R (Window) { gtk_video_rescale (GTK_VIDEO(gtv), (double) v / 100.0); } +JS_CB_T (WindowAutosize) { gtk_video_set_auto_resize (GTK_VIDEO(gtv), v); } +JS_CB_T (WindowMagLow) { gtk_video_set_auto_rescale (GTK_VIDEO(gtv), v); } +JS_CB (ZoomIn, "vo_zoom.v += 5;") +JS_CB (ZoomOut, "vo_zoom.v -= 5;") +JS_CB (Zoom100, "vo_zoom.v = 100;") +JS_CB_R (Aspect) { xine_set_param (stream, XINE_PARAM_VO_ASPECT_RATIO, v); } +JS_CB_R (Subtitles) +{ + if (v > -3) + xine_set_param (stream, XINE_PARAM_SPU_CHANNEL, v); +} + +/* Video */ +JS_CB (VideoSettings, "settings_show (0);") +JS_CB_T (Deinterlace) +{ + gtk_video_set_use_post_plugins_deinterlace (GTK_VIDEO(gtv), v); +} +JS_CB_T (VideoPP) { gtk_video_set_use_post_plugins_video (GTK_VIDEO(gtv), v); } +JS_CB (DeinterlaceConf, "deinterlace_show ();") +JS_CB (VideoPPConf, "postproc_video_show ();") + +/* Audio */ +JS_CB (AudioSettings, "settings_show (1);") +JS_CB (AudioEq, "settings_show (2);") +JS_CB_T (AudioPP) +{ + gtk_video_set_use_post_plugins_audio (GTK_VIDEO(gtv), v, audio_port); +} +JS_CB (AudioPPConf, "postproc_audio_show ();") + +/* Media */ +JS_CB (MediaAdd, "mm_add_show ();") +JS_CB (MediaManage, "mm_manage_show ();") +JS_CB (MediaImport, "import_mediamarks ();") + +/* Help */ +JS_CB (About, "about_show ();") +JS_CB (EngineLog, "log_show ();") +JS_CB (StreamInfo, "stream_info_show ();") +JS_CB (SetupWizards, "run_wizards ();") + +#define CB(name, stock, label, key) \ + { #name, (stock), (label), (key), NULL, G_CALLBACK(js_##name##_cb) } +static const GtkActionEntry main_actions[] = { + { "FileMenu", NULL, N_("_File") }, + CB(Open, GTK_STOCK_OPEN, N_("_Open..."), "<control>O"), + CB(MRL, GTK_STOCK_OPEN, N_("Open _MRL..."), "<control>M"), + CB(Playlist, "gxine-media-playlist", N_("Play_list..."), NULL), + CB(Prefs, GTK_STOCK_PREFERENCES, N_("_Preferences..."), NULL), + CB(Keys, GTK_STOCK_PREFERENCES, N_("_Keybindings..."), NULL), + CB(Snapshot, NULL, N_("_Snapshot..."), "<control>S"), + CB(Quit, GTK_STOCK_QUIT, N_("_Quit"), "<control>Q"), + { "ViewMenu", NULL, N_("_View") }, + { "FSToolbarMenu", NULL, N_("Fullscreen _toolbar") }, + { "WindowMenu", NULL, N_("_Window") }, + CB(ZoomIn, GTK_STOCK_ZOOM_IN, N_("Zoom _in"), NULL), + CB(ZoomOut, GTK_STOCK_ZOOM_OUT, N_("Zoom _out"), NULL), + CB(Zoom100, GTK_STOCK_ZOOM_100, N_("_Zoom 100%"), NULL), + { "AspectMenu", NULL, N_("_Aspect ratio"), NULL }, + { "VisMenu", NULL, N_("_Visualisations"), NULL }, + { "SubsMenu", NULL, N_("_Subtitles"), NULL }, + { "VideoMenu", NULL, N_("V_ideo"), NULL }, + CB(VideoSettings, GTK_STOCK_PROPERTIES, N_("_Settings..."), NULL), + { "VideoConfigMenu", NULL, N_("_Configure"), NULL }, + CB(DeinterlaceConf, GTK_STOCK_PREFERENCES, N_("_Deinterlace..."), NULL), + CB(VideoPPConf, GTK_STOCK_PREFERENCES, N_("_Post-processing..."), NULL), + { "AudioMenu", NULL, N_("_Audio"), NULL }, + CB(AudioSettings, GTK_STOCK_PREFERENCES, N_("_Settings..."), NULL), + CB(AudioEq, GTK_STOCK_PREFERENCES, N_("_Equaliser..."), NULL), + { "AudioConfigMenu", NULL, N_("_Configure"), NULL }, + CB(AudioPPConf, GTK_STOCK_PREFERENCES, N_("_Post-processing..."), NULL), + { "MediaMenu", NULL, N_("_Media"), NULL }, + CB(MediaAdd, GTK_STOCK_NEW, N_("_Add media mark.."), "<control>D"), + CB(MediaManage, NULL, N_("_Manage media marks..."), "<control>B"), + CB(MediaImport, GTK_STOCK_OPEN, N_("_Import media marks..."), NULL), + { "HelpMenu", NULL, N_("_Help"), NULL }, + CB(About, GTK_STOCK_ABOUT, N_("_About..."), NULL), + CB(EngineLog, NULL, N_("Engine _Log..."), "<control>L"), + CB(StreamInfo, NULL, N_("Stream _Info..."), NULL), + CB(SetupWizards, NULL, N_("_Re-run setup wizards..."), NULL), +}; +#undef CB + +#define CB(name, stock, label, key, state) \ + { #name, (stock), (label), (key), NULL, G_CALLBACK(js_##name##_cb), (state) } +typedef enum { + TOGGLE_FULLSCREEN, + TOGGLE_FULLSCREEN_TOOLBAR, + TOGGLE_WINDOW_AUTOSIZE, + TOGGLE_WINDOW_MAGNIFY, + TOGGLE_DEINTERLACE, + TOGGLE_VIDEO_PP, + TOGGLE_AUDIO_PP, +} toggle_actions_e; +static GtkToggleActionEntry toggle_actions[] = { + CB(Fullscreen, NULL, N_("_Fullscreen mode"), "<control>F", FALSE), + CB(FSToolbarVisible, NULL, N_("_Visible"), NULL, FALSE), + CB(WindowAutosize, NULL, N_("Auto _resize"), NULL, TRUE), + CB(WindowMagLow, NULL, N_("_Magnify low-res video"), NULL, FALSE), + CB(Deinterlace, NULL, N_("_Deinterlace"), "<control>I", FALSE), + CB(VideoPP, NULL, N_("_Post-processing"), NULL, FALSE), + CB(AudioPP, NULL, N_("_Post-processing"), NULL, FALSE), +}; +static const char *const toggle_prefs[] = { + NULL, NULL, NULL, + "gui.magnify_lowres_video", "gui.post_plugins.deinterlace_enable", + "gui.post_plugins.video_enable", "gui.post_plugins.audio_enable", }; +#undef CB -GtkWidget *create_menu_tree (GtkItemFactory **factory, GtkWidget *window, - GtkAccelGroup **accel, - GtkItemFactoryEntry *menu_items, - gint nmenu_items) +static const GtkRadioActionEntry +fstoolbar_actions[] = { + { "FSToolbarTop", NULL, N_("At _top"), NULL, NULL, 1 }, + { "FSToolbarBottom", NULL, N_("At _bottom"), NULL, NULL, 0 }, +}, +window_actions[] = { + { "WindowOther", NULL, "", NULL, NULL, 0 }, + { "Window50", NULL, N_("_50%"), NULL, NULL, 50 }, + { "Window100", NULL, N_("_100%"), NULL, NULL, 100 }, + { "Window200", NULL, N_("_200%"), NULL, NULL, 200 }, +}, +aspect_actions[] = { + { "AspectAuto", NULL, N_("_Auto"), NULL, NULL, XINE_VO_ASPECT_AUTO }, + { "AspectSquare", NULL, N_("_Square"), NULL, NULL, XINE_VO_ASPECT_SQUARE }, + { "Aspect4_3", NULL, N_("_4:3"), NULL, NULL, XINE_VO_ASPECT_4_3 }, + { "Aspect16_9", NULL, N_("_16:9"), NULL, NULL, XINE_VO_ASPECT_ANAMORPHIC }, + { "Aspect2_1", NULL, N_("_2:1"), NULL, NULL, XINE_VO_ASPECT_DVB }, +}, +vis_actions[] = { + { "VisNone", NULL, N_("_None"), NULL, NULL, 0 }, +}, +subtitle_actions[] = { + { "SubtitlesOther", NULL, "", NULL, NULL, -3 }, + { "SubtitlesNone", NULL, N_("_None"), NULL, NULL, -2 }, + { "SubtitlesAuto", NULL, N_("_Auto"), NULL, NULL, -1 }, + { "Subtitles0", NULL, N_("Channel _0"), NULL, NULL, 0 }, + { "Subtitles1", NULL, N_("Channel _1"), NULL, NULL, 1 }, + { "Subtitles2", NULL, N_("Channel _2"), NULL, NULL, 2 }, + { "Subtitles3", NULL, N_("Channel _3"), NULL, NULL, 3 }, + { "Subtitles4", NULL, N_("Channel _4"), NULL, NULL, 4 }, + { "Subtitles5", NULL, N_("Channel _5"), NULL, NULL, 5 }, + { "Subtitles6", NULL, N_("Channel _6"), NULL, NULL, 6 }, + { "Subtitles7", NULL, N_("Channel _7"), NULL, NULL, 7 }, +}; + +static GtkWidget *add_menu_ui (GtkUIManager *ui, int i) { - if (window) - { - GtkAccelGroup *accel_group = - (accel && *accel) ? *accel : gtk_accel_group_new (); - if (accel) - *accel = accel_group; - *factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", - accel_group); -#ifdef ENABLE_NLS - gtk_item_factory_set_translate_func (GTK_ITEM_FACTORY (*factory), - (GtkTranslateFunc) gettext, - NULL, NULL); -#endif - gtk_item_factory_create_items (*factory, nmenu_items, menu_items, NULL); - gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); - } - else + static const char def[] = + "<menu action='FileMenu'>\n" + "<menuitem action='Open' />\n" + "<menuitem action='MRL' />\n" + "<menuitem action='Playlist' />\n" + "<separator />\n" + "<menuitem action='Prefs' />\n" + "<menuitem action='Keys' />\n" + "<separator />\n" + "<placeholder name='AutoPlay' />\n" + "<separator />\n" + "<menuitem action='Snapshot' />\n" + "<menuitem action='Quit' />\n" + "</menu>\n" + "<menu action='ViewMenu'>\n" + "<menuitem action='Fullscreen' />\n" + "<menu action='FSToolbarMenu'>\n" + "<menuitem action='FSToolbarVisible' />\n" + "<menuitem action='FSToolbarTop' />\n" + "<menuitem action='FSToolbarBottom' />\n" + "</menu>\n" + "<separator />\n" + "<menu action='WindowMenu'>\n" + "<menuitem action='Window50' />\n" + "<menuitem action='Window100' />\n" + "<menuitem action='Window200' />\n" + "<menuitem action='WindowAutosize' />\n" + "<menuitem action='WindowMagLow' />\n" + "</menu>\n" + "<menuitem action='ZoomIn' />\n" + "<menuitem action='ZoomOut' />\n" + "<menuitem action='Zoom100' />\n" + "<menu action='AspectMenu'>\n" + "<menuitem action='AspectAuto' />\n" + "<menuitem action='AspectSquare' />\n" + "<menuitem action='Aspect4_3' />\n" + "<menuitem action='Aspect16_9' />\n" + "<menuitem action='Aspect2_1' />\n" + "</menu>\n" + "<separator />\n" + "<menu action='VisMenu'>\n" + "<menuitem action='VisNone' />\n" + "<placeholder name='VisItems' />\n" + "</menu>\n" + "<separator />\n" + "<menu action='SubsMenu'>\n" + "<menuitem action='SubtitlesAuto' />\n" + "<menuitem action='SubtitlesNone' />\n" + "<menuitem action='Subtitles0' />\n" + "<menuitem action='Subtitles1' />\n" + "<menuitem action='Subtitles2' />\n" + "<menuitem action='Subtitles3' />\n" + "<menuitem action='Subtitles4' />\n" + "<menuitem action='Subtitles5' />\n" + "<menuitem action='Subtitles6' />\n" + "<menuitem action='Subtitles7' />\n" + "</menu>\n" + "</menu>\n" + "<menu action='VideoMenu'>\n" + "<menuitem action='VideoSettings' />\n" + "<menuitem action='Deinterlace' />\n" + "<menuitem action='VideoPP' />\n" + "<menu action='VideoConfigMenu'>\n" + "<menuitem action='DeinterlaceConf' />\n" + "<menuitem action='VideoPPConf' />\n" + "</menu>\n" + "</menu>\n" + "<menu action='AudioMenu'>\n" + "<menuitem action='AudioSettings' />\n" + "<menuitem action='AudioEq' />\n" + "<menuitem action='AudioPP' />\n" + "<menu action='AudioConfigMenu'>\n" + "<menuitem action='AudioPPConf' />\n" + "</menu>\n" + "</menu>\n" + "<menu action='MediaMenu'>\n" + "<menuitem action='MediaAdd' />\n" + "<menuitem action='MediaManage' />\n" + "<menuitem action='MediaImport' />\n" + "<separator />\n" + "<placeholder name='MediaItems' />\n" + "</menu>\n" + "<menu action='HelpMenu' position='bot'>\n" + "<menuitem action='About' />\n" + "<menuitem action='EngineLog' />\n" + "<menuitem action='StreamInfo' />\n" + "<separator />\n" + "<menuitem action='SetupWizards' />\n" + "</menu>\n"; + GError *error = NULL; + char *key = NULL; + + char *xml = g_strdup_printf ("<ui><%s name='%s'>%s</%s></ui>", + type[i], type[i], def, type[i]); + gtk_ui_manager_add_ui_from_string (ui, xml, -1, &error); + free (xml); + + asreprintf (&key, "/ui/%s", type[i]); { - *factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL); -#ifdef ENABLE_NLS - gtk_item_factory_set_translate_func (GTK_ITEM_FACTORY (*factory), - (GtkTranslateFunc) gettext, - NULL, NULL); -#endif - gtk_item_factory_create_items (*factory, nmenu_items, menu_items, NULL); + GtkWidget *toplevel = gtk_ui_manager_get_widget (ui, key); + free (key); + return toplevel; } - - return gtk_item_factory_get_widget (*factory, "<main>"); } - void create_menus (GtkWidget *window) { - GtkItemFactory *item_factory[2]; - GtkRadioMenuItem *none_item; - int i; + GtkActionGroup *action; + static const int scale[] = { 50, 100, 200 }; - if (window) - menubar = create_menu_tree (&item_factory[0], window, NULL, - menu_items, num_menu_items (menu_items)); - popup_menu = create_menu_tree (&item_factory[1], NULL, NULL, - menu_items, num_menu_items (menu_items)); + ui = ui_create_manager ("gxine", window); + action = ui_get_action_group (ui); - for (i = !window; i < 2; ++i) - { - GtkMenuShell *menu; - xine_cfg_entry_t entry; + xine_cfg_entry_t entry; + int i; - media_menu[i] = GTK_MENU_SHELL (gtk_item_factory_get_widget (item_factory[i], "/Media")); + for (i = 0; i < G_N_ELEMENTS(toggle_prefs); ++i) + if (toggle_prefs[i] && + xine_config_lookup_entry (xine, toggle_prefs[i], &entry)) + toggle_actions[i].is_active = entry.num_value; + + if (!xine_config_lookup_entry (xine, "gui.fullscreen_toolbar", &entry)) + entry.num_value = 0; + toggle_actions[TOGGLE_FULLSCREEN_TOOLBAR].is_active = (entry.num_value >> 1) & 1; + +#define AG(group) (group), G_N_ELEMENTS((group)) + gtk_action_group_add_actions (action, AG(main_actions), NULL); + gtk_action_group_add_toggle_actions (action, AG(toggle_actions), NULL); + gtk_action_group_add_radio_actions (action, AG(fstoolbar_actions), !(entry.num_value & 1), G_CALLBACK(js_FSToolbarPos_cb), NULL); + if (!xine_config_lookup_entry (xine, "gui.window_size", &entry)) + entry.num_value = 0; + gtk_action_group_add_radio_actions (action, AG(window_actions), scale[entry.num_value], G_CALLBACK(js_Window_cb), NULL); + gtk_action_group_add_radio_actions (action, AG(aspect_actions), 0, G_CALLBACK(js_Aspect_cb), NULL); + gtk_action_group_add_radio_actions (action, AG(vis_actions), 0, G_CALLBACK(vis_cb), NULL); + gtk_action_group_add_radio_actions (action, AG(subtitle_actions), -1, G_CALLBACK(js_Subtitles_cb), NULL); - fullscreen_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Fullscreen mode")); + menubar = add_menu_ui (ui, 0); + popup_menu = add_menu_ui (ui, 1); - deinterlace_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/Video/Deinterlace")); - if (xine_config_lookup_entry (xine, "gui.post_plugins.deinterlace_enable", - &entry)) - deinterlace_menu_item[i]->active = entry.num_value; - - pp_video_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/Video/Post-processing")); - if (xine_config_lookup_entry (xine, "gui.post_plugins.video_enable", - &entry)) - pp_video_menu_item[i]->active = entry.num_value; - - pp_audio_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/Audio/Post-processing")); - if (xine_config_lookup_entry (xine, "gui.post_plugins.audio_enable", - &entry)) - pp_audio_menu_item[i]->active = entry.num_value; - - auto_resize_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Window/Auto resize")); - auto_resize_menu_item[i]->active = TRUE; - - auto_rescale_menu_item[i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Window/Magnify low-res video")); - if (xine_config_lookup_entry (xine, "gui.magnify_lowres_video", &entry)) - auto_rescale_menu_item[i]->active = entry.num_value; - - toolbar_item[0][i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Fullscreen toolbar/Visible")); - toolbar_item[1][i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Fullscreen toolbar/At bottom")); - toolbar_item[2][i] = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Fullscreen toolbar/At top")); - if (xine_config_lookup_entry (xine, "gui.fullscreen_toolbar", &entry)) - { - toolbar_item[0][i]->active = (entry.num_value >> 1) & 1; - toolbar_item[1][i]->active = (entry.num_value & 1); - toolbar_item[2][i]->active = !(entry.num_value & 1); - } - - none_item = GTK_RADIO_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Aspect ratio/Auto")); - aspect_menu_items[i] = gtk_radio_menu_item_get_group (none_item); - - menu = GTK_MENU_SHELL (gtk_item_factory_get_widget (item_factory[i], - "/File")); - add_autoplay_entries (menu, g_list_index (menu->children, - gtk_item_factory_get_widget (item_factory[i], - "/File/sep1"))); - - none_item = GTK_RADIO_MENU_ITEM (gtk_item_factory_get_item (item_factory[i], "/View/Visualisations/None")); - vis_menu[i] = GTK_MENU_SHELL (gtk_item_factory_get_widget (item_factory[i], "/View/Visualisations")); - add_vis_entries (vis_menu[i], none_item); + { + guint merge = gtk_ui_manager_new_merge_id (ui); + size_t n_autoplay = add_autoplay_actions (ui); + size_t n_vis = add_vis_actions (ui, get_action ("VisNone")); + menu_add_items (ui, "FileMenu/AutoPlay", AUTOPLAY_NAME, merge, n_autoplay); + menu_add_items (ui, "ViewMenu/VisMenu/VisItems", VIS_NAME, merge, n_vis); } + gtk_ui_manager_ensure_update (ui); + + action_items.fullscreen = get_toggle ("Fullscreen"); + action_items.auto_resize = get_toggle ("WindowAutosize"); + action_items.auto_rescale = get_toggle ("WindowMagLow"); + action_items.deinterlace = get_toggle ("Deinterlace"); + action_items.vo_postproc = get_toggle ("VideoPP"); + action_items.ao_postproc = get_toggle ("AudioPP"); + action_items.toolbar = get_toggle ("FSToolbarVisible"); + + action_items.aspect = get_radio_group ("AspectAuto"); + action_items.vis = get_radio_group ("VisNone"); + action_items.toolbar_pos = get_radio_group ("FSToolbarTop"); + action_items.video_size = get_radio_group ("Window50"); + action_items.subtitles = get_radio_group ("Subtitles0"); g_signal_connect (GTK_OBJECT(popup_menu), "key-press-event", G_CALLBACK(popup_key_cb), NULL); Index: menu.h =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/menu.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- menu.h 3 Jan 2005 22:06:04 -0000 1.4 +++ menu.h 11 May 2005 20:13:18 -0000 1.5 @@ -23,13 +23,11 @@ #ifndef HAVE_MENU_H #define HAVE_MENU_H -#include <gtk/gtk.h> +#include <gtk/gtkwidget.h> -#define num_menu_items(tree) (sizeof ((tree)) / sizeof ((tree)[0])) - -GtkWidget *create_menu_tree (GtkItemFactory **, GtkWidget *window, - GtkAccelGroup **, GtkItemFactoryEntry *, - gint items); void create_menus (GtkWidget *window); +void menu_add_items (GtkUIManager *, const char *const prefix, + const char *const label, guint merge, size_t count); +const char *menu_get_tree_name (int); #endif Index: noskin_window.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/noskin_window.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- noskin_window.c 6 May 2005 18:22:15 -0000 1.50 +++ noskin_window.c 11 May 2005 20:13:18 -0000 1.51 @@ -278,9 +278,17 @@ ui_set_status (UI_TOOLBAR); } +static void cw_toggle_cb (GtkWidget *widget) +{ + gtk_action_activate (action_items.toolbar); +} + static void cw_top_bottom_cb (GtkWidget *widget, GtkWidget *other) { - window_toolbar_position (widget == cw_top); + if (widget == cw_top) + gtk_action_activate (action_items.toolbar_pos->next->data); /* top */ + else + gtk_action_activate (action_items.toolbar_pos->data); /* bottom */ } static gboolean window_toolbar_configure_cb (GtkWidget *widget, @@ -504,8 +512,8 @@ w = button_icon_new (GTK_STOCK_CLOSE, _("Hide toolbar")); gtk_box_pack_start_defaults (GTK_BOX(vbox), w); - g_signal_connect_swapped (GTK_OBJECT(w), "clicked", - G_CALLBACK(ui_toolbar_toggle), NULL); + g_signal_connect (GTK_OBJECT(w), "clicked", + G_CALLBACK(cw_toggle_cb), NULL); cw_top = button_icon_new (GTK_STOCK_GO_UP, _("Move toolbar to top")); gtk_box_pack_start_defaults (GTK_BOX(vbox), cw_top); @@ -554,7 +562,7 @@ if (xine_config_lookup_entry (xine, "gui.window_size", &entry)) { - const float scale[] = { 0.5, 1, 2 }; + static const float scale[] = { 0.5, 1, 2 }; gtk_video_rescale ((GtkVideo *)gtv, scale[entry.num_value]); } if (xine_config_lookup_entry (xine, "gui.magnify_lowres_video", &entry)) Index: player.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/player.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- player.c 10 May 2005 02:14:43 -0000 1.37 +++ player.c 11 May 2005 20:13:18 -0000 1.38 @@ -39,6 +39,7 @@ #include "player.h" #define GXINE_VO_ZOOM_MIN (XINE_VO_ZOOM_MIN < 0 ? 0 : XINE_VO_ZOOM_MIN) +#define GXINE_MAX_SPU_CHANNEL (31) xine_stream_t *stream; /* global stream */ xine_audio_port_t *audio_port; @@ -193,93 +194,76 @@ xine_set_param (stream, XINE_PARAM_VO_ZOOM_Y, zoom); } -static void set_fullscreen (int fs) -{ - fullscreen_menu_item[0]->active = fs; - fullscreen_menu_item[1]->active = fs; - gtk_video_set_fullscreen (GTK_VIDEO(gtv), fs); - if (fs) - window_toolbar_restore (); - else - window_toolbar_reset (); -} +#define ACTION_SET(Func) \ + static void set_##Func (int v) \ + { \ + if (gtk_toggle_action_get_active (action_items.Func) != v) \ + gtk_action_activate (GTK_ACTION(action_items.Func)); \ + } +ACTION_SET(fullscreen) static void get_fullscreen (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_is_fullscreen (GTK_VIDEO(gtv)); } -static void set_deinterlace (int di) -{ - deinterlace_menu_item[0]->active = di; - deinterlace_menu_item[1]->active = di; - gtk_video_set_use_post_plugins_deinterlace (GTK_VIDEO(gtv), di); -} - +ACTION_SET(deinterlace) static void get_deinterlace (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_get_use_post_plugins_deinterlace (GTK_VIDEO(gtv)); } -static void set_aspect (int aspect) +static void set_subtitles (int sub) { - int i; - for (i = 0; i < 2; ++i) + if (sub >= -2 && sub <= GXINE_MAX_SPU_CHANNEL) { - GSList *menuitem = aspect_menu_items[i]; - int count = g_slist_length (menuitem); - while (--count >= 0) - { - GTK_CHECK_MENU_ITEM (menuitem->data)->active = (aspect == count); - menuitem = menuitem->next; + GSList *menuitem = action_items.subtitles; + int count = g_slist_length (menuitem) - 3; + if (count >= sub) + { + while (menuitem && --count > sub) + menuitem = menuitem->next; + if (menuitem) + { + gtk_action_activate (menuitem->data); + return; + } } + /* not in menu */ + gtk_action_activate (g_slist_last (action_items.subtitles)->data); + xine_set_param (stream, XINE_PARAM_SPU_CHANNEL, sub); } - xine_set_param (stream, XINE_PARAM_VO_ASPECT_RATIO, aspect); } -static void set_auto_resize (int ar) +static void set_aspect (int aspect) { - auto_resize_menu_item[0]->active = ar; - auto_resize_menu_item[1]->active = ar; - gtk_video_set_auto_resize (GTK_VIDEO(gtv), ar); + GSList *menuitem = action_items.aspect; + int count = g_slist_length (menuitem); + while (--count > aspect && menuitem->next) + menuitem = menuitem->next; + if (menuitem) + gtk_action_activate (menuitem->data); } +ACTION_SET(auto_resize) static void get_auto_resize (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_get_auto_resize (GTK_VIDEO(gtv)); } -static void set_auto_rescale (int ar) -{ - auto_rescale_menu_item[0]->active = ar; - auto_rescale_menu_item[1]->active = ar; - gtk_video_set_auto_rescale (GTK_VIDEO(gtv), ar); -} - +ACTION_SET(auto_rescale) static void get_auto_rescale (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_get_auto_rescale (GTK_VIDEO(gtv)); } -static void set_vo_postproc (int di) -{ - pp_video_menu_item[0]->active = di; - pp_video_menu_item[1]->active = di; - gtk_video_set_use_post_plugins_video (GTK_VIDEO(gtv), di); -} - +ACTION_SET(vo_postproc) static void get_vo_postproc (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_get_use_post_plugins_video (GTK_VIDEO(gtv)); } -static void set_ao_postproc (int di) -{ - pp_audio_menu_item[0]->active = di; - pp_audio_menu_item[1]->active = di; - gtk_video_set_use_post_plugins_audio (GTK_VIDEO(gtv), di, audio_port); -} - +ACTION_SET(ao_postproc) static void get_ao_postproc (se_prop_t *prop, se_prop_read_t *value) { value->i = gtk_video_get_use_post_plugins_audio (GTK_VIDEO(gtv)); @@ -568,7 +552,21 @@ else if (zoom>XINE_VO_ZOOM_MAX) zoom = XINE_VO_ZOOM_MAX; - gtk_video_rescale (GTK_VIDEO(gtv), (double) zoom / 100.0); + switch (zoom) + { + case 50: + gtk_action_activate (action_items.video_size->next->next->data); + break; + case 100: + gtk_action_activate (action_items.video_size->next->data); + break; + case 200: + gtk_action_activate (action_items.video_size->data); + break; + default: /* not in menu */ + gtk_action_activate (action_items.video_size->next->next->next->data); + gtk_video_rescale (GTK_VIDEO(gtv), (double) zoom / 100.0); + } return JS_TRUE; } @@ -1191,7 +1189,7 @@ static const player_prop_t int_props[] = { { "av_speed", N_("v=int, min, max; playback speed"), XINE_PARAM_SPEED, NULL, NULL, XINE_SPEED_PAUSE, XINE_SPEED_FAST_4 }, { "vo_aspect", N_("v=int; aspect ratio"), XINE_PARAM_VO_ASPECT_RATIO, NULL, set_aspect, 0, XINE_VO_ASPECT_NUM_RATIOS - 1, TRUE }, - { "vo_subtitle", N_("v=int, min, max; subtitle channel"), XINE_PARAM_SPU_CHANNEL, NULL, NULL, -1, 32 }, + { "vo_subtitle", N_("v=int, min, max; subtitle channel"), XINE_PARAM_SPU_CHANNEL, NULL, set_subtitles, -2, GXINE_MAX_SPU_CHANNEL }, { "vo_zoom", N_("v=int, min, max; video zoom (within window)"), XINE_PARAM_VO_ZOOM_X, NULL, set_zoom, XINE_VO_ZOOM_MIN, XINE_VO_ZOOM_MAX }, { NULL } }; Index: ui.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/ui.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ui.c 10 May 2005 17:26:57 -0000 1.9 +++ ui.c 11 May 2005 20:13:18 -0000 1.10 @@ -101,12 +101,10 @@ static void ui_int_toolbar_state (void) { - toolbar_item[0][0]->active = toolbar_visible; - toolbar_item[0][1]->active = toolbar_visible; - toolbar_item[1][0]->active = !toolbar_at_top; - toolbar_item[1][1]->active = !toolbar_at_top; - toolbar_item[2][0]->active = toolbar_at_top; - toolbar_item[2][1]->active = toolbar_at_top; + if (gtk_radio_action_get_current_value (action_items.toolbar_pos->data)) + gtk_action_activate (action_items.toolbar_pos->next->data); /* top */ + else + gtk_action_activate (action_items.toolbar_pos->data); /* bottom */ } /* Set/show play/pause/stop/mute status in control buttons */ @@ -303,7 +301,9 @@ { GtkUIManager *ui = gtk_ui_manager_new (); GtkActionGroup *action = gtk_action_group_new (label); +#ifdef ENABLE_NLS gtk_action_group_set_translation_domain (action, PACKAGE); +#endif gtk_ui_manager_insert_action_group (ui, action, 0); if (window) gtk_window_add_accel_group (GTK_WINDOW(window), @@ -362,7 +362,10 @@ if (engine_mutex_trylock (se)) return JS_TRUE; - window_toolbar_position (top); + if (gtk_radio_action_get_current_value (action_items.toolbar_pos->data)) + gtk_action_activate (action_items.toolbar_pos->next->data); /* top */ + else + gtk_action_activate (action_items.toolbar_pos->data); /* bottom */ pthread_mutex_unlock (&engine_lock); return JS_TRUE; Index: vis.c =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/vis.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- vis.c 4 May 2005 01:02:12 -0000 1.10 +++ vis.c 11 May 2005 20:13:19 -0000 1.11 @@ -30,6 +30,7 @@ #include "engine.h" #include "script_engine.h" #include "ui.h" +#include "utils.h" gboolean vis_show (GtkVideo *this, xine_audio_port_t **audio_port) { @@ -39,31 +40,31 @@ return gtk_video_set_vis (this, audio_port, TRUE); } -void vis_set (GtkVideo *this, const char *id, xine_audio_port_t **audio_p) +void vis_cb (GtkRadioAction *action, gpointer data) { - int i; - gtk_video_select_vis (this, id, audio_p); + gtk_video_select_vis (GTK_VIDEO(gtv), data, &audio_port); window_check_vis (TRUE); - for (i = 0; i < 2; ++i) +} + +void vis_set (const char *str) +{ + GSList *action; + foreach_glist (action, action_items.vis) { - GList *items = vis_menu[i]->children; - while (items) - { - GtkCheckMenuItem *item = items->data; - const char *data = g_object_get_data (G_OBJECT(item), "vis"); - if (!data && (!id || !strcasecmp ("none", id))) - item->active = TRUE; - else if (data && id && !strcasecmp (data, id)) - item->active = TRUE; - else - item->active = FALSE; - items = g_list_next (items); - } + char *name; + g_object_get (action->data, "name", &name, NULL); + if (name[0] != '_' && !strcasecmp (str, "none")) + break; + g_object_get (action->data, "label", &name, NULL); + if (!strcasecmp (str, name)) + break; } + if (action) + gtk_action_activate (action->data); } static JSBool js_set_vis (JSContext *cx, JSObject *obj, uintN argc, - jsval *argv, jsval *rval) + jsval *argv, jsval *rval) { se_t *se = (se_t *) JS_GetContextPrivate(cx); JSString *str; @@ -76,7 +77,7 @@ str = JS_ValueToString (cx, argv[0]); if (engine_mutex_trylock (se)) return JS_TRUE; - vis_set (GTK_VIDEO(gtv), JS_GetStringBytes (str), &audio_port); + vis_set (JS_GetStringBytes (str)); pthread_mutex_unlock (&engine_lock); return JS_TRUE; Index: vis.h =================================================================== RCS file: /cvsroot/xine/gnome-xine/src/vis.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- vis.h 4 May 2005 01:02:13 -0000 1.5 +++ vis.h 11 May 2005 20:13:19 -0000 1.6 @@ -23,11 +23,14 @@ #ifndef HAVE_VIS_H #define HAVE_VIS_H +#include <gtk/gtkradioaction.h> + #include "gtkvideo.h" #define vis_hide(V,A) gtk_video_set_vis ((V), (A), FALSE) gboolean vis_show (GtkVideo *, xine_audio_port_t **); -void vis_set (GtkVideo *, const char *, xine_audio_port_t **); +void vis_set (const char *); +void vis_cb (GtkRadioAction *, gpointer); void vis_init (void); |