<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>烂磁头 - 好记性不如烂磁头</title>
    <link>https://blog.lancitou.net/</link>
    <description>Recent content on 烂磁头 - 好记性不如烂磁头</description>
    <generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Tue, 22 Aug 2023 11:33:45 +0000</lastBuildDate><atom:link href="https://blog.lancitou.net/feed" rel="self" type="application/rss+xml" /><item>
      <title>雅思机考初体验</title>
      <link>https://blog.lancitou.net/first-computer-based-ielts/</link>
      <pubDate>Tue, 22 Aug 2023 11:33:45 +0000</pubDate><author>Philip Ye</author>
      
      <guid>https://blog.lancitou.net/first-computer-based-ielts/</guid>
      <description>&lt;p&gt;是的，你没有看错，我又去考雅思了。距离&lt;a href=&#34;/how-i-got-band-7-in-my-first-ielts/&#34; title=&#34;雅思备考两个月首战 7.0&#34;&gt;上一次考雅思&lt;/a&gt;已经过去五年半了，这一次的成绩不但没有退步，大部分科目反而有了进步，把均分拉到了 7.5：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/axPuDiW.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;这次因为想要早点拿到成绩，首次体验了一下机考。雅思官方宣称 3-5 个自然日出成绩（且看下文吐槽），考试场次较多，每场考生人数较少。六月底报名，八月初考试，备考时间一个月多点。考点选在了离家近、停车方便的 &lt;a href=&#34;https://www.manukau.ac.nz/campus-facilities/facilities/ielts-testing-centre&#34; title=&#34;British Council IELTS test centre&#34;&gt;MIT Otara 校区&lt;/a&gt;，属于 British Council 考点，报名费 NZ$395。&lt;/p&gt;
&lt;h1 id=&#34;考前&#34;&gt;考前&lt;/h1&gt;
&lt;p&gt;由于手边除了之前从国内带过来的《&lt;a href=&#34;https://www.goodreads.com/book/show/56863737-10&#34; title=&#34;十天突破雅思写作&#34;&gt;十天突破雅思写作&lt;/a&gt;》附带的必备短语集（还是剑 11 版），就没有其它纸本备考材料了。所以匆忙从图书馆借了最新的几本剑桥真题集（已经能借到剑 17 了）、《&lt;a href=&#34;https://www.cambridge.org/us/cambridgeenglish/catalog/cambridge-english-exams-ielts/ielts-common-mistakes&#34; title=&#34;IELTS Common Mistakes&#34;&gt;IELTS Common Mistakes For Bands 6.0-7.0&lt;/a&gt;》以及《&lt;a href=&#34;https://www.cambridge.org/ve/cambridgeenglish/catalog/cambridge-english-exams-ielts/ielts/ielts-vocabulary-bands-65/ielts-vocabulary-bands-65-and-above-answers-and-downloadable-audio&#34; title=&#34;IELTS Vocabulary For Bands 6.5 and above&#34;&gt;IELTS Vocabulary For Bands 6.5 and above&lt;/a&gt;》。然而，图书馆借的真题集上满是涂写的痕迹，根本没法用；另外两本太多细节以及基础知识，更适用于长期备考，我只随意翻了几页。&lt;/p&gt;
&lt;p&gt;真正派上用场的是 British Council 附赠的 &lt;a href=&#34;https://takeielts.britishcouncil.org/take-ielts/prepare/ielts-ready-premium&#34; title=&#34;Your Pathway to Success with IELTS Ready: Premium&#34;&gt;IELTS Ready: Premium&lt;/a&gt;，是由 &lt;a href=&#34;https://www.gelielts.com/&#34; title=&#34;GEL IELTS Prep&#34;&gt;GEL IELTS Prep&lt;/a&gt; 出品的在线备考网站，上面有大量的视频教程、练习题、模拟题以及对应的答案、写作各个分数档的范文等等。不仅可以设置考试日期和目标分数（只能设置均分），从而提醒距离考试剩余天数，每次练习或者模拟考试后与目标分数的比较；另外还不时有老师在线直播，虽然直播的内容和视频教程大同小异，但好处是可以直接问老师问题。&lt;/p&gt;
&lt;p&gt;现在想来，我第一次考雅思是在深圳的考场，也是 British Council 的考点，为什么就没有发现这么好用的网站呢？我回头搜索了一下之前的邮件，当时报名的&lt;a href=&#34;https://ielts.etest.net.cn/&#34; title=&#34;教育部考试中心雅思报名网站&#34;&gt;教育部考试中心雅思报名网站&lt;/a&gt;已经不存在了，貌似转移到了&lt;a href=&#34;https://ielts.neea.cn/&#34; title=&#34;IELTS - 中国教育考试网&#34;&gt;中国教育考试网&lt;/a&gt;。 雅思中文官网倒是可以找到&lt;a href=&#34;https://www.chinaielts.org/IELTSReady.shtml&#34; title=&#34;雅思备考冲刺 - IELTS Ready: Premium&#34;&gt;雅思备考冲刺 - IELTS Ready: Premium&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;刚开始备考时，先做了两套阅读，发现依然可以保持在 8 分以上，就再也没有看阅读了。口语也基本是裸考，找了一些常见的话题，感觉太简单了，在新西兰生活了快五年，这些话题我应该可以临场发挥，就没再花时间练口语。大部分时间都花在准备写作和听力上，尤其是写作，拿到题之后怎么规则段落，怎么写开头和结尾，各个主体段落怎么起承转合，尽管直到考前也就完整地练习了两套大小作文，但可以说是成竹在胸。&lt;/p&gt;
&lt;h1 id=&#34;考中&#34;&gt;考中&lt;/h1&gt;
&lt;p&gt;到了考试当天，我一直处于比较放松的状态。一大早随意吃了点早餐就开车去了考点，结果我是第一个到的，当时才刚刚八点，还得等一个小时才开考。下次不用那么早到考点了，可以有充足的时间吃早餐。&lt;/p&gt;
&lt;p&gt;终于等到大家都到了，按考位号顺序排队跟着工作人员进入考场。不知道其它考点情况，但这个考点每场机考至多十个人，在一个很小的机房排着两排电脑。每台电脑都配有普通有线头戴式耳机（并不是传闻的降噪耳机）和防偷窥屏保，所以我个人感觉屏幕亮度有点不够，即使是亮度调到最高。&lt;/p&gt;
&lt;p&gt;在三个机考的科目开始之前，都会分发一张登录信息页，上有个人信息和唯一的登录密码。这张纸可以用作考试过程中的草稿，每个科目考完都会收回。考题在电脑上的呈现方式和 &lt;a href=&#34;https://takeielts.britishcouncil.org/take-ielts/prepare/ielts-on-computer/familiarisation-test&#34; title=&#34;Free IELTS on computer familiarisation test&#34;&gt;familiarisation test&lt;/a&gt; 基本相同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;屏幕底部有各题标号，答过的题会标下划线；&lt;/li&gt;
&lt;li&gt;选中某一题，屏幕左下角可选 Review，此时底部对应题的标号由方框变成圆圈，方便后续快速定位；&lt;/li&gt;
&lt;li&gt;按 Tab 键可快速跳转到下一题；&lt;/li&gt;
&lt;li&gt;鼠标左键划选文本，右键选择高亮或标注。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然也有一些不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;考题正式出现之前，可选择字体大小和文本配色方案。近视如我为了考试过程中不戴眼镜，每个科目都把字体调到了 Large（比 Standard 大一档），缺点是考题不能在一个屏幕上完整呈现，需要使用鼠标滚轮；&lt;/li&gt;
&lt;li&gt;屏幕底部标号的最后，有一个指向左下角的黄色箭头↙，用于切换题目标号的不同展示方式，个人感觉作用不大；&lt;/li&gt;
&lt;li&gt;屏幕右上角有 Hide 按钮，上厕所时用于锁屏；&lt;/li&gt;
&lt;li&gt;没有用于切换到下一个 section 的按钮，考试时间到了自动锁屏并提交。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;几个科目的个人感觉是，听力一如既往地很多题靠朦（尤其是多选题和配对题），有些词太久没用到有点陌生，比如有一题应该填 advertisements，我听到时楞了一下，等反应过来什么意思了又不确定怎么拼写，最后填了 ads；就这么一卡壳，导致下一题没听到，又是朦着填上 internet。阅读很轻松，我以为又可以拿满分，结果不知道哪里错了一题；做完阅读还有 16 分钟多点，按照之前预定的策略，我去了趟厕所，回来正好还剩最后十分钟不允许上厕所了，哈哈。写作的&lt;a href=&#34;https://www.ielts-gt.com/writing-task-1-sample/you-have-recently-bought-a-new-mobile-phone&#34; title=&#34;Letter Sample #156 – You have recently bought a new mobile phone&#34;&gt;小作文&lt;/a&gt;是手机坏了写投诉信，之前在 &lt;a href=&#34;https://takeielts.britishcouncil.org/take-ielts/prepare/ielts-ready-premium&#34; title=&#34;Your Pathway to Success with IELTS Ready: Premium&#34;&gt;IELTS Ready: Premium&lt;/a&gt; 上练过收音机坏了写投诉信，可以说撞上原题了；&lt;a href=&#34;https://ieltsmaterial.com/some-parents-think-that-helping-their-children-with-homework-is-a-good-idea/&#34; title=&#34;Some Parents think that Helping their Children with Homework is a Good Idea- IELTS Writing Task 2&#34;&gt;大作文&lt;/a&gt;写家长是否应该帮小孩写家庭作业，讨论双方观点并给出自己的观点。机考最大的受益科目应该就是写作了，电脑上打字比手写快多了，也方便修改，我快速地写完大小作文，最后还有十分钟可以润色大作文，体验简直不能更好。&lt;/p&gt;
&lt;p&gt;中午去麦当劳啃了个汉堡，又是等下午两点开考，下次应该选最早的考试时间，早点考完早点回家。&lt;/p&gt;
&lt;p&gt;口语的 Part 1 除了必问的工作了还是学生、做什么工作、为什么选择这份工作、办公环境有什么可以改进的地方之外，另外两个话题是图书馆和钥匙。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多久去一次图书馆？去图书馆都做啥？年轻的时候会不会更频繁地去？当时去图书馆的目的有什么不同？对做图书馆的工作什么看法？&lt;/li&gt;
&lt;li&gt;平常带很多钥匙出门吗？会不会忘了带钥匙？对留备用钥匙给邻居什么看法？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Part 2 给我的是描述一个吵闹的场所（&lt;a href=&#34;https://9ielts.com/describe-a-noisy-place-you-have-been-to&#34; title=&#34;Describe a noisy place you have been to&#34;&gt;Describe a noisy place you have been to&lt;/a&gt;），刚拿到题时我完全想不出来可以说什么，后来想到中午给 Linda 打电话时工作人员正在家里安装保温棉有点吵，又想到之前有次周五晚上邻居开 party 非常吵，就决定讲这次事件。磕磕绊绊讲完题卡上所有的内容，估计还不到一分钟，考官 Anna 非常 nice 地继续问了我一些问题，就进入 Part 3 了。&lt;/p&gt;
&lt;p&gt;Part 3 当然就是针对 noise 话题一顿穷追猛打：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你觉得是不是有人很享受噪音？&lt;/li&gt;
&lt;li&gt;你觉得噪音有哪里常见的来源？&lt;/li&gt;
&lt;li&gt;你觉得人们在公共场合是不是应该减少制造噪音？&lt;/li&gt;
&lt;li&gt;你觉得小孩有时是不是应该暴露在一些噪音中？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;呼，能想起来的就这么多了，我已尽力，哈哈。&lt;/p&gt;
&lt;h1 id=&#34;考后&#34;&gt;考后&lt;/h1&gt;
&lt;p&gt;雅思官方说法是考后 3-5 个自然日就出成绩，于是我第三天就开始蹲守雅思网站。可是……&lt;/p&gt;
&lt;p&gt;第三天，没有。&lt;/p&gt;
&lt;p&gt;第四天，没有。&lt;/p&gt;
&lt;p&gt;第五天，还是没有。&lt;/p&gt;
&lt;p&gt;第六天我打电话给考点，得到的答复是当天下午五点出成绩，好吧，我等到五点。可是……&lt;/p&gt;
&lt;p&gt;第六天、第七天、第八天都没有出成绩，周末了也只好先发邮件等着周一答复，顺便预约了周一上午直接到考点取成绩单，跟他们耗不起啊。&lt;/p&gt;
&lt;p&gt;周一正开着晨会呢，收到出成绩的邮件了！这已经是第九天了！考点在回复我的邮件时，忽略了我在邮件中关于为什么迟迟不出成绩的咨询，告诉我说，对，没错，今天下午一点前你都可以过来拿成绩单，一点之后我们就都邮寄出去啦！&lt;/p&gt;
&lt;p&gt;出成绩前我自己估分是 6.5 / 8.5 / 6.5 / 6，Linda 给我的估分是 7 / 8.5 / 7 / 6.5，最终成绩是 7.5 / 8.5 / 7 / 6.5，Linda 估对了除听力之外的所有三个科目，比我自己都更了解我自己！听力成绩完全超乎我俩的预料，居然只差 1-2 题就达到目标分数了。&lt;/p&gt;
&lt;p&gt;听力和口语是接下来的备考重点，五年了口语分数一点长进都没有，也该好好反省一下了。写作能上 7 也有很大的侥幸成分，持续练习不能松懈。阅读只要偶尔做一套题，保持对答题技巧的敏感性即可。&lt;/p&gt;
&lt;p&gt;最后附上一些不错的备考网站链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.culips.com/&#34;&gt;Culips.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bbc.co.uk/learningenglish/&#34;&gt;BBC Learning English&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learnenglish.britishcouncil.org/&#34;&gt;British Council Learn English&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learningenglish.voanews.com/&#34;&gt;VOA Learning English&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上。&lt;/p&gt;
</description>
    </item><item>
      <title>恭喜你一岁半了</title>
      <link>https://blog.lancitou.net/congrats-on-18-months/</link>
      <pubDate>Sun, 02 Jul 2023 09:06:25 +0000</pubDate><author>Linda Ye</author>
      
      <guid>https://blog.lancitou.net/congrats-on-18-months/</guid>
      <description>&lt;p&gt;一岁半的小娃每天以惊人的速度成长，令我们惊喜不断。&lt;/p&gt;
&lt;h2 id=&#34;语言方面&#34;&gt;语言方面&lt;/h2&gt;
&lt;p&gt;除了会喊自己的名字，也能说出全班同学的名字。每到放学时刻，看到家长在门口出现，就会轻拍对应小娃娃的脑袋，激动喊出他/她的名字，意思说“你爸妈来接你啦！”&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/8ONGZtk.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;自小听到音乐就爱扭动，现在又会接歌了。比如我唱 ”If you’re happy and you know, nod your head”，娃接：“nod nod”。我唱“This is the way we brush our teeth, early in the…”，娃接：“Mor-Ning”。这几天先生在教歌，比如：“只有我最摇摆”，娃接“摇（摆）摇（摆）”。“没有谁比我帅”，娃接“米有米有”。男人们的画风果然不一样，哼。&lt;/p&gt;
&lt;p&gt;热爱各种车，每天上学路上看到车来车往激动地尖叫，把会说的汽车种类都说一遍，car，bus，digger，bike，“尼诺尼诺”（救护车）等。看到广告牌的图片指着说“Boots”或者“Owl”。遇到红灯，先生刚减速，娃就急吼吼说“走走走”。到达目的地，一定要以欢呼结尾“Yeah!”&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/G8IJSkL.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/o8Ah4Ga.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;现在办完“大事儿”会指着自己的尿布说“臭臭”，然后领着我们去尿布台边示意“该换尿布了”。&lt;/p&gt;
&lt;p&gt;说“No”的频率永远最多。&lt;/p&gt;
&lt;h2 id=&#34;运动方面&#34;&gt;运动方面&lt;/h2&gt;
&lt;p&gt;热爱各种球类运动，家里有皮球、气球、橄榄球，每天玩一小时不带喘气。去体育馆看青少年篮球赛，不仅要玩大孩子的篮球，还要挣扎着上场，全身细胞都在跃跃欲试，无惧这样激烈又嘈杂的比赛气氛。&lt;/p&gt;
&lt;p&gt;骑平衡车有段时间了，在家里提着车头各种转弯，偶尔还会把车反过来，专门玩车轱辘。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/cOLGKjs.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/QBUO4bk.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;h2 id=&#34;饮食方面&#34;&gt;饮食方面&lt;/h2&gt;
&lt;p&gt;目前对鸡蛋、虾和酱油过敏，饮食清淡为主，喜爱面食和蔬菜，尤其热爱冷冻蔬菜粒包装里的老三样-胡萝卜、豌豆和玉米，可以干吃一整碗，绝对吃草动物，肉得混在蔬菜或者饭里藏起来，才能吃进去。&lt;/p&gt;
&lt;p&gt;爱吃香蕉和橘子，爱吃带皮的苹果，自己嚼到最后吐出薄薄的干干的果皮。还喜欢连皮啃斐济果，酸到眉头皱起来。蓝莓当季时，每次只给 10 颗，基本上一转身能全部消灭。零食只给米饼，还没尝过甜食，比如巧克力或者冰淇淋。家里常备健康的自制香蕉蛋糕和低糖酸奶蛋糕，虽然娃对鸡蛋过敏，但对含有鸡蛋的烘焙食品不过敏。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/bTAJfQL.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;h2 id=&#34;社交方面&#34;&gt;社交方面&lt;/h2&gt;
&lt;p&gt;前段时间是人前装安静，人后超热情。见面哄着让喊“叔叔阿姨”“你好再见”，一脸茫然。等别人一转身，重复说人家名字并且配合“你好再见”的手势。最近开始主动对陌生人打招呼，也会大方地跟老师和同学拥抱。&lt;/p&gt;
&lt;p&gt;去动物园最爱看小鸟和逛礼品店，去超市喜欢拿着整袋吐司逢人就说“toast”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/TsdsHTn.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;h2 id=&#34;与爸妈斗智斗勇&#34;&gt;与爸妈斗智斗勇&lt;/h2&gt;
&lt;p&gt;每天送去幼儿园时，在门口赖着不肯进教室。放学时宁愿绕着教室跑圈，也不肯跟我们回家。这个戏码天天上演。&lt;/p&gt;
&lt;p&gt;在幼儿园是优等生，被老师夸得嘴都歪了。每次我问老师，娃今天吃得如何？老师都说，吃饭不用问，每天都很好，自己吃两碗。午睡时间稳定，午饭后被老师抱去小床，老师一说开始睡觉咯，他可以自己躺下秒睡。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/HKnS3R2.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;在家吃饭花样多，乖巧时候拿勺子一口接一口吃，碗底也要舔干净。调皮时把餐具食物扔的满天飞，一边扔一边学我们的语气说：“NO!”，简直是大写的“明知故犯”和“公然挑衅”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/O40g3Xv.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/f5HuWIF.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;睡觉的前提必须是电量耗尽，不然黑灯瞎火的还会要求出门看月亮看飞机看绕在门前栅栏上的圣诞彩灯。有时就算屋里灯全关，还得跟先生嘻嘻哈哈一小时才能睡下。&lt;/p&gt;
&lt;p&gt;生气时会大叫，被我严肃地纠正时会先斜眼看我，再把小眼珠轱辘一转，噗哧笑出来。有时无理由的扔玩具，被制止后，扔得更凶，不过扔完娃自己会依次捡回来分类摆放好，应该是比较享受这个过程吧。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/mulFeCM.png&#34; alt=&#34;&#34;&gt;​&lt;/p&gt;
&lt;p&gt;娃在今晚第一次抢过先生的拖把，自己来回在客厅和厨房之间拖了十分钟的地，先生跟着夸了十分钟，是正向教育的楷模。但截止到今日，先生的脑袋被玩具车砸过，脸被睡熟的娃的无影小短腿踢过，脖子被娃啃坏的指甲挠过……（为什么受伤的总是爸爸？因为妈妈比较凶。）&lt;/p&gt;
&lt;p&gt;时间有限，成长无限。我得先去睡觉，才能保持体力对小娃娃见招拆招。&lt;/p&gt;
&lt;p&gt;十八个月快乐，小可爱。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/pFwxCxW.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
</description>
    </item><item>
      <title>奥克兰 | 一周办妥旅行证</title>
      <link>https://blog.lancitou.net/travel-permit-application/</link>
      <pubDate>Sun, 25 Jun 2023 09:27:14 +0000</pubDate><author>Linda Ye</author>
      
      <guid>https://blog.lancitou.net/travel-permit-application/</guid>
      <description>&lt;p&gt;给娃办理旅行证，耗时一周。旅行证的适用情况可参考&lt;a href=&#34;http://auckland.china-consulate.gov.cn/&#34;&gt;中国驻奥克兰总领馆官网&lt;/a&gt;信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/22avaFi.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;时间线：&lt;/p&gt;
&lt;p&gt;06.17. 在线提交资料&lt;/p&gt;
&lt;p&gt;06.18. 收到 App 通知初审通过，预约第二天现场办理&lt;/p&gt;
&lt;p&gt;06.22. 收到 App 通知可取证&lt;/p&gt;
&lt;p&gt;06.23. 下午两点排队取证&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/4wzEh2A.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;办理流程要点：&lt;/p&gt;
&lt;p&gt;下载 “中国领事” App，在线提交材料初审。照片可以自己拍，找淘宝修图（40 RMB）。签名文件需要去领事馆网站下载最新模板，然后打印出来填写再拍照，因为最后文件都是以图片形式在 App 上传。照片在 Warehouse Stationary 打印，一份 $10，共六张。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/b9NNKcF.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;初审通过后预约现场办理时间。现场办理时提前准备好预约申请单（可出示 App 信息或者提前打印出来），带上护照，带上娃（一般爸爸去办理比较容易把娃给忘记）。领事馆门口很难找停车位，早点去找。&lt;/p&gt;
&lt;p&gt;取证时需要提供订单最后五位数字，下午两点到四点可取证，无需预约。取证时再付款。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/lbV8hk4.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;服务嘛，有的人很好很细心，有的人凶巴巴。办证大厅延续国内风格。进门有体温自动检测仪器，建议戴口罩。办证进度信息都是在 App 里更新，没有短信或者邮件提醒。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/lEuIQFL.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;以上。&lt;/p&gt;
</description>
    </item><item>
      <title>来自 St John 的账单</title>
      <link>https://blog.lancitou.net/bill-from-st-john/</link>
      <pubDate>Tue, 13 Jun 2023 11:00:55 +0000</pubDate><author>Linda Ye</author>
      
      <guid>https://blog.lancitou.net/bill-from-st-john/</guid>
      <description>&lt;p&gt;六月初的国王生日假期因为经历宝宝第一次高烧惊厥，全家坐上了救护车。&lt;/p&gt;
&lt;p&gt;假期三天，宝宝完全正常，没有一点感冒发烧的迹象。晚上睡着后哼唧了几声，我去房间把他抱起来哄睡时发现额头有些烫，怪我没有及时量体温，只确认手脚冰凉，凭手感以为是低烧。半小时后先生进屋，我正说着宝宝好像发烧了，听到宝宝大叫一声，立马开始抽搐、翻白眼，我整个魂都没了，先生立刻把他抱过去，再面朝下，让我赶紧打 111。&lt;/p&gt;
&lt;p&gt;电话接通的很快，我颤抖着报了家里地址，接线员让我保持冷静，问宝宝现在如何。这时候听到他咳嗽哭出了声音，但软软的趴在先生身上，睡衣已被先生脱掉，只留了包屁衣。我告诉接线员，目前有了呼吸，但眼周和鼻子成紫色。随后家里来了两位陌生人，一个帮助查看宝宝生命体征，一个安抚我情绪，我因为太害怕，没听清他们的身份，看起来像社区急救志愿者，因为他们就住在附近 （后来朋友告知，他们是 First Responder)。我把电话给了其中一个人，让他跟接线员沟通。急救人员大概十分钟之内抵达。（因为查看通话记录显示十分钟，至于当时谁结束通话，啥时候结束通话，志愿者什么时候走的，我完全没印象）。一直趴在床边哭得发抖的我和先生两人，看着宝宝昏昏沉沉的表情，面部的紫色逐渐退去，头顶开着大灯，屋里站着陌生人，他也不知道哭。急救人员量了体温，测了生命体征，脱掉宝宝的衣服袜子，就剩一个尿布，对我说：“情况稳定了，但我们还是要送去医院看看。你整理下东西，跟我们去。但千万不要着急。” 我正准备拿上宝宝厚外套，急救人员说现在不能给他穿。在初冬深夜，从出家门到进医院，宝宝只穿着纸尿裤。&lt;/p&gt;
&lt;p&gt;上了救护车，吃了药，宝宝独自靠在病床上，我的位置面对着他，但由于安全带问题，没办法抱他，听他哭着喊了一路 “Mummy”。救护人员说没关系，听他哭，我们知道他精神还不错。到医院确诊是 Febrile Seizure，我一辈子也不会忘记这个词。接着做病毒检测，排除 COVID 和 UTI，但具体哪种病毒目前还不知道。在医院的五小时，宝宝精神挺好，清醒好动，凌晨三点出院回家，终于睡了。&lt;/p&gt;
&lt;p&gt;接下来是三天的连续发烧，我和先生简直如履薄冰。白天宝宝虽然小脸和耳朵通红，但不影响吃喝玩乐。夜里手脚冰凉，我俩轮流看护两小时，眼皮打架也不敢睡，积极散热加量体温，防止变化过快，自然也只给他穿短袖包屁衣，冻一点无妨。幸运的是，情况一天天好转，我们连续请了两天病假，带他在家休养。&lt;/p&gt;
&lt;p&gt;在医生的建议下，我们在 &lt;a href=&#34;https://www.kidshealth.org.nz/febrile-seizures&#34;&gt;KidsHealth 网站&lt;/a&gt;查看了关于 Febrile Seizure 的基本信息，了解到 Febrile Seizure 是小孩六个月到六岁之间会发生的常见疾病，但不会对大脑产生影响。它是身体对高温的主动防御机制，不能避免，大人能做的是在发生时让宝宝侧躺防呛，计时和请求救援。特别是面对自己的孩子，父母在紧急情况时一定要试着保持冷静，这样才能保证救援的及时有效。&lt;/p&gt;
&lt;p&gt;目前回想起来依然脆弱和难受，愿小朋友们都健康。&lt;/p&gt;
</description>
    </item><item>
      <title>Add support of filtering step values in pipewire</title>
      <link>https://blog.lancitou.net/add-support-of-filtering-step-values-in-pipewire/</link>
      <pubDate>Sat, 10 Jun 2023 11:59:53 +0000</pubDate><author>Philip Ye</author>
      
      <guid>https://blog.lancitou.net/add-support-of-filtering-step-values-in-pipewire/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note: The patch in this post is out-dated because pipewire has already added the support in &lt;a href=&#34;https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/0f4fcd63ac3ea00322500c34d0bd8609ad49da95&#34; title=&#34;filter: Better SPA_CHOICE_Step support&#34;&gt;this commit&lt;/a&gt;. The commit message describes the exact case we need that support: encode a screencast with a hardware encoder.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;the-issue&#34;&gt;The issue&lt;/h1&gt;
&lt;p&gt;When constructing a gstreamer pipeline for RTSP, we use &lt;code&gt;pipewiresrc&lt;/code&gt; element to get the video stream from Weston and &lt;code&gt;vpuenc_h264&lt;/code&gt; element to encode it to H.264 format with VPU before streaming out to &lt;code&gt;rtph264pay&lt;/code&gt; element. But between &lt;code&gt;pipewiresrc&lt;/code&gt; and &lt;code&gt;vpuenc_h264&lt;/code&gt;, we have to explicitly specify the resolution of the video:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pipewiresrc ! video/x-raw,format=BGRx,width=800,height=480 ! vpuenc_h264 ! rtph264pay name=pay0 pt=96
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After enabling the debug log of GStreamer, I&amp;rsquo;ve figured out that during the negotiation of capabilities, the size in capabilities of &lt;code&gt;pipewiresrc&lt;/code&gt; is determined values &lt;code&gt;800x480&lt;/code&gt; (type &lt;code&gt;SPA_CHOICE_None&lt;/code&gt; in pipewire), but the size in capabilities of &lt;code&gt;vpuenc_h264&lt;/code&gt; is a step values &lt;code&gt;[64, 1920, 8]&lt;/code&gt; and &lt;code&gt;[64, 1088, 8]&lt;/code&gt; (type &lt;code&gt;SPA_CHOICE_Step&lt;/code&gt; in pipewire).&lt;/p&gt;
&lt;p&gt;However, pipewire doesn&amp;rsquo;t support comparing (filtering) &lt;code&gt;SPA_CHOICE_None&lt;/code&gt; with &lt;code&gt;SPA_CHOICE_Step&lt;/code&gt; or vice versa, so it will fail to negotiate the capabilities if &lt;code&gt;pipewiresrc&lt;/code&gt; and &lt;code&gt;vpuenc_h264&lt;/code&gt; is connected directly without explicitly specify the resolution inbetween.&lt;/p&gt;
&lt;h1 id=&#34;the-fix&#34;&gt;The fix&lt;/h1&gt;
&lt;p&gt;The fix is obvious: add the support of filtering step values in pipewire.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SPA_CHOICE_Step&lt;/code&gt; is pretty much similar to &lt;code&gt;SPA_CHOICE_Range&lt;/code&gt; so could deal them in the same way. So the patch is as simple as below (also add support of comparing with &lt;code&gt;SPA_CHOICE_Enum&lt;/code&gt; to keep consistency):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;diff --git a/spa/include/spa/pod/filter.h b/spa/include/spa/pod/filter.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;index dd2e9931..f2c996be 100644
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;--- a/spa/include/spa/pod/filter.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+++ b/spa/include/spa/pod/filter.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -153,7 +153,9 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        if ((p1c == SPA_CHOICE_None &amp;amp;&amp;amp; p2c == SPA_CHOICE_Range) ||
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-           (p1c == SPA_CHOICE_Enum &amp;amp;&amp;amp; p2c == SPA_CHOICE_Range)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_Enum &amp;amp;&amp;amp; p2c == SPA_CHOICE_Range) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_None &amp;amp;&amp;amp; p2c == SPA_CHOICE_Step) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_Enum &amp;amp;&amp;amp; p2c == SPA_CHOICE_Step)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;                int n_copied = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                /* copy all values inside the range */
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                for (j = 0, a1 = alt1, a2 = alt2; j &amp;lt; nalt1; j++, a1 = SPA_MEMBER(a1,size,void)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -169,13 +171,10 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;                nc-&amp;gt;body.type = SPA_CHOICE_Enum;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-       if ((p1c == SPA_CHOICE_None &amp;amp;&amp;amp; p2c == SPA_CHOICE_Step) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-           (p1c == SPA_CHOICE_Enum &amp;amp;&amp;amp; p2c == SPA_CHOICE_Step)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-               return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-       }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;        if ((p1c == SPA_CHOICE_Range &amp;amp;&amp;amp; p2c == SPA_CHOICE_None) ||
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-           (p1c == SPA_CHOICE_Range &amp;amp;&amp;amp; p2c == SPA_CHOICE_Enum)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_Range &amp;amp;&amp;amp; p2c == SPA_CHOICE_Enum) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_None) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+           (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_Enum)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;                int n_copied = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                /* copy all values inside the range */
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                for (k = 0, a1 = alt1, a2 = alt2; k &amp;lt; nalt2; k++, a2 = SPA_MEMBER(a2,size,void)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -220,15 +219,11 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;        if (p1c == SPA_CHOICE_Enum &amp;amp;&amp;amp; p2c == SPA_CHOICE_Flags)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-       if (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_None)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-               return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;        if (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_Range)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        if (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_Step)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-       if (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_Enum)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-               return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;        if (p1c == SPA_CHOICE_Step &amp;amp;&amp;amp; p2c == SPA_CHOICE_Flags)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                return -ENOTSUP;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After applying this patch, the pipeline for RTSP can be simplified to:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pipewiresrc ! vpuenc_h264 ! rtph264pay name=pay0 pt=96
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which is screen resolution agnostic and can be used generally on different systems.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
</description>
    </item><item>
      <title>Duplicated device in libinput</title>
      <link>https://blog.lancitou.net/duplicated-device-in-libinput/</link>
      <pubDate>Sat, 10 Jun 2023 10:52:22 +0000</pubDate><author>Philip Ye</author>
      
      <guid>https://blog.lancitou.net/duplicated-device-in-libinput/</guid>
      <description>&lt;h1 id=&#34;the-issue-and-a-hack&#34;&gt;The issue and a hack&lt;/h1&gt;
&lt;p&gt;An issue was reported that touch focus didn&amp;rsquo;t work properly in application. After a quick investigation, I found that when the issue occurs, two identical touch devices are added in weston and each touch action will trigger two same touch events (same coordinates of &lt;code&gt;(X, Y)&lt;/code&gt; but from different &lt;code&gt;struct libinput_device&lt;/code&gt; instances).&lt;/p&gt;
&lt;p&gt;By a hack of ignoring the duplicate touch event in weston, touch focus works properly in application. So the next step is to find out why the touch device is being added twice and what the proper fix is.&lt;/p&gt;
&lt;h1 id=&#34;searching-mailing-list&#34;&gt;Searching mailing list&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://lists.freedesktop.org/archives/wayland-devel/2016-August/030803.html&#34; title=&#34;How can I prevent duplicated device?&#34;&gt;A post&lt;/a&gt; in libinput mailing list mentioned duplicated device issue and also proposed a patch to prevent this issue. However, a maintainer suggested the fix should be in the place where the duplicated device comes from (udev in the case of that post):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;if we get the same device twice from udev that&amp;rsquo;s a bug in udev and needs to
be fixed there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://lists.freedesktop.org/archives/wayland-devel/2018-April/037726.html&#34; title=&#34;Initialization race against udev&#34;&gt;Another thread&lt;/a&gt; in libinput mailing list mentioned running &lt;code&gt;udevadm trigger&lt;/code&gt; would cause device added event triggered twice:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But there is a snag: if a device like /dev/input/event0 has been
coldplugged once with the hands-on technique, then all the daemons that
care about it have already seen one UDev ACTION=add event for it. When the
late-running &amp;lsquo;udevadm trigger&amp;rsquo; does its exhaustive sweep across
/sys/devices, this will cause a second ACTION=add event to be triggered for
/dev/input/event0. Currently (well, with libinput 1.1.1) this causes
libinput – and consequently Weston – to open a second filedescriptor
against /dev/input/event0, so that all input events are received in
duplicate. That confuses the compositor&amp;rsquo;s and applications&amp;rsquo; input event
handling.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That reminds me that we have a &lt;code&gt;udevadm trigger&lt;/code&gt; in &lt;code&gt;rc.weston&lt;/code&gt; before starting weston as a workaround of tagging the touch driver as input device type.&lt;/p&gt;
&lt;h1 id=&#34;the-proper-fix&#34;&gt;The proper fix&lt;/h1&gt;
&lt;p&gt;For the device adding process, libinput will first enumerate all the existing devices and add them in &lt;code&gt;udev_input_add_devices()&lt;/code&gt;, and for hotplugged devices, libinput uses a udev monitor &lt;code&gt;evdev_udev_handler()&lt;/code&gt; to detect &lt;code&gt;ACTION=add&lt;/code&gt; events.&lt;/p&gt;
&lt;p&gt;When the issue occurs, log shows the touch device is added twice in the aforementioned two parts - one in enumeration, the other in udev monitor.&lt;/p&gt;
&lt;p&gt;And &lt;code&gt;udevadm trigger&lt;/code&gt; in &lt;code&gt;rc.weston&lt;/code&gt; is the cause of the second adding operation. So the fix is simply removing it as we don&amp;rsquo;t need that workaround any more.&lt;/p&gt;
&lt;h1 id=&#34;unmerged-patch&#34;&gt;Unmerged patch&lt;/h1&gt;
&lt;p&gt;The patch in the second thread mentioned above had been merged in &lt;a href=&#34;https://gitlab.freedesktop.org/libinput/libinput/-/commit/23d543b711cf027df3f7322e5dc51d352ed6179c&#34; title=&#34;udev: validate input devices during cold-plug&#34;&gt;this commit&lt;/a&gt; to fix a race between udev events and libinput startup, but the patch in the first thread wasn&amp;rsquo;t merged.&lt;/p&gt;
&lt;p&gt;Keep a copy of that patch here for reference and in case it may help:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;diff --git a/src/evdev.c b/src/evdev.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;index 99713f2c..a3cc8f48 100644
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;--- a/src/evdev.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+++ b/src/evdev.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -2058,6 +2058,7 @@ evdev_device_create(struct libinput_seat *seat,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;                    struct udev_device *udev_device)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        struct libinput *libinput = seat-&amp;gt;libinput;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+       struct libinput_device *dev = NULL;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;        struct evdev_device *device = NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        int rc;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        int fd;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -2075,6 +2076,15 @@ evdev_device_create(struct libinput_seat *seat,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;                return NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+       list_for_each(dev, &amp;amp;seat-&amp;gt;devices_list, link) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+               struct evdev_device *d = (struct evdev_device*)dev;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+               if (streq(devnode, udev_device_get_devnode(d-&amp;gt;udev_device))) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+                       log_info(libinput,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+                               &amp;#34;%s device is already opened\n&amp;#34;, d-&amp;gt;devname);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+                       goto err;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+               }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+       }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;        /* Use non-blocking mode so that we can loop on read on
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         * evdev_device_data() until all events on the fd are
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         * read.  mtdev_get() also expects this. */
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Have fun!&lt;/p&gt;
</description>
    </item><item>
      <title>Popup window repositioning in weston</title>
      <link>https://blog.lancitou.net/popup-window-repositioning-in-weston/</link>
      <pubDate>Sun, 04 Jun 2023 11:29:19 +0000</pubDate><author>Philip Ye</author>
      
      <guid>https://blog.lancitou.net/popup-window-repositioning-in-weston/</guid>
      <description>&lt;h1 id=&#34;the-problem&#34;&gt;The problem&lt;/h1&gt;
&lt;p&gt;When removing a output in handling unplugging a HDMI display, weston will reposition all views into the first output if the views aren&amp;rsquo;t within the region of any outputs in &lt;a href=&#34;https://gitlab.freedesktop.org/wayland/weston/-/blob/main/desktop-shell/shell.c#L4639&#34; title=&#34;shell_reposition_view_on_output_change()&#34;&gt;&lt;code&gt;shell_reposition_view_on_output_change()&lt;/code&gt;&lt;/a&gt; of desktop-shell/shell.c. And if a view is a popup, the geometry of that view is set to a relation position to its parent view &lt;a href=&#34;https://gitlab.freedesktop.org/wayland/weston/-/blob/main/libweston/desktop/xdg-shell-v6.c#L1135&#34; title=&#34;weston_desktop_xdg_surface_protocol_get_popup()&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When the relative position of a popup view has negative values, the repositioning in aforementioned function will reckon this view invisible and move it to first quarter of the first output!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (!visible) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	first_output = &lt;span style=&#34;color:#447fcf&#34;&gt;container_of&lt;/span&gt;(ec-&amp;gt;output_list.next,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				    &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;struct&lt;/span&gt; weston_output, link);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	x = first_output-&amp;gt;x + first_output-&amp;gt;width / &lt;span style=&#34;color:#3677a9&#34;&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	y = first_output-&amp;gt;y + first_output-&amp;gt;height / &lt;span style=&#34;color:#3677a9&#34;&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#447fcf&#34;&gt;weston_view_set_position&lt;/span&gt;(view, x, y);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For example, in our use case, Brightness Bar is a popup view and its parent is System Controls. The following table shows the positions of these two views on an internal display of resolution 1920x1080 (first output):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Window&lt;/th&gt;
&lt;th&gt;Absolute Position&lt;/th&gt;
&lt;th&gt;Relative Position&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System Controls&lt;/td&gt;
&lt;td&gt;(534,281)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brightness Bar&lt;/td&gt;
&lt;td&gt;(1045,135)&lt;/td&gt;
&lt;td&gt;(511,-146)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The position (511,-146) is out of the region of 1920x1080 in the checking of &lt;a href=&#34;https://gitlab.freedesktop.org/wayland/weston/-/blob/main/desktop-shell/shell.c#L4639&#34; title=&#34;shell_reposition_view_on_output_change()&#34;&gt;&lt;code&gt;shell_reposition_view_on_output_change()&lt;/code&gt;&lt;/a&gt;. When a HDMI display is unplugged, the Brightness Bar will move to absolute position (480,270), which is different from its original absolute position (1045,135).&lt;/p&gt;
&lt;h1 id=&#34;the-fix&#34;&gt;The fix&lt;/h1&gt;
&lt;p&gt;Since the position of popup view is relative to its parent, so when repositioning a popup view, we should convert it to the absolute position before checking if the position is within the region of any outputs.&lt;/p&gt;
&lt;p&gt;In order to do the conversion, we should check if the role of the view is &lt;code&gt;WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP&lt;/code&gt;, but the role information is only accessible in &lt;a href=&#34;https://gitlab.freedesktop.org/wayland/weston/-/blob/main/libweston/desktop/xdg-shell-v6.c#L59&#34; title=&#34;enum weston_desktop_xdg_surface_role&#34;&gt;libweston-desktop/xdg-shell-v6.c&lt;/a&gt;. To keep it simple, we check if any coordinate is negative:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (x &amp;lt; &lt;span style=&#34;color:#3677a9&#34;&gt;0&lt;/span&gt; || y &amp;lt; &lt;span style=&#34;color:#3677a9&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	parent_view = view-&amp;gt;geometry.parent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (parent_view) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		x += parent_view-&amp;gt;geometry.pos_offset.x;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		y += parent_view-&amp;gt;geometry.pos_offset.y;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If both coordinates are positive, the check of within a output region is sufficient to make sure the view is visible.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;visible = &lt;span style=&#34;color:#3677a9&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (ec-&amp;gt;clone_mode &amp;amp;&amp;amp; ec-&amp;gt;primary_output) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#999;font-style:italic&#34;&gt;/* In clone mode, all outputs have the same geometry and region,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#999;font-style:italic&#34;&gt;	 * so only need to check if the view is visible in primary output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#999;font-style:italic&#34;&gt;	 */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#447fcf&#34;&gt;weston_output_contains_point&lt;/span&gt;(ec-&amp;gt;primary_output, x,y)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		visible = &lt;span style=&#34;color:#3677a9&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#447fcf&#34;&gt;wl_list_for_each&lt;/span&gt;(output, &amp;amp;ec-&amp;gt;output_list, link) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#447fcf&#34;&gt;weston_output_contains_point&lt;/span&gt;(output, x, y)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			visible = &lt;span style=&#34;color:#3677a9&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;side-note&#34;&gt;Side note&lt;/h1&gt;
&lt;p&gt;In wayland protocol, &lt;a href=&#34;https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/xdg-shell/xdg-shell.xml#L170&#34; title=&#34;xdg_positioner.set_anchor_rect&#34;&gt;&lt;code&gt;xdg_positioner.set_anchor_rect&lt;/code&gt;&lt;/a&gt; is used to implement the position of a popup surface:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;request&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;set_anchor_rect&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;description&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;summary=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;set the anchor rectangle within the parent surface&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	Specify the anchor rectangle within the parent surface that the child
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	surface will be placed relative to. The rectangle is relative to the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	window geometry as defined by xdg_surface.set_window_geometry of the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	parent surface.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	When the xdg_positioner object is used to position a child surface, the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	anchor rectangle may not extend outside the window geometry of the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	positioned child&amp;#39;s parent surface.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	If a negative size is set the invalid_input error is raised.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;int&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;summary=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;x position of anchor rectangle&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;y&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;int&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;summary=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;y position of anchor rectangle&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;width&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;int&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;summary=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;width of anchor rectangle&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;height&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;int&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;summary=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;height of anchor rectangle&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;/request&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Qt, it&amp;rsquo;s done in &lt;a href=&#34;https://github.com/qt/qtwayland/blob/dev/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp#L464&#34; title=&#34;QWaylandXdgSurface::setPopup()&#34;&gt;&lt;code&gt;QWaylandXdgSurface::setPopup()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;void&lt;/span&gt; QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Q_ASSERT(!m_toplevel &amp;amp;&amp;amp; !m_popup);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;auto&lt;/span&gt; positioner = &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;new&lt;/span&gt; QtWayland::xdg_positioner(m_shell-&amp;gt;m_xdgWmBase-&amp;gt;create_positioner());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#999;font-style:italic&#34;&gt;// set_popup expects a position relative to the parent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#999;font-style:italic&#34;&gt;&lt;/span&gt;    QRect windowGeometry = m_window-&amp;gt;windowContentGeometry();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    QMargins windowMargins = m_window-&amp;gt;windowContentMargins() - m_window-&amp;gt;clientSideMargins();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    QMargins parentMargins = parent-&amp;gt;windowContentMargins() - parent-&amp;gt;clientSideMargins();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    QPoint transientPos = m_window-&amp;gt;geometry().topLeft(); &lt;span style=&#34;color:#999;font-style:italic&#34;&gt;// this is absolute
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#999;font-style:italic&#34;&gt;&lt;/span&gt;    transientPos += QPoint(windowMargins.left(), windowMargins.top());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    transientPos -= parent-&amp;gt;geometry().topLeft();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    transientPos -= QPoint(parentMargins.left(), parentMargins.top());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;set_anchor_rect(transientPos.x(), transientPos.y(), &lt;span style=&#34;color:#3677a9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#3677a9&#34;&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;set_anchor(QtWayland::xdg_positioner::anchor_top_left);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;set_size(windowGeometry.width(), windowGeometry.height());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;set_constraint_adjustment(QtWayland::xdg_positioner::constraint_adjustment_slide_x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        | QtWayland::xdg_positioner::constraint_adjustment_slide_y);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    m_popup = &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;new&lt;/span&gt; Popup(&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;this&lt;/span&gt;, parent, positioner);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    positioner-&amp;gt;destroy();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;delete&lt;/span&gt; positioner;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And there&amp;rsquo;s actually &lt;a href=&#34;https://github.com/qt/qtwayland/commit/ca65a264c8d0259a8699d1c93eee47d840806aad&#34; title=&#34;Compositor xdg-shell: Warn when clients supply invalid anchor rects&#34;&gt;a commit in upstream qtwayland&lt;/a&gt; about invalid anchor rectangles. As the comment in that commit said, Qt&amp;rsquo;s own clients are supplying invalid anchor rectangles (and violating &lt;code&gt;xdg_positioner&lt;/code&gt; protocol), so it&amp;rsquo;s just a warning but not an error.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
</description>
    </item><item>
      <title>RTS / CTS of UART in i.MX8</title>
      <link>https://blog.lancitou.net/rts-cts-of-uart-in-imx8/</link>
      <pubDate>Sat, 03 Jun 2023 12:03:51 +0000</pubDate><author>Philip Ye</author>
      
      <guid>https://blog.lancitou.net/rts-cts-of-uart-in-imx8/</guid>
      <description>&lt;p&gt;After removing the voltage divider before &lt;code&gt;WLAN_EN&lt;/code&gt; and &lt;code&gt;BT_EN&lt;/code&gt; described in &lt;a href=&#34;/wifi-bluetooth-bringup-failure-due-to-voltage-divider/&#34; title=&#34;Wi-Fi / Bluetooth bringup failure due to voltage divider&#34;&gt;Wi-Fi / Bluetooth bringup failure due to voltage divider&lt;/a&gt;, Wi-Fi worked properly but Bluetooth didn&amp;rsquo;t. It turned out to be an issue in hardware flow control (RTS / CTS) of UART module used for Bluetooth.&lt;/p&gt;
&lt;h1 id=&#34;the-problem&#34;&gt;The problem&lt;/h1&gt;
&lt;p&gt;After updating the device tree and pinmux for Bluetooth, it can read local version and construct file path of firmware correctly, but timeout in downloading firmware:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[   10.225930] (hci_tty): inside hci_tty_init
[   10.230294] (hci_tty): allocated 239, 0
[   11.283024] Bluetooth: Core ver 2.22
[   11.291184] Bluetooth: HCI device and connection manager initialized
[   11.297581] Bluetooth: HCI socket layer initialized
[   11.302483] Bluetooth: L2CAP socket layer initialized
[   11.307565] Bluetooth: SCO socket layer initialized
[   11.320108] (stc):  chnl_id list empty :4
[   11.320121] (stk) : st_kim_start
[   11.429318] (stk) :ldisc_install = 1
[   11.433544] (stc): st_tty_open
[   11.437217] (stk) :line discipline installed
[   11.443662] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   14.889097] (stk) :response timeout/signaled during fw download
[   14.889144] (stk) :download firmware failed
[   14.895301] (stk) :ldisc_install = 0
[   14.899913] (stc): st_tty_close
[   15.010623] (stk) :ldisc_install = 1
[   15.014808] (stc): st_tty_open
[   15.018473] (stk) :line discipline installed
[   15.024931] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   18.441153] (stk) :response timeout/signaled during fw download
[   18.441237] (stk) :download firmware failed
[   18.447384] (stk) :ldisc_install = 0
[   18.452352] (stc): st_tty_close
[   18.563189] (stk) :ldisc_install = 1
[   18.567503] (stc): st_tty_open
[   18.571304] (stk) :line discipline installed
[   18.578099] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   21.993065] (stk) :response timeout/signaled during fw download
[   21.993115] (stk) :download firmware failed
[   21.999229] (stk) :ldisc_install = 0
[   22.003712] (stc): st_tty_close
[   22.114387] (stk) :ldisc_install = 1
[   22.118485] (stc): st_tty_open
[   22.122126] (stk) :line discipline installed
[   22.128549] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   25.545340] (stk) :response timeout/signaled during fw download
[   25.550477] (stk) :download firmware failed
[   25.556642] (stk) :ldisc_install = 0
[   25.561862] (stc): st_tty_close
[   25.672592] (stk) :ldisc_install = 1
[   25.676935] (stc): st_tty_open
[   25.680607] (stk) :line discipline installed
[   25.687076] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   29.097130] (stk) :response timeout/signaled during fw download
[   29.102354] (stk) :download firmware failed
[   29.108441] (stk) :ldisc_install = 0
[   29.113030] (stc): st_tty_close
[   29.223777] (stk) :ldisc_install = 1
[   29.227927] (stc): st_tty_open
[   29.231613] (stk) :line discipline installed
[   29.238036] (stk) :ti-connectivity/TIInit_11.8.32.bts
[   32.649118] (stk) :response timeout/signaled during fw download
[   32.654232] (stk) :download firmware failed
[   32.660286] (stk) :ldisc_install = 0
[   32.664766] (stc): st_tty_close
[   32.670438] Bluetooth: st_register failed -22
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Interesting enough, by enabling the following debug print in &lt;a href=&#34;https://github.com/nxp-imx/linux-imx/blob/29549c7073bf72cfb2c4614d37de45ec36b60475/drivers/misc/ti-st/st_kim.c#L313&#34; title=&#34;download_firmware()&#34;&gt;download_firmware()&lt;/a&gt;, the firmware could be downloaded successfully:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;index 048f2fd17275..11e675f9fa9f 100644
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;--- a/drivers/misc/ti-st/st_kim.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+++ b/drivers/misc/ti-st/st_kim.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;@@ -321,7 +321,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fff;text-decoration:underline&#34;&gt;&lt;/span&gt;        len -= sizeof(struct bts_header);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        while (len &amp;gt; 0 &amp;amp;&amp;amp; ptr) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;-               pr_debug(&amp;#34; action size %d, type %d &amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d22323&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#589819&#34;&gt;+               printk(&amp;#34; action size %d, type %d &amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#589819&#34;&gt;&lt;/span&gt;                           ((struct bts_action *)ptr)-&amp;gt;size,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           ((struct bts_action *)ptr)-&amp;gt;type);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apparently the debug print changes the timing of firmware download and it seems like a flow control issue. So I probed RTS and CTS pins and found there were no signal on these two pins during the download.&lt;/p&gt;
&lt;h1 id=&#34;direction-is-the-key&#34;&gt;Direction is the key&lt;/h1&gt;
&lt;p&gt;Currently we are using the pinmux and presuming the direction between i.MX8MM and Bluetooth module as below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/c2CUOS4.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;This matches the pin attributes on Bluetooth UART side from &lt;a href=&#34;https://www.ti.com/lit/gpn/wl1835mod&#34; title=&#34;WL1835MOD datasheet&#34;&gt;WL1835MOD datasheet&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/geRBaC5.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;However, on i.MX 8M Mini reference manual, &lt;code&gt;RTS_B&lt;/code&gt; is described as INPUT signal:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/L6omveD.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;whereas &lt;code&gt;CTS_B&lt;/code&gt; is described as OUTPUT signal:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/Gq7Cjcv.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Both of them have clear statement that the operation is the same regardless of whether the UART is in DTE or DCE mode. See the screenshot below on how DCE and DTE mode affects the routing of external signals to the UART model:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/kgZBGWQ.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;What makes it even confusing is, on i.MX 8QuadMax reference manual, these two pins have opposite directions - &lt;code&gt;RTS_B&lt;/code&gt; is O (output) and &lt;code&gt;CTS_B&lt;/code&gt; is I (input):&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/yR82pvg.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;In our use case, Bluetooth UART is definitely DTE, so UART module on i.MX 8M Mini side should be in DCE mode. Hence, &lt;code&gt;RTS_B&lt;/code&gt; should be an input signal and &lt;code&gt;CTS_B&lt;/code&gt; should be a output. The correct connection should be:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/8WvsS9Z.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;the-fix&#34;&gt;The fix&lt;/h1&gt;
&lt;p&gt;Tried to swap &lt;code&gt;RTS_B&lt;/code&gt; and &lt;code&gt;CTS_B&lt;/code&gt; pins in pinmux but it didn&amp;rsquo;t work. Confirmed with FAE that these two pins cannot be swapped by pinmux. So we ended up by changing the layout of hardware to make them have correct directions.&lt;/p&gt;
&lt;h1 id=&#34;similar-to-imx6&#34;&gt;Similar to i.MX6&lt;/h1&gt;
&lt;p&gt;UART on i.MX 8M Mini is much more similar to UART on i.MX6, so the same confusing happens there as well. See the following posts as reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community.nxp.com/docs/DOC-97509&#34;&gt;https://community.nxp.com/docs/DOC-97509&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.nxp.com/thread/326489&#34;&gt;https://community.nxp.com/thread/326489&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
</description>
    </item><item>
      <title>双休日｜我是一台永动机</title>
      <link>https://blog.lancitou.net/i-am-a-perpetual-motion-machine/</link>
      <pubDate>Wed, 31 May 2023 11:15:21 +0000</pubDate><author>Linda Ye</author>
      
      <guid>https://blog.lancitou.net/i-am-a-perpetual-motion-machine/</guid>
      <description>&lt;p&gt;近几日， 娃睡眠比较好，从晚上七点睡到早上六点，只要不是半夜哭醒吵着要出门转转，我没有更多要求了。&lt;/p&gt;
&lt;p&gt;周六的娃娃牌闹钟在六点准时响，好像小孩睡醒不需要缓冲，前一秒还在睡梦中，后一秒“噌”就爬起来喊爸爸妈妈，如果我俩不吭声（清晨缓冲中），娃就自己在小床上蹦蹦跳跳玩起来了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/8uXrwc8.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;看了眼天气，晴天必须出门。奥克兰的冬天多雨， 潮湿阴冷。但凡周末有个晴天，户外公园沙滩都是人，反之则涌在商场里避雨。&lt;/p&gt;
&lt;p&gt;九点出发去市区参加 “Africa Day”公共活动，非洲鼓和非洲舞蹈，缺一不可。除了独舞，还邀请所有人到场地中间一起蹦迪。没有人能抵挡这份热情，大人小孩都跟着音乐跳起来。平日在家听到音乐就点头的娃自然不能错过这次机会，还遇到一个两岁的小姐姐过来击掌。跳舞、爬高低、见小朋友，一上午四肢和大脑都在忙碌，回家路上坐车里拿着饼干就睡着了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/aXtXI2y.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;但“好景不长”，到家转场至小床时就醒了，继续在家蹦迪，剩下我俩顶着黑眼圈，一整个以“身体坐直，大脑休眠”的神态陪着小家伙。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/fT8wrdc.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;周日依然六点起床（苍天啊），阴天迫使我们转去商场遛娃。&lt;/p&gt;
&lt;p&gt;逛了两家超市，娃在伸手够到的区域摸个遍，小机灵鬼还总要抱抱来节省体力。会选喜欢的吐司和好吃的果泥，放在购物车里过过瘾。喜欢埋头推着购物车走，车停就着急。要求提三升的牛奶，冰凉凉的感觉很新鲜。一直指着天花板说“Dodo”（婴语：气球），是因为记得圣诞期间这里高高悬挂着节日装饰气球。&lt;/p&gt;
&lt;p&gt;商家的“坏心眼”是总喜欢把孩子们喜欢的东西放在低处，比如抱熊毛毯，娃不经意间就抱起一个亲亲拍拍不撒手。排队结账时，先生总得单独拿出几包果泥走自助快速通道先买单，因为娃迫不及待要把果泥连同包装袋往嘴里塞。三五分钟后，两袋果泥不见踪影。用先生的话形容，“总有几袋果泥不能活着走出停车场”……&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/c7qqslB.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;心想逛了一早上超市，吃完午饭该睡了吧。先生眼皮先打架，娃的战斗力看起来却还是五颗星。按照“双职工独立带娃不成文规定”，我让先生先去小眯一小时再来换岗。&lt;/p&gt;
&lt;p&gt;带娃骑了车，拍拍球，玩玩滑梯，讲完故事之后，小家伙丝毫没有睡意，因为一抱他起来就要挣扎着下地走。无奈只好指明去房间的路，让他去“骚扰”爸爸。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/AUcO97U.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;换岗后，我的眼皮巨沉，门外“爸爸爸爸”的声音虽然没停过，但我逐渐也听不见了。等我醒来，接近下午四点，我们也放弃让他午睡了，趁着下午茶时间，让他多吃点，这个小小身体应该是撑不到晚饭时间的。&lt;/p&gt;
&lt;p&gt;快速洗了澡，刷完牙，虽然身体还是扭动，小嘴喳喳说不停，抱着在门外看会儿亮起的路灯和爬升的月亮，不一会儿就睡着了。五点半正式没电。这一觉后来睡到第二天早上六点钟。&lt;/p&gt;
&lt;p&gt;得益于娃提早睡觉，我俩终于同频吃上了不需要着急的晚饭。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/pBedIwj.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;所以说，风里雨里，遛娃不要心软，否则吃苦的是自己。&lt;/p&gt;
</description>
    </item><item>
      <title>升级打怪 | 幼儿急疹</title>
      <link>https://blog.lancitou.net/roseola/</link>
      <pubDate>Tue, 30 May 2023 10:46:24 +0000</pubDate><author>Linda Ye</author>
      
      <guid>https://blog.lancitou.net/roseola/</guid>
      <description>&lt;p&gt;之前看过不少妈妈分享宝宝们得幼儿急疹的情况以及如何应对，等轮到自家娃时，还是措手不及。&lt;/p&gt;
&lt;p&gt;周四下午错过幼儿园两个电话和一条短信通知，开完会赶紧回拨，老师说宝宝发烧，但吃了药，情况稳定，希望我们尽早接回去。半小时后去到幼儿园，小家伙精神还不错，老师说吃得也很好，几小时前突然要抱，哼哼唧唧，量了体温才知道是不舒服。&lt;/p&gt;
&lt;p&gt;接回家先睡觉，醒来后体温恢复正常。我俩想着是不是长牙的原因，因为他每次长牙必发烧，好在只是夜里低烧，睡一觉到白天就恢复了。这个情况跟长牙很像，周五早上又变成精神小伙，决定继续送去幼儿园。&lt;/p&gt;
&lt;p&gt;午饭后再次接到老师电话，说小家伙还是发烧了，困难的是当时我必须留在办公室参加全天的会议，先生打算把娃接回来之后，请半天假陪他。下午我抽空打电话问先生，宝宝情况怎么样？他说感觉比昨天更严重一些，好在睡着了，且应该能睡几小时，省去他请假。后来这一整个半天加晚上，小家伙都在睡眠中恢复，偶尔睡醒喝点水。我们夜里也定时起来测他的体温，幸好没有升温。&lt;/p&gt;
&lt;p&gt;周六早上看到小家伙眼角和耳根有些红疹，随即检查了全身，胸口、肚子和背部也有浅浅的稀疏红疹，心想两岁以内的幼儿急诊大概就这么来了？烧退疹出，不痛不痒。&lt;/p&gt;
&lt;p&gt;第二天疹子密布前胸后背，连成片，非颗粒状，凸起的手感不强，颜色属于浅红色，区域没有扩散，视觉冲击力比较温柔，不知是不是因为自己娃的原因。第三天疹子没有增多，且有消退的趋势。看着他一直能吃能玩能睡，就没有特别担心。不记得疹子大概是第几天完全消退，但一周内恢复是没有问题的。&lt;/p&gt;
&lt;p&gt;恭喜再次闯关成功，免疫力更上一层楼。&lt;/p&gt;
&lt;p&gt;至于之前的闯关经验，包括 COVID-19，Tummy Bug，疑似手足口和其他。特别是七个月刚上幼儿园时，在这个吃吃玩具、摸爬无惧的环境里，正式开始升级免疫系统。大鼻涕挂了三个月，柔软的抽纸供不应求；半夜呕吐两次，凌晨四点开车去看急诊，吃了药之后开心在病床上玩；嘴巴里溃疡横生，口水流成河，补水成了第一要务……再然后，自身抗病毒能力越来越强，恢复得也越来越快，咳嗽流鼻涕倒成了小意思。&lt;/p&gt;
&lt;p&gt;我们陪着娃攒了不少经验。日常生活中，我们带着他一起勤洗手，感冒发烧注意隔离；多喝水防止脱水，其他不重要；不论是凭借直觉还是经验，只要对小宝宝生病情况有一点担忧，就去看医生，小孩无小事。对于这个年龄，医院诊断也会优先。&lt;/p&gt;
&lt;p&gt;愿所有小孩少生病，多健康。&lt;/p&gt;
</description>
    </item></channel>
</rss>
