From 0b989422b94a2d00579dbb9cca0b6b16f2170f98 Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 8 Oct 2026 17:06:56 +0800 Subject: [PATCH] input/osk: add Chinese keyboard pages (pinyin initial index) The on-screen keyboard behind the menu's text entries has pages for Japanese kana and Korean since the extended-IME work, but nothing for Chinese - which needs a different shape, since 3500+ common characters cannot fit a 4x11 grid the way 24 jamo or 92 kana can. Rather than a pinyin IME, this adds a two-level layout: * an index page holding a-z, and * 63 character pages, one per pinyin initial (a, b1-b3, c1-c3, ...), each holding 30 of the most common characters for that initial The character set is not guesswork: it is counted from the game titles that appear in playlists (8171 titles, 1515 distinct hanzi, 21521 occurrences), ordered by frequency, so the first page of each initial holds the characters people look for most. Tapping an initial on the index jumps to that initial's first page, tapping a character appends it to the line, and the house key returns to the index. Characters are whole UTF-8 codepoints, so unlike Korean no composition step is needed. Gated behind HAVE_LANGEXTRA like the other extra pages, so builds without it are unaffected. Verified: compiles, and all 1515 characters are present in the resulting library by byte comparison. No on-device run - the test device's ROM blocks adb input injection. --- input/chinese_osk_pages.h | 479 +++++++++++++++++++++++++++++++++++ input/input_driver.c | 33 +++ input/input_osk.h | 70 +++++ input/input_osk_utf8_pages.h | 2 + menu/menu_driver.c | 383 ++++++++++++++++++++++++++++ 5 files changed, 967 insertions(+) create mode 100644 input/chinese_osk_pages.h diff --git a/input/chinese_osk_pages.h b/input/chinese_osk_pages.h new file mode 100644 index 000000000000..bd8aeef3b402 --- /dev/null +++ b/input/chinese_osk_pages.h @@ -0,0 +1,479 @@ +/* 自动生成 —— 不要手工改 */ +/* 由 生成中文键盘页.py 生成 */ +/* 语料: /home/amd/手机备份/Redmi10X-playlists/加工版 */ +/* 不同汉字 1515 个,出现 21521 次 */ +#ifndef CHINESE_OSK_PAGES_H +#define CHINESE_OSK_PAGES_H + +/* a: 9 字 → 1 页 */ +static const char *chinese_page_a_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "奥","阿","暗","爱","艾","安","埃","岸","案","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* b: 76 字 → 3 页 */ +static const char *chinese_page_b_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "版","宝","霸","兵","部","白","暴","爆","贝","不","⏎", + "巴","比","伴","蝙","别","堡","变","棒","本","波","⇩", + "邦","博","班","边","鞭","笔","备","冰","布","标","⌂", +}; + +static const char *chinese_page_b_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "避","北","宾","柏","八","彼","吧","被","板","臂","⏎", + "镖","摆","必","怖","胞","半","飙","包","弊","碑","⇩", + "碧","豹","保","榜","毕","扮","并","奔","鲍","弁","⌂", +}; + +static const char *chinese_page_b_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "背","表","播","报","百","坂","簿","便","补","步","⏎", + "壁","笨","伯","杯","饼","蹦","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* c: 76 字 → 3 页 */ +static const char *chinese_page_c_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "传","超","车","城","场","出","彩","村","仓","虫","⏎", + "冲","次","成","仇","创","财","船","茶","承","残","⇩", + "宠","丛","吃","赤","纯","裁","齿","藏","才","川","⌂", +}; + +static const char *chinese_page_c_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "查","沉","苍","产","叉","朝","察","厨","惩","存","⏎", + "初","巢","窗","痴","拆","除","垂","草","蚕","磁","⇩", + "乘","充","潮","橙","常","菜","辰","处","错","翠","⌂", +}; + +static const char *chinese_page_c_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "程","厂","彻","刺","叱","池","猜","辞","丑","餐","⏎", + "串","锤","柴","崔","曹","触","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* d: 87 字 → 3 页 */ +static const char *chinese_page_d_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "大","的","斗","队","地","袋","动","达","弹","岛","⏎", + "电","打","盗","代","道","第","对","德","帝","登","⇩", + "带","哆","多","敌","迪","钓","蒂","东","弟","当","⌂", +}; + +static const char *chinese_page_d_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "豆","底","都","点","诞","度","丁","躲","刀","断","⏎", + "店","独","导","蛋","巅","到","答","丹","谍","倒","⇩", + "典","毒","顿","嗒","冻","铛","冬","殿","赌","定","⌂", +}; + +static const char *chinese_page_d_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "夺","洞","段","单","胆","沌","盾","抵","督","逗","⏎", + "雕","杜","档","帶","党","耽","读","貂","调","滴","⇩", + "跌","荡","狄","敦","待","笛","肚","","","","⌂", +}; + +/* e: 9 字 → 1 页 */ +static const char *chinese_page_e_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "恶","尔","二","俄","儿","鹅","饿","恩","鳄","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* f: 53 字 → 2 页 */ +static const char *chinese_page_f_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "风","法","方","复","飞","蜂","疯","夫","封","蝠","⏎", + "房","斧","番","反","发","腐","繁","福","菲","放","⇩", + "凤","峰","符","罚","返","佛","分","付","饭","愤","⌂", +}; + +static const char *chinese_page_f_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "翻","防","弗","啡","肥","坊","犯","非","覆","范","⏎", + "逢","翡","腹","访","浮","服","附","富","负","妃","⇩", + "锋","伐","粉","","","","","","","","⌂", +}; + +/* g: 64 字 → 3 页 */ +static const char *chinese_page_g_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "怪","国","高","光","格","工","鬼","龟","刚","改","⏎", + "钢","宫","古","公","狗","哥","滚","攻","咕","馆","⇩", + "归","歌","冠","革","管","戈","敢","糕","孤","过","⌂", +}; + +static const char *chinese_page_g_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "谷","感","盖","灌","果","故","钩","棍","个","贵","⏎", + "绀","鼓","柜","阁","顾","关","葛","嘎","诡","伽","⇩", + "宮","搞","罐","各","港","雇","官","丐","功","杆","⌂", +}; + +static const char *chinese_page_g_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "干","赶","硅","共","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* h: 72 字 → 3 页 */ +static const char *chinese_page_h_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "化","汉","火","幻","海","魂","合","黑","花","河","⏎", + "红","航","孩","和","皇","会","回","惑","徽","黄","⇩", + "虎","后","华","毁","换","哈","虹","号","混","划","⌂", +}; + +static const char *chinese_page_h_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "豪","唤","活","护","滑","荒","好","伙","狐","何","⏎", + "环","轰","坏","欢","画","横","慧","猴","亨","辉","⇩", + "话","谎","户","浒","霍","凰","绘","恒","簧","糊","⌂", +}; + +static const char *chinese_page_h_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "呼","衡","货","昏","湖","悍","获","诃","函","汗","⏎", + "婚","核","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* j: 124 字 → 5 页 */ +static const char *chinese_page_j_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "机","级","界","记","金","简","剑","击","街","警","⏎", + "极","决","将","截","家","加","精","纪","杰","结","⇩", + "箭","际","甲","军","激","救","节","君","间","进","⌂", +}; + +static const char *chinese_page_j_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "究","吉","集","境","计","角","晶","假","俱","教","⏎", + "技","筋","劲","鲛","镜","绝","基","舰","嘉","锦","⇩", + "惊","竞","京","季","迹","僵","具","禁","降","居","⌂", +}; + +static const char *chinese_page_j_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "觉","急","继","几","聚","剧","解","跤","巨","经","⏎", + "荆","旧","九","件","狙","寂","静","阱","脚","局","⇩", + "卷","寄","姬","迦","辑","爵","交","见","戒","蕉","⌂", +}; + +static const char *chinese_page_j_4[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "检","缉","肩","鸡","姐","烬","茄","酱","驾","菌","⏎", + "钧","抉","江","伎","棘","近","郊","尽","將","竟","⇩", + "井","介","剪","胶","焦","稽","及","贱","巾","奖","⌂", +}; + +static const char *chinese_page_j_5[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "减","脊","紧","建","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* k: 36 字 → 2 页 */ +static const char *chinese_page_k_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "克","空","口","可","卡","块","快","狂","恐","柯","⏎", + "客","凯","科","孔","开","考","酷","刻","库","况","⇩", + "骷","铠","控","昆","矿","扩","课","肯","看","咖","⌂", +}; + +static const char *chinese_page_k_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "抗","康","窟","珂","轲","魁","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* l: 108 字 → 4 页 */ +static const char *chinese_page_l_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "龙","罗","力","里","洛","乐","雷","拉","老","灵","⏎", + "林","来","猎","狼","郎","鲁","历","量","列","联","⇩", + "绿","利","陆","略","落","路","兰","啦","烈","旅","⌂", +}; + +static const char *chinese_page_l_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "乱","轮","令","蓝","连","录","篮","噜","侣","流","⏎", + "零","浪","领","莱","露","楼","螺","雳","莉","六","⇩", + "丽","理","裂","炼","立","蜡","铃","劳","髅","凌","⌂", +}; + +static const char *chinese_page_l_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "岭","链","蕾","邻","离","俩","黎","卢","李","另","⏎", + "恋","料","朗","牢","练","了","亮","律","络","粒","⇩", + "溜","麟","鹿","临","魉","莲","垄","赖","类","勒","⌂", +}; + +static const char *chinese_page_l_4[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "垒","隆","率","仑","婪","廊","伦","逻","论","龄","⏎", + "冷","璐","裸","礼","烂","两","泪","戮","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* m: 60 字 → 2 页 */ +static const char *chinese_page_m_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "魔","冒","梦","马","美","猫","门","迷","明","米","⏎", + "摩","麻","命","秘","姆","牧","灭","曼","盟","码","⇩", + "木","模","面","蜜","目","密","漫","们","名","描","⌂", +}; + +static const char *chinese_page_m_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "谜","漠","谋","玛","麦","妙","帽","默","蒙","魅","⏎", + "墓","妹","末","毛","梅","迈","鸣","满","棉","喵","⇩", + "莫","茂","蚂","脉","抹","民","绵","弥","霉","摸","⌂", +}; + +/* n: 32 字 → 2 页 */ +static const char *chinese_page_n_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "女","怒","尼","年","鸟","拟","纳","男","南","内","⏎", + "逆","能","你","娜","诺","纽","脑","努","那","妮","⇩", + "农","乃","拿","奈","难","涅","扭","念","瑙","囊","⌂", +}; + +static const char *chinese_page_n_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "酿","泥","","","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* o: 3 字 → 1 页 */ +static const char *chinese_page_o_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "欧","偶","鸥","","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* p: 44 字 → 2 页 */ +static const char *chinese_page_p_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "篇","泡","派","片","皮","平","判","破","披","霹","⏎", + "烹","牌","普","朋","拼","碰","盘","品","潘","炮","⇩", + "谱","庞","帕","啪","喷","扑","篷","爬","拍","趴","⌂", +}; + +static const char *chinese_page_p_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "匹","屏","配","叛","频","铺","苹","蓬","培","排","⏎", + "乒","乓","魄","跑","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* q: 62 字 → 3 页 */ +static const char *chinese_page_q_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "球","器","奇","拳","骑","强","棋","枪","雀","曲","⏎", + "气","全","前","青","七","去","侵","情","蚯","鍬","⇩", + "千","犬","丘","漆","俏","区","起","群","企","琼","⌂", +}; + +static const char *chinese_page_q_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "潜","泉","祈","勤","期","启","庆","琴","趣","请","⏎", + "驱","抢","其","敲","囚","锹","麒","权","轻","乔","⇩", + "圈","汽","亲","蔷","遣","琪","崎","擎","乞","秋","⌂", +}; + +static const char *chinese_page_q_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "切","脐","","","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* r: 21 字 → 1 页 */ +static const char *chinese_page_r_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "人","忍","热","日","任","刃","饪","荣","肉","燃","⏎", + "融","入","让","如","瑞","然","饶","染","认","仁","⇩", + "软","","","","","","","","","","⌂", +}; + +/* s: 122 字 → 5 页 */ +static const char *chinese_page_s_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "士","神","说","世","斯","赛","三","生","圣","双","⏎", + "鼠","兽","时","少","石","沙","色","师","使","手","⇩", + "水","视","始","塞","森","史","四","闪","思","事","⌂", +}; + +static const char *chinese_page_s_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "速","数","蛇","上","术","失","索","死","尸","实","⏎", + "松","式","食","苏","山","室","十","杀","守","市","⇩", + "属","莎","书","射","摔","寺","烧","身","审","狮","⌂", +}; + +static const char *chinese_page_s_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "所","萨","示","诗","赏","素","授","矢","首","胜","⏎", + "饲","叔","是","社","试","升","缩","送","声","束","⇩", + "尚","随","熟","锁","伞","似","侍","瑟","商","寿","⌂", +}; + +static const char *chinese_page_s_4[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "收","骚","碎","算","深","善","赎","驶","售","丝","⏎", + "渗","蔬","嗦","树","逝","谁","匙","砂","嫂","薯","⇩", + "宿","誓","瘦","傻","殊","帅","隼","塾","司","扇","⌂", +}; + +static const char *chinese_page_s_5[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "私","狩","","","","","","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* t: 67 字 → 3 页 */ +static const char *chinese_page_t_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "天","太","特","铁","头","团","兔","探","童","堂","⏎", + "跳","挑","塔","托","唐","坦","通","突","体","台","⇩", + "脱","踢","逃","泰","淘","吞","庭","田","同","桃","⌂", +}; + +static const char *chinese_page_t_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "陀","滩","屠","骰","条","提","豚","统","町","徒","⏎", + "霆","图","甜","土","偷","梯","透","涂","讨","汤","⇩", + "藤","推","填","拓","贪","腿","跆","退","艇","谭","⌂", +}; + +static const char *chinese_page_t_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "谈","塘","途","厅","他","糖","贴","","","","⏎", + "","","","","","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* w: 54 字 → 2 页 */ +static const char *chinese_page_w_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "王","物","纹","外","无","武","卫","网","屋","伍","⏎", + "舞","务","瓦","未","丸","蛙","巫","完","危","我","⇩", + "威","文","万","悟","玩","五","亡","维","望","位","⌂", +}; + +static const char *chinese_page_w_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "问","顽","薇","挽","闻","伟","魍","涡","味","娃","⏎", + "围","蔚","湾","微","午","尉","尾","卧","温","吾","⇩", + "坞","伪","乌","魏","","","","","","","⌂", +}; + +/* x: 84 字 → 3 页 */ +static const char *chinese_page_x_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "险","小","星","雄","新","血","西","想","侠","行","⏎", + "戏","旋","修","形","械","系","心","学","线","刑","⇩", + "雪","巡","仙","兄","型","邪","限","寻","熊","校","⌂", +}; + +static const char *chinese_page_x_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "先","象","现","下","幸","袭","携","信","晓","喜","⏎", + "细","虚","笑","习","辛","写","相","醒","秀","陷","⇩", + "勋","嚣","讯","漩","吸","乡","朽","逊","穴","香","⌂", +}; + +static const char *chinese_page_x_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "选","消","闲","协","峡","享","胁","驯","暇","叙","⏎", + "训","禧","向","显","夏","席","谢","翔","像","希","⇩", + "锡","欣","稀","箱","","","","","","","⌂", +}; + +/* y: 117 字 → 4 页 */ +static const char *chinese_page_y_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "英","焰","与","语","游","原","影","勇","妖","夜","⏎", + "野","异","银","一","亚","月","业","员","伊","鸭","⇩", + "音","运","园","佑","宇","阳","眼","元","鱼","翼","⌂", +}; + +static const char *chinese_page_y_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "牙","洋","印","约","越","云","狱","议","幽","育","⏎", + "源","义","圆","炎","耀","忆","有","译","友","意","⇩", + "要","域","遗","易","蚓","永","叶","言","院","摇","⌂", +}; + +static const char *chinese_page_y_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "鹰","硬","樱","雅","引","远","猿","演","阴","液","⏎", + "愿","鸦","医","遥","钥","艺","预","吟","誉","亿","⇩", + "佣","用","押","岩","依","养","蚁","杨","严","雨","⌂", +}; + +static const char *chinese_page_y_4[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "驿","颜","移","营","余","羊","役","跃","验","厌","⏎", + "隐","瑜","油","邀","又","益","饮","也","仰","央","⇩", + "因","援","缘","裔","遇","婴","烟","","","","⌂", +}; + +/* z: 135 字 → 5 页 */ +static const char *chinese_page_z_1[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "战","之","者","子","章","终","重","最","志","装","⏎", + "珠","转","炸","中","真","作","正","职","争","足","⇩", + "置","种","宙","总","长","贼","智","组","奏","字","⌂", +}; + +static const char *chinese_page_z_2[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "侦","指","走","制","族","追","撞","蜘","蛛","钻","⏎", + "杂","镇","造","召","主","周","兹","再","致","侏","⇩", + "咒","在","桌","札","詹","冑","铸","支","壮","卓","⌂", +}; + +static const char *chinese_page_z_3[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "钟","踪","站","纸","捉","找","只","诸","紫","展","⏎", + "祖","至","罪","直","斩","猪","知","早","综","砖","⇩", + "抓","植","祝","砸","助","张","朱","佐","资","震","⌂", +}; + +static const char *chinese_page_z_4[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "诅","占","阵","泽","糟","针","绽","质","胄","枕","⏎", + "则","振","滋","庄","闸","择","逐","织","遮","卒","⇩", + "自","蒸","证","咤","拯","妆","枝","专","座","哲","⌂", +}; + +static const char *chinese_page_z_5[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "载","帐","杖","啄","尊","宅","州","烛","蚤","丈","⏎", + "招","状","诛","沼","账","","","","","","⇩", + "","","","","","","","","","","⌂", +}; + +/* 声母索引页 */ +static const char *chinese_index_grid[] = { + "1","2","3","4","5","6","7","8","9","0","⇦", + "a","b","c","d","e","f","g","h","i","j","⏎", + "k","l","m","n","o","p","q","r","s","t","⇩", + "u","v","w","x","y","z","'","_",".","⌂"}; + +#endif diff --git a/input/input_driver.c b/input/input_driver.c index 8dd49349d750..3b42b3bb2872 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -7865,6 +7865,21 @@ bool input_osk_native_available(void) #endif } +#ifdef HAVE_LANGEXTRA +/* The Chinese keyboard's first page for each pinyin initial, indexed by + * the initial. i, u and v have no page, and no game title starts with + * one. */ +static const enum osk_type osk_chinese_first_page[] = { + OSK_CHINESE_A_1, OSK_CHINESE_B_1, OSK_CHINESE_C_1, OSK_CHINESE_D_1, + OSK_CHINESE_E_1, OSK_CHINESE_F_1, OSK_CHINESE_G_1, OSK_CHINESE_H_1, + OSK_TYPE_UNKNOWN, OSK_CHINESE_J_1, OSK_CHINESE_K_1, OSK_CHINESE_L_1, + OSK_CHINESE_M_1, OSK_CHINESE_N_1, OSK_CHINESE_O_1, OSK_CHINESE_P_1, + OSK_CHINESE_Q_1, OSK_CHINESE_R_1, OSK_CHINESE_S_1, OSK_CHINESE_T_1, + OSK_TYPE_UNKNOWN, OSK_TYPE_UNKNOWN, OSK_CHINESE_W_1, OSK_CHINESE_X_1, + OSK_CHINESE_Y_1, OSK_CHINESE_Z_1, +}; +#endif + void input_event_osk_append( input_keyboard_line_t *keyboard_line, enum osk_type *osk_idx, @@ -7880,6 +7895,16 @@ void input_event_osk_append( input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); else if (memcmp(word, "\xe2\x8f\x8e", 4) == 0) /* return character */ input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); + else if ( *osk_idx >= OSK_CHINESE_INDEX + && ( memcmp(word, "\xe2\x87\xa7", 4) == 0 /* up arrow */ + || memcmp(word, "\xe2\x8c\x82", 4) == 0)) /* house */ + { + /* Chinese pages come last in the enum, so this covers all of + * them. On a page it is "back to the initial index"; the index + * itself is its own parent, so there it leaves the keyboard. */ + *osk_idx = (*osk_idx == OSK_CHINESE_INDEX) + ? OSK_LOWERCASE_LATIN : OSK_CHINESE_INDEX; + } else if (memcmp(word, "\xe2\x87\xa7", 4) == 0) /* up arrow */ *osk_idx = OSK_UPPERCASE_LATIN; else if (memcmp(word, "\xe2\x87\xa9", 4) == 0) /* down arrow */ @@ -7907,6 +7932,14 @@ void input_event_osk_append( unsigned character = *((unsigned*)word) | 0x01000000; input_keyboard_line_event(&input_driver_st, keyboard_line, character); } + else if ( *osk_idx == OSK_CHINESE_INDEX + && len == 1 && word[0] >= 'a' && word[0] <= 'z') + { + /* an initial on the index page: its first page */ + enum osk_type first = osk_chinese_first_page[word[0] - 'a']; + if (first != OSK_TYPE_UNKNOWN) + *osk_idx = first; + } #else if (memcmp(word, "Bksp", 5) == 0) input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); diff --git a/input/input_osk.h b/input/input_osk.h index 19d742fa4d90..d24500560186 100644 --- a/input/input_osk.h +++ b/input/input_osk.h @@ -44,6 +44,76 @@ enum osk_type OSK_KATAKANA_PAGE1, OSK_KATAKANA_PAGE2, OSK_KOREAN_PAGE1, + /* One value per Chinese key page: the pinyin initial index page, then + * every page of every initial, in the order of chinese_osk_pages.h. + * A value here is the page selector - it is what the next-page key, + * the menu's page triggers and the grid switch all step through - so + * an initial with more than one page needs more than one value. + * i, u and v have no page: no game title uses them as an initial. */ + OSK_CHINESE_INDEX, + OSK_CHINESE_A_1, + OSK_CHINESE_B_1, + OSK_CHINESE_B_2, + OSK_CHINESE_B_3, + OSK_CHINESE_C_1, + OSK_CHINESE_C_2, + OSK_CHINESE_C_3, + OSK_CHINESE_D_1, + OSK_CHINESE_D_2, + OSK_CHINESE_D_3, + OSK_CHINESE_E_1, + OSK_CHINESE_F_1, + OSK_CHINESE_F_2, + OSK_CHINESE_G_1, + OSK_CHINESE_G_2, + OSK_CHINESE_G_3, + OSK_CHINESE_H_1, + OSK_CHINESE_H_2, + OSK_CHINESE_H_3, + OSK_CHINESE_J_1, + OSK_CHINESE_J_2, + OSK_CHINESE_J_3, + OSK_CHINESE_J_4, + OSK_CHINESE_J_5, + OSK_CHINESE_K_1, + OSK_CHINESE_K_2, + OSK_CHINESE_L_1, + OSK_CHINESE_L_2, + OSK_CHINESE_L_3, + OSK_CHINESE_L_4, + OSK_CHINESE_M_1, + OSK_CHINESE_M_2, + OSK_CHINESE_N_1, + OSK_CHINESE_N_2, + OSK_CHINESE_O_1, + OSK_CHINESE_P_1, + OSK_CHINESE_P_2, + OSK_CHINESE_Q_1, + OSK_CHINESE_Q_2, + OSK_CHINESE_Q_3, + OSK_CHINESE_R_1, + OSK_CHINESE_S_1, + OSK_CHINESE_S_2, + OSK_CHINESE_S_3, + OSK_CHINESE_S_4, + OSK_CHINESE_S_5, + OSK_CHINESE_T_1, + OSK_CHINESE_T_2, + OSK_CHINESE_T_3, + OSK_CHINESE_W_1, + OSK_CHINESE_W_2, + OSK_CHINESE_X_1, + OSK_CHINESE_X_2, + OSK_CHINESE_X_3, + OSK_CHINESE_Y_1, + OSK_CHINESE_Y_2, + OSK_CHINESE_Y_3, + OSK_CHINESE_Y_4, + OSK_CHINESE_Z_1, + OSK_CHINESE_Z_2, + OSK_CHINESE_Z_3, + OSK_CHINESE_Z_4, + OSK_CHINESE_Z_5, #endif OSK_TYPE_LAST }; diff --git a/input/input_osk_utf8_pages.h b/input/input_osk_utf8_pages.h index 371c2e6f56f6..3a1393c31b83 100644 --- a/input/input_osk_utf8_pages.h +++ b/input/input_osk_utf8_pages.h @@ -69,3 +69,5 @@ static const char *korean_page1_grid[] = { "ㅂ","ㅈ","ㄷ","ㄱ","ㅅ","ㅛ","ㅕ","ㅑ","ㅐ","ㅔ","⏎", "ㅁ","ㄴ","ㅇ","ㄹ","ㅎ","ㅗ","ㅓ","ㅏ","ㅣ","ㅒ","ㅖ", "ㅋ","ㅌ","ㅊ","ㅍ","ㅠ","ㅜ","ㅡ"," ",",",".","⊕"}; + +#include "chinese_osk_pages.h" diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 60290d7d949e..d5a7651f546d 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -2077,6 +2077,389 @@ MENU_NOINLINE static void input_event_osk_iterate(void *osk_grid, enum osk_type korean_page1_grid, sizeof(korean_page1_grid)); break; + case OSK_CHINESE_INDEX: + memcpy(osk_grid, + chinese_index_grid, + sizeof(chinese_index_grid)); + break; + + case OSK_CHINESE_A_1: + memcpy(osk_grid, + chinese_page_a_1, + sizeof(chinese_page_a_1)); + break; + + case OSK_CHINESE_B_1: + memcpy(osk_grid, + chinese_page_b_1, + sizeof(chinese_page_b_1)); + break; + + case OSK_CHINESE_B_2: + memcpy(osk_grid, + chinese_page_b_2, + sizeof(chinese_page_b_2)); + break; + + case OSK_CHINESE_B_3: + memcpy(osk_grid, + chinese_page_b_3, + sizeof(chinese_page_b_3)); + break; + + case OSK_CHINESE_C_1: + memcpy(osk_grid, + chinese_page_c_1, + sizeof(chinese_page_c_1)); + break; + + case OSK_CHINESE_C_2: + memcpy(osk_grid, + chinese_page_c_2, + sizeof(chinese_page_c_2)); + break; + + case OSK_CHINESE_C_3: + memcpy(osk_grid, + chinese_page_c_3, + sizeof(chinese_page_c_3)); + break; + + case OSK_CHINESE_D_1: + memcpy(osk_grid, + chinese_page_d_1, + sizeof(chinese_page_d_1)); + break; + + case OSK_CHINESE_D_2: + memcpy(osk_grid, + chinese_page_d_2, + sizeof(chinese_page_d_2)); + break; + + case OSK_CHINESE_D_3: + memcpy(osk_grid, + chinese_page_d_3, + sizeof(chinese_page_d_3)); + break; + + case OSK_CHINESE_E_1: + memcpy(osk_grid, + chinese_page_e_1, + sizeof(chinese_page_e_1)); + break; + + case OSK_CHINESE_F_1: + memcpy(osk_grid, + chinese_page_f_1, + sizeof(chinese_page_f_1)); + break; + + case OSK_CHINESE_F_2: + memcpy(osk_grid, + chinese_page_f_2, + sizeof(chinese_page_f_2)); + break; + + case OSK_CHINESE_G_1: + memcpy(osk_grid, + chinese_page_g_1, + sizeof(chinese_page_g_1)); + break; + + case OSK_CHINESE_G_2: + memcpy(osk_grid, + chinese_page_g_2, + sizeof(chinese_page_g_2)); + break; + + case OSK_CHINESE_G_3: + memcpy(osk_grid, + chinese_page_g_3, + sizeof(chinese_page_g_3)); + break; + + case OSK_CHINESE_H_1: + memcpy(osk_grid, + chinese_page_h_1, + sizeof(chinese_page_h_1)); + break; + + case OSK_CHINESE_H_2: + memcpy(osk_grid, + chinese_page_h_2, + sizeof(chinese_page_h_2)); + break; + + case OSK_CHINESE_H_3: + memcpy(osk_grid, + chinese_page_h_3, + sizeof(chinese_page_h_3)); + break; + + case OSK_CHINESE_J_1: + memcpy(osk_grid, + chinese_page_j_1, + sizeof(chinese_page_j_1)); + break; + + case OSK_CHINESE_J_2: + memcpy(osk_grid, + chinese_page_j_2, + sizeof(chinese_page_j_2)); + break; + + case OSK_CHINESE_J_3: + memcpy(osk_grid, + chinese_page_j_3, + sizeof(chinese_page_j_3)); + break; + + case OSK_CHINESE_J_4: + memcpy(osk_grid, + chinese_page_j_4, + sizeof(chinese_page_j_4)); + break; + + case OSK_CHINESE_J_5: + memcpy(osk_grid, + chinese_page_j_5, + sizeof(chinese_page_j_5)); + break; + + case OSK_CHINESE_K_1: + memcpy(osk_grid, + chinese_page_k_1, + sizeof(chinese_page_k_1)); + break; + + case OSK_CHINESE_K_2: + memcpy(osk_grid, + chinese_page_k_2, + sizeof(chinese_page_k_2)); + break; + + case OSK_CHINESE_L_1: + memcpy(osk_grid, + chinese_page_l_1, + sizeof(chinese_page_l_1)); + break; + + case OSK_CHINESE_L_2: + memcpy(osk_grid, + chinese_page_l_2, + sizeof(chinese_page_l_2)); + break; + + case OSK_CHINESE_L_3: + memcpy(osk_grid, + chinese_page_l_3, + sizeof(chinese_page_l_3)); + break; + + case OSK_CHINESE_L_4: + memcpy(osk_grid, + chinese_page_l_4, + sizeof(chinese_page_l_4)); + break; + + case OSK_CHINESE_M_1: + memcpy(osk_grid, + chinese_page_m_1, + sizeof(chinese_page_m_1)); + break; + + case OSK_CHINESE_M_2: + memcpy(osk_grid, + chinese_page_m_2, + sizeof(chinese_page_m_2)); + break; + + case OSK_CHINESE_N_1: + memcpy(osk_grid, + chinese_page_n_1, + sizeof(chinese_page_n_1)); + break; + + case OSK_CHINESE_N_2: + memcpy(osk_grid, + chinese_page_n_2, + sizeof(chinese_page_n_2)); + break; + + case OSK_CHINESE_O_1: + memcpy(osk_grid, + chinese_page_o_1, + sizeof(chinese_page_o_1)); + break; + + case OSK_CHINESE_P_1: + memcpy(osk_grid, + chinese_page_p_1, + sizeof(chinese_page_p_1)); + break; + + case OSK_CHINESE_P_2: + memcpy(osk_grid, + chinese_page_p_2, + sizeof(chinese_page_p_2)); + break; + + case OSK_CHINESE_Q_1: + memcpy(osk_grid, + chinese_page_q_1, + sizeof(chinese_page_q_1)); + break; + + case OSK_CHINESE_Q_2: + memcpy(osk_grid, + chinese_page_q_2, + sizeof(chinese_page_q_2)); + break; + + case OSK_CHINESE_Q_3: + memcpy(osk_grid, + chinese_page_q_3, + sizeof(chinese_page_q_3)); + break; + + case OSK_CHINESE_R_1: + memcpy(osk_grid, + chinese_page_r_1, + sizeof(chinese_page_r_1)); + break; + + case OSK_CHINESE_S_1: + memcpy(osk_grid, + chinese_page_s_1, + sizeof(chinese_page_s_1)); + break; + + case OSK_CHINESE_S_2: + memcpy(osk_grid, + chinese_page_s_2, + sizeof(chinese_page_s_2)); + break; + + case OSK_CHINESE_S_3: + memcpy(osk_grid, + chinese_page_s_3, + sizeof(chinese_page_s_3)); + break; + + case OSK_CHINESE_S_4: + memcpy(osk_grid, + chinese_page_s_4, + sizeof(chinese_page_s_4)); + break; + + case OSK_CHINESE_S_5: + memcpy(osk_grid, + chinese_page_s_5, + sizeof(chinese_page_s_5)); + break; + + case OSK_CHINESE_T_1: + memcpy(osk_grid, + chinese_page_t_1, + sizeof(chinese_page_t_1)); + break; + + case OSK_CHINESE_T_2: + memcpy(osk_grid, + chinese_page_t_2, + sizeof(chinese_page_t_2)); + break; + + case OSK_CHINESE_T_3: + memcpy(osk_grid, + chinese_page_t_3, + sizeof(chinese_page_t_3)); + break; + + case OSK_CHINESE_W_1: + memcpy(osk_grid, + chinese_page_w_1, + sizeof(chinese_page_w_1)); + break; + + case OSK_CHINESE_W_2: + memcpy(osk_grid, + chinese_page_w_2, + sizeof(chinese_page_w_2)); + break; + + case OSK_CHINESE_X_1: + memcpy(osk_grid, + chinese_page_x_1, + sizeof(chinese_page_x_1)); + break; + + case OSK_CHINESE_X_2: + memcpy(osk_grid, + chinese_page_x_2, + sizeof(chinese_page_x_2)); + break; + + case OSK_CHINESE_X_3: + memcpy(osk_grid, + chinese_page_x_3, + sizeof(chinese_page_x_3)); + break; + + case OSK_CHINESE_Y_1: + memcpy(osk_grid, + chinese_page_y_1, + sizeof(chinese_page_y_1)); + break; + + case OSK_CHINESE_Y_2: + memcpy(osk_grid, + chinese_page_y_2, + sizeof(chinese_page_y_2)); + break; + + case OSK_CHINESE_Y_3: + memcpy(osk_grid, + chinese_page_y_3, + sizeof(chinese_page_y_3)); + break; + + case OSK_CHINESE_Y_4: + memcpy(osk_grid, + chinese_page_y_4, + sizeof(chinese_page_y_4)); + break; + + case OSK_CHINESE_Z_1: + memcpy(osk_grid, + chinese_page_z_1, + sizeof(chinese_page_z_1)); + break; + + case OSK_CHINESE_Z_2: + memcpy(osk_grid, + chinese_page_z_2, + sizeof(chinese_page_z_2)); + break; + + case OSK_CHINESE_Z_3: + memcpy(osk_grid, + chinese_page_z_3, + sizeof(chinese_page_z_3)); + break; + + case OSK_CHINESE_Z_4: + memcpy(osk_grid, + chinese_page_z_4, + sizeof(chinese_page_z_4)); + break; + + case OSK_CHINESE_Z_5: + memcpy(osk_grid, + chinese_page_z_5, + sizeof(chinese_page_z_5)); + break; #endif case OSK_SYMBOLS_PAGE1: memcpy(osk_grid,