Enabling multithreaded compilation.
[debian/lxpanel.git] / src / 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 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/ioctl.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <stdio.h>
26
27 #include <gdk/gdkkeysyms.h>
28 #include <gtk/gtk.h>
29 #include <glib/gi18n.h>
30
31 #include "volume-impl.h"
32
33 #ifdef __FreeBSD__
34 #include <sys/soundcard.h>
35 #elif defined(__linux__) || defined(__Linux__)
36 #include <linux/soundcard.h>
37 #else
38 #error "Not supported platform"
39 #endif
40
41 #include <fcntl.h>
42
43 extern int mixer_fd;
44 extern GtkSpinButton* vol_spin;
45
46 typedef struct stereovolume
47 {
48 unsigned char left;
49 unsigned char right;
50 } StereoVolume;
51
52 static StereoVolume tmpvol;
53
54 typedef struct _originalset
55 {
56 unsigned char mainvol;
57 unsigned char pcm;
58 unsigned char speaker;
59 unsigned char line1;
60 unsigned char cd;
61 unsigned char mic;
62 } originalset;
63
64 static originalset orig;
65
66 static GtkWidget *volume_window;
67 static GtkWidget *vbox1;
68 static GtkWidget *hbox1;
69 static GtkWidget *spinbutton1;
70 static GtkWidget *hbox3;
71 static GtkWidget *vscale1;
72 static GtkAccelGroup *accel_group;
73 static GtkAdjustment *vol_adjustment;
74 static GtkWidget *hbox4;
75 static GtkWidget *frame;
76
77 static gboolean
78 on_spinbutton1_button_release_event (GtkWidget *widget,
79 GdkEventButton *event,
80 gpointer user_data);
81
82 static gboolean
83 on_vscale1_button_release_event (GtkWidget *widget,
84 GdkEventButton *event,
85 gpointer user_data);
86
87 static void
88 get_current_levels()
89 {
90 ioctl(mixer_fd, MIXER_READ(SOUND_MIXER_VOLUME), &tmpvol);
91 orig.mainvol = tmpvol.left;
92 gtk_adjustment_set_value(GTK_ADJUSTMENT(vol_adjustment), (double) tmpvol.left);
93 }
94
95 GtkWidget*
96 create_volume_window (void)
97 {
98 accel_group = gtk_accel_group_new ();
99
100 volume_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
101 gtk_widget_set_size_request (volume_window, 60, 240);
102 gtk_container_set_border_width (GTK_CONTAINER (volume_window), 2);
103
104 gtk_window_set_resizable (GTK_WINDOW (volume_window), FALSE);
105 gtk_window_set_position (GTK_WINDOW (volume_window), GTK_WIN_POS_MOUSE);
106 gtk_window_set_decorated (GTK_WINDOW (volume_window), FALSE);
107 gtk_window_set_skip_taskbar_hint( GTK_WINDOW (volume_window), TRUE );
108
109 frame = gtk_frame_new (_("Volume"));
110
111 vbox1 = gtk_vbox_new (FALSE, 0);
112 gtk_widget_show (vbox1);
113 gtk_container_add (GTK_CONTAINER (frame), vbox1);
114 gtk_container_add (GTK_CONTAINER (volume_window), frame);
115 gtk_widget_show (frame);
116 vol_adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 100, 1, 10, 0));
117
118 /* get original adjustments */
119 get_current_levels();
120
121 hbox1 = gtk_hbox_new (FALSE, 0);
122 gtk_widget_show (hbox1);
123 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 8);
124
125
126 /* ajustment, climb rate, digits */
127 spinbutton1 = gtk_spin_button_new (GTK_ADJUSTMENT (vol_adjustment), 1, 0);
128 gtk_widget_show (spinbutton1);
129
130 gtk_box_pack_start (GTK_BOX (hbox1), spinbutton1, TRUE, FALSE, 0);
131 gtk_widget_set_size_request (spinbutton1, -1, 22);
132 g_signal_connect ((gpointer) spinbutton1, "value_changed",
133 G_CALLBACK (on_spinbutton1_button_release_event),
134 NULL);
135 g_object_set_data_full(G_OBJECT (volume_window), "spinbutton1",
136 gtk_widget_ref (spinbutton1),
137 (GDestroyNotify) gtk_widget_unref);
138
139 hbox3 = gtk_hbox_new (FALSE, 0);
140 gtk_widget_show (hbox3);
141 gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, TRUE, 5);
142
143 vscale1 = gtk_vscale_new (GTK_ADJUSTMENT (vol_adjustment));
144 gtk_widget_show (vscale1);
145 gtk_range_set_inverted (GTK_RANGE (vscale1), TRUE);
146 gtk_box_pack_start (GTK_BOX (hbox3), vscale1, TRUE, TRUE, 0);
147 gtk_scale_set_draw_value (GTK_SCALE (vscale1), FALSE);
148 g_signal_connect ((gpointer) vscale1, "button_release_event",
149 G_CALLBACK (on_vscale1_button_release_event),
150 vol_adjustment);
151 g_object_set_data_full(G_OBJECT (volume_window), "vscale1",
152 gtk_widget_ref (vscale1),
153 (GDestroyNotify) gtk_widget_unref);
154
155 hbox4 = gtk_hbox_new (FALSE, 0);
156 gtk_widget_show (hbox4);
157 gtk_box_pack_start (GTK_BOX (vbox1), hbox4, FALSE, TRUE, 8);
158
159 g_signal_connect ((gpointer) volume_window, "destroy",
160 G_CALLBACK (gtk_widget_destroy),
161 NULL);
162
163 g_object_set_data (G_OBJECT (volume_window), "volume_window", volume_window);
164 g_object_set_data_full (G_OBJECT (volume_window), "frame",
165 gtk_widget_ref (frame),
166 (GDestroyNotify) gtk_widget_unref);
167 g_object_set_data_full (G_OBJECT (volume_window), "vbox1",
168 gtk_widget_ref (vbox1),
169 (GDestroyNotify) gtk_widget_unref);
170 g_object_set_data_full (G_OBJECT (volume_window), "hbox1",
171 gtk_widget_ref (hbox1),
172 (GDestroyNotify) gtk_widget_unref);
173 g_object_set_data_full (G_OBJECT (volume_window), "hbox3",
174 gtk_widget_ref (hbox3),
175 (GDestroyNotify) gtk_widget_unref);
176 g_object_set_data_full (G_OBJECT (volume_window), "hbox4",
177 gtk_widget_ref (hbox4),
178 (GDestroyNotify) gtk_widget_unref);
179
180 gtk_window_add_accel_group (GTK_WINDOW (volume_window), accel_group);
181
182 vol_spin = spinbutton1;
183
184 return volume_window;
185 }
186
187 static StereoVolume vol;
188
189 static gboolean
190 on_spinbutton1_button_release_event (GtkWidget *widget,
191 GdkEventButton *event,
192 gpointer user_data)
193 {
194 GtkSpinButton *spin;
195 extern GtkWidget *spinbutton1;
196 spin = GTK_SPIN_BUTTON (spinbutton1);
197 vol.left = vol.right = (int) gtk_spin_button_get_value_as_int (spin);
198 ioctl(mixer_fd,MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
199
200 return FALSE;
201 }
202
203 static gboolean
204 on_vscale1_button_release_event (GtkWidget *widget,
205 GdkEventButton *event,
206 gpointer user_data)
207 {
208 vol.left = vol.right =
209 (int) gtk_adjustment_get_value(GTK_ADJUSTMENT(user_data));
210 ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
211 return FALSE;
212 }