Enabling multithreaded compilation.
[debian/lxpanel.git] / src / plugins / volume / volume-impl.c
CommitLineData
6cc5e1a6 1/**
10862fa6
DB
2 * Copyright (c) 2006, 2008 LxDE Developers,
3 * see the file AUTHORS for details.
6cc5e1a6
DB
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
43extern int mixer_fd;
10862fa6 44extern GtkSpinButton* vol_spin;
6cc5e1a6
DB
45
46typedef struct stereovolume
47{
48 unsigned char left;
49 unsigned char right;
50} StereoVolume;
51
52static StereoVolume tmpvol;
53
54typedef 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
64static originalset orig;
65
66static GtkWidget *volume_window;
67static GtkWidget *vbox1;
68static GtkWidget *hbox1;
69static GtkWidget *spinbutton1;
70static GtkWidget *hbox3;
71static GtkWidget *vscale1;
72static GtkAccelGroup *accel_group;
73static GtkAdjustment *vol_adjustment;
74static GtkWidget *hbox4;
75static GtkWidget *frame;
76
77static gboolean
78on_spinbutton1_button_release_event (GtkWidget *widget,
79 GdkEventButton *event,
80 gpointer user_data);
81
82static gboolean
83on_vscale1_button_release_event (GtkWidget *widget,
84 GdkEventButton *event,
85 gpointer user_data);
86
87static void
88get_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
95GtkWidget*
96create_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
10862fa6
DB
182 vol_spin = spinbutton1;
183
6cc5e1a6
DB
184 return volume_window;
185}
186
187static StereoVolume vol;
188
189static gboolean
190on_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
203static gboolean
204on_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}