Applied linker optimizations: prevent gaps between symbols due to
[lxde/lxpanel.git] / src / plugins / volume / volume.c
CommitLineData
a99ee9e1
JH
1/**
2 * Copyright (c) 2006 LxDE Developers, see the file AUTHORS for details.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
31b80004
JH
19#include <gtk/gtk.h>
20#include <stdlib.h>
21#include <fcntl.h>
22#include <unistd.h>
23
f277dbb7 24#include <glib/gi18n.h>
31b80004
JH
25#include <gdk-pixbuf/gdk-pixbuf.h>
26
27#include "panel.h"
28#include "misc.h"
29#include "plugin.h"
30
31#include "dbg.h"
32
33#include "volume-impl.h"
34
35#include "volume_xpm.h"
460e2e78 36#undef const
31b80004
JH
37
38int mixer_fd;
39
40typedef struct {
41 GtkWidget *mainw;
42 GtkWidget *dlg;
c6780e74 43 GtkTooltips* tooltips;
31b80004
JH
44} volume_t;
45
46static void
47volume_destructor(plugin *p)
48{
f277dbb7 49 volume_t *vol = (volume_t *) p->priv;
31b80004
JH
50
51 ENTER;
f277dbb7
HJYP
52 if (vol->dlg)
53 gtk_widget_destroy(vol->dlg);
c6780e74 54 g_object_unref( vol->tooltips );
f277dbb7 55 gtk_widget_destroy(vol->mainw);
31b80004
JH
56 if (mixer_fd)
57 close(mixer_fd);
f277dbb7 58 g_free(vol);
31b80004
JH
59 RET();
60}
61
f277dbb7 62static void on_volume_focus (GtkWidget* dlg, GdkEventFocus *event, volume_t *vol)
31b80004
JH
63{
64 /* FIXME: use smarter method */
65 gtk_widget_destroy( dlg );
f277dbb7 66 vol->dlg = NULL;
31b80004
JH
67}
68
69static void on_button_press (GtkWidget* widget, GdkEventButton* evt, plugin* p)
70{
f277dbb7 71 volume_t *vol = (volume_t*) p->priv;
31b80004
JH
72
73 if( evt->button == 1 ) { /* Left click*/
f277dbb7
HJYP
74 if( ! vol->dlg ) {
75 vol->dlg = create_volume_window();
cecb0eaa
FC
76
77 /* setting background to default */
78 gtk_widget_set_style(vol->dlg, p->panel->defstyle);
79
c6780e74
JH
80 g_signal_connect( vol->dlg, "focus-out-event",
81 G_CALLBACK(on_volume_focus), vol );
cecb0eaa
FC
82
83 gtk_window_present( GTK_WINDOW(vol->dlg) );
84 } else {
85 gtk_widget_destroy(vol->dlg);
86 vol->dlg = NULL;
31b80004 87 }
31b80004
JH
88 }
89}
90
91static int
db449f6e 92volume_constructor(plugin *p, char **fp)
31b80004 93{
f277dbb7 94 volume_t *vol;
31b80004
JH
95 line s;
96 GdkPixbuf *icon;
97 GtkWidget *image;
c6780e74
JH
98 GtkIconTheme* theme;
99 GtkIconInfo* info;
31b80004
JH
100
101 ENTER;
102 s.len = 256;
f277dbb7
HJYP
103 vol = g_new0(volume_t, 1);
104 g_return_val_if_fail(vol != NULL, 0);
105 p->priv = vol;
31b80004
JH
106
107 /* check if OSS mixer device could be open */
108 mixer_fd = open ("/dev/mixer", O_RDWR, 0);
109 if (mixer_fd < 0) {
110 RET(0);
111 }
112
f277dbb7
HJYP
113 vol->mainw = gtk_event_box_new();
114
c6780e74
JH
115 theme = gtk_icon_theme_get_default();
116 if ( (info = gtk_icon_theme_lookup_icon( theme, "stock_volume", 24, 0 ) ) ) {
117 icon = gdk_pixbuf_new_from_file_at_size(
118 gtk_icon_info_get_filename( info ),
119 24, 24, NULL );
120 gtk_icon_info_free( info );
121 }
122 else
123 icon = gdk_pixbuf_new_from_xpm_data((const char **) volume_xpm);
124 if (icon) {
31b80004 125 image = gtk_image_new_from_pixbuf(icon);
f277dbb7 126 gtk_container_add (GTK_CONTAINER (vol->mainw), image);
31b80004
JH
127 }
128
f277dbb7
HJYP
129 gtk_widget_add_events( vol->mainw, GDK_BUTTON_PRESS_MASK );
130 g_signal_connect( vol->mainw, "button-press-event",
31b80004 131 G_CALLBACK(on_button_press), p );
f277dbb7
HJYP
132 gtk_widget_set_size_request( vol->mainw, 24, 24 );
133
134 vol->dlg = NULL;
135 gtk_widget_show_all(vol->mainw);
31b80004 136
f277dbb7 137 gtk_container_add(GTK_CONTAINER(p->pwid), vol->mainw);
31b80004 138
c6780e74 139 vol->tooltips = gtk_tooltips_new ();
3806c5aa
HJYP
140#if GLIB_CHECK_VERSION( 2, 10, 0 )
141 g_object_ref_sink( vol->tooltips );
142#else
143 g_object_ref( vol->tooltips );
144 gtk_object_sink( vol->tooltips );
145#endif
146
c6780e74
JH
147 /* FIXME: display current level in tooltip. ex: "Volume Control: 80%" */
148 gtk_tooltips_set_tip (vol->tooltips, vol->mainw, _("Volume control"), NULL);
31b80004
JH
149
150 RET(1);
31b80004
JH
151}
152
153
154plugin_class volume_plugin_class = {
155 fname: NULL,
156 count: 0,
157
158 type : "volume",
ce522551 159 name : N_("Volume Control"),
31b80004
JH
160 version: "1.0",
161 description : "Display and control volume",
162
163 constructor : volume_constructor,
164 destructor : volume_destructor,
9c97f69e
HJYP
165 config : NULL,
166 save : NULL
31b80004 167};