From ef1736dc4fa9679f76f795bbef6139e3ea96797e Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Mon, 29 Mar 2010 12:39:01 +0300 Subject: [PATCH] op_runfbapp and op_gammatool --- Makefile | 23 +++ font.c | 70 +++++++ op_gammatool.c | 430 +++++++++++++++++++++++++++++++++++++++++++ op_runfbapp.c | 217 ++++++++++++++++++++++ scripts/op_gammatool | 12 ++ 5 files changed, 752 insertions(+) create mode 100644 Makefile create mode 100644 font.c create mode 100644 op_gammatool.c create mode 100644 op_runfbapp.c create mode 100755 scripts/op_gammatool diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b77ba5a --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CROSS_COMPILE ?= arm-none-linux-gnueabi- +CC = $(CROSS_COMPILE)gcc + +CFLAGS += -Wall -O2 +LDFLAGS += -s +INSTALL ?= bin + +BIN = op_runfbapp op_gammatool + +all: $(BIN) + +clean: + $(RM) *.o $(BIN) + +op_runfbapp: LDFLAGS += -lpthread -lX11 + +$(INSTALL): + mkdir -p $(INSTALL) + +install: $(INSTALL) $(BIN) + cp op_runfbapp $(INSTALL)/ + cp op_gammatool $(INSTALL)/op_gammatool_bin + cp scripts/op_gammatool $(INSTALL)/op_gammatool diff --git a/font.c b/font.c new file mode 100644 index 0000000..3a9553f --- /dev/null +++ b/font.c @@ -0,0 +1,70 @@ +/* CGA 8x8 font? */ + +static const unsigned char fontdata8x8[64*16] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C, + 0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00, + 0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00, + 0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00, + 0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00, + 0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40, + 0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00, + 0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00, + 0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00, + 0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00, + 0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00, + 0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00, + 0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00, + 0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00, + 0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + 0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00, + 0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00, + 0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00, + 0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00, + 0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, + 0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30, + 0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + 0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00, + 0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00, + 0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00, + 0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00, + 0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00, + 0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00, + 0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00, + 0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00, + 0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, + 0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00, + 0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00, + 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00, + 0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00, + 0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00, + 0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, + 0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, + 0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, + 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00, + 0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00, + 0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00, + 0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C, + 0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00, + 0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00, + 0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00, + 0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00, + 0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06, + 0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00, + 0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00, + 0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00, + 0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, + 0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00, + 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00, + 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00, +}; + diff --git a/op_gammatool.c b/op_gammatool.c new file mode 100644 index 0000000..cda8e01 --- /dev/null +++ b/op_gammatool.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2010, Gražvydas Ignotas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SPLIT 12 + +#define DO_RGB(type,d,after,r,g,b) { \ + int i, u, c, l, div = (w << 8) / SPLIT; \ + char lines[8][dotsz * w]; \ + type *dest; \ + for (dest = (void *)lines[0], i = 0; i < w; i++) { \ + d = (i * (1 << r) / w) << (g+b); \ + after; \ + } \ + for (dest = (void *)lines[1], i = 0; i < w; i++) { \ + d = (i * (1 << g) / w) << b; \ + after; \ + } \ + for (dest = (void *)lines[2], i = 0; i < w; i++) { \ + d = (i * (1 << b) / w); \ + after; \ + } \ + for (dest = (void *)lines[3], i = 0; i < w; i++) { \ + d = ((i * (1 << r) / w) << (g+b)) | \ + ((i * (1 << g) / w) << b) | \ + (i * (1 << b) / w); \ + after; \ + } \ +\ + for (dest = (void *)lines[4], i = 0; i < w; i++) { \ + c = (((i << 8) / div + 1) * div) >> 8; \ + d = ((c * (1 << r) / w) << (g+b)) | \ + ((c * (1 << g) / w) << b) | \ + (c * (1 << b) / w); \ + after; \ + } \ + for (dest = (void *)lines[5], i = 0; i < w; i++) { \ + c = (((i << 8) / div + 1) * div) >> 8; \ + d = (c * (1 << b) / w); \ + after; \ + } \ + for (dest = (void *)lines[6], i = 0; i < w; i++) { \ + c = (((i << 8) / div + 1) * div) >> 8; \ + d = (c * (1 << g) / w) << b; \ + after; \ + } \ + for (dest = (void *)lines[7], i = 0; i < w; i++) { \ + c = (((i << 8) / div + 1) * div) >> 8; \ + d = (c * (1 << r) / w) << (g+b); \ + after; \ + } \ +\ + for (u = 0; u < h; u++) { \ + l = u / (h / 8); \ + memcpy((char *)ptr + u * dotsz * w, lines[l], dotsz * w); \ + } \ +} + +#include "font.c" + +static void text_out(void *fbi, int x, int y, int dotsz, int stride, const char *text) +{ + int i, l, v = -1; + char *fb; + + fb = (char *)fbi + x * dotsz + y * stride; + + for (i = 0; i < strlen(text); i++) + { + for (l=0;l<8;l++) + { + #define pix(fdmask,add) \ + if (fontdata8x8[((text[i])*8)+l]&fdmask) \ + memcpy(fb + l*stride + add*dotsz, &v, dotsz) + pix(0x80, 0); + pix(0x40, 1); + pix(0x20, 2); + pix(0x10, 3); + pix(0x08, 4); + pix(0x04, 5); + pix(0x02, 6); + pix(0x01, 7); + #undef pix + } + fb += dotsz * 8; + } +} + +static void get_config(char *buff, size_t size, int just_dir) +{ + char *home; + + home = getenv("HOME"); + if (home == NULL) + home = ""; + if (just_dir) + snprintf(buff, size, "%s/.config", home); + else + snprintf(buff, size, "%s/.config/op_gammatool", home); +} + +static int do_load(int *gamma) +{ + int ret, *g = gamma; + char buff[128]; + FILE *f; + + get_config(buff, sizeof(buff), 0); + f = fopen(buff, "r"); + if (f == NULL) + return -1; + ret = fscanf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n", + &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], + &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); + fclose(f); + + return (ret == 12) ? 0 : -1; +} + +static int do_save(const int *gamma) +{ + const int *g = gamma; + char buff[128]; + FILE *f; + int ret; + + get_config(buff, sizeof(buff), 1); + mkdir(buff, 0644); + get_config(buff, sizeof(buff), 0); + f = fopen(buff, "w"); + if (f == NULL) + return -1; + ret = fprintf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n", + g[0], g[1], g[2], g[3], g[4], g[5], + g[6], g[7], g[8], g[9], g[10], g[11]); + fclose(f); + + return (ret > 0) ? 0 : -1; +} + +int main(int argc, char *argv[]) +{ + const char *msg_once = "Start - exit, Y - change bpp, A/B - save/load, " + "hold R for faster tuning"; + int pressed_up = 0, pressed_down = 0, pressed_r = 0; + struct fb_var_screeninfo fbvar; + int fbdev, ifd, ret, sel = 0; + int i, w, h, dotsz = 0, stride; + int gamma[12] = { 0, }; + char buff[64]; + FILE *f; + void *ptr; + + fbdev = open("/dev/fb0", O_RDWR); + if (fbdev == -1) { + perror("open(\"/dev/fb0\") failed"); + return 1; + } + + ret = ioctl(fbdev, FBIOGET_VSCREENINFO, &fbvar); + if (ret == -1) { + perror("ioctl(FBIOGET_FSCREENINFO) failed"); + return 1; + } + + if (argv[1] != NULL) { + fbvar.bits_per_pixel = atoi(argv[1]); + ret = ioctl(fbdev, FBIOPUT_VSCREENINFO, &fbvar); + if (ret == -1) + { + perror("ioctl FBIOPUT_VSCREENINFO"); + } + } + + printf("visible resolution: %i %i\n", fbvar.xres, fbvar.yres); + printf("virtual resolution: %i %i\n", fbvar.xres_virtual, fbvar.yres_virtual); + printf("offset from virtual to visible: %i %i\n", fbvar.xoffset, fbvar.yoffset); + printf("bits_per_pixel: %i\n", fbvar.bits_per_pixel); + + ptr = mmap(0, fbvar.xres * fbvar.yres * 4, + PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0); + if (ptr == MAP_FAILED) + ptr = mmap(0, fbvar.xres * fbvar.yres * fbvar.bits_per_pixel / 8, + PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0); + if (ptr == MAP_FAILED) + { + perror("mmap(fbptr) failed"); + return 1; + } + + w = fbvar.xres; + h = fbvar.yres; + + // search for gpio keys + for (ifd = -1, i = 0; ; i++) { + snprintf(buff, sizeof(buff), "/dev/input/event%i", i); + ifd = open(buff, O_RDONLY | O_NONBLOCK); + if (ifd == -1) + break; + + ioctl(ifd, EVIOCGNAME(sizeof(buff)), buff); + + if (strcasestr(buff, "gpio") != NULL) + break; + close(ifd); + } + + ret = 0; + f = fopen("/sys/devices/platform/omap2_mcspi.1/spi1.1/gamma", "r+"); + if (f != NULL) { + int *g = gamma; + rewind(f); + ret = fscanf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n", + &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], + &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); + } + + if (ret != 12) { + fprintf(stderr, "gamma file missing or bad\n"); + goto out; + } + + while (1) + { + if (f != NULL) { + int *g = gamma; + rewind(f); + fscanf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n", + &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], + &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); + } + + //ioctl(fbdev, FBIO_WAITFORVSYNC, &ret); + if (fbvar.bits_per_pixel == 16) + { + dotsz = 2; + DO_RGB(unsigned short, dest[i],, 5, 6, 5); + } + else if (fbvar.bits_per_pixel == 24) + { + // BGR? + unsigned char *p; + unsigned int d = 0; + dotsz = 3; + DO_RGB(unsigned char, d, p = &dest[i*3]; p[0] = d; p[1] = d >> 8; p[2] = d >> 16, 8, 8, 8); + } + else if (fbvar.bits_per_pixel == 32) + { + dotsz = 4; + DO_RGB(unsigned int, dest[i],, 8, 8, 8); + } + else + { + fprintf(stderr, "unhandled bpp: %d\n", fbvar.bits_per_pixel); + goto out; + } + stride = dotsz * w; + + snprintf(buff, sizeof(buff), "%dbpp", fbvar.bits_per_pixel); + text_out(ptr, 8, 10, dotsz, stride, buff); + if (msg_once != NULL) { + text_out(ptr, 80, 10, dotsz, stride, msg_once); + msg_once = NULL; + } + for (i = 0; i < 12; i++) { + int x = i * w / 12 + 8; + if (i == sel) + text_out(ptr, x, h - 18, dotsz, stride, "____"); + snprintf(buff, sizeof(buff), "%d", gamma[i]); + text_out(ptr, x, h - 20, dotsz, stride, buff); + } + + // do input + if (ifd == -1) + break; + + while (1) + { + struct input_event ev; + ret = read(ifd, &ev, sizeof(ev)); + if (ret < (int) sizeof(ev)) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + goto input_no_change; + + perror("evtest: read error"); + goto out; + } + + if (ev.type != EV_KEY) + continue; + + switch (ev.code) { + case KEY_LEFT: + if (ev.value) + sel--; + if (sel < 0) + sel = 11; + goto input_done; + case KEY_RIGHT: + if (ev.value) + sel++; + if (sel > 11) + sel = 0; + goto input_done; + case KEY_UP: + pressed_up = ev.value; + break; + case KEY_DOWN: + pressed_down = ev.value; + break; + case KEY_RIGHTCTRL: + case BTN_TR: + pressed_r = ev.value; + break; + case KEY_PAGEUP: + case BTN_BASE: + if (ev.value) { + fbvar.bits_per_pixel += 8; + if (fbvar.bits_per_pixel > 32) + fbvar.bits_per_pixel = 16; + ret = ioctl(fbdev, FBIOPUT_VSCREENINFO, &fbvar); + if (ret == -1) + perror("ioctl FBIOPUT_VSCREENINFO"); + } + goto input_done; + case KEY_END: + case BTN_BASE2: + if (!ev.value) + break; + if (do_load(gamma) == 0) + msg_once = "loaded"; + else + msg_once = "load failed"; + goto input_done_gamma; + case KEY_HOME: + case BTN_BASE4: + if (!ev.value) + break; + if (do_save(gamma) == 0) + msg_once = "saved"; + else + msg_once = "save failed"; + goto input_done; + case KEY_LEFTALT: + case BTN_START: + goto out; + case KEY_LEFTCTRL: + case BTN_SELECT: + goto out; + } + +input_no_change: + if (pressed_up) { + gamma[sel]++; + if (gamma[sel] >= 1023) + gamma[sel] = 1023; + if (!pressed_r) + usleep(30000); + goto input_done_gamma; + } + if (pressed_down) { + gamma[sel]--; + if (gamma[sel] < 0) + gamma[sel] = 0; + if (!pressed_r) + usleep(30000); + goto input_done_gamma; + } + + usleep(10000); + } + +input_done_gamma: + if (f != NULL) { + int *g = gamma; + rewind(f); + fprintf(f, "%d %d %d %d %d %d %d %d %d %d %d %d\n", + g[0], g[1], g[2], g[3], g[4], g[5], + g[6], g[7], g[8], g[9], g[10], g[11]); + } +input_done:; + } + +out: + munmap(ptr, fbvar.xres * fbvar.yres * fbvar.bits_per_pixel / 8); + close(fbdev); + if (ifd != -1) + close(ifd); + return 0; +} + diff --git a/op_runfbapp.c b/op_runfbapp.c new file mode 100644 index 0000000..2e480e4 --- /dev/null +++ b/op_runfbapp.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2010, Gražvydas Ignotas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PFX "op_runfbapp: " + +static struct termios g_kbd_termios_saved; +static int g_kbdfd; + +static Cursor transparent_cursor(Display *display, Window win) +{ + Cursor cursor; + Pixmap pix; + XColor dummy; + char d = 0; + + memset(&dummy, 0, sizeof(dummy)); + pix = XCreateBitmapFromData(display, win, &d, 1, 1); + cursor = XCreatePixmapCursor(display, pix, pix, + &dummy, &dummy, 0, 0); + XFreePixmap(display, pix); + return cursor; +} + +static void *x11_handler(void *arg) +{ + unsigned int display_width, display_height; + XSetWindowAttributes attributes; + Window win; + XEvent report; + Display *display; + int screen; + + display = XOpenDisplay(NULL); + if (display == NULL) + { + fprintf(stderr, PFX "(not hiding X): Can't open display: %s\n", + XDisplayName(NULL)); + return NULL; + } + + screen = DefaultScreen(display); + + display_width = DisplayWidth(display, screen); + display_height = DisplayHeight(display, screen); + + win = XCreateSimpleWindow(display, + RootWindow(display, screen), + 0, 0, display_width, display_height, 0, + BlackPixel(display, screen), + BlackPixel(display, screen)); + + attributes.override_redirect = True; + attributes.cursor = transparent_cursor(display, win); + XChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes); + + XSelectInput(display, win, ExposureMask); + XMapWindow(display, win); + XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + + while (1) + { + XNextEvent(display, &report); + + if (report.type == Expose) + while (XCheckTypedEvent(display, Expose, &report)) + ; + } + + return NULL; +} + +static void hidecon_start(void) +{ + struct termios kbd_termios; + int mode; + + g_kbdfd = open("/dev/tty", O_RDWR); + if (g_kbdfd == -1) { + perror(PFX "open /dev/tty"); + return; + } + + if (ioctl(g_kbdfd, KDGETMODE, &mode) == -1) { + perror(PFX "(not hiding FB): KDGETMODE"); + goto fail; + } + + if (tcgetattr(g_kbdfd, &kbd_termios) == -1) { + perror(PFX "tcgetattr"); + goto fail; + } + + g_kbd_termios_saved = kbd_termios; + kbd_termios.c_lflag &= ~(ICANON | ECHO); // | ISIG); + kbd_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + kbd_termios.c_cc[VMIN] = 0; + kbd_termios.c_cc[VTIME] = 0; + + if (tcsetattr(g_kbdfd, TCSAFLUSH, &kbd_termios) == -1) { + perror(PFX "tcsetattr"); + goto fail; + } + + if (ioctl(g_kbdfd, KDSETMODE, KD_GRAPHICS) == -1) { + perror(PFX "KDSETMODE KD_GRAPHICS"); + tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved); + goto fail; + } + + return; + +fail: + close(g_kbdfd); + g_kbdfd = -1; +} + +static void hidecon_end(void) +{ + if (g_kbdfd < 0) + return; + + if (ioctl(g_kbdfd, KDSETMODE, KD_TEXT) == -1) + perror(PFX "KDSETMODE KD_TEXT"); + + if (tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved) == -1) + perror(PFX "tcsetattr"); + + close(g_kbdfd); + g_kbdfd = -1; +} + +int main(int argc, char *argv[]) +{ + pthread_t tid; + char *cmd, *p; + int len = 0; + int ret; + int i; + + for (i = 1; i < argc; i++) + len += strlen(argv[i]) + 1; + + cmd = malloc(len); + if (cmd == NULL) + { + fprintf(stderr, PFX "OOM\n"); + return 1; + } + + /* rebuild command line for program we launch */ + for (p = cmd, i = 1; i < argc; i++) { + strcpy(p, argv[i]); + p += strlen(p); + + if (i < argc - 1) + *p++ = ' '; + } + + ret = pthread_create(&tid, NULL, x11_handler, NULL); + if (ret != 0) { + fprintf(stderr, PFX "pthread_create: %d\n", ret); + return 1; + } + pthread_detach(tid); + + hidecon_start(); + + ret = system(cmd); + if (ret == -1) + perror(PFX "system"); + free(cmd); + + hidecon_end(); + + /* XXX: maybe stop the X thread nicely? */ + + return 0; +} + diff --git a/scripts/op_gammatool b/scripts/op_gammatool new file mode 100755 index 0000000..bbc9eaa --- /dev/null +++ b/scripts/op_gammatool @@ -0,0 +1,12 @@ +#!/bin/sh + +OLDDEPTH=`fbset | grep geometry | awk '{ print $6 }'` + +if [ -n "$DISPLAY" -a "$(id -u)" != "0" ] +then + gksudo ./op_runfbapp ./op_gammatool_bin +else + ./op_runfbapp ./op_gammatool_bin +fi + +fbset -depth $OLDDEPTH -- 2.39.2