热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Linux字符终端如何用鼠标移动一个红色矩形详解

这篇文章主要给大家介绍了关于Linux字符终端如何用鼠标移动一个红色矩形的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Linux具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

一切皆文件! UNIX已经说了。埃里克雷蒙德这样说的,不服吗?

既然 /dev/fb0 被抽象成了显示器,可以在字符终端通过操作映射了 /dev/fb0 的内存在屏幕上画32bit真彩图,那么如何操作鼠标键盘呢?

/dev/input/mouse0 可以用来读取鼠标事件。当你在字符终端cat它并移动鼠标时,它貌似告诉你有事情发生了,但是你却无法解读:


为了找到解读它的正确方法,要么谷歌,要么百度,要么还有一个最直接的方法,那就是查Linux内核源码中关于mouse0这个文件的read回调函数:

static ssize_t mousedev_read(struct file *file, char __user *buffer,
     size_t count, loff_t *ppos)
{
 struct mousedev_client *client = file->private_data;
 struct mousedev *mousedev = client->mousedev;
 // mousedev_client结构体里查找到ps2的大小是6个字节。
 signed char data[sizeof(client->ps2)];
 int retval = 0;

 spin_lock_irq(&client->packet_lock);

 if (!client->buffer && client->ready) {
  // 这里就是核心了,继续跟过去
  mousedev_packet(client, client->ps2);
  client->buffer = client->bufsiz;
 }
 ...

我们看看 mousedev_packet 是如何组装包的:

static void mousedev_packet(struct mousedev_client *client,
    signed char *ps2_data)
{
 struct mousedev_motion *p = &client->packets[client->tail];

 ps2_data[0] = 0x08 |
  ((p->dx <0) <<4) | ((p->dy <0) <<5) | (p->buttons & 0x07);
 ps2_data[1] = mousedev_limit_delta(p->dx, 127);
 ps2_data[2] = mousedev_limit_delta(p->dy, 127);
 p->dx -= ps2_data[1];
 p->dy -= ps2_data[2];
...

非常明白,我不管别的,我也没有动机去学,我现在就是想知道鼠标的X,Y坐标:

  • p->dx,p->dy从名字上和从代码上都可以看出,这是 相对于上一次 的坐标的变化!

所有信息都有了。

那么,现在,可以写代码了:

#include 
#include 
#include 
#include 
#include 

// 正方形边长为100个像素点
#define LENGTH 100

// 显示器显存的抽象
unsigned int *mem = NULL;
// 保存上一次的屏幕
unsigned int *old_mem = NULL;
// 屏幕信息
static struct fb_var_screeninfo info;
int mouse_fd, fb_fd;

// 正方形涂成红色
int start = 0xffff0000;

int main(int argc, char **argv)
{
 signed char mouse_event[6];
 char rel_x, rel_y;
 int old_x = 0, old_y = 0;
 int abs_x = 0, abs_y = 0;

 mouse_fd = open("/dev/input/mouse0", O_RDONLY);
 fb_fd = open("/dev/fb0", O_RDWR);

 ioctl(fb_fd, FBIOGET_VSCREENINFO, &info);

 mem = (unsigned int *)mmap(NULL, info.xres*info.yres*info.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);

 while(read(mouse_fd, &mouse_event[0], 6)) {
 int i, w, h;
 static int idx = 0;

 // 按照内核mousedev_packet的定义,解析出相对位移。
 rel_x = (char) mouse_event[1];
 rel_y = (char) mouse_event[2];
 // 计算绝对位移
 abs_x += rel_x;
 abs_y -= rel_y;
 if (abs_x <= 0 || abs_x >= info.xres - LENGTH || abs_y <= 0 || abs_y >= info.yres - LENGTH) {
 continue;
 }

 if (old_mem == NULL) {
 old_mem = (unsigned int *)mmap(NULL, info.xres*info.yres*info.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
 if (old_mem == NULL) {
 exit(1);
 }
 } else {
 // 恢复上一次正方形区域里的像素
 for (w = old_x; w 

运行它,然后在字符终端移动鼠标,效果如下:

嗯,矩形随着鼠标而移动,并且不会破坏任何所到之处的字符。

现在,我来回顾一下这个周末做的这些事情,意味着什么。

  • 我可以在字符终端上画32位真彩图;
  • 我可以检测到鼠标键盘的事件并且反应。

这意味着,如果有时间和精力,我可以实现一个GUI系统了。

当然,GUI系统和网络协议栈那是隔行如隔山,肯定会遇到超级多的麻烦,不是仅仅读写两个文件:

  • /dev/fb0
  • /dev/input/mouse0

就可以搞定的。

事实上,真正的GUI系统从来不用这种方式。它们貌似在反抗着 UNIX一切皆文件 的理念,并且证明这样会更好!哦,对了,Windows GUI的成功就是一个证明,还有后来最新版本的MacOS…

说什么字符终端,字符也是 画出来的 。没什么大不了的。只不过,想要用像素去设置字符,那就要了解一下 字符点阵 的information了…这又是另一个领域的话题。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。


推荐阅读
  • 本文将详细探讨PHP中C的作用,并对比其他编程语言如Java和C的特点及其适用场景。 ... [详细]
  • 本文通过基准测试(Benchmark)对.NET Core环境下Thrift和HTTP客户端的微服务通信性能进行对比分析。基准测试是一种评估系统或组件性能的方法,通过运行一系列标准化的测试来衡量其表现。 ... [详细]
  • 华为捐赠欧拉操作系统,承诺不推商用版
    华为近日宣布将欧拉开源操作系统捐赠给开放原子开源基金会,并承诺不会推出欧拉的商用发行版。此举旨在推动欧拉和鸿蒙操作系统的全场景融合与生态发展。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • Parallels Desktop for Mac 是一款功能强大的虚拟化软件,能够在不重启的情况下实现在同一台电脑上无缝切换和使用 Windows 和 macOS 系统中的各种应用程序。该软件不仅提供了高效稳定的性能,还支持多种高级功能,如拖放文件、共享剪贴板等,极大地提升了用户的生产力和使用体验。 ... [详细]
  • Dense Matrix Inversion Results in Segmentation Fault: Causes and Solutions ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • Python学习:环境配置与安装指南
    Python作为一种跨平台的编程语言,适用于Windows、Linux和macOS等多种操作系统。为了确保本地已成功安装Python,用户可以通过终端或命令行界面输入`python`或`python3`命令进行验证。此外,建议使用虚拟环境管理工具如`venv`或`conda`,以便更好地隔离不同项目依赖,提高开发效率。 ... [详细]
  • 如何在Ubuntu系统中直接使用Snap安装软件
    Canonical与Opera Software近日宣布,基于Chromium的Opera浏览器现已作为Snap包提供给Ubuntu用户,显著提升了在Linux操作系统上的安装便捷性和兼容性。通过Snap,用户可以在Ubuntu系统中轻松安装和更新Opera浏览器,享受更流畅的浏览体验。此外,Snap的容器化特性还确保了应用的安全性和稳定性,为用户提供更加可靠的软件环境。 ... [详细]
  • 本文详细介绍了如何在Windows操作系统中通过Samba服务访问Red Hat Linux中的资源,包括配置Samba服务器、设置工作组名称、添加用户和共享目录等步骤。 ... [详细]
  • 从零开始编译Linux系统:第16章 全新起点
    本章将详细介绍如何从零开始编译一套完整的Linux系统,涵盖关键组件如glibc库的介绍及其重要性。通过本文,读者将了解从源代码构建Linux系统的全过程。 ... [详细]
  • 本文介绍了如何在Linux和Windows环境中使用C语言中的beep函数来生成不同频率的声音,并提供了详细的代码示例和解释。 ... [详细]
  • 本文介绍了如何查看PHP网站及其源码的方法,包括环境搭建、本地测试、源码查看和在线查找等步骤。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
  • 在CentOS 7上部署WebRTC网关Janus
    在CentOS 7上部署WebRTC网关Janus ... [详细]
author-avatar
米粒多可爱几_642
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有