⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sony lcd mcu driver.h

📁 本程序内附液晶电视MCU驱动C语言源程序代码
💻 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 + -