标签 屏幕 下的文章

你不希望别人能够监视甚至控制你的电脑,你通常会努力使用各种安全机制来切断任何此类企图。然而,有时会出现这样的情况:你迫切需要一个朋友,或一个专家来帮助你解决电脑问题,但他们并不同时在同一地点。你如何向他们展示呢?你应该拿着你的手机,拍下你的屏幕照片,然后发给他们吗?你应该录制一个视频吗?当然不是。你可以与他们分享你的屏幕,并可能让他们远程控制你的电脑一段时间。在这篇文章中,我将介绍如何在 Gnome 中允许共享电脑屏幕。

设置服务器以共享屏幕

服务器 是一台提供(服务)一些内容的计算机,其他计算机(客户端)将消费这些内容。在本文中,服务器运行的是 Fedora Workstation 和标准的 Gnome 桌面

打开 Gnome 屏幕共享

默认情况下,Gnome 中共享计算机屏幕的功能是 关闭 的。要使用它,你需要把它打开:

  1. 启动 Gnome 控制中心 Gnome Control Center
  2. 点击 共享 Sharing 标签。 Sharing switched off
  3. 用右上角的滑块打开共享。
  4. 单击 屏幕共享 Screen sharing Sharing switched on
  5. 用窗口左上角的滑块打开屏幕共享。
  6. 如果你希望能够从客户端控制屏幕,请勾选 允许连接控制屏幕 Allow connections to control the screen 。不勾选这个按钮访问共享屏幕只允许 仅浏览 view-only
  7. 如果你想手动确认所有传入的连接,请选择 新连接必须请求访问 New connections must ask for access
  8. 如果你想允许知道密码的人连接(你不会被通知),选择 需要密码 Require a password 并填写密码。密码的长度只能是 8 个字符。
  9. 勾选 显示密码 Show password 以查看当前的密码是什么。为了多一点保护,不要在这里使用你的登录密码,而是选择一个不同的密码。
  10. 如果你有多个网络可用,你可以选择在哪个网络上访问该屏幕。

设置客户端以显示远程屏幕

客户端 是一台连接到由服务器提供的服务(或内容)的计算机。本演示还将在客户端上运行 Fedora Workstation,但如果它运行一个 VNC 客户端,操作系统实际上应该不太重要。

检查可见性

在 Gnome 中,服务器和客户端之间共享计算机屏幕需要一个有效的网络连接,以及它们之间可见的“路由”。如果你不能建立这样的连接,你将无法查看或控制服务器的共享屏幕,这里描述的整个过程将无法工作。

为了确保连接的存在,找出服务器的 IP 地址。

启动 Gnome 控制中心 Gnome Control Center ,又称 设置 Settings 。使用右上角的菜单,或活动模式。当在活动中时,输入:

settings

并点击相应的图标。

选择 网络 Network 标签。

点击设置按钮(齿轮)以显示你的网络配置文件的参数。

打开 详情 Details 标签,查看你的计算机的 IP 地址。

进入 你的客户端的 终端(你想从它连接到别的计算机),使用 ping 命令找出客户和服务器之间是否有连接。

$ ping -c 5 192.168.122.225

检查该命令的输出。如果它与下面的例子相似,说明计算机之间的连接存在。

PING 192.168.122.225 (192.168.122.225) 56(84) bytes of data.
64 bytes from 192.168.122.225: icmp_seq=1 ttl=64 time=0.383 ms
64 bytes from 192.168.122.225: icmp_seq=2 ttl=64 time=0.357 ms
64 bytes from 192.168.122.225: icmp_seq=3 ttl=64 time=0.322 ms
64 bytes from 192.168.122.225: icmp_seq=4 ttl=64 time=0.371 ms
64 bytes from 192.168.122.225: icmp_seq=5 ttl=64 time=0.319 ms
--- 192.168.122.225 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4083ms
rtt min/avg/max/mdev = 0.319/0.350/0.383/0.025 ms

如果两台计算机存在同一个子网中,例如在你的家里或办公室,你可能不会遇到任何问题,但当你的服务器没有公共 IP 地址,无法从外部互联网上看到时,可能会出现问题。除非你是互联网接入点的唯一管理员,否则你可能需要就你的情况向你的管理员或你的 ISP 咨询。请注意,将你的计算机暴露在外部互联网上始终是一个有风险的策略,你必须充分注意保护你的计算机免受不必要的访问。

安装 VNC 客户端(Remmina)

Remmina 是一个图形化的远程桌面客户端,你可以使用多种协议连接到远程服务器,如 VNC、Spice 或 RDP。Remmina 可以从 Fedora 仓库中获得,所以你可以用 dnf 命令或 软件中心 Software 来安装它,以你喜欢的方式为准。使用 dnf,下面的命令将安装该软件包和几个依赖项。

$ sudo dnf install remmina

连接到服务器

如果服务器和客户端之间有连接,请确保以下情况:

  1. 计算机正在运行。
  2. Gnome 会话正在运行。
  3. 启用了屏幕共享的用户已经登录。
  4. 会话 没有被锁定,也就是说,用户可以使用该会话。

然后你可以尝试从客户端连接到该会话:

  1. 启动 Remmina
  2. 在地址栏左侧的下拉菜单中选择 VNC 协议。
  3. 在地址栏中输入服务器的IP地址,然后按下 回车Remmina Window
  4. 当连接开始时,会打开另一个连接窗口。根据服务器的设置,你可能需要等待,直到服务器用户允许连接,或者你可能需要提供密码。
  5. 输入密码,然后按 OKRemmina Connected to Server
  6. 按下 Align with resolution button 调整连接窗口的大小,使之与服务器的分辨率一致,或者按 Full Screen Button 调整连接窗口的大小,使其覆盖整个桌面。当处于全屏模式时,注意屏幕上边缘的白色窄条。那是 Remmina 菜单,当你需要离开全屏模式或改变一些设置时,你可以把鼠标移到它上面。

当你回到服务器时,你会注意到现在在上栏有一个黄色的图标,这表明你正在 Gnome 中共享电脑屏幕。如果你不再希望共享屏幕,你可以进入菜单,点击 屏幕正在被共享 Screen is being shared ,然后再选择 关闭 Turn off ,立即停止共享屏幕。

Turn off menu item

会话锁定时终止屏幕共享

默认情况下,当会话锁定时,连接 将总是终止 will always terminate 。在会话被解锁之前,不能建立新的连接。

一方面,这听起来很合理。如果你想和别人分享你的屏幕,你可能不想让他们在你不在的时候使用你的电脑。另一方面,如果你想从远程位置控制你自己的电脑,无论是你在另一个房间的床上,还是你岳母的地方,同样的方法也不是很有用。有两个选项可以处理这个问题。你可以完全禁止锁定屏幕,或者使用支持通过 VNC 连接解锁会话的 Gnome 扩展。

禁用屏幕锁定

要禁用屏幕锁定:

  1. 打开 Gnome 控制中心 Gnome Control Center
  2. 点击 隐私 Privacy 标签。
  3. 选择 屏幕锁定 Screen Lock 设置。
  4. 关掉 自动屏幕锁定 Automatic Screen Lock

现在,会话将永远不会被锁定(除非你手动锁定),所以它能启动一个 VNC 连接到它。

使用 Gnome 扩展来允许远程解锁会话

如果你不想关闭锁定屏幕的功能,或者你想有一个远程解锁会话的选项,即使它被锁定,你将需要安装一个提供这种功能的扩展,因为这种行为是默认不允许的。

要安装该扩展:

  1. 打开火狐浏览器,并打开 Gnome 扩展页面Gnome Extensions Page
  2. 在页面的上部,找到一个信息块,告诉你为火狐安装 “GNOME Shell integration”。
  3. 点击 点此安装浏览器扩展 Click here to install browser extension 来安装 Firefox 扩展。
  4. 安装完毕后,注意到 Firefox 的菜单部分有 Gnome 的标志。
  5. 点击 Gnome 标志,回到扩展页面。
  6. 搜索 “allow locked remote desktop”。
  7. 点击显示的项目,进入该扩展的页面。
  8. 使用右边的开/关按钮,将扩展打开Extension selected

现在,可以在任何时候启动 VNC 连接。注意,你需要知道会话密码以解锁会话。如果你的 VNC 密码与会话密码不同,你的会话仍然受到 一点 保护。

总结

这篇文章介绍了在 Gnome 中实现共享计算机屏幕的方法。它提到了受限(仅浏览)访问和非受限(完全)访问之间的区别。然而,对于正式任务的远程访问,例如管理一个生产服务器,这个解决方案无论如何都不算是一个正确的方法。为什么?

  1. 服务器将始终保持其控制模式。任何在服务器会话中的人都将能够控制鼠标和键盘。
  2. 如果会话被锁定,从客户端解锁也会在服务器上解锁。它也会把显示器从待机模式中唤醒。任何能看到你的服务器屏幕的人都能看到你此刻正在做什么。
  3. VNC 协议本身没有加密或保护,所以你通过它发送的任何东西都可能被泄露。

你几种可以建立一个受保护的 VNC 连接的方法。例如,你可以通过 SSH 协议建立隧道,以提高安全性。然而,这些都超出了本文的范围。

免责声明:上述工作流程在 Fedora 35 上使用几个虚拟机工作时没有问题。如果它对你不起作用,那么你可能遇到了一个错误。请报告它。


via: https://fedoramagazine.org/sharing-the-computer-screen-in-gnome/

作者:Lukáš Růžička 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

其它平台上的屏幕共享或屏幕镜像应用并不那么好。尽管大多数选项仅适用于 Windows/Mac,而你可能很难找到一个适用于 Linux 的开源解决方案。

有了这个应用,你可以与连接到网络的任何设备共享你的屏幕。

如果你有多显示器设置,你会意识到拥有多个屏幕的好处。而且,有了 Deskreen,你可以把任何设备变成你的副屏,多么令人激动啊!

Deskreen:将任何设备变成你的 Linux 系统的副屏

我把我的 Linux Mint 桌面镜像到我的 Android 手机上

Deskreen 是一个自由开源的应用,可以让你使用任何带有 Web 浏览器的设备来作为电脑的副屏。

如果你愿意,它还支持多个设备连接。

Deskreen 很容易使用,当你的所有设备都连接到同一个 Wi-Fi 网络时,它可以正常工作。

让我们来看看它的功能和工作原理。

Deskreen 的功能

Deskreen 的功能包括以下要点:

  • 分享整个屏幕的能力
  • 选择一个特定的应用窗口进行串流
  • 翻转模式,将你的屏幕作为提词器使用
  • 支持多种设备
  • 高级视频质量设置
  • 提供端对端加密
  • 最小的系统要求
  • 黑暗模式

没有一个冗长的功能列表,但对大多数用户来说应该是足够的。

如何使用 Deskreen 应用?

Deskreen 使用分为三个简单的步骤,让我为你强调一下,以便你开始使用:

首先,当你启动该应用时,它会显示一个二维码和一个 IP 地址,以帮助你用 Web 浏览器连接其他设备,以串流你的屏幕。

你可以按你喜欢的方式,在你的辅助设备上的 Web 浏览器的帮助下建立连接。

当你扫描二维码或在浏览器的地址栏中输入 IP 地址,你会在 Deskreen 应用上得到一个提示,允许或拒绝连接。除非是你不认识它,否则就允许吧。

接下来,你将被要求选择你想要串流的内容(你的整个屏幕或特定的应用窗口):

你可以选择串流整个屏幕或选择你想串流的窗口。然而,并不是每个应用窗口都能被检测到。

在我的快速测试中,我没有检测到 Rocket.Chat 应用窗口,但它似乎能检测到 Slack 窗口、Deskscreen 窗口和终端。

你只需要选择源并确认,就可以了。你应该注意到它在你的副屏(手机/桌面)上开始串流。

这是它完成后的样子:

Deskreen 还为你提供了管理连接设备的能力。因此,如果你需要断开任何会话或所有会话的连接,你可以从设置中进行操作。

在 Linux 中安装 Deskreen

你会找到一个用于 Linux 机器的 DEB 包和 AppImage 文件。如果你不知道,可以通过我们的 安装 DEB 包使用 AppImage 文件 指南来安装它。

你可以从 官方网站 下载它,或者从它的 GitHub 页面探索更多的信息。

结束语

考虑到它使用 Wi-Fi 网络工作,在串流方面绝对没有问题。这是一种奇妙的方式,可以与别人分享你的屏幕,或者出于任何目的将其串流到第二个设备上。

当然,它不能取代你的电脑的第二个显示器的优势,但在一些使用情况下,你可能不需要第二个屏幕。

现在,我想问你,你能想到哪些实际应用可以用到 Deskreen?


via: https://itsfoss.com/deskreen/

作者:Ankush Das 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在终端上工作时,通常会发现终端屏幕上显示了太多的命令及其输出。

你可能需要清除终端屏幕并专注于要执行的下一个任务。相信我,清除 Linux 终端屏幕会很有帮助。

使用 clear 命令清除 Linux 终端

那么,如何清除 Linux 中的终端?最简单,最常见的方法是使用 clear 命令:

clear

clear 命令无需选项。就是这么简单,但是你还需要了解其他一些内容。

clear 命令和其他清除屏幕的方法可能取决于你使用的终端模拟器。终端模拟器是用于访问 Linux Shell(命令行)的终端应用。

如果你在带有 GNOME 终端的 Ubuntu 上使用 clear 命令,它将清除屏幕,并且你将无法看到之前屏幕上的内容。

在许多其他终端模拟器或 Putty 中,它可能只清除一页屏幕。如果使用鼠标或 PageUpPageDown 键滚动,那么仍然可以看到以前的屏幕输出。

坦白说,这取决于你的需要。如果你突然意识到需要引用以前运行的命令的输出,那么也许可以使用该方式。

在 Linux 中清除终端屏幕的其他方法

clear 命令不是清除终端屏幕的唯一方法。

你可以在 Linux 中使用 Ctrl+L 键盘快捷键来清除屏幕。它适用于大多数终端模拟器。

Ctrl+L

如果你在 GNOME 终端(Ubuntu 中默认)中使用 Ctrl+Lclear 命令,那么你会注意到它们的影响有所不同。Ctrl+L 将屏幕向下移动一页,给人一种干净的错觉,但是你仍然可以通过向上滚动来访问命令输出历史。

某些其他终端模拟器将此键盘快捷键设置为 Ctrl+Shift+K

你也可以使用 reset 命令清除终端屏幕。实际上,此命令执行完整的终端重新初始化。但是,它可能比 clear 命令要花费更长的时间。

reset

当你想完全清除屏幕时,还有几种其他复杂的方法可以清除屏幕。但是由于命令有点复杂,所以最好将它作为 Linux 中的别名

alias cls='printf "\033c"'

你可以将此别名添加到你的 bash 配置文件中,以便作为命令使用。

我知道这是一个非常基本的主题,大多数 Linux 用户可能已经知道了,但这对于为新 Linux 用户介绍基本主题并没有什么坏处。是不是?

在清除终端屏幕上有些秘密提示​​吗?为什么不与我们分享呢?


via: https://itsfoss.com/clear-terminal-ubuntu/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

欢迎来到屏幕系列课程。在本系列中,你将学习在树莓派中如何使用汇编代码控制屏幕,从显示随机数据开始,接着学习显示一个固定的图像和显示文本,然后格式化数字为文本。假设你已经完成了 OK 系列课程的学习,所以在本系列中出现的有些知识将不再重复。

第一节的屏幕课程教你一些关于图形的基础理论,然后用这些理论在屏幕或电视上显示一个图案。

1、入门

预期你已经完成了 OK 系列的课程,以及那个系列课程中在 gpio.ssystemTimer.s 文件中调用的函数。如果你没有完成这些,或你喜欢完美的实现,可以去下载 OK05.s 解决方案。在这里也要使用 main.s 文件中从开始到包含 mov sp,#0x8000 的这一行之前的代码。请删除这一行以后的部分。

2、计算机图形

正如你所认识到的,从根本上来说,计算机是非常愚蠢的。它们只能执行有限数量的指令,仅仅能做一些数学,但是它们也能以某种方式来做很多很多的事情。而在这些事情中,我们目前想知道的是,计算机是如何将一个图像显示到屏幕上的。我们如何将这个问题转换成二进制?答案相当简单;我们为每个颜色设计一些编码方法,然后我们为在屏幕上的每个像素保存一个编码。一个像素就是你的屏幕上的一个非常小的点。如果你离屏幕足够近,你或许能够辨别出你的屏幕上的单个像素,能够看到每个图像都是由这些像素组成的。

将颜色表示为数字有几种方法。在这里我们专注于 RGB 方法,但 HSL 也是很常用的另一种方法。

随着计算机时代的进步,人们希望显示越来越复杂的图形,于是发明了图形卡的概念。图形卡是你的计算机上用来在屏幕上专门绘制图像的第二个处理器。它的任务就是将像素值信息转换成显示在屏幕上的亮度级别。在现代计算机中,图形卡已经能够做更多更复杂的事情了,比如绘制三维图形。但是在本系列教程中,我们只专注于图形卡的基本使用;从内存中取得像素然后把它显示到屏幕上。

不管使用哪种方法,现在马上出现的一个问题就是我们使用的颜色编码。这里有几种选择,每个产生不同的输出质量。为了完整起见,我在这里只是简单概述它们。

名字唯一颜色数量描述示例
单色2每个像素使用 1 位去保存,其中 1 表示白色,0 表示黑色。Monochrome image of a bird
灰度256每个像素使用 1 个字节去保存,使用 255 表示白色,0 表示黑色,介于这两个值之间的所有值表示这两个颜色的一个线性组合。Geryscale image of a bird
8 色8每个像素使用 3 位去保存,第一位表示红色通道,第二位表示绿色通道,第三位表示蓝色通道。8 colour image of a bird
低色值256每个像素使用 8 位去保存,前三位表示红色通道的强度,接下来的三位表示绿色通道的强度,最后两位表示蓝色通道的强度。Low colour image of a bird
高色值65,536每个像素使用 16 位去保存,前五位表示红色通道的强度,接下来的六位表示绿色通道的强度,最后的五位表示蓝色通道的强度。High colour image of a bird
真彩色16,777,216每个像素使用 24 位去保存,前八位表示红色通道,第二个八位表示绿色通道,最后八位表示蓝色通道。True colour image of a bird
RGBA3216,777,216 带 256 级透明度每个像素使用 32 位去保存,前八位表示红色通道,第二个八位表示绿色通道,第三个八位表示蓝色通道。只有一个图像绘制在另一个图像的上方时才考虑使用透明通道,值为 0 时表示下面图像的颜色,值为 255 时表示上面这个图像的颜色,介于这两个值之间的所有值表示这两个图像颜色的混合。
不过这里的一些图像只用了很少的颜色,因为它们使用了一个叫空间抖动的技术。这允许它们以很少的颜色仍然能表示出非常好的图像。许多早期的操作系统就使用了这种技术。

在本教程中,我们将从使用高色值开始。这样你就可以看到图像的构成,它的形成过程清楚,图像质量好,又不像真彩色那样占用太多的空间。也就是说,显示一个比较小的 800x600 像素的图像,它只需要小于 1 MiB 的空间。它另外的好处是它的大小是 2 次幂的倍数,相比真彩色这将极大地降低了获取信息的复杂度。

树莓派和它的图形处理器有一种特殊而奇怪的关系。在树莓派上,首先运行的事实上是图形处理器,它负责启动主处理器。这是很不常见的。最终它不会有太大的差别,但在许多交互中,它经常给人感觉主处理器是次要的,而图形处理器才是主要的。在树莓派上这两者之间依靠一个叫 “邮箱” 的东西来通讯。它们中的每一个都可以为对方投放邮件,这个邮件将在未来的某个时刻被对方收集并处理。我们将使用这个邮箱去向图形处理器请求一个地址。这个地址将是一个我们在屏幕上写入像素颜色信息的位置,我们称为帧缓冲,图形卡将定期检查这个位置,然后更新屏幕上相应的像素。

保存 帧缓冲 frame buffer 给计算机带来了很大的内存负担。基于这种原因,早期计算机经常作弊,比如,保存一屏幕文本,在每次单独刷新时,它只绘制刷新了的字母。

3、编写邮差程序

接下来我们做的第一件事情就是编写一个“邮差”程序。它有两个方法:MailboxRead,从寄存器 r0 中的邮箱通道读取一个消息。而 MailboxWrite,将寄存器 r0 中的头 28 位的值写到寄存器 r1 中的邮箱通道。树莓派有 7 个与图形处理器进行通讯的邮箱通道。但仅第一个对我们有用,因为它用于协调帧缓冲。

消息传递是组件间通讯时使用的常见方法。一些操作系统在程序之间使用虚拟消息进行通讯。

下列的表和示意图描述了邮箱的操作。

表 3.1 邮箱地址

地址大小 / 字节名字描述读 / 写
2000B8804Read接收邮件R
2000B8904Poll不检索接收R
2000B8944Sender发送者信息R
2000B8984Status信息R
2000B89C4Configuration设置RW
2000B8A04Write发送邮件W

为了给指定的邮箱发送一个消息:

  1. 发送者等待,直到 Status 字段的头一位为 0。
  2. 发送者写入到 Write,低 4 位是要发送到的邮箱,高 28 位是要写入的消息。

为了读取一个消息:

  1. 接收者等待,直到 Status 字段的第 30 位为 0。
  2. 接收者读取消息。
  3. 接收者确认消息来自正确的邮箱,否则再次重试。

如果你觉得有信心,你现在已经有足够的信息去写出我们所需的两个方法。如果没有信心,请继续往下看。

与以前一样,我建议你实现的第一个方法是获取邮箱区域的地址。

.globl GetMailboxBase
GetMailboxBase:
ldr r0,=0x2000B880
mov pc,lr

发送程序相对简单一些,因此我们将首先去实现它。随着你的方法越来越复杂,你需要提前去规划它们。规划它们的一个好的方式是写出一个简单步骤列表,详细地列出你需要做的事情,像下面一样。

  1. 我们的输入将要写什么(r0),以及写到什么邮箱(r1)。我们必须验证邮箱的真实性,以及它的低 4 位的值是否为 0。不要忘了验证输入。
  2. 使用 GetMailboxBase 去检索地址。
  3. 读取 Status 字段。
  4. 检查头一位是否为 0。如果不是,回到第 3 步。
  5. 将写入的值和邮箱通道组合到一起。
  6. 写入到 Write

我们来按顺序写出它们中的每一步。

1、这将实现我们验证 r0r1 的目的。tst 是通过计算两个操作数的逻辑与来比较两个操作数的函数,然后将结果与 0 进行比较。在本案例中,它将检查在寄存器 r0 中的输入的低 4 位是否为全 0。

.globl MailboxWrite
MailboxWrite:
tst r0,#0b1111
movne pc,lr
cmp r1,#15
movhi pc,lr
tst reg,#val 计算寄存器 reg#val 的逻辑与,然后将计算结果与 0 进行比较。

2、这段代码确保我们不会覆盖我们的值,或链接寄存器,然后调用 GetMailboxBase

channel .req r1
value .req r2
mov value,r0
push {lr}
bl GetMailboxBase
mailbox .req r0

3、这段代码加载当前状态。

wait1$:
status .req r3
ldr status,[mailbox,#0x18]

4、这段代码检查状态字段的头一位是否为 0,如果不为 0,循环回到第 3 步。

tst status,#0x80000000
.unreq status
bne wait1$

5、这段代码将通道和值组合到一起。

add value,channel
.unreq channel

6、这段代码保存结果到写入字段。

str value,[mailbox,#0x20]
.unreq value
.unreq mailbox
pop {pc}

MailboxRead 的代码和它非常类似。

  1. 我们的输入将从哪个邮箱读取(r0)。我们必须要验证邮箱的真实性。不要忘了验证输入。
  2. 使用 GetMailboxBase 去检索地址。
  3. 读取 Status 字段。
  4. 检查第 30 位是否为 0。如果不为 0,返回到第 3 步。
  5. 读取 Read 字段。
  6. 检查邮箱是否是我们所要的,如果不是返回到第 3 步。
  7. 返回结果。

我们来按顺序写出它们中的每一步。

1、这一段代码来验证 r0 中的值。

.globl MailboxRead
MailboxRead:
cmp r0,#15
movhi pc,lr

2、这段代码确保我们不会覆盖掉我们的值,或链接寄存器,然后调用 GetMailboxBase

channel .req r1
mov channel,r0
push {lr}
bl GetMailboxBase
mailbox .req r0

3、这段代码加载当前状态。

rightmail$:
wait2$:
status .req r2
ldr status,[mailbox,#0x18]

4、这段代码检查状态字段第 30 位是否为 0,如果不为 0,返回到第 3 步。

tst status,#0x40000000
.unreq status
bne wait2$

5、这段代码从邮箱中读取下一条消息。

mail .req r2
ldr mail,[mailbox,#0]

6、这段代码检查我们正在读取的邮箱通道是否为提供给我们的通道。如果不是,返回到第 3 步。

inchan .req r3
and inchan,mail,#0b1111
teq inchan,channel
.unreq inchan
bne rightmail$
.unreq mailbox
.unreq channel

7、这段代码将答案(邮件的前 28 位)移动到寄存器 r0 中。

and r0,mail,#0xfffffff0
.unreq mail
pop {pc}

4、我心爱的图形处理器

通过我们新的邮差程序,我们现在已经能够向图形卡上发送消息了。我们应该发送些什么呢?这对我来说可能是个很难找到答案的问题,因为它不是任何线上手册能够找到答案的问题。尽管如此,通过查找有关树莓派的 GNU/Linux,我们能够找出我们需要发送的内容。

消息很简单。我们描述我们想要的帧缓冲区,而图形卡要么接受我们的请求,给我们返回一个 0,然后用我们写的一个小的调查问卷来填充屏幕;要么发送一个非 0 值,我们知道那表示很遗憾(出错了)。不幸的是,我并不知道它返回的其它数字是什么,也不知道它意味着什么,但我们知道仅当它返回一个 0,才表示一切顺利。幸运的是,对于合理的输入,它总是返回一个 0,因此我们不用过于担心。

由于在树莓派的内存是在图形处理器和主处理器之间共享的,我们能够只发送可以找到我们信息的位置即可。这就是 DMA,许多复杂的设备使用这种技术去加速访问时间。

为简单起见,我们将提前设计好我们的请求,并将它保存到 framebuffer.s 文件的 .data 节中,它的代码如下:

.section .data
.align 4
.globl FrameBufferInfo
FrameBufferInfo:
.int 1024 /* #0 物理宽度 */
.int 768 /* #4 物理高度 */
.int 1024 /* #8 虚拟宽度 */
.int 768 /* #12 虚拟高度 */
.int 0 /* #16 GPU - 间距 */
.int 16 /* #20 位深 */
.int 0 /* #24 X */
.int 0 /* #28 Y */
.int 0 /* #32 GPU - 指针 */
.int 0 /* #36 GPU - 大小 */

这就是我们发送到图形处理器的消息格式。第一对两个关键字描述了物理宽度和高度。第二对关键字描述了虚拟宽度和高度。帧缓冲的宽度和高度就是虚拟的宽度和高度,而 GPU 按需要伸缩帧缓冲去填充物理屏幕。如果 GPU 接受我们的请求,接下来的关键字将是 GPU 去填充的参数。它们是帧缓冲每行的字节数,在本案例中它是 2 × 1024 = 2048。下一个关键字是每个像素分配的位数。使用了一个 16 作为值意味着图形处理器使用了我们上面所描述的高色值模式。值为 24 是真彩色,而值为 32 则是 RGBA32。接下来的两个关键字是 x 和 y 偏移量,它表示当将帧缓冲复制到屏幕时,从屏幕左上角跳过的像素数目。最后两个关键字是由图形处理器填写的,第一个表示指向帧缓冲的实际指针,第二个是用字节数表示的帧缓冲大小。

在这里我非常谨慎地使用了一个 .align 4 指令。正如前面所讨论的,这样确保了下一行地址的低 4 位是 0。所以,我们可以确保将被放到那个地址上的帧缓冲(FrameBufferInfo)是可以发送到图形处理器上的,因为我们的邮箱仅发送低 4 位全为 0 的值。

当设备使用 DMA 时,对齐约束变得非常重要。GPU 预期该消息都是 16 字节对齐的。

到目前为止,我们已经有了待发送的消息,我们可以写代码去发送它了。通讯将按如下的步骤进行:

  1. 写入 FrameBufferInfo + 0x40000000 的地址到邮箱 1。
  2. 从邮箱 1 上读取结果。如果它是非 0 值,意味着我们没有请求一个正确的帧缓冲。
  3. 复制我们的图像到指针,这时图像将出现在屏幕上!

我在步骤 1 中说了一些以前没有提到的事情。我们在发送之前,在帧缓冲地址上加了 0x40000000。这其实是一个给 GPU 的特殊信号,它告诉 GPU 应该如何写到结构上。如果我们只是发送地址,GPU 将写到它的回复上,这样不能保证我们可以通过刷新缓存看到它。缓存是处理器使用的值在它们被发送到存储之前保存在内存中的片段。通过加上 0x40000000,我们告诉 GPU 不要将写入到它的缓存中,这样将确保我们能够看到变化。

因为在那里发生很多事情,因此最好将它实现为一个函数,而不是将它以代码的方式写入到 main.s 中。我们将要写一个函数 InitialiseFrameBuffer,由它来完成所有协调和返回指向到上面提到的帧缓冲数据的指针。为方便起见,我们还将帧缓冲的宽度、高度、位深作为这个方法的输入,这样就很容易地修改 main.s 而不必知道协调的细节了。

再一次,来写下我们要做的详细步骤。如果你有信心,可以略过这一步直接尝试去写函数。

  1. 验证我们的输入。
  2. 写输入到帧缓冲。
  3. 发送 frame buffer + 0x40000000 的地址到邮箱。
  4. 从邮箱中接收回复。
  5. 如果回复是非 0 值,方法失败。我们应该返回 0 去表示失败。
  6. 返回指向帧缓冲信息的指针。

现在,我们开始写更多的方法。以下是上面其中一个实现。

1、这段代码检查宽度和高度是小于或等于 4096,位深小于或等于 32。这里再次使用了条件运行的技巧。相信自己这是可行的。

.section .text
.globl InitialiseFrameBuffer
InitialiseFrameBuffer:
width .req r0
height .req r1
bitDepth .req r2
cmp width,#4096
cmpls height,#4096
cmpls bitDepth,#32
result .req r0
movhi result,#0
movhi pc,lr

2、这段代码写入到我们上面定义的帧缓冲结构中。我也趁机将链接寄存器推入到栈上。

fbInfoAddr .req r3
push {lr}
ldr fbInfoAddr,=FrameBufferInfo
str width,[fbInfoAddr,#0]
str height,[fbInfoAddr,#4]
str width,[fbInfoAddr,#8]
str height,[fbInfoAddr,#12]
str bitDepth,[fbInfoAddr,#20]
.unreq width
.unreq height
.unreq bitDepth

3、MailboxWrite 方法的输入是写入到寄存器 r0 中的值,并将通道写入到寄存器 r1 中。

mov r0,fbInfoAddr
add r0,#0x40000000
mov r1,#1
bl MailboxWrite

4、MailboxRead 方法的输入是写入到寄存器 r0 中的通道,而输出是值读数。

mov r0,#1
bl MailboxRead

5、这段代码检查 MailboxRead 方法的结果是否为 0,如果不为 0,则返回 0。

teq result,#0
movne result,#0
popne {pc}

6、这是代码结束,并返回帧缓冲信息地址。

mov result,fbInfoAddr
pop {pc}
.unreq result
.unreq fbInfoAddr

5、在一帧中一行之内的一个像素

到目前为止,我们已经创建了与图形处理器通讯的方法。现在它已经能够给我们返回一个指向到帧缓冲的指针去绘制图形了。我们现在来绘制一个图形。

第一示例中,我们将在屏幕上绘制连续的颜色。它看起来并不漂亮,但至少能说明它在工作。我们如何才能在帧缓冲中设置每个像素为一个连续的数字,并且要持续不断地这样做。

将下列代码复制到 main.s 文件中,并放置在 mov sp,#0x8000 行之后。

mov r0,#1024
mov r1,#768
mov r2,#16
bl InitialiseFrameBuffer

这段代码使用了我们的 InitialiseFrameBuffer 方法,简单地创建了一个宽 1024、高 768、位深为 16 的帧缓冲区。在这里,如果你愿意可以尝试使用不同的值,只要整个代码中都一样就可以。如果图形处理器没有给我们创建好一个帧缓冲区,这个方法将返回 0,我们最好检查一下返回值,如果出现返回值为 0 的情况,我们打开 OK LED 灯。

teq r0,#0
bne noError$

mov r0,#16
mov r1,#1
bl SetGpioFunction
mov r0,#16
mov r1,#0
bl SetGpio

error$:
b error$

noError$:
fbInfoAddr .req r4
mov fbInfoAddr,r0

现在,我们已经有了帧缓冲信息的地址,我们需要取得帧缓冲信息的指针,并开始绘制屏幕。我们使用两个循环来做实现,一个走行,一个走列。事实上,树莓派中的大多数应用程序中,图片都是以从左到右然后从上到下的顺序来保存的,因此我们也按这个顺序来写循环。

render$:

    fbAddr .req r3
    ldr fbAddr,[fbInfoAddr,#32]
    
    colour .req r0
    y .req r1
    mov y,#768
    drawRow$:
    
        x .req r2
        mov x,#1024
        drawPixel$:
        
            strh colour,[fbAddr]
            add fbAddr,#2
            sub x,#1
            teq x,#0
            bne drawPixel$
        
        sub y,#1
        add colour,#1
        teq y,#0
        bne drawRow$
    
    b render$

.unreq fbAddr
.unreq fbInfoAddr
strh reg,[dest] 将寄存器中的低位半个字保存到给定的 dest 地址上。

这是一个很长的代码块,它嵌套了三层循环。为了帮你理清头绪,我们将循环进行缩进处理,这就有点类似于高级编程语言,而汇编器会忽略掉这些用于缩进的 tab 字符。我们看到,在这里它从帧缓冲信息结构中加载了帧缓冲的地址,然后基于每行来循环,接着是每行上的每个像素。在每个像素上,我们使用一个 strh(保存半个字)命令去保存当前颜色,然后增加地址继续写入。每行绘制完成后,我们增加绘制的颜色号。在整个屏幕绘制完成后,我们跳转到开始位置。

6、看到曙光

现在,你已经准备好在树莓派上测试这些代码了。你应该会看到一个渐变图案。注意:在第一个消息被发送到邮箱之前,树莓派在它的四个角上一直显示一个渐变图案。如果它不能正常工作,请查看我们的排错页面。

如果一切正常,恭喜你!你现在可以控制屏幕了!你可以随意修改这些代码去绘制你想到的任意图案。你还可以做更精彩的渐变图案,可以直接计算每个像素值,因为每个像素包含了一个 Y 坐标和 X 坐标。在下一个 课程 7:Screen 02 中,我们将学习一个更常用的绘制任务:行。


via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen01.html

作者:Alex Chadwick 选题:lujun9972 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

当你开始在计算机前花费大量时间的时候,问题自然开始显现。这健康吗?怎样才能舒缓我眼睛的压力呢?为什么光线灼烧着我?尽管解答这些问题的研究仍然在不断进行着,许多程序员已经采用了一些应用来改变他们的日常习惯,让他们的眼睛更健康点。在这些应用中,我发现了两个特别有趣的东西:Calise和Redshift。

Calise

处于时断时续的开发中,Calise的意思是“相机光感应器(Camera Light Sensor)”。换句话说,它是一个根据摄像头接收到的光强度计算屏幕最佳的背光级别的开源程序。更进一步地说,Calise可以基于你的地理坐标来考虑你所在地区的天气。我喜欢它是因为它兼容各个桌面,甚至非X系列。

它同时附带了命令行界面和图形界面,支持多用户配置,而且甚至可以导出数据为CSV。安装完后,你必须在见证奇迹前对它进行快速校正。

不怎么令人喜欢的是,如果你和我一样有被偷窥妄想症,在你的摄像头前面贴了一条胶带,那就会比较不幸了,这会大大影响Calise的精确度。除此之外,Calise还是个很棒的应用,值得我们关注和支持。正如我先前提到的,它在过去几年中经历了一段修修补补的艰难阶段,所以我真的希望这个项目继续开展下去。

Redshift

如果你想过要减少由屏幕导致的眼睛的压力,那么你很可能听过f.lux,它是一个免费的专有软件,用于根据一天中的时间来修改显示器的亮度和配色。然而,如果真的偏好于开源软件,那么一个可选方案就是:Redshift。灵感来自f.lux,Redshift也可以改变配色和亮度来加强你夜间坐在屏幕前的体验。启动时,你可以使用经度和纬度来配置地理坐标,然后就可以让它在托盘中运行了。Redshift将根据太阳的位置平滑地调整你的配色或者屏幕。在夜里,你可以看到屏幕的色温调向偏暖色,这会让你的眼睛少遭些罪。

和Calise一样,它提供了一个命令行界面,同时也提供了一个图形客户端。要快速启动Redshift,只需使用命令:

$ redshift -l [LAT]:[LON] 

替换[LAT]:[LON]为你的维度和经度。

然而,它也可以通过gpsd模块来输入你的坐标。对于Arch Linux用户,我推荐你读一读这个维基页面

尾声

总而言之,Linux用户没有理由不去保护自己的眼睛,Calise和Redshift两个都很棒。我真希望它们的开发能够继续下去,让它们获得应有的支持。当然,还有比这两个更多的程序可以满足保护眼睛和保持健康的目的,但是我感觉Calise和Redshift会是一个不错的开端。

如果你有一个经常用来舒缓眼睛的压力的喜欢的程序,请在下面的评论中留言吧。


via: http://xmodulo.com/automatically-dim-your-screen-linux.html

作者:Adrien Brochard 译者:GOLinux 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出