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