Merging upstream version 0.8.1.
[debian/lxpanel.git] / plugins / volume / volume-impl.c
1 /**
2 * Copyright (c) 2006, 2008 LxDE Developers,
3 * see the file AUTHORS for details.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/ioctl.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <gdk/gdkkeysyms.h>
32 #include <gtk/gtk.h>
33 #include <glib/gi18n.h>
34
35 #include "volume-impl.h"
36
37 #ifdef HAVE_SYS_SOUNDCARD_H
38 #include <sys/soundcard.h>
39 #elif defined(HAVE_LINUX_SOUNDCARD_H)
40 #include <linux/soundcard.h>
41 #else
42 #error "Not supported platform"
43 #endif
44
45 #include <fcntl.h>
46
47 extern int mixer_fd;
48 extern GtkSpinButton* vol_spin;
49
50 typedef struct stereovolume
51 {
52 unsigned char left;
53 unsigned char right;
54 } StereoVolume;
55
56 static StereoVolume tmpvol;
57
58 typedef struct _originalset
59 {
60 unsigned char mainvol;
61 unsigned char pcm;
62 unsigned char speaker;
63 unsigned char line1;
64 unsigned char cd;
65 unsigned char mic;
66 } originalset;
67
68 static originalset orig;
69
70 static GtkWidget *volume_window;
71 static GtkWidget *vbox1;
72 static GtkWidget *hbox1;
73 static GtkWidget *spinbutton1;
74 static GtkWidget *hbox3;
75 static GtkWidget *vscale1;
76 static GtkAccelGroup *accel_group;
77 static GtkAdjustment *vol_adjustment;
78 static GtkWidget *hbox4;
79 static GtkWidget *frame;
80
81 static gboolean
82 on_spinbutton1_button_release_event (GtkWidget *widget,
83 GdkEventButton *event,
84 gpointer user_data);
85
86 static gboolean
87 on_vscale1_button_release_event (GtkWidget *widget,
88 GdkEventButton *event,
89 gpointer user_data);
90
91 static void
92 get_current_levels()
93 {
94 ioctl(mixer_fd, MIXER_READ(SOUND_MIXER_VOLUME), &tmpvol);
95 orig.mainvol = tmpvol.left;
96 gtk_adjustment_set_value(GTK_ADJUSTMENT(vol_adjustment), (double) tmpvol.left);
97 }
98
99 GtkWidget*
100 create_volume_window (void)
101 {
102 accel_group = gtk_accel_group_new ();
103
104 volume_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
105 gtk_widget_set_size_request (volume_window, 60, 240);
106 gtk_container_set_border_width (GTK_CONTAINER (volume_window), 2);
107
108 gtk_window_set_resizable (GTK_WINDOW (volume_window), FALSE);
109 gtk_window_set_position (GTK_WINDOW (volume_window), GTK_WIN_POS_MOUSE);
110 gtk_window_set_decorated (GTK_WINDOW (volume_window), FALSE);
111 gtk_window_set_skip_taskbar_hint( GTK_WINDOW (volume_window), TRUE );
112
113 frame = gtk_frame_new (_("Volume"));
114
115 vbox1 = gtk_vbox_new (FALSE, 0);
116 gtk_widget_show (vbox1);
117 gtk_container_add (GTK_CONTAINER (frame), vbox1);
118 gtk_container_add (GTK_CONTAINER (volume_window), frame);
119 gtk_widget_show (frame);
120 vol_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 100, 1, 10, 0));
121
122 /* get original adjustments */
123 get_current_levels();
124
125 hbox1 = gtk_hbox_new (FALSE, 0);
126 gtk_widget_show (hbox1);
127 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 8);
128
129
130 /* ajustment, climb rate, digits */
131 spinbutton1 = gtk_spin_button_new (GTK_ADJUSTMENT (vol_adjustment), 1, 0);
132 gtk_widget_show (spinbutton1);
133
134 gtk_box_pack_start (GTK_BOX (hbox1), spinbutton1, TRUE, FALSE, 0);
135 gtk_widget_set_size_request (spinbutton1, -1, 22);
136 g_signal_connect ((gpointer) spinbutton1, "value-changed",
137 G_CALLBACK (on_spinbutton1_button_release_event),
138 NULL);
139 g_object_set_data_full(G_OBJECT (volume_window), "spinbutton1",
140 gtk_widget_ref (spinbutton1),
141 (GDestroyNotify) gtk_widget_unref);
142
143 hbox3 = gtk_hbox_new (FALSE, 0);
144 gtk_widget_show (hbox3);
145 gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, TRUE, 5);
146
147 vscale1 = gtk_vscale_new (GTK_ADJUSTMENT (vol_adjustment));
148 gtk_widget_show (vscale1);
149 gtk_range_set_inverted (GTK_RANGE (vscale1), TRUE);
150 gtk_box_pack_start (GTK_BOX (hbox3), vscale1, TRUE, TRUE, 0);
151 gtk_scale_set_draw_value (GTK_SCALE (vscale1), FALSE);
152 g_signal_connect ((gpointer) vscale1, "button-release-event",
153 G_CALLBACK (on_vscale1_button_release_event),
154 vol_adjustment);
155 g_object_set_data_full(G_OBJECT (volume_window), "vscale1",
156 gtk_widget_ref (vscale1),
157 (GDestroyNotify) gtk_widget_unref);
158
159 hbox4 = gtk_hbox_new (FALSE, 0);
160 gtk_widget_show (hbox4);
161 gtk_box_pack_start (GTK_BOX (vbox1), hbox4, FALSE, TRUE, 8);
162
163 g_signal_connect ((gpointer) volume_window, "destroy",
164 G_CALLBACK (gtk_widget_destroy),
165 NULL);
166
167 g_object_set_data (G_OBJECT (volume_window), "volume_window", volume_window);
168 g_object_set_data_full (G_OBJECT (volume_window), "frame",
169 gtk_widget_ref (frame),
170 (GDestroyNotify) gtk_widget_unref);
171 g_object_set_data_full (G_OBJECT (volume_window), "vbox1",
172 gtk_widget_ref (vbox1),
173 (GDestroyNotify) gtk_widget_unref);
174 g_object_set_data_full (G_OBJECT (volume_window), "hbox1",
175 gtk_widget_ref (hbox1),
176 (GDestroyNotify) gtk_widget_unref);
177 g_object_set_data_full (G_OBJECT (volume_window), "hbox3",
178 gtk_widget_ref (hbox3),
179 (GDestroyNotify) gtk_widget_unref);
180 g_object_set_data_full (G_OBJECT (volume_window), "hbox4",
181 gtk_widget_ref (hbox4),
182 (GDestroyNotify) gtk_widget_unref);
183
184 gtk_window_add_accel_group (GTK_WINDOW (volume_window), accel_group);
185
186 vol_spin = spinbutton1;
187
188 return volume_window;
189 }
190
191 static StereoVolume vol;
192
193 static gboolean
194 on_spinbutton1_button_release_event (GtkWidget *widget,
195 GdkEventButton *event,
196 gpointer user_data)
197 {
198 GtkSpinButton *spin;
199 extern GtkWidget *spinbutton1;
200 spin = GTK_SPIN_BUTTON (spinbutton1);
201 vol.left = vol.right = (int) gtk_spin_button_get_value_as_int (spin);
202 ioctl(mixer_fd,MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
203
204 return FALSE;
205 }
206
207 static gboolean
208 on_vscale1_button_release_event (GtkWidget *widget,
209 GdkEventButton *event,
210 gpointer user_data)
211 {
212 vol.left = vol.right =
213 (int) gtk_adjustment_get_value(GTK_ADJUSTMENT(user_data));
214 ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
215 return FALSE;
216 }