linux的触摸屏之五:帧缓冲设备上较准界面的配置

(1)帧缓冲设备跟TTY的关系。需要关注tty跟帧缓冲设备的关系,一般情况下帧缓冲设备是可以独立操作的,但是如果为了保证单独占用不被抢占,似乎还要关联一个tty终端。这里用的是虚终端VT。

      虚终端,也叫虚屏,它的英文名字为virtual terminal,缩写为VT或vt。在Unix系统用户中,虚终端有着广泛的应用。它解决了主控台单一交互界面的限制,使用户可在保护当前界面的情况下启用另一界面去做另一工作。我们可利用Unix系统提供的系统调用来编制虚终端程序,并可把它加入到我们的应用程序中去。

      我们可利用ioctl函数操纵虚终端设备文件,实现与Unix系统内核的交互,得到我们所需要的服务。使用ioctl的具体形式如下:
int ioct1(int filedes,int request,…/*参数*/。request为请求的服务,随后的参数可为各种数据类型,视具体情况而定。

VT_OPENQRY 查找一个可利用的虚终端。

VT_SETMODE 设置虚终端模式(自动或进程控制)。

VT_GETSTATE   获取全部虚终端的状态信息。

VT_ACTIVATE 使在参数中指定的虚终端号为活动虚终端。如果指定的虚终端不处于打开状态或者不存在,调用将失败。

VT_WAITACTIVE 等待虚终端被激活,不需要参数。

      有了上面的介绍,现在我们就可以实现虚终端了:
1,查找是否有可利用的虚终端,如没有,则结束。
2,打开可利用虚终端设备文件,以便进行。
3,利用ioctl的TCSETSW功能设置虚终端参数。

4,利用ioctl的VT_ACTIVATE功能激活虚终端,并利用VT_WAITACTIVE功能等待其可用。
5,用putenv函数设置环境变量。
  至此,一个虚终端程序就实现了。

(2)open_framebuffer

static int con_fd, fb_fd, last_vt = -1;
static struct fb_fix_screeninfo fix;
static struct fb_var_screeninfo var;
static unsigned char *fbuffer;
static unsigned char **line_addr;
static int fb_fd=0;
static int bytes_per_pixel;
static unsigned colormap [256];
__u32 xres, yres;

 

#define TSLIB_FBDEVICE   "/dev/graphics/fb0"

static char *defaultfbdevice = "/dev/graphics/fb0";
static char *defaultconsoledevice = "/dev/tty";
static char *fbdevice = NULL;
static char *consoledevice = NULL;

int open_framebuffer(void)

{

        struct vt_stat vts; char vtname[128]; int fd, nr; unsigned y, addr;

        if ((fbdevice = getenv ("TSLIB_FBDEVICE")) == NULL)

               fbdevice = defaultfbdevice;                                    //帧设备

        if ((consoledevice = getenv ("TSLIB_CONSOLEDEVICE")) == NULL)
               consoledevice = defaultconsoledevice;                  //控制台设备

        if (strcmp (consoledevice, "none") != 0)

        {

               sprintf (vtname,"%s%d", consoledevice, 1);    //组合成dev/tty1

               fd = open (vtname, O_WRONLY);

               if (ioctl(fd, VT_OPENQRY, &nr) < 0) {                 //查找可用的虚终端

                       return -1;

               }

               close(fd);

               sprintf(vtname, "%s%d", consoledevice, nr);    //获得可以的虚终端名字

               con_fd = open(vtname, O_RDWR | O_SYNC);

               if (ioctl(con_fd, VT_GETSTATE, &vts) == 0)         //获取虚终端设备状态信息

               {

                      last_vt = vts.v_active;

               }

               if (ioctl(con_fd, VT_ACTIVATE, nr) < 0)                //如果激活失败

               {

                      close(con_fd);return -1;

               }

               if (ioctl(con_fd, VT_WAITACTIVE, nr) < 0)            //是否可用

               {
                      close(con_fd);return -1;
                }

                if (ioctl(con_fd, KDSETMODE, KD_GRAPHICS) < 0)   //设置中断工作在图像模式

                {
                       close(con_fd);return -1;
                }

        }

        fb_fd = open(fbdevice, O_RDWR);     //在打开帧缓冲设备

        ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix);

        ioctl(fb_fd, FBIOGET_VSCREENINFO, &var);  //获得设备的配置参数

        xres = var.xres;
        yres = var.yres;  //获得屏幕分辨率

        fbuffer = mmap(NULL, fix.smem_len, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fb_fd, 0);

        memset(fbuffer,0,fix.smem_len);

        bytes_per_pixel = (var.bits_per_pixel + 7) / 8;
        line_addr = malloc (sizeof (__u32) * var.yres_virtual);
        addr = 0;
        for (y = 0; y < var.yres_virtual; y++, addr += fix.line_length)
             line_addr [y] = fbuffer + addr;        //得到后面画点画线的基础地址

}

(3)close_framebuffer

void close_framebuffer(void)
{
        munmap(fbuffer, fix.smem_len);
        close(fb_fd);                         //关闭映射和帧缓冲

        if(strcmp(consoledevice,"none")!=0)

        {
              if (ioctl(con_fd, KDSETMODE, KD_TEXT) < 0)
                    LOGE("KDSETMODE");
              if (last_vt >= 0)
                    if (ioctl(con_fd, VT_ACTIVATE, last_vt))
                          LOGE("VT_ACTIVATE");
              close(con_fd);
         }

        free (line_addr);
}

 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值