📄 sony lcd mcu driver.h
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#include <linux/sonypi.h>
#include <string.h>
extern "C" {
#include <xosd.h>
}
#include <iostream>
typedef enum {MUTE, VOLUME, BRIGHTNESS, VGAOUT, TVOUT, UP, DOWN, JOGPRESSED, TIMEOUT} Event;
class EventGenerator {
private:
int sonypi;
Display* display;
int timeout;
bool keyboardGrabbed;
public:
EventGenerator(int sonypi, Display* display, int timeout)
: sonypi(sonypi), display(display), timeout(timeout), keyboardGrabbed(false)
{
XAllowEvents(display, AsyncBoth, CurrentTime);
XSelectInput(display, DefaultRootWindow(display), KeyPressMask);
}
Event getNextEvent() {
while (true) {
// select descriptors
fd_set readset;
FD_ZERO(&readset);
FD_SET(sonypi, &readset);
if (keyboardGrabbed) {
FD_SET(ConnectionNumber(display), &readset);
}
// wait for event
timeval t;
t.tv_sec = timeout;
t.tv_usec = 0;
int s = select(FD_SETSIZE, &readset, 0, 0, &t);
// timeout
if (s == 0) {
return TIMEOUT;
}
// input event
else if (s > 0) {
// X event
if (keyboardGrabbed && FD_ISSET(ConnectionNumber(display), &readset)) {
XEvent e;
XNextEvent(display, &e);
switch (e.type) {
case KeyPress:
switch (XKeycodeToKeysym(display, e.xkey.keycode, 0)) {
case XK_Up: case XK_Right:
return UP;
case XK_Down: case XK_Left:
return DOWN;
}
}
}
// Sonypi event
else if (FD_ISSET(sonypi, &readset)) {
unsigned char e;
read(sonypi, &e, sizeof(e));
switch (e) {
case SONYPI_EVENT_FNKEY_F3:
return MUTE;
case SONYPI_EVENT_FNKEY_F4:
return VOLUME;
case SONYPI_EVENT_FNKEY_F5:
return BRIGHTNESS;
case SONYPI_EVENT_FNKEY_F7:
return VGAOUT;
case SONYPI_EVENT_FNKEY_F8:
return TVOUT;
case SONYPI_EVENT_JOGDIAL_UP:
return UP;
case SONYPI_EVENT_JOGDIAL_DOWN:
return DOWN;
case SONYPI_EVENT_JOGDIAL_PRESSED:
return JOGPRESSED;
}
}
}
}
}
void grabKeyboard() {
if (keyboardGrabbed) return;
XGrabKey(display, XKeysymToKeycode(display, XK_Up), 0,
DefaultRootWindow(display), False,
GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, XK_Down), 0,
DefaultRootWindow(display), False,
GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, XK_Left), 0,
DefaultRootWindow(display), False,
GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, XK_Right), 0,
DefaultRootWindow(display), False,
GrabModeAsync, GrabModeAsync);
XFlush(display);
keyboardGrabbed = true;
}
void ungrabKeyboard() {
if (!keyboardGrabbed) return;
XUngrabKey(display, AnyKey, 0, DefaultRootWindow(display));
XFlush(display);
keyboardGrabbed = false;
}
};
class VolumeController {
private:
xosd* osd;
int volume, mutedVolume;
int getVolume() {
FILE *pin;
char buf[100];
pin = popen("aumix -vq", "r");
fgets(buf, sizeof(buf) - 1, pin);
pclose(pin);
return atoi(buf + 4);
}
void setVolume(int v) {
char buf[100];
sprintf(buf, "aumix -v%d", v);
system(buf);
}
void displayVolume(int v) {
xosd_display(osd, 0, XOSD_string, "Volume");
xosd_display(osd, 1, XOSD_percentage, v);
}
public:
VolumeController(xosd* osd)
: osd(osd) {
}
void show() {
volume = getVolume();
displayVolume(volume);
}
void up() {
volume += 10;
if (volume > 100) volume = 100;
setVolume(volume);
displayVolume(volume);
}
void down() {
volume -= 10;
if (volume < 0) volume = 0;
setVolume(volume);
displayVolume(volume);
}
void mute() {
volume = getVolume();
if (volume > 0) mutedVolume = 0;
if (mutedVolume == 0) {
mutedVolume = volume;
volume = 0;
} else {
volume = mutedVolume;
mutedVolume = 0;
}
setVolume(volume);
displayVolume(volume);
}
};
class BrightnessController {
private:
xosd* osd;
int brightness;
int getBrightness() {
FILE *pin0, *pin;
char buf[100];
/* Read brightness twice due to a bug in spicctrl */
pin0 = popen("spicctrl -B", "r");
pclose(pin0);
pin = popen("spicctrl -B", "r");
fgets(buf, sizeof(buf) - 1, pin);
pclose(pin);
return atoi(buf) * 100 / 255;;
}
void setBrightness(int b) {
char buf[100];
sprintf(buf, "spicctrl -b %d", b * 255 / 100);
system(buf);
}
void displayBrightness(int b) {
xosd_display(osd, 0, XOSD_string, "Brightness");
xosd_display(osd, 1, XOSD_percentage, b);
}
public:
BrightnessController(xosd* osd)
: osd(osd) {
}
void show() {
brightness = getBrightness();
displayBrightness(brightness);
}
void up() {
brightness += 10;
if (brightness > 100) brightness = 100;
setBrightness(brightness);
displayBrightness(brightness);
}
void down() {
brightness -= 10;
if (brightness < 0) brightness = 0;
setBrightness(brightness);
displayBrightness(brightness);
}
};
class VideoController {
private:
static const int LCD = 1;
static const int VGA = 2;
static const int TV = 4;
xosd* osd;
int getVideo() {
FILE *pin;
char buf[100];
int out = 0;
pin = popen("atitvout -f active", "r");
while (fgets(buf, sizeof(buf) - 1, pin)) {
if (strncmp(buf, "LCD", 3) == 0) {
out |= LCD;
}
if (strncmp(buf, "CRT", 3) == 0) {
out |= VGA;
}
if (strncmp(buf, "TV", 2) == 0) {
out |= TV;
}
}
pclose(pin);
return out;
}
void setVideo(int out) {
char buf[100];
switch (out) {
case LCD | VGA | TV:
sprintf(buf, "atitvout -f lct");
break;
case LCD | VGA:
sprintf(buf, "atitvout -f lc");
break;
case LCD | TV:
sprintf(buf, "atitvout -f lt");
break;
case VGA | TV:
sprintf(buf, "atitvout -f ct");
break;
case LCD:
sprintf(buf, "atitvout -f l");
break;
case VGA:
sprintf(buf, "atitvout -f c");
break;
case TV:
sprintf(buf, "atitvout -f t");
break;
default:
return;
}
system(buf);
}
void displayVideo(int v) {
switch (v) {
case LCD | VGA | TV:
xosd_display(osd, 0, XOSD_string, "LCD + VGA + TV");
break;
case LCD | VGA:
xosd_display(osd, 0, XOSD_string, "LCD + VGA");
break;
case LCD | TV:
xosd_display(osd, 0, XOSD_string, "LCD + TV");
break;
case VGA | TV:
xosd_display(osd, 0, XOSD_string, "VGA + TV");
break;
case LCD:
xosd_display(osd, 0, XOSD_string, "LCD");
break;
case VGA:
xosd_display(osd, 0, XOSD_string, "VGA");
break;
case TV:
xosd_display(osd, 0, XOSD_string, "TV");
break;
default:
return;
}
xosd_display(osd, 1, XOSD_string, "");
}
public:
VideoController(xosd* osd)
: osd(osd) {
}
void toggleVGA() {
int output, test;
output = getVideo(); /* current state */
if (output < 0) /* can't set video out */
return;
if (output & LCD) {
if (output & VGA) { /* LCD + VGA is active */
output &= ~LCD; /* turn LCD off */
}
else { /* only LCD is active */
output |= VGA; /* turn VGA on */
}
}
else {
if (output & VGA) { /* only VGA is active */
output |= LCD; /* turn LCD on and VGA off */
output &= ~VGA;
}
else { /* neither LCD nor VGA is active */
output |= LCD; /* turn LCD on */
}
}
setVideo(output); /* try to set new output */
test = getVideo(); /* check new state */
if (test != output) { /* no success, try easier configuration */
if (output & VGA) {
setVideo(VGA);
}
else {
setVideo(LCD);
}
test = getVideo();
}
displayVideo(test);
}
void toggleTV() {
int output, test;
output = getVideo(); /* current state */
if (output < 0) /* can't set video out */
return;
if (output & LCD) {
if (output & TV) { /* LCD + TV is active */
output &= ~LCD; /* turn LCD off */
}
else { /* only LCD is active */
output |= TV; /* turn TV on */
}
}
else {
if (output & TV) { /* only TV is active */
output |= LCD; /* turn LCD on and TV off */
output &= ~TV;
}
else { /* neither LCD nor TV is active */
output |= LCD; /* turn LCD on */
}
}
setVideo(output); /* try to set new output */
test = getVideo(); /* check new state */
if (test != output) { /* no success, try easier configuration */
if (output & TV) {
setVideo(TV);
}
else {
setVideo(LCD);
}
test = getVideo();
}
displayVideo(test);
}
};
int main() {
// open /dev/sonypi
int sonypi = open("/dev/sonypi", O_RDONLY);
// open display
Display* display = XOpenDisplay(NULL);
EventGenerator g(sonypi, display, 2);
xosd* osd = xosd_init("-*-helvetica-*-r-*-*-40-*-*-*-*-*-*-*", "LawnGreen", -1, XOSD_bottom, 0, 2, 2);
VolumeController volume(osd);
BrightnessController brightness(osd);
VideoController video(osd);
enum {IDLE, VOLUME, BRIGHTNESS} mode = IDLE;
while (true) {
Event e = g.getNextEvent();
switch (e) {
case MUTE:
mode = VOLUME;
g.grabKeyboard();
volume.mute();
break;
case VOLUME:
mode = VOLUME;
g.grabKeyboard();
volume.show();
break;
case BRIGHTNESS:
mode = BRIGHTNESS;
g.grabKeyboard();
brightness.show();
break;
case VGAOUT:
mode = IDLE;
g.ungrabKeyboard();
video.toggleVGA();
break;
case TVOUT:
mode = IDLE;
g.ungrabKeyboard();
video.toggleTV();
break;
case UP:
switch (mode) {
case IDLE:
XTestGrabControl(display, True);
XTestFakeButtonEvent(display, 4, True, CurrentTime);
XTestFakeButtonEvent(display, 4, False, 30);
XSync(display, False);
XTestGrabControl(display, False);
break;
case VOLUME:
volume.up();
break;
case BRIGHTNESS:
brightness.up();
break;
}
break;
case DOWN:
switch (mode) {
case IDLE:
XTestGrabControl(display, True);
XTestFakeButtonEvent(display, 5, True, CurrentTime);
XTestFakeButtonEvent(display, 5, False, 30);
XSync(display, False);
XTestGrabControl(display, False);
break;
case VOLUME:
volume.down();
break;
case BRIGHTNESS:
brightness.down();
break;
}
break;
case JOGPRESSED:
XTestGrabControl(display, True);
XTestFakeButtonEvent(display, 2, True, CurrentTime);
XTestFakeButtonEvent(display, 2, False, 30);
XSync(display, False);
XTestGrabControl(display, False);
break;
case TIMEOUT:
mode = IDLE;
g.ungrabKeyboard();
xosd_hide(osd);
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -