1. Replace hardcoded "-rdynamic" with proper "-export-dynamic" in
[lxde/lxpanel.git] / src / plugins / volume / volume.c
1 #include <gtk/gtk.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5
6 #include <glib/gi18n.h>
7 #include <gdk-pixbuf/gdk-pixbuf.h>
8
9 #include "panel.h"
10 #include "misc.h"
11 #include "plugin.h"
12
13 #include "dbg.h"
14
15 #include "volume-impl.h"
16
17 #include "volume_xpm.h"
18
19 int mixer_fd;
20
21 typedef struct {
22 GtkWidget *mainw;
23 GtkWidget *dlg;
24 GtkTooltips* tooltips;
25 } volume_t;
26
27 static void
28 volume_destructor(plugin *p)
29 {
30 volume_t *vol = (volume_t *) p->priv;
31
32 ENTER;
33 if (vol->dlg)
34 gtk_widget_destroy(vol->dlg);
35 g_object_unref( vol->tooltips );
36 gtk_widget_destroy(vol->mainw);
37 if (mixer_fd)
38 close(mixer_fd);
39 g_free(vol);
40 RET();
41 }
42
43 static void on_volume_focus (GtkWidget* dlg, GdkEventFocus *event, volume_t *vol)
44 {
45 /* FIXME: use smarter method */
46 gtk_widget_destroy( dlg );
47 vol->dlg = NULL;
48 }
49
50 static void on_button_press (GtkWidget* widget, GdkEventButton* evt, plugin* p)
51 {
52 volume_t *vol = (volume_t*) p->priv;
53
54 if( evt->button == 1 ) { /* Left click*/
55 if( ! vol->dlg ) {
56 vol->dlg = create_volume_window();
57 g_signal_connect( vol->dlg, "focus-out-event",
58 G_CALLBACK(on_volume_focus), vol );
59 }
60 gtk_window_present( GTK_WINDOW(vol->dlg) );
61 }
62 }
63
64 static int
65 volume_constructor(plugin *p)
66 {
67 volume_t *vol;
68 line s;
69 GdkPixbuf *icon;
70 GtkWidget *image;
71 GtkIconTheme* theme;
72 GtkIconInfo* info;
73
74 ENTER;
75 s.len = 256;
76 vol = g_new0(volume_t, 1);
77 g_return_val_if_fail(vol != NULL, 0);
78 p->priv = vol;
79
80 /* check if OSS mixer device could be open */
81 mixer_fd = open ("/dev/mixer", O_RDWR, 0);
82 if (mixer_fd < 0) {
83 RET(0);
84 }
85
86 vol->mainw = gtk_event_box_new();
87
88 theme = gtk_icon_theme_get_default();
89 if ( (info = gtk_icon_theme_lookup_icon( theme, "stock_volume", 24, 0 ) ) ) {
90 icon = gdk_pixbuf_new_from_file_at_size(
91 gtk_icon_info_get_filename( info ),
92 24, 24, NULL );
93 gtk_icon_info_free( info );
94 }
95 else
96 icon = gdk_pixbuf_new_from_xpm_data((const char **) volume_xpm);
97 if (icon) {
98 image = gtk_image_new_from_pixbuf(icon);
99 gtk_container_add (GTK_CONTAINER (vol->mainw), image);
100 }
101
102 gtk_widget_add_events( vol->mainw, GDK_BUTTON_PRESS_MASK );
103 g_signal_connect( vol->mainw, "button-press-event",
104 G_CALLBACK(on_button_press), p );
105 gtk_widget_set_size_request( vol->mainw, 24, 24 );
106
107 vol->dlg = NULL;
108 gtk_widget_show_all(vol->mainw);
109
110 gtk_container_add(GTK_CONTAINER(p->pwid), vol->mainw);
111
112 vol->tooltips = gtk_tooltips_new ();
113 /* FIXME: display current level in tooltip. ex: "Volume Control: 80%" */
114 gtk_tooltips_set_tip (vol->tooltips, vol->mainw, _("Volume control"), NULL);
115
116 RET(1);
117 }
118
119
120 plugin_class volume_plugin_class = {
121 fname: NULL,
122 count: 0,
123
124 type : "volume",
125 name : "volume",
126 version: "1.0",
127 description : "Display and control volume",
128
129 constructor : volume_constructor,
130 destructor : volume_destructor,
131 };