青草久久影院-青草久久伊人-青草久久久-青草久久精品亚洲综合专区-SM双性精跪趴灌憋尿调教H-SM脚奴调教丨踩踏贱奴

17站長網(wǎng)

17站長網(wǎng) 首頁 網(wǎng)站 服務器 查看內(nèi)容

Linux字符終端如何用鼠標移動一個紅色矩形詳解

2022-10-6 09:41| 查看: 1432 |來源: 互聯(lián)網(wǎng)

一切皆文件! UNIX已經(jīng)說了。埃里克雷蒙德這樣說的,不服嗎? 既然 /dev/fb0 被抽象成了顯示器,可以在字符終端通過操作映射了 /dev/fb0 的內(nèi)存在屏幕上畫32bit真彩圖,那么如何操作鼠標鍵盤呢? /dev/input/mouse

一切皆文件! UNIX已經(jīng)說了。埃里克雷蒙德這樣說的,不服嗎?

既然 /dev/fb0 被抽象成了顯示器,可以在字符終端通過操作映射了 /dev/fb0 的內(nèi)存在屏幕上畫32bit真彩圖,那么如何操作鼠標鍵盤呢?

/dev/input/mouse0 可以用來讀取鼠標事件。當你在字符終端cat它并移動鼠標時,它貌似告訴你有事情發(fā)生了,但是你卻無法解讀:


為了找到解讀它的正確方法,要么谷歌,要么百度,要么還有一個最直接的方法,那就是查Linux內(nèi)核源碼中關于mouse0這個文件的read回調(diào)函數(shù):

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個字節(jié)。 signed char data[sizeof(client->ps2)]; int retval = 0; spin_lock_irq(&client->packet_lock); if (!client->buffer && client->ready) { // 這里就是核心了,繼續(xù)跟過去 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]; ...

非常明白,我不管別的,我也沒有動機去學,我現(xiàn)在就是想知道鼠標的X,Y坐標:

  • p->dx,p->dy從名字上和從代碼上都可以看出,這是 相對于上一次 的坐標的變化!

所有信息都有了。

那么,現(xiàn)在,可以寫代碼了:

#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; // 按照內(nèi)核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 { // 恢復上一次正方形區(qū)域里的像素 for (w = old_x; w < old_x + LENGTH; w++) { for (h = old_y; h < old_y + LENGTH; h++) { idx = h*info.xres + w; mem[idx] = old_mem[idx]; } } old_x = abs_x; old_y = abs_y; } // 保存當前的像素,以便下一次恢復 for (w = abs_x; w < abs_x + LENGTH; w++) { for (h = abs_y; h < abs_y + LENGTH; h++) { idx = h*info.xres + w; old_mem[idx] = mem[idx]; } } // 根據(jù)鼠標的位置涂抹紅色矩形 for (w = abs_x; w < abs_x + LENGTH; w++) { for (h = abs_y; h < abs_y + LENGTH; h++) { idx = h*info.xres + w; mem[idx] = start; } } } return 0; }

運行它,然后在字符終端移動鼠標,效果如下:

嗯,矩形隨著鼠標而移動,并且不會破壞任何所到之處的字符。

現(xiàn)在,我來回顧一下這個周末做的這些事情,意味著什么。

  • 我可以在字符終端上畫32位真彩圖;
  • 我可以檢測到鼠標鍵盤的事件并且反應。

這意味著,如果有時間和精力,我可以實現(xiàn)一個GUI系統(tǒng)了。

當然,GUI系統(tǒng)和網(wǎng)絡協(xié)議棧那是隔行如隔山,肯定會遇到超級多的麻煩,不是僅僅讀寫兩個文件:

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

就可以搞定的。

事實上,真正的GUI系統(tǒng)從來不用這種方式。它們貌似在反抗著 UNIX一切皆文件 的理念,并且證明這樣會更好!哦,對了,Windows GUI的成功就是一個證明,還有后來最新版本的MacOS…

說什么字符終端,字符也是 畫出來的 。沒什么大不了的。只不過,想要用像素去設置字符,那就要了解一下 字符點陣 的information了…這又是另一個領域的話題。

本文最后更新于 2022-10-6 09:41,某些文章具有時效性,若有錯誤或已失效,請在網(wǎng)站留言或聯(lián)系站長:17tui@17tui.com
·END·
站長網(wǎng)微信號:w17tui,關注站長、創(chuàng)業(yè)、關注互聯(lián)網(wǎng)人 - 互聯(lián)網(wǎng)創(chuàng)業(yè)者營銷服務中心

免責聲明:本站部分文章和圖片均來自用戶投稿和網(wǎng)絡收集,旨在傳播知識,文章和圖片版權歸原作者及原出處所有,僅供學習與參考,請勿用于商業(yè)用途,如果損害了您的權利,請聯(lián)系我們及時修正或刪除。謝謝!

17站長網(wǎng)微信二維碼

始終以前瞻性的眼光聚焦站長、創(chuàng)業(yè)、互聯(lián)網(wǎng)等領域,為您提供最新最全的互聯(lián)網(wǎng)資訊,幫助站長轉型升級,為互聯(lián)網(wǎng)創(chuàng)業(yè)者提供更加優(yōu)質(zhì)的創(chuàng)業(yè)信息和品牌營銷服務,與站長一起進步!讓互聯(lián)網(wǎng)創(chuàng)業(yè)者不再孤獨!

掃一掃,關注站長網(wǎng)微信

大家都在看

熱門排行

    最近更新

      返回頂部
      主站蜘蛛池模板: 激情床戏视频片段有叫声 | 嘟嘟嘟在线视频免费观看高清中文 | 边做边爱播放3免费观看 | 毛片免费观看 | 国产永久免费观看视频软件 | 欧美雌雄双性人交xxxx | 久久视频这里只精品6国产 久久视频在线视频观品15 | 亚洲色欲H网在线观看 | 国产精品亚洲AV色欲在线观看 | 猛烈抽插H1V1| 亚洲AV怡红院影院怡春院 | 国产精品自在在线午夜精品 | yin荡体育课羞耻play双性 | 哒哒哒影院在线观看免费高清 | 欧美又粗又长又大AAAA片 | 99er热精品视频国产免费 | avove主播| 久久偷拍vs国产在线播放 | 天天射天天干天天插 | 狼与美女谐音歌词 | 久久综合久综合久久鬼色 | 国产免费午夜 | 美女快播第一网 | 98久久人妻少妇激情啪啪 | 久草热在线 | 亚洲欧美日韩高清中文在线 | 久久国产香蕉 | 精品国产麻豆免费人成网站 | 24小时日本在线观看片 | 玩弄放荡人妻一区二区三区 | 国产亚洲欧美在线中文BT天堂网 | 久久视频这里只精品99热在线观看 | 亚洲免费无码av线观看 | 欧美整片华人play | 久久成人免费观看草草影院 | 久久99热只有频精品 | 免费可以看黄的视频s色 | 97超在线视频 | 国产精品.XX视频.XXTV | 久久全国免费观看视频 | 国产精品久久久久久免费字体 |