📄 mainapp.cpp
字号:
}}ginthxwindow_handle_remote_command(HXMainWindow* window, const gchar* remote_command){ GError* error = NULL; gint argc; gchar** argv; gboolean parse_result; gint result = -1; parse_result = g_shell_parse_argv(remote_command, &argc, &argv, &error); if(error) { g_warning(error->message); g_free(error); return -1; } g_return_val_if_fail(parse_result, -1); if(argc > 0) { if(strcasecmp(argv[0], "OpenURL") == 0 && argc == 2) { hxwindow_open(window, argv[1]); result = 0; } } g_strfreev(argv); return result;}/* Signal handler implementations (hmw_*, houd_*) * Remaining HXMainWindow function implementations (hxwindow_*) * ======================================================== * Often, a hwm_* function will lookup the hxwindow object * associated with the window, and call the corresponding * hxwindow function. * * XXXRGG: hmw's and hxwindow's could be combined if we * could set the user_data argument with glade in an easy way, * and tell glade to connect signals swapped. *//* Creation function for a custom HXBin widget */GtkWidget*hmw_create_hxbin(gchar *, gchar *, gchar *, gint, gint){ GtkWidget* hxbin; hxbin = hx_bin_new(); gtk_widget_show(hxbin); return hxbin;}GtkWidget*hmw_create_status_area(gchar *, gchar *, gchar *, gint, gint){ GtkWidget* status_display; status_display = hxstatus_display_top_new(); gtk_widget_show(status_display); return status_display;}GtkWidget*hmw_create_position_slider(gchar *, gchar *, gchar *, gint, gint){ GtkWidget* slider; slider = hxstatus_display_position_slider_new(); gtk_widget_show(slider); return slider;}voidhmw_realize (GtkWidget* widget, gpointer){ /* Add properties for remote operation */ GdkAtom hxplay_remote_version; GdkAtom xa_string; hxplay_remote_version = gdk_atom_intern(HXPLAY_REMOTE_VERSION_PROP, FALSE); xa_string = gdk_x11_xatom_to_atom(XA_STRING); gdk_property_change (widget->window, hxplay_remote_version, xa_string, 8, GDK_PROP_MODE_REPLACE, (const guchar*) HXPLAY_REMOTE_VERSION, sizeof(HXPLAY_REMOTE_VERSION));}gbooleanhmw_configure_event(GtkWidget* widget, GdkEventConfigure *event, gpointer){ HXMainWindow* window = hxwindow_get_from_widget(widget); window->x_pos = event->x; window->y_pos = event->y; return FALSE; // propagate event}gbooleanhmw_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data){ /* XXXRGG: This function is driven from hmw_property_notify_event instead of gtk-2.0, as gtk-2.0.x does not synthesize fullscreen and above events. When our gtk baseline goes up, property_notify will go away, and this function will be hooked up the the window-state-event signal directly. */ HXMainWindow* window = hxwindow_get_from_widget(widget); g_return_val_if_fail(event != NULL, FALSE); /* Other states of interest: GDK_WINDOW_STATE_WITHDRAWN GDK_WINDOW_STATE_ICONIFIED GDK_WINDOW_STATE_MAXIMIZED GDK_WINDOW_STATE_STICKY GDK_WINDOW_STATE_BELOW */ if(event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) { if(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) { window->is_fullscreened = TRUE; } else { window->is_fullscreened = FALSE; } hxwindow_update_fullscreen(window); } if(event->changed_mask & GDK_WINDOW_STATE_ABOVE) { /* Update the menu */ if(window->on_top_always_menu_item && window->on_top_while_playing_menu_item && window->on_top_always_menu_item) { gboolean is_on_top = event->new_window_state & GDK_WINDOW_STATE_ABOVE; switch(window->on_top) { case ON_TOP_WHILE_PLAYING: /* If we were expecting an on top event, great. If we weren't, the user is changing on top, probably via the window manager. If this is the case, revert to always/never on top. */ if(window->on_top_while_playing_request_pending) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(window->on_top_while_playing_menu_item), TRUE); window->on_top_while_playing_request_pending = FALSE; break; } /* Not our request -- fall through and flip to either always on top or never on top as appropriate. */ case ON_TOP_ALWAYS: case ON_TOP_NEVER: default: if(is_on_top) { window->on_top = ON_TOP_ALWAYS; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(window->on_top_always_menu_item), TRUE); } else { window->on_top = ON_TOP_NEVER; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(window->on_top_never_menu_item), TRUE); } break; } } } return FALSE;}gbooleanhmw_property_notify_event(GtkWidget *widget, GdkEventProperty *event, gpointer){ /* XXXRGG: The _NET_WM_STATE portion of this function should be removed when our gtk baseline goes up. */ GdkAtom net_wm_state; GdkAtom hxplay_remote_command; GdkAtom hxplay_remote_response; GdkAtom xa_string; GdkAtom type; gint format; gint length; GdkAtom* atoms = NULL; gint i; gboolean result; static gboolean last_is_above = FALSE; static gboolean last_is_fullscreen = FALSE; net_wm_state = gdk_atom_intern("_NET_WM_STATE", FALSE); hxplay_remote_command = gdk_atom_intern(HXPLAY_REMOTE_COMMAND_PROP, FALSE); hxplay_remote_response = gdk_atom_intern(HXPLAY_REMOTE_RESPONSE_PROP, FALSE); xa_string = gdk_x11_xatom_to_atom(XA_STRING); if(event->atom == net_wm_state) { GdkAtom fullscreen_atom, above_atom; gboolean is_above = FALSE; gboolean is_fullscreen = FALSE; fullscreen_atom = gdk_atom_intern("_NET_WM_STATE_FULLSCREEN", FALSE); above_atom = gdk_atom_intern("_NET_WM_STATE_ABOVE", FALSE); result = gdk_property_get(widget->window, net_wm_state, 0, 0, G_MAXLONG - 3, FALSE, &type, &format, &length, (guchar**)&atoms); if(result) { for(i = 0; i < length; i++) { if(atoms[i] == fullscreen_atom) { is_fullscreen = TRUE; } else if(atoms[i] == above_atom) { is_above = TRUE; } } g_free(atoms); GdkEventWindowState temp_event; temp_event.window = widget->window; temp_event.type = GDK_WINDOW_STATE; temp_event.send_event = FALSE; temp_event.new_window_state = (GdkWindowState)0; temp_event.changed_mask = (GdkWindowState)0; if(is_fullscreen) { temp_event.new_window_state = (GdkWindowState) (temp_event.new_window_state | GDK_WINDOW_STATE_FULLSCREEN); } if(is_above) { temp_event.new_window_state = (GdkWindowState) (temp_event.new_window_state | GDK_WINDOW_STATE_ABOVE); } if(is_fullscreen != last_is_fullscreen) { temp_event.changed_mask = (GdkWindowState) (temp_event.changed_mask | GDK_WINDOW_STATE_FULLSCREEN); } if(is_above != last_is_above) { temp_event.changed_mask = (GdkWindowState) (temp_event.changed_mask | GDK_WINDOW_STATE_ABOVE); } hmw_window_state_event(widget, &temp_event, NULL); last_is_above = is_above; last_is_fullscreen = is_fullscreen; } } else if(event->atom == hxplay_remote_command && event->state == GDK_PROPERTY_NEW_VALUE) { gchar* remote_command = NULL; gint response = -1; gchar* remote_response = NULL; /* Process the command */ result = gdk_property_get(widget->window, hxplay_remote_command, xa_string, 0, G_MAXLONG - 3, TRUE, &type, &format, &length, (guchar**)&remote_command); if(result && format == 8 && length > 0 && type == xa_string && remote_command) { HXMainWindow* window = hxwindow_get_from_widget(widget); response = hxwindow_handle_remote_command(window, remote_command); } remote_response = g_strdup_printf("%d", response); /* Set the response property */ gdk_property_change (widget->window, hxplay_remote_response, xa_string, 8, GDK_PROP_MODE_REPLACE, (const guchar*) remote_response, strlen(remote_response) + 1); gdk_flush(); g_free(remote_command); g_free(remote_response); } return FALSE; // propagate}/* This function gets a HXMainWindow object associated with a given window, given a widget somewhere in that window. We use this instead of setting the data on gtk signals to make signal hookup using glade_xml_signal_autoconnect work easily. */HXMainWindow*hxwindow_get_from_widget(GtkWidget* widget){ GtkWidget* toplevel; HXMainWindow* window; toplevel = hxcommon_get_toplevel_widget_no_menus(widget); window = (HXMainWindow*) g_object_get_data(G_OBJECT(toplevel), "hxwindow"); g_assert(window != NULL); return window;}/* Main menu callbacks & supporting functions *//* Helper function to feed data from stdin to a datastream */static gbooleanwrite_stream_data(GIOChannel *channel, GIOCondition condition, gpointer data){ gchar buf[1024]; gsize bytes_read; GError* error; GIOStatus status; HXPlayer* window = HX_PLAYER(data); HXDataStream* stream = (HXDataStream*)g_object_get_data(G_OBJECT(window), "stream"); g_return_val_if_fail(window != NULL, TRUE); g_return_val_if_fail(stream != NULL, TRUE); if(condition == G_IO_IN) { do { error = NULL; status = g_io_channel_read_chars(channel, buf, sizeof(buf), &bytes_read, &error); if(error) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "g_io_channel_read_chars: %s", error->message); g_free(error); } switch(status) { case G_IO_STATUS_ERROR: case G_IO_STATUS_EOF: hx_player_close_data_stream(window, stream); /* Remove input source */ return FALSE; case G_IO_STATUS_AGAIN: continue; case G_IO_STATUS_NORMAL: hx_player_write_data_stream(window, stream, buf, bytes_read); break; default: g_assert(FALSE); /* not reached */ } } while(status == G_IO_STATUS_NORMAL); } r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -