diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | ChangeLog | 0 | ||||
-rw-r--r-- | Makefile.am | 19 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rw-r--r-- | README | 0 | ||||
-rw-r--r-- | TODO | 0 | ||||
-rwxr-xr-x | autogen.sh | 3 | ||||
-rw-r--r-- | configure.ac | 32 | ||||
-rw-r--r-- | light-applet.c | 520 | ||||
-rw-r--r-- | mb-applet-light.desktop | 7 | ||||
-rw-r--r-- | mblight-high.png | bin | 0 -> 2786 bytes | |||
-rw-r--r-- | mblight-low.png | bin | 0 -> 2786 bytes | |||
-rw-r--r-- | mblight-mid.png | bin | 0 -> 2786 bytes | |||
-rw-r--r-- | mblight-zero.png | bin | 0 -> 2786 bytes |
14 files changed, 582 insertions, 0 deletions
@@ -0,0 +1 @@ +Chris Lord <chris@openedhand.com> diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..950e22e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,19 @@ +pngs = mblight-high.png mblight-mid.png mblight-low.png mblight-zero.png + +EXTRA_DIST = $(pngs) mb-applet-light.desktop TODO + +INCLUDES = @APPLET_CFLAGS@ + +bin_PROGRAMS = mb-applet-light + +mb_applet_light_SOURCES = light-applet.c + +mb_applet_light_LDADD = @APPLET_LIBS@ + +desktopdir = $(datadir)/applications/ +pixmapsdir = $(datadir)/pixmaps/ + +pixmaps_DATA = $(pngs) + +desktop_DATA = mb-applet-light.desktop + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..b1376df --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install || exit 1 +./configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..8a2ab32 --- /dev/null +++ b/configure.ac @@ -0,0 +1,32 @@ +AC_PREREQ(2.53) +AC_INIT([mb-applet-light], 0.1, [chris@openedhand.com]) +AC_CONFIG_SRCDIR([light-applet.c]) + +AM_INIT_AUTOMAKE() +AM_MAINTAINER_MODE +AM_CONFIG_HEADER(config.h) + +# Checks for programs. +AC_PROG_CC + +PKG_CHECK_MODULES(APPLET, [gtk+-2.0 libmb]) + +if test "x$GCC" = "xyes"; then + GCC_WARNINGS="-Wall -fno-strict-aliasing" + XLIBS_CFLAGS="$GCC_WARNINGS" +fi + +AC_SUBST(APPLET_CFLAGS) +AC_SUBST(APPLET_LIBS) + +# Checks for header files. + +AC_HEADER_STDC + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_PID_T + +# Checks for library functions. + +AC_OUTPUT([Makefile]) diff --git a/light-applet.c b/light-applet.c new file mode 100644 index 0000000..4db8e1d --- /dev/null +++ b/light-applet.c @@ -0,0 +1,520 @@ +/* mb-light-applet - A tiny back-light control tray app + + GTk bits based on GPE's minilite.c bu p.blundell + + Copyright 2004 Matthew Allum + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + + +#include <libmb/mb.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <linux/ioctl.h> +#include <sys/ioctl.h> + +#include <gtk/gtk.h> +#include <gdk/gdkx.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define IMG_EXT "png" + +/* +#else +#define IMG_EXT "xpm" +#endif +*/ + +#define POPUP_WIDTH 33 +#define POPUP_HEIGHT 130 +#define POPUP_PTR_SZ 10 + +#define BRIGHTNESS_ZERO 0 +#define BRIGHTNESS_LOW 1 +#define BRIGHTNESS_MID 2 +#define BRIGHTNESS_HIGH 3 + +#define BRIGHTNESS_ZERO_IMG "mblight-zero." IMG_EXT +#define BRIGHTNESS_LOW_IMG "mblight-low." IMG_EXT +#define BRIGHTNESS_MID_IMG "mblight-mid." IMG_EXT +#define BRIGHTNESS_HIGH_IMG "mblight-high." IMG_EXT + +#define SLIDER_HEIGHT 100 + +#define SYSCLASS "/sys/class/backlight/" +static char *SYS_BRIGHTNESS = NULL; +static char *SYS_MAXBRIGHTNESS = NULL; +static char *SYS_POWER = NULL; + +static char *ImgLookup[64] = { + BRIGHTNESS_ZERO_IMG, + BRIGHTNESS_LOW_IMG, + BRIGHTNESS_MID_IMG, + BRIGHTNESS_HIGH_IMG +}; + +static char *ThemeName = NULL; +static MBPixbuf *pb; +static MBPixbufImage *Imgs[4] = { 0,0,0,0 }, *ImgsScaled[4] = { 0,0,0,0 }; + +static Window WinPopup; +static int mixerfd; +static Bool PopupIsMapped = False; + +static int PopupYOffset = 5; +static Bool SliderActive = False; + +static gint Brightness; +static gint MaxBrightness; + +GtkWidget *slider_window; +GtkWidget *slider; + + +static gboolean +setup_sysclass(void) +{ + GDir *dir; + gchar *dirname = NULL; + gboolean retval = FALSE; + + if (!(dir = g_dir_open (SYSCLASS, 0, NULL))) { + g_warning ("Unable to open %s", SYSCLASS); + return FALSE; + } + + if ((dirname = g_dir_read_name (dir))) { + SYS_BRIGHTNESS = g_strconcat (SYSCLASS, dirname, + G_DIR_SEPARATOR_S, "brightness", NULL); + SYS_MAXBRIGHTNESS = g_strconcat (SYSCLASS, dirname, + G_DIR_SEPARATOR_S, "max_brightness", NULL); + SYS_POWER = g_strconcat (SYSCLASS, dirname, + G_DIR_SEPARATOR_S, "power", NULL); + retval = TRUE; + } + + g_dir_close (dir); + + return retval; +} + +static void +sysclass_set_level (gint level) +{ + FILE *f_light; + + f_light = fopen (SYS_BRIGHTNESS, "w"); + if (f_light != NULL) { + fprintf (f_light,"%d\n", level); + fclose (f_light); + } else + return -1; + + f_light = fopen (SYS_POWER, "w"); + if (f_light != NULL) { + fprintf (f_light,"%d\n", level ? SYS_STATE_ON : SYS_STATE_OFF); + fclose (f_light); + } +} + +static gint +sysclass_get_level () +{ + FILE *f_light; + gfloat level; + + f_light = fopen (SYS_BRIGHTNESS, "r"); + if (f_light != NULL) { + fscanf (f_light,"%f", &level); + fclose (f_light); + return (gint)level; + } + return -1; +} + +static gint +sysclass_get_maxlevel () +{ + FILE *f_max; + float maxlevel, factor; + + f_max = fopen (SYS_MAXBRIGHTNESS, "r"); + if (f_max != NULL) { + fscanf (f_max,"%f", &maxlevel); + fclose (f_max); + return (gint)maxlevel; + } + return -1; +} + +/* -- tray app callbacks -- */ + +void +paint_callback (MBTrayApp *app, Drawable drw ) +{ + int img_index = 0; + MBPixbufImage *img_backing = NULL; + + img_backing = mb_tray_app_get_background (app, pb); + + if (!err_str) + { + img_index = (Brightness*4)/MaxBrightness; + + if (img_index > 3) img_index = 3; + if (img_index < 0) img_index = 0; + } + + /* CurrentLightLevel */ + mb_pixbuf_img_composite(pb, img_backing, + ImgsScaled[img_index], + 0, 0); + + mb_pixbuf_img_render_to_drawable(pb, img_backing, drw, 0, 0); + + mb_pixbuf_img_free( pb, img_backing ); +} + +void +resize_callback (MBTrayApp *app, int w, int h ) +{ + int i; + + for (i=0; i<4; i++) + { + if (ImgsScaled[i] != NULL) mb_pixbuf_img_free(pb, ImgsScaled[i]); + ImgsScaled[i] = mb_pixbuf_img_scale(pb, Imgs[i], w, h); + } +} + +void +load_icons(void) +{ + int i; + char *icon_path; + + for (i=0; i<4; i++) + { + if (Imgs[i] != NULL) mb_pixbuf_img_free(pb, Imgs[i]); + icon_path = mb_dot_desktop_icon_get_full_path (ThemeName, + 32, + ImgLookup[i]); + + if (icon_path == NULL + || !(Imgs[i] = mb_pixbuf_img_new_from_file(pb, icon_path))) + { + g_error ("Failed to load icon (%s)", icon_path ? icon_path : "null" ); + } + + free(icon_path); + } +} + +void +theme_callback (MBTrayApp *app, char *theme_name) +{ + if (!theme_name) return; + if (ThemeName) free(ThemeName); + ThemeName = strdup(theme_name); + load_icons(); + resize_callback (app, mb_tray_app_width(app), mb_tray_app_width(app) ); +} + +gboolean +popup_close (GtkWidget *w, GtkWidget *list_view) +{ + gtk_widget_hide (slider_window); + PopupIsMapped = False; + +} + +static void +slider_clicked (GtkWidget *w, GdkEventButton *ev) +{ + gdk_pointer_ungrab (ev->time); + + gtk_widget_hide (slider_window); +} + + +static void +button_callback (MBTrayApp *app, int cx, int cy, Bool is_released) +{ + int level; + int x, y, win_w, win_h; + + if (!is_released) return; + + mb_tray_app_get_absolute_coords (app, &x, &y); + + gdk_window_get_geometry (slider_window->window, NULL, NULL, + &win_w, &win_h, NULL); + + if (mb_tray_app_tray_is_vertical (app)) + { + if (x > (DisplayWidth(mb_tray_app_xdisplay(app), + mb_tray_app_xscreen(app)) /2) ) + x -= ( mb_tray_app_width(app) + win_w ); + else + x += mb_tray_app_width(app); + + /* + if ( (y - win_h) < 0 ) + y = 0; + else if ( (y + POPUP_HEIGHT) > root_attr.height ) + y = root_attr.height - POPUP_HEIGHT; + */ + } + else + { + if (y < mb_tray_app_height(app)) + { y = mb_tray_app_height(app); } + else + { + y = DisplayHeight(mb_tray_app_xdisplay(app), + mb_tray_app_xscreen(app)) + - win_h - mb_tray_app_height(app) - 4; + } + + x -= (mb_tray_app_width(app)/2); + + if ((x + win_w) > DisplayWidth(mb_tray_app_xdisplay(app), + mb_tray_app_xscreen(app))) + x = DisplayWidth(mb_tray_app_xdisplay(app), + mb_tray_app_xscreen(app)) - win_w - 2; + } + + + + gtk_widget_set_uposition (GTK_WIDGET (slider_window), x, y); + + Brightness = sysclass_get_level (); + MaxBrightness = sysclass_get_maxlevel (); + + gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(slider)), + Brightness); + + gtk_widget_show_all (slider_window); + + gdk_pointer_grab (slider_window->window, TRUE, GDK_BUTTON_PRESS_MASK, NULL, NULL, CurrentTime); + + PopupIsMapped = True; +} + + +void +popup_light_changed_cb (GtkAdjustment *adj, gpointer data) +{ + int value; + MBTrayApp *app = (MBTrayApp *)data; + + Brightness = gtk_adjustment_get_value (adj); + + sysclass_set_level (app, value); + + mb_tray_app_repaint(app); +} + +void +popup_init(MBTrayApp *app) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *button_ok; + GtkAdjustment *adj; + + vbox = gtk_vbox_new (FALSE, 2); + + /* hbox for text */ + hbox = gtk_hbox_new (FALSE, 2); + + label = gtk_label_new(NULL); + gtk_label_set_markup (GTK_LABEL(label), "<b>Low</b>"); + + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + + label = gtk_label_new(NULL); + gtk_label_set_markup (GTK_LABEL(label), "<b>High</b>"); + + gtk_box_pack_end (GTK_BOX (hbox), label, TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); + + slider_window = gtk_window_new (GTK_WINDOW_POPUP); + + slider = gtk_vscale_new_with_range (0, 100, 1); + + gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE); + gtk_widget_set_usize (slider_window, -1, SLIDER_HEIGHT); + gtk_range_set_inverted (GTK_RANGE (slider), TRUE); + + adj = gtk_range_get_adjustment (GTK_RANGE (slider)); + + g_signal_connect (G_OBJECT (adj), "value-changed", + G_CALLBACK (popup_light_changed_cb), (gpointer)app); + + gtk_container_add (GTK_CONTAINER (slider_window), slider); + + /* + g_signal_connect (G_OBJECT (window), "button-press-event", G_CALLBACK (clicked), NULL); + */ + + g_signal_connect (G_OBJECT (slider_window), "button-press-event", G_CALLBACK (slider_clicked), NULL); + + gtk_widget_add_events (slider_window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + + + /* + gtk_window_set_decorated (GTK_WINDOW(slider_window), FALSE); + + gtk_window_set_type_hint (GTK_WINDOW(slider_window), + GDK_WINDOW_TYPE_HINT_DIALOG); + + gtk_widget_set_usize (slider_window, SLIDER_WIN_WIDTH, -1 ); + + slider = gtk_hscale_new_with_range (0, 100, 1); + + gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE); + + adj = gtk_range_get_adjustment (GTK_RANGE (slider)); + + g_signal_connect (G_OBJECT (adj), "value-changed", + G_CALLBACK (popup_light_changed_cb), (gpointer)app); + + gtk_box_pack_start (GTK_BOX (vbox), slider, TRUE, TRUE, 0); + + hbox = gtk_hbox_new (FALSE, 2); + + button_mute = gtk_check_button_new_with_label ( "Mute" ); + */ + + /* + gtk_box_pack_start (GTK_BOX (hbox), button_mute, TRUE, TRUE, 0); + */ + + button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); + + gtk_box_pack_end (GTK_BOX (hbox), button_ok, FALSE, FALSE, 0); + + /* XXX mute callback */ + + gtk_box_pack_end (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); + + gtk_container_set_border_width (GTK_CONTAINER (slider_window), 6); + + gtk_container_add (GTK_CONTAINER (slider_window), vbox); + + g_signal_connect (G_OBJECT (button_ok), "clicked", + G_CALLBACK (popup_close), NULL); + + gtk_widget_realize (slider_window); +} + + + +GdkFilterReturn +event_filter (GdkXEvent *xev, GdkEvent *gev, gpointer data) +{ + XEvent *ev = (XEvent *)xev; + MBTrayApp *app = (MBTrayApp*)data; + + Display *dpy = ev->xany.display; + + mb_tray_handle_xevent (app, ev); + + return GDK_FILTER_CONTINUE; +} + +static gboolean +brightness_timeout_cb (MBTrayApp *app) +{ + /* check light data */ + int this_bri = sysclass_get_level (); + + if (this_bri != -1 && this_bri != Brightness) + { + Brightness = this_bri; + + gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(slider)), + Brightness); + + mb_tray_app_repaint(app); + } + + return TRUE; +} + +int +main( int argc, char *argv[]) +{ + char *mixer_dev = "/dev/mixer"; + int devmask = 0; + + MBTrayApp *app = NULL; + + gtk_init (&argc, &argv); + +#if ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, DATADIR "/locale"); + bind_textdomain_codeset (PACKAGE, "UTF-8"); + textdomain (PACKAGE); +#endif + + if (!setup_sysclass ()) + g_error ("Failed to open a backlight"); + + app = mb_tray_app_new_with_display ( "Brightness Control", + resize_callback, + paint_callback, + &argc, + &argv, + GDK_DISPLAY ()); + + if (!app) exit(0); + + pb = mb_pixbuf_new(mb_tray_app_xdisplay(app), + mb_tray_app_xscreen(app)); + + mb_tray_app_set_theme_change_callback (app, theme_callback ); + + mb_tray_app_set_button_callback (app, button_callback ); + + gtk_timeout_add (500, + (GSourceFunc) brightness_timeout_cb, + app); + + load_icons(); + + mb_tray_app_set_icon(app, pb, Imgs[3]); + + popup_init(app); + + mb_tray_app_main_init (app); + + gdk_window_add_filter (NULL, event_filter, (gpointer)app ); + + gtk_main (); + + return 1; +} diff --git a/mb-applet-light.desktop b/mb-applet-light.desktop new file mode 100644 index 0000000..fd40f46 --- /dev/null +++ b/mb-applet-light.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=Backlight control +Comment=Panel based backlight control +Exec=mb-applet-light +Type=PanelApp +Icon=mblight-high.png +Categories=Panel;Utility;MB diff --git a/mblight-high.png b/mblight-high.png Binary files differnew file mode 100644 index 0000000..64d0580 --- /dev/null +++ b/mblight-high.png diff --git a/mblight-low.png b/mblight-low.png Binary files differnew file mode 100644 index 0000000..64d0580 --- /dev/null +++ b/mblight-low.png diff --git a/mblight-mid.png b/mblight-mid.png Binary files differnew file mode 100644 index 0000000..64d0580 --- /dev/null +++ b/mblight-mid.png diff --git a/mblight-zero.png b/mblight-zero.png Binary files differnew file mode 100644 index 0000000..64d0580 --- /dev/null +++ b/mblight-zero.png |