aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drv_X11.c215
1 files changed, 175 insertions, 40 deletions
diff --git a/drv_X11.c b/drv_X11.c
index e4502e5..ef56245 100644
--- a/drv_X11.c
+++ b/drv_X11.c
@@ -55,7 +55,10 @@
#include "timer.h"
#include "plugin.h"
#include "drv.h"
+#include "widget.h"
+#include "widget_keypad.h"
#include "drv_generic_graphic.h"
+#include "drv_generic_keypad.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
@@ -130,6 +133,74 @@ static void drv_X11_blit(const int row, const int col, const int height, const i
}
+static int drv_X11_brightness(int brightness)
+{
+ static unsigned char Brightness = 0;
+ RGBA col = BL_COL;
+ int i;
+ float dim;
+
+ /* -1 is used to query the current brightness */
+ if (brightness == -1)
+ return Brightness;
+
+ if (brightness < 0)
+ brightness = 0;
+ if (brightness > 255)
+ brightness = 255;
+ Brightness = brightness;
+ dim = Brightness / 255.0;
+ col.R *= dim;
+ col.G *= dim;
+ col.B *= dim;
+
+ debug("%s: set backlight to %d%%, bl_col=0x%8x, dimmed=0x%8x", Name, (int)(dim * 100), BL_COL, col);
+ for (i = 0; i < DCOLS * DROWS; i++) {
+ drv_X11_FB[i] = col;
+ }
+
+ drv_X11_color(col);
+
+ XFillRectangle(dp, pm, gc, 0, 0, dimx + 2 * border + btnwidth, dimy + 2 * border);
+ XSetWindowBackground(dp, w, xc.pixel);
+ XClearWindow(dp, w);
+
+ return Brightness;
+}
+
+
+static int drv_X11_keypad(const int num)
+{
+ int val = WIDGET_KEY_PRESSED;
+
+ switch (num) {
+ case 1:
+ val += WIDGET_KEY_UP;
+ break;
+ case 2:
+ val += WIDGET_KEY_DOWN;
+ break;
+ case 3:
+ val += WIDGET_KEY_LEFT;
+ break;
+ case 4:
+ val += WIDGET_KEY_RIGHT;
+ break;
+ case 5:
+ val += WIDGET_KEY_CONFIRM;
+ break;
+ case 6:
+ val += WIDGET_KEY_CANCEL;
+ break;
+ default:
+ error("%s: unknown keypad value %d", Name, num);
+ }
+
+ debug("%s: key %c (0x%x) pressed", Name, num, num);
+ return val;
+}
+
+
static void drv_X11_expose(const int x, const int y, const int width, const int height)
{
/*
@@ -143,12 +214,13 @@ static void drv_X11_expose(const int x, const int y, const int width, const int
int r, c;
int x0, y0;
int x1, y1;
- XFontStruct *xfs = XQueryFont(dp, XGContextFromGC(DefaultGC(dp, 0)));
+ XFontStruct *xfs;
int xoffset = border + (DCOLS / XRES) * cgap + DCOLS * (pixel + pgap);
int yoffset = border + (DROWS / YRES) * rgap;
int yk;
- char s[3];
-
+ char *s;
+ char unknownTxt[10];
+
x0 = x - pixel;
x1 = x + pixel + width;
y0 = y - pixel;
@@ -166,22 +238,43 @@ static void drv_X11_expose(const int x, const int y, const int width, const int
XFillRectangle(dp, w, gc, xc, yc, pixel, pixel);
}
}
-
+
/* Keypad on the right side */
- debug("buttons: %d (%dx%d), xfont: %dx%d",
- buttons, btnwidth, btnheight, xfs->max_bounds.width, xfs->max_bounds.ascent);
- drv_X11_color(FG_COL);
- for (r = 0; r < buttons; r++) {
- yk = yoffset + r * (btnheight + pgap);
- snprintf(s, sizeof(s), "%d", r);
- debug("x: %d, y: %d, text: %s", xoffset, y, s);
-
- XDrawRectangle(dp, w, gc, xoffset, yk, btnwidth, btnheight - 2);
- XDrawString(dp, w, gc,
- xoffset + btnwidth / 2 - xfs->max_bounds.width / 2, yk + btnheight / 2 + xfs->max_bounds.ascent / 2,
- s, 1);
+ if (x1 >= xoffset) {
+ xfs = XQueryFont(dp, XGContextFromGC(DefaultGC(dp, 0)));
+ drv_X11_color(FG_COL);
+ for (r = 0; r < buttons; r++) {
+ yk = yoffset + r * (btnheight + pgap);
+ switch(r) {
+ case 0:
+ s = "Up";
+ break;
+ case 1:
+ s = "Down";
+ break;
+ case 2:
+ s = "Left";
+ break;
+ case 3:
+ s = "Right";
+ break;
+ case 4:
+ s = "Confirm";
+ break;
+ case 5:
+ s = "Cancel";
+ break;
+ default:
+ snprintf(unknownTxt, sizeof(unknownTxt), "#%d??", r);
+ s = unknownTxt;
+ }
+ XDrawRectangle(dp, w, gc, xoffset, yk, btnwidth, btnheight - 2);
+ XDrawString(dp, w, gc,
+ xoffset + btnwidth / 2 - (xfs->max_bounds.width * strlen(s)) / 2, yk + btnheight / 2 + xfs->max_bounds.ascent / 2,
+ s, strlen(s));
+ }
}
- XSync(dp, False);
+ //XSync(dp, False);
}
@@ -191,19 +284,33 @@ static void drv_X11_timer( __attribute__ ((unused))
XEvent ev;
int xoffset = border + (DCOLS / XRES) * cgap + DCOLS * (pixel + pgap);
int yoffset = border + (DROWS / YRES) * rgap;
- int btn;
-
- if (XCheckWindowEvent(dp, w, ExposureMask | ButtonPressMask, &ev) == 0)
+ static int btn = 0;
+
+ if (XCheckWindowEvent(dp, w, ExposureMask | ButtonPressMask | ButtonReleaseMask, &ev) == 0)
return;
- if (ev.type == Expose) {
- drv_X11_expose(ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height);
- }
- if (ev.type == ButtonPress) {
- if (ev.xbutton.x >= xoffset && ev.xbutton.x <= xoffset + btnwidth
- && ev.xbutton.y >= yoffset && ev.xbutton.y <= yoffset + buttons * btnheight + (buttons - 1) * pgap) {
- btn = (ev.xbutton.y - yoffset) / (btnheight + pgap);
- info("Button %d pressed", btn);
- }
+ switch(ev.type) {
+ case Expose:
+ drv_X11_expose(ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height);
+ break;
+ case ButtonPress:
+ if ( ev.xbutton.x >= xoffset && ev.xbutton.x <= xoffset + btnwidth
+ && ev.xbutton.y >= yoffset && ev.xbutton.y <= yoffset + buttons * btnheight + (buttons -1 ) *pgap ) {
+ btn = (ev.xbutton.y - yoffset) / (btnheight + pgap) + 1; /* btn 0 is unused */
+ drv_X11_color(BG_COL);
+ XFillRectangle(dp, w, gc, xoffset + 1, yoffset + (btn - 1) * (btnheight + pgap) + 1, btnwidth - 1, btnheight - 2 - 1);
+ drv_generic_keypad_press(btn);
+ }
+ break;
+ case ButtonRelease:
+ if ( ev.xbutton.x >= xoffset && ev.xbutton.x <= xoffset + btnwidth
+ && ev.xbutton.y >= yoffset && ev.xbutton.y <= yoffset + buttons * btnheight + (buttons -1 ) *pgap ) {
+ XClearArea(dp, w, xoffset, yoffset + (btn - 1) * (btnheight + pgap), btnwidth, btnheight - 2, 1 /* true */);
+ btn = (ev.xbutton.y - yoffset) / (btnheight + pgap) + 1; /* btn 0 is unused */
+ info("%s: Button %d released", Name, btn);
+ }
+ break;
+ default:
+ debug("%s: unknown XEvent %d", Name, ev.type);
}
}
@@ -212,7 +319,6 @@ static int drv_X11_start(const char *section)
{
int i;
char *s;
- RGBA BC;
XSetWindowAttributes wa;
XSizeHints sh;
XEvent ev;
@@ -254,14 +360,16 @@ static int drv_X11_start(const char *section)
if (cfg_number(section, "border", 0, 0, -1, &border) < 0)
return -1;
+ /* we need the basecolor for the brightness early */
s = cfg_get(section, "basecolor", "000000ff");
- if (color2RGBA(s, &BC) < 0) {
+ if (color2RGBA(s, &BL_COL) < 0) {
error("%s: ignoring illegal color '%s'", Name, s);
}
free(s);
-
- if (cfg_number(section, "buttons", 0, 0, 10, &buttons) < 0)
- return -1;
+
+ /* virtual keyboard: number of buttons (0..6) */
+ if (cfg_number(section, "buttons", 0, 0, 6, &buttons) < 0)
+ return -1;
drv_X11_FB = malloc(DCOLS * DROWS * sizeof(*drv_X11_FB));
if (drv_X11_FB == NULL) {
@@ -270,7 +378,7 @@ static int drv_X11_start(const char *section)
}
for (i = 0; i < DCOLS * DROWS; i++) {
- drv_X11_FB[i] = BC;
+ drv_X11_FB[i] = BL_COL;
}
if ((dp = XOpenDisplay(NULL)) == NULL) {
@@ -292,7 +400,7 @@ static int drv_X11_start(const char *section)
btnheight = (DROWS * pixel + (DROWS - 1) * pgap) / buttons;
}
- wa.event_mask = ExposureMask | ButtonPressMask;
+ wa.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask;
sh.min_width = sh.max_width = dimx + 2 * border + btnwidth;
sh.min_height = sh.max_height = dimy + 2 * border;
@@ -304,12 +412,17 @@ static int drv_X11_start(const char *section)
XSetWMProperties(dp, w, NULL, NULL, NULL, 0, &sh, NULL, NULL);
- drv_X11_color(BC);
+ drv_X11_color(BL_COL);
XFillRectangle(dp, pm, gc, 0, 0, sh.min_width, sh.min_height);
XSetWindowBackground(dp, w, xc.pixel);
XClearWindow(dp, w);
+ /* set brightness (after first background painting) */
+ if (cfg_number(section, "Brightness", 0, 0, 255, &i) > 0) {
+ drv_X11_brightness(i);
+ }
+
XStoreName(dp, w, "LCD4Linux");
XMapWindow(dp, w);
@@ -317,7 +430,6 @@ static int drv_X11_start(const char *section)
while (1) {
XNextEvent(dp, &ev);
- info("XEvent %d", ev.type);
if (ev.type == Expose && ev.xexpose.count == 0)
break;
}
@@ -335,7 +447,24 @@ static int drv_X11_start(const char *section)
/*** plugins ***/
/****************************************/
-/* none at the moment... */
+static void plugin_brightness(RESULT * result, const int argc, RESULT * argv[])
+{
+ double brightness;
+
+ switch (argc) {
+ case 0:
+ brightness = drv_X11_brightness(-1);
+ SetResult(&result, R_NUMBER, &brightness);
+ break;
+ case 1:
+ brightness = drv_X11_brightness(R2N(argv[0]));
+ SetResult(&result, R_NUMBER, &brightness);
+ break;
+ default:
+ error("%s.brightness(): wrong number of parameters", Name);
+ SetResult(&result, R_STRING, "");
+ }
+}
/****************************************/
@@ -364,11 +493,16 @@ int drv_X11_init(const char *section, const int quiet)
/* real worker functions */
drv_generic_graphic_real_blit = drv_X11_blit;
+ drv_generic_keypad_real_press = drv_X11_keypad;
/* initialize generic graphic driver */
if ((ret = drv_generic_graphic_init(section, Name)) != 0)
return ret;
+ /* initialize generic key pad driver */
+ if ((ret = drv_generic_keypad_init(section, Name)) != 0)
+ return ret;
+
drv_generic_graphic_clear();
/* initially expose window */
@@ -384,7 +518,7 @@ int drv_X11_init(const char *section, const int quiet)
}
/* register plugins */
- /* none at the moment... */
+ AddFunction("LCD::brightness", -1, plugin_brightness);
return 0;
@@ -398,6 +532,7 @@ int drv_X11_quit(const __attribute__ ((unused))
info("%s: shutting down.", Name);
drv_generic_graphic_quit();
+ drv_generic_keypad_quit();
if (drv_X11_FB) {
free(drv_X11_FB);