/** * Callback function for the mixer element which is * set in alsaset(). * * @param e mixer element * @param mask event mask * @return 0 on success otherwise a negative error code */ static int alsa_cb(snd_mixer_elem_t *e, unsigned int mask) { /* Test MASK_REMOVE first, according to Alsa documentation */ if (mask == SND_CTL_EVENT_MASK_REMOVE) { return 0; } /* Then check if mixer value changed */ if (mask & SND_CTL_EVENT_MASK_VALUE) { int muted; get_current_levels(); muted = ismuted(); on_volume_has_changed(); if (enable_noti && external_noti) { int vol = getvol(); if (muted) do_notify_volume(vol, FALSE); else do_notify_volume(vol, TRUE); } } return 0; }
/** * Creates the volume popup window. */ void create_popup_window(void) { GtkBuilder *builder; GError *error = NULL; gchar *uifile; gchar *slider_orientation; slider_orientation = prefs_get_string("SliderOrientation", "vertical"); if (!g_strcmp0(slider_orientation, "horizontal")) uifile = get_ui_file(UI_FILE_POPUP_VOLUME_HORIZONTAL); else uifile = get_ui_file(UI_FILE_POPUP_VOLUME_VERTICAL); g_free(slider_orientation); if (!uifile) { report_error(_ ("Can't find the volume popup window interface file. " "Please ensure PNMixer is installed correctly. Exiting.")); exit(1); } DEBUG_PRINT("Loading volume popup ui from '%s'", uifile); builder = gtk_builder_new(); if (!gtk_builder_add_from_file(builder, uifile, &error)) { g_warning("%s", error->message); report_error(error->message); exit(1); } g_free(uifile); vol_adjustment = GTK_ADJUSTMENT(gtk_builder_get_object(builder, "vol_scale_adjustment")); /* get original adjustments */ get_current_levels(); vol_scale = GTK_WIDGET(gtk_builder_get_object(builder, "vol_scale")); mute_check_popup_window = GTK_WIDGET(gtk_builder_get_object(builder, "mute_check_popup_window")); popup_window = GTK_WIDGET(gtk_builder_get_object(builder, "popup_window")); gtk_builder_connect_signals(builder, NULL); g_object_unref(G_OBJECT(builder)); gtk_widget_grab_focus(vol_scale); }
/** * Handles the 'activate' signal on the tray_icon, * usually opening the popup_window and grabbing pointer and keyboard. * * @param status_icon the object which received the signal * @param user_data user data set when the signal handler was connected */ void tray_icon_on_click(G_GNUC_UNUSED GtkStatusIcon *status_icon, G_GNUC_UNUSED gpointer user_data) { get_current_levels(); if (!gtk_widget_get_visible(GTK_WIDGET(popup_window))) { gtk_widget_show_now(popup_window); gtk_widget_grab_focus(vol_scale); #ifdef WITH_GTK3 GdkDevice *pointer_dev = gtk_get_current_event_device(); if (pointer_dev != NULL) { GdkDevice *keyboard_dev = gdk_device_get_associated_device(pointer_dev); if (gdk_device_grab(pointer_dev, gtk_widget_get_window(GTK_WIDGET(popup_window)), GDK_OWNERSHIP_NONE, TRUE, GDK_BUTTON_PRESS_MASK, NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) g_warning("Could not grab %s\n", gdk_device_get_name(pointer_dev)); if (keyboard_dev != NULL) { if (gdk_device_grab(keyboard_dev, gtk_widget_get_window(GTK_WIDGET(popup_window)), GDK_OWNERSHIP_NONE, TRUE, GDK_KEY_PRESS_MASK, NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) g_warning("Could not grab %s\n", gdk_device_get_name(keyboard_dev)); } } #else gdk_keyboard_grab(gtk_widget_get_window(popup_window), TRUE, GDK_CURRENT_TIME); gdk_pointer_grab(gtk_widget_get_window(popup_window), TRUE, GDK_BUTTON_PRESS_MASK, NULL, NULL, GDK_CURRENT_TIME); #endif } else { gtk_widget_hide(popup_window); } }
/** * This function is called before gdk/gtk can respond * to any(!) window event and handles pressed hotkeys. * * @param gdk_xevent the native event to filter * @param event the GDK event to which the X event will be translated * @param data user data set when the filter was installed * @return a GdkFilterReturn value, should be GDK_FILTER_CONTINUE only */ static GdkFilterReturn key_filter(GdkXEvent *gdk_xevent, G_GNUC_UNUSED GdkEvent *event, G_GNUC_UNUSED gpointer data) { int type; guint key, state; XKeyEvent *xevent; //gboolean bResult; xevent = gdk_xevent; type = xevent->type; if (type == KeyPress) { key = ((XKeyEvent *) xevent)->keycode; state = ((XKeyEvent *) xevent)->state; if ((int) key == volMuteKey && checkModKey(state, volMuteMods)) { setmute(enable_noti && hotkey_noti); on_volume_has_changed(); return GDK_FILTER_CONTINUE; } else { int cv = getvol(); if ((int) key == volUpKey && checkModKey(state, volUpMods)) { setvol(cv + volStep, 1, enable_noti && hotkey_noti); } else if ((int) key == volDownKey && checkModKey(state, volDownMods)) { setvol(cv - volStep, -1, enable_noti && hotkey_noti); } // just ignore unknown hotkeys if (ismuted() == 0) setmute(enable_noti && hotkey_noti); on_volume_has_changed(); // this will set the slider value get_current_levels(); } } return GDK_FILTER_CONTINUE; }
static GdkFilterReturn key_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { int type; unsigned int key,state; XKeyEvent *xevent; //gboolean bResult; xevent = gdk_xevent; type = xevent->type; if (type == KeyPress) { key = ((XKeyEvent *)xevent)->keycode; state = ((XKeyEvent *)xevent)->state; if (key == volMuteKey && state == volMuteMods) { setmute(enable_noti&&hotkey_noti); get_mute_state(TRUE); return GDK_FILTER_CONTINUE; } else { int cv = getvol(); if (key == volUpKey && state == volUpMods) { setvol(cv+volStep,enable_noti&&hotkey_noti); } else if (key == volDownKey && state == volDownMods) { setvol(cv-volStep,enable_noti&&hotkey_noti); } // just ignore unknown hotkeys if (get_mute_state(TRUE) == 0) setmute(enable_noti&&hotkey_noti); // this will set the slider value get_current_levels(); } } return GDK_FILTER_CONTINUE; }
/** * Creates the popup windows from popup_window-gtk3.xml or * popup_window-gtk2.xml */ void create_popups (void) { GtkBuilder *builder; GError *error = NULL; gchar *uifile; builder = gtk_builder_new(); #ifdef WITH_GTK3 uifile = get_ui_file("popup_window-gtk3.xml"); #else uifile = get_ui_file("popup_window-gtk2.xml"); #endif if (!uifile) { report_error(_("Can't find main user interface file. Please insure PNMixer is installed correctly. Exiting\n")); exit(1); } if (!gtk_builder_add_from_file( builder, uifile, &error )) { g_warning("%s",error->message); report_error(error->message); exit(1); } g_free(uifile); vol_adjustment = GTK_ADJUSTMENT(gtk_builder_get_object(builder,"vol_scale_adjustment")); /* get original adjustments */ get_current_levels(); vol_scale = GTK_WIDGET(gtk_builder_get_object(builder,"vol_scale")); mute_check = GTK_WIDGET(gtk_builder_get_object(builder,"mute_check")); popup_window = GTK_WIDGET(gtk_builder_get_object(builder,"popup_window")); popup_menu = GTK_WIDGET(gtk_builder_get_object(builder,"popup_menu")); gtk_builder_connect_signals(builder, NULL); g_object_unref (G_OBJECT (builder)); gtk_widget_grab_focus(vol_scale); }
GtkWidget* create_volume_window (void) { accel_group = gtk_accel_group_new (); volume_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (volume_window, 60, 240); gtk_container_set_border_width (GTK_CONTAINER (volume_window), 2); gtk_window_set_resizable (GTK_WINDOW (volume_window), FALSE); gtk_window_set_position (GTK_WINDOW (volume_window), GTK_WIN_POS_MOUSE); gtk_window_set_decorated (GTK_WINDOW (volume_window), FALSE); gtk_window_set_skip_taskbar_hint( GTK_WINDOW (volume_window), TRUE ); frame = gtk_frame_new (_("Volume")); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (frame), vbox1); gtk_container_add (GTK_CONTAINER (volume_window), frame); gtk_widget_show (frame); vol_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 100, 1, 10, 0)); /* get original adjustments */ get_current_levels(); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 8); /* ajustment, climb rate, digits */ spinbutton1 = gtk_spin_button_new (GTK_ADJUSTMENT (vol_adjustment), 1, 0); gtk_widget_show (spinbutton1); gtk_box_pack_start (GTK_BOX (hbox1), spinbutton1, TRUE, FALSE, 0); gtk_widget_set_size_request (spinbutton1, -1, 22); g_signal_connect ((gpointer) spinbutton1, "value-changed", G_CALLBACK (on_spinbutton1_button_release_event), NULL); g_object_set_data_full(G_OBJECT (volume_window), "spinbutton1", gtk_widget_ref (spinbutton1), (GDestroyNotify) gtk_widget_unref); hbox3 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox3); gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, TRUE, 5); vscale1 = gtk_vscale_new (GTK_ADJUSTMENT (vol_adjustment)); gtk_widget_show (vscale1); gtk_range_set_inverted (GTK_RANGE (vscale1), TRUE); gtk_box_pack_start (GTK_BOX (hbox3), vscale1, TRUE, TRUE, 0); gtk_scale_set_draw_value (GTK_SCALE (vscale1), FALSE); g_signal_connect ((gpointer) vscale1, "button-release-event", G_CALLBACK (on_vscale1_button_release_event), vol_adjustment); g_object_set_data_full(G_OBJECT (volume_window), "vscale1", gtk_widget_ref (vscale1), (GDestroyNotify) gtk_widget_unref); hbox4 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox4); gtk_box_pack_start (GTK_BOX (vbox1), hbox4, FALSE, TRUE, 8); g_signal_connect ((gpointer) volume_window, "destroy", G_CALLBACK (gtk_widget_destroy), NULL); g_object_set_data (G_OBJECT (volume_window), "volume_window", volume_window); g_object_set_data_full (G_OBJECT (volume_window), "frame", gtk_widget_ref (frame), (GDestroyNotify) gtk_widget_unref); g_object_set_data_full (G_OBJECT (volume_window), "vbox1", gtk_widget_ref (vbox1), (GDestroyNotify) gtk_widget_unref); g_object_set_data_full (G_OBJECT (volume_window), "hbox1", gtk_widget_ref (hbox1), (GDestroyNotify) gtk_widget_unref); g_object_set_data_full (G_OBJECT (volume_window), "hbox3", gtk_widget_ref (hbox3), (GDestroyNotify) gtk_widget_unref); g_object_set_data_full (G_OBJECT (volume_window), "hbox4", gtk_widget_ref (hbox4), (GDestroyNotify) gtk_widget_unref); gtk_window_add_accel_group (GTK_WINDOW (volume_window), accel_group); vol_spin = spinbutton1; return volume_window; }