From 9b6590a0e899da7ec9576de9520ced30375d1407 Mon Sep 17 00:00:00 2001 From: Alexey Dokuchaev Date: Fri, 8 Mar 2013 09:10:13 +0000 Subject: [PATCH] - Implement nice little temperature widget (read via sysctl(3) API) - Trim Makefile header and slightly touch COMMENT while I am here --- x11/bmpanel2/Makefile | 18 +- .../files/extra-patch-temperature-widget | 280 ++++++++++++++++++ 2 files changed, 292 insertions(+), 6 deletions(-) create mode 100644 x11/bmpanel2/files/extra-patch-temperature-widget diff --git a/x11/bmpanel2/Makefile b/x11/bmpanel2/Makefile index 9fbdf48fbdd0..628e324cce54 100644 --- a/x11/bmpanel2/Makefile +++ b/x11/bmpanel2/Makefile @@ -1,9 +1,5 @@ -# New ports collection makefile for: BMPanel 2 -# Date created: 17 May 2012 -# Whom: Alexey Dokuchaev -# +# Created by: Alexey Dokuchaev # $FreeBSD$ -# PORTNAME= bmpanel2 DISTVERSION= 2.1pre1 @@ -11,7 +7,7 @@ CATEGORIES= x11 MASTER_SITES= GOOGLE_CODE MAINTAINER= ports@FreeBSD.org -COMMENT= Nice, lightweight NETWM compliant panel for X +COMMENT= Nice, lightweight NETWM compliant panel for X11 LICENSE= MIT @@ -21,6 +17,15 @@ USE_XORG= x11 xext LDFLAGS+= -L${LOCALBASE}/lib # XXX should not be needed +OPTIONS_DEFINE= TEMPERATURE +TEMPERATURE_DESC= Build with temperature widget (for CPU, etc.) + +.include + +.if ${PORT_OPTIONS:MTEMPERATURE} +EXTRA_PATCHES= ${FILESDIR}/extra-patch-temperature-widget +.endif + post-patch: @${REINPLACE_CMD} -e 's,/usr/local,${PREFIX},' ${WRKSRC}/xdg.c @${REINPLACE_CMD} -e '/^#include/s,alloca,stdlib,' \ @@ -28,5 +33,6 @@ post-patch: @${REINPLACE_CMD} -e 's,uint,unsigned,' ${WRKSRC}/args.c # Disable unused optional features (and thus unbreak "make clean") @${REINPLACE_CMD} -e '/^OPTION/s, ON, OFF,' ${WRKSRC}/CMakeLists.txt + @${RM} -f ${WRKSRC}/themes/striped/theme.orig .include diff --git a/x11/bmpanel2/files/extra-patch-temperature-widget b/x11/bmpanel2/files/extra-patch-temperature-widget new file mode 100644 index 000000000000..99b077fcd72d --- /dev/null +++ b/x11/bmpanel2/files/extra-patch-temperature-widget @@ -0,0 +1,280 @@ +--- CMakeLists.txt.orig 2013-03-08 16:05:26.000000000 +0800 ++++ CMakeLists.txt 2013-02-26 15:42:05.000000000 +0800 +@@ -30,6 +30,7 @@ + ${CMAKE_CURRENT_SOURCE_DIR}/widget-systray.c + ${CMAKE_CURRENT_SOURCE_DIR}/widget-launchbar.c + ${CMAKE_CURRENT_SOURCE_DIR}/widget-empty.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/widget-temperature.c + ${CMAKE_CURRENT_SOURCE_DIR}/render-normal.c + ${CMAKE_CURRENT_SOURCE_DIR}/render-pseudo.c + ${CMAKE_CURRENT_SOURCE_DIR}/args.c +--- bmpanel.c.orig 2009-11-01 13:50:26.000000000 +0800 ++++ bmpanel.c 2013-03-08 11:58:46.000000000 +0800 +@@ -290,6 +290,7 @@ + register_widget_interface(&desktops_interface); + register_widget_interface(&taskbar_interface); + register_widget_interface(&clock_interface); ++ register_widget_interface(&temperature_interface); + register_widget_interface(&decor_interface); + register_widget_interface(&systray_interface); + register_widget_interface(&launchbar_interface); +--- builtin-widgets.h.orig 2009-11-01 13:50:26.000000000 +0800 ++++ builtin-widgets.h 2013-03-08 12:10:45.000000000 +0800 +@@ -92,6 +92,18 @@ + extern struct widget_interface clock_interface; + + /************************************************************************** ++ ACPI TZ Temperature (CPU) ++**************************************************************************/ ++ ++struct temperature_widget { ++ struct triple_image background; ++ struct text_info font; ++ char *sysctl_oid; ++}; ++ ++extern struct widget_interface temperature_interface; ++ ++/************************************************************************** + Desktop Switcher + **************************************************************************/ + +--- widget-temperature.c.orig 1970-01-01 08:00:00.000000000 +0800 ++++ widget-temperature.c 2013-03-08 15:55:36.000000000 +0800 +@@ -0,0 +1,216 @@ ++#include ++#include ++#include ++ ++#include "settings.h" ++#include "builtin-widgets.h" ++ ++static int create_widget_private(struct widget *w, ++ struct config_format_entry *e, struct config_format_tree *tree); ++static void destroy_widget_private(struct widget *w); ++static void draw(struct widget *w); ++static void clock_tick(struct widget *w); ++static int get_temperature(const char *sysctl_oid); ++static void hsv2rgb(float h, float s, float v, float *r, float *g, float *b); ++ ++struct widget_interface temperature_interface = { ++ .theme_name = "temperature", ++ .size_type = WIDGET_SIZE_CONSTANT, ++ .create_widget_private = create_widget_private, ++ .destroy_widget_private = destroy_widget_private, ++ .draw = draw, ++ .clock_tick = clock_tick, ++}; ++ ++/* current temperature */ ++int curtemp; ++ ++/************************************************************************** ++ TZ Temp "theme" (widget, really) ++**************************************************************************/ ++ ++static int parse_temperature_theme(struct temperature_widget *tw, ++ struct config_format_entry *e, struct config_format_tree *tree) ++{ ++ if (parse_text_info_named(&tw->font, "font", e, 1)) ++ return -1; ++ ++ parse_triple_image_named(&tw->background, "background", e, tree, 0); ++ tw->sysctl_oid = parse_string("sysctl_oid", e, ++ "hw.acpi.thermal.tz0.temperature"); ++ ++ return 0; ++} ++ ++/************************************************************************** ++ TZ Temp interface ++**************************************************************************/ ++ ++static int create_widget_private(struct widget *w, ++ struct config_format_entry *e, struct config_format_tree *tree) ++{ ++ struct temperature_widget *tw = xmallocz(sizeof(struct temperature_widget)); ++ if (parse_temperature_theme(tw, e, tree)) { ++ xfree(tw); ++ XWARNING("Failed to parse temperature theme"); ++ return -1; ++ } ++ ++ /* get widget width */ ++ int text_width = 0; ++ int pics_width = 0; ++ ++ /* this should give us enough width for any real temperature */ ++ char buftemp[8] = "999°"; ++ ++ text_extents(w->panel->layout, tw->font.pfd, buftemp, &text_width, 0); ++ ++ /* background is drawn only if the center is here */ ++ if (tw->background.center) { ++ pics_width += image_width(tw->background.left); ++ pics_width += image_width(tw->background.right); ++ } ++ ++ w->width = text_width + pics_width; ++ w->private = tw; ++ return 0; ++} ++ ++static void destroy_widget_private(struct widget *w) ++{ ++ struct temperature_widget *tw = (struct temperature_widget *)w->private; ++ ++ free_triple_image(&tw->background); ++ free_text_info(&tw->font); ++ xfree(tw->sysctl_oid); ++ xfree(tw); ++} ++ ++static void draw(struct widget *w) ++{ ++ struct temperature_widget *tw = (struct temperature_widget *)w->private; ++ char buftemp[8]; ++ int temp; ++ float tempfraq, r, g, b; ++ ++ temp = get_temperature(tw->sysctl_oid); ++ snprintf(buftemp, sizeof(buftemp), "%d°", temp); ++ ++ /* drawing */ ++ cairo_t *cr = w->panel->cr; ++ int x = w->x; ++ ++ /* calcs */ ++ int leftw = 0; ++ int rightw = 0; ++ int centerw = w->width; ++ ++ /* draw background only if the center image is here */ ++ if (tw->background.center) { ++ leftw += image_width(tw->background.left); ++ rightw += image_width(tw->background.right); ++ centerw -= leftw + rightw; ++ ++ /* left part */ ++ if (leftw) ++ blit_image(tw->background.left, cr, x, 0); ++ x += leftw; ++ ++ /* center part */ ++ pattern_image(tw->background.center, cr, x, 0, centerw, 1); ++ x += centerw; ++ ++ /* right part */ ++ if (rightw) ++ blit_image(tw->background.right, cr, x, 0); ++ x -= centerw; ++ } ++ ++ /* ++ * map temperature (30C~100C) to the text color: from nice blueish ++ * 0%R, 60%G, 100%B (HSV: 200, 100%, 100%) to reddish 100%R, 0%G, ++ * 0%B (HSV: 0, 100%, 100%) through the hue shift (think rainbow). ++ */ ++#if 0 ++ tempfraq = (temp - 30) / 70.0; ++ tw->font.color[0] = 255 * tempfraq; ++ tw->font.color[1] = 153 * (1 - tempfraq); ++ tw->font.color[2] = 255 * (1 - tempfraq); ++#endif ++ tempfraq = (temp - 30) / 70.0; ++ hsv2rgb(.56 * (1 - tempfraq), 1, 1, &r, &g, &b); ++ tw->font.color[0] = 255 * r; ++ tw->font.color[1] = 255 * g; ++ tw->font.color[2] = 255 * b; ++ ++ /* text */ ++ draw_text(cr, w->panel->layout, &tw->font, buftemp, x, 0, ++ centerw, w->panel->height, 0); ++} ++ ++static void clock_tick(struct widget *w) ++{ ++ struct temperature_widget *tw = (struct temperature_widget *)w->private; ++ int temp; ++ ++ if ((temp = get_temperature(tw->sysctl_oid)) < 0) ++ return; ++ ++ if (curtemp == temp) ++ return; ++ ++ curtemp = temp; ++ w->needs_expose = 1; ++} ++ ++static int get_temperature(const char *sysctl_oid) ++{ ++ int temp; ++ size_t len = sizeof(temp); ++ ++ if (sysctlbyname(sysctl_oid, &temp, &len, NULL, 0)) ++ return -1; ++ return (temp - 2732) / 10; ++} ++ ++static void hsv2rgb(float h, float s, float v, float *r, float *g, float *b) ++{ ++ float f, p, q, t; ++ int i; ++ ++ /* achromatic case, set level of gray */ ++ if (s <= 0) { ++ *r = *g = *b = v; ++ return; ++ } ++ ++ h = 6.0 * (h - floorf(h)); ++ ++ i = (int)truncf(h); /* should be in the range 0..5 */ ++ f = h - i; /* fractional part */ ++ p = v * (1 - s); ++ q = v * (1 - s * f); ++ t = v * (1 - s * (1 - f)); ++ ++ switch (i) { ++ case 0: ++ *r = v; *g = t; *b = p; ++ return; ++ case 1: ++ *r = q; *g = v; *b = p; ++ return; ++ case 2: ++ *r = p; *g = v; *b = t; ++ return; ++ case 3: ++ *r = p; *g = q; *b = v; ++ return; ++ case 4: ++ *r = t; *g = p; *b = v; ++ return; ++ case 5: ++ default: /* to silence compiler warning */ ++ *r = v; *g = p; *b = q; ++ return; ++ } ++} +--- themes/striped/theme.orig 2009-11-01 13:50:26.000000000 +0800 ++++ themes/striped/theme 2013-03-08 16:17:55.000000000 +0800 +@@ -96,6 +96,17 @@ + + empty 3 + ++temperature ++ font DejaVu Sans condensed bold 9 ++ offset 0 0 ++ shadow_offset 1 1 ++ shadow_color 0 0 0 ++ align center ++ ++ #sysctl_oid dev.cpu.0.temperature ++ ++empty 3 ++ + clock + font DejaVu Sans condensed bold 9 + color 247 247 247